comparison dmd/template.c @ 92:70d6113eeb8c trunk

[svn r96] Updated to DMD 1.023. Regular bugfixes.
author lindquist
date Thu, 08 Nov 2007 19:13:28 +0100
parents 788401029ecf
children a7dfa0ed966c
comparison
equal deleted inserted replaced
91:3f949c6e2e9d 92:70d6113eeb8c
72 //return dynamic_cast<Tuple *>(o); 72 //return dynamic_cast<Tuple *>(o);
73 if (!o || o->dyncast() != DYNCAST_TUPLE) 73 if (!o || o->dyncast() != DYNCAST_TUPLE)
74 return NULL; 74 return NULL;
75 return (Tuple *)o; 75 return (Tuple *)o;
76 } 76 }
77
77 78
78 /*********************** 79 /***********************
79 * Try to get arg as a type. 80 * Try to get arg as a type.
80 */ 81 */
81 82
200 /**************************************** 201 /****************************************
201 */ 202 */
202 203
203 void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg) 204 void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg)
204 { 205 {
206 //printf("ObjectToCBuffer()\n");
205 Type *t = isType(oarg); 207 Type *t = isType(oarg);
206 Expression *e = isExpression(oarg); 208 Expression *e = isExpression(oarg);
207 Dsymbol *s = isDsymbol(oarg); 209 Dsymbol *s = isDsymbol(oarg);
208 Tuple *v = isTuple(oarg); 210 Tuple *v = isTuple(oarg);
209 if (t) 211 if (t)
212 { //printf("\tt: %s ty = %d\n", t->toChars(), t->ty);
210 t->toCBuffer(buf, NULL, hgs); 213 t->toCBuffer(buf, NULL, hgs);
214 }
211 else if (e) 215 else if (e)
212 e->toCBuffer(buf, hgs); 216 e->toCBuffer(buf, hgs);
213 else if (s) 217 else if (s)
214 { 218 {
215 char *p = s->ident ? s->ident->toChars() : s->toChars(); 219 char *p = s->ident ? s->ident->toChars() : s->toChars();
442 Objects *dedtypes, int flag) 446 Objects *dedtypes, int flag)
443 { MATCH m; 447 { MATCH m;
444 int dedtypes_dim = dedtypes->dim; 448 int dedtypes_dim = dedtypes->dim;
445 449
446 #if LOG 450 #if LOG
447 printf("+TemplateDeclaration::matchWithInstance(this = %p, ti = %p, flag = %d)\n", this, ti, flag); 451 printf("+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
448 #endif 452 #endif
449 453
450 #if 0 454 #if 0
451 printf("dedtypes->dim = %d, parameters->dim = %d\n", dedtypes_dim, parameters->dim); 455 printf("dedtypes->dim = %d, parameters->dim = %d\n", dedtypes_dim, parameters->dim);
452 if (ti->tiargs->dim) 456 if (ti->tiargs->dim)
484 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 488 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
485 Declaration *sparam; 489 Declaration *sparam;
486 490
487 //printf("\targument [%d]\n", i); 491 //printf("\targument [%d]\n", i);
488 #if 0 492 #if 0
489 printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null"); 493 //printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
490 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter(); 494 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
491 if (ttp) 495 if (ttp)
492 printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : ""); 496 printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : "");
493 #endif 497 #endif
494 498
495 m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam); 499 m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam);
500 //printf("\tm2 = %d\n", m2);
496 501
497 if (m2 == MATCHnomatch) 502 if (m2 == MATCHnomatch)
498 { 503 {
499 #if 0 504 #if 0
500 printf("\tmatchArg() for parameter %i failed\n", i); 505 printf("\tmatchArg() for parameter %i failed\n", i);
581 * instance. 586 * instance.
582 * If it works, then this template is at least as specialized 587 * If it works, then this template is at least as specialized
583 * as td2. 588 * as td2.
584 */ 589 */
585 590
586 TemplateInstance ti(0, ident); // create dummy template instance 591 TemplateInstance ti(0, ident); // create dummy template instance
587 Objects dedtypes; 592 Objects dedtypes;
588 593
589 #define LOG_LEASTAS 0 594 #define LOG_LEASTAS 0
590 595
591 #if LOG_LEASTAS 596 #if LOG_LEASTAS
801 /* If no match, see if there's a conversion to a delegate 806 /* If no match, see if there's a conversion to a delegate
802 */ 807 */
803 if (!m && fparam->type->toBasetype()->ty == Tdelegate) 808 if (!m && fparam->type->toBasetype()->ty == Tdelegate)
804 { 809 {
805 TypeDelegate *td = (TypeDelegate *)fparam->type->toBasetype(); 810 TypeDelegate *td = (TypeDelegate *)fparam->type->toBasetype();
806 TypeFunction *tf = (TypeFunction *)td->nextOf(); 811 TypeFunction *tf = (TypeFunction *)td->next;
807 812
808 if (!tf->varargs && Argument::dim(tf->parameters) == 0) 813 if (!tf->varargs && Argument::dim(tf->parameters) == 0)
809 { 814 {
810 m = farg->type->deduceType(scope, tf->nextOf(), parameters, &dedtypes); 815 m = farg->type->deduceType(scope, tf->next, parameters, &dedtypes);
811 if (!m && tf->nextOf()->toBasetype()->ty == Tvoid) 816 if (!m && tf->next->toBasetype()->ty == Tvoid)
812 m = MATCHconvert; 817 m = MATCHconvert;
813 } 818 }
814 //printf("\tm2 = %d\n", m); 819 //printf("\tm2 = %d\n", m);
815 } 820 }
816 821
960 TemplateTupleParameter *TemplateDeclaration::isVariadic() 965 TemplateTupleParameter *TemplateDeclaration::isVariadic()
961 { 966 {
962 return ::isVariadic(parameters); 967 return ::isVariadic(parameters);
963 } 968 }
964 969
970 /***********************************
971 * We can overload templates.
972 */
973
974 int TemplateDeclaration::isOverloadable()
975 {
976 return 1;
977 }
978
965 /************************************************* 979 /*************************************************
966 * Given function arguments, figure out which template function 980 * Given function arguments, figure out which template function
967 * to expand, and return that function. 981 * to expand, and return that function.
968 * If no match, give error message and return NULL. 982 * If no match, give error message and return NULL.
969 * Input: 983 * Input:
1150 /**** 1164 /****
1151 * Given an identifier, figure out which TemplateParameter it is. 1165 * Given an identifier, figure out which TemplateParameter it is.
1152 * Return -1 if not found. 1166 * Return -1 if not found.
1153 */ 1167 */
1154 1168
1169 int templateIdentifierLookup(Identifier *id, TemplateParameters *parameters)
1170 {
1171 for (size_t i = 0; i < parameters->dim; i++)
1172 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1173
1174 if (tp->ident->equals(id))
1175 return i;
1176 }
1177 return -1;
1178 }
1179
1155 int templateParameterLookup(Type *tparam, TemplateParameters *parameters) 1180 int templateParameterLookup(Type *tparam, TemplateParameters *parameters)
1156 { 1181 {
1157 assert(tparam->ty == Tident); 1182 assert(tparam->ty == Tident);
1158 TypeIdentifier *tident = (TypeIdentifier *)tparam; 1183 TypeIdentifier *tident = (TypeIdentifier *)tparam;
1159 //printf("\ttident = '%s'\n", tident->toChars()); 1184 //printf("\ttident = '%s'\n", tident->toChars());
1160 if (tident->idents.dim == 0) 1185 if (tident->idents.dim == 0)
1161 { 1186 {
1162 Identifier *id = tident->ident; 1187 return templateIdentifierLookup(tident->ident, parameters);
1163
1164 for (size_t i = 0; i < parameters->dim; i++)
1165 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1166
1167 if (tp->ident->equals(id))
1168 return i;
1169 }
1170 } 1188 }
1171 return -1; 1189 return -1;
1172 } 1190 }
1173 1191
1174 /* These form the heart of template argument deduction. 1192 /* These form the heart of template argument deduction.
1266 if (tparam) 1284 if (tparam)
1267 { 1285 {
1268 if (tparam->ty == Tsarray) 1286 if (tparam->ty == Tsarray)
1269 { 1287 {
1270 TypeSArray *tp = (TypeSArray *)tparam; 1288 TypeSArray *tp = (TypeSArray *)tparam;
1271 if (dim->toInteger() != tp->dim->toInteger()) 1289
1290 if (tp->dim->op == TOKvar &&
1291 ((VarExp *)tp->dim)->var->storage_class & STCtemplateparameter)
1292 { int i = templateIdentifierLookup(((VarExp *)tp->dim)->var->ident, parameters);
1293 // This code matches code in TypeInstance::deduceType()
1294 if (i == -1)
1295 goto Lnomatch;
1296 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
1297 TemplateValueParameter *tvp = tp->isTemplateValueParameter();
1298 if (!tvp)
1299 goto Lnomatch;
1300 Expression *e = (Expression *)dedtypes->data[i];
1301 if (e)
1302 {
1303 if (!dim->equals(e))
1304 goto Lnomatch;
1305 }
1306 else
1307 { Type *vt = tvp->valType->semantic(0, sc);
1308 MATCH m = (MATCH)dim->implicitConvTo(vt);
1309 if (!m)
1310 goto Lnomatch;
1311 dedtypes->data[i] = dim;
1312 }
1313 }
1314 else if (dim->toInteger() != tp->dim->toInteger())
1272 return MATCHnomatch; 1315 return MATCHnomatch;
1273 } 1316 }
1274 else if (tparam->ty == Taarray) 1317 else if (tparam->ty == Taarray)
1275 { 1318 {
1276 TypeAArray *tp = (TypeAArray *)tparam; 1319 TypeAArray *tp = (TypeAArray *)tparam;
1319 return MATCHnomatch; 1362 return MATCHnomatch;
1320 } 1363 }
1321 1364
1322 MATCH TypeAArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes) 1365 MATCH TypeAArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes)
1323 { 1366 {
1324 //printf("TypeAArray::deduceType()\n"); 1367 #if 0
1325 //printf("\tthis = %d, ", ty); print(); 1368 printf("TypeAArray::deduceType()\n");
1326 //printf("\ttparam = %d, ", tparam->ty); tparam->print(); 1369 printf("\tthis = %d, ", ty); print();
1370 printf("\ttparam = %d, ", tparam->ty); tparam->print();
1371 #endif
1327 1372
1328 // Extra check that index type must match 1373 // Extra check that index type must match
1329 if (tparam && tparam->ty == Taarray) 1374 if (tparam && tparam->ty == Taarray)
1330 { 1375 {
1331 TypeAArray *tp = (TypeAArray *)tparam; 1376 TypeAArray *tp = (TypeAArray *)tparam;
1461 TypeInstance *tp = (TypeInstance *)tparam; 1506 TypeInstance *tp = (TypeInstance *)tparam;
1462 1507
1463 //printf("tempinst->tempdecl = %p\n", tempinst->tempdecl); 1508 //printf("tempinst->tempdecl = %p\n", tempinst->tempdecl);
1464 //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl); 1509 //printf("tp->tempinst->tempdecl = %p\n", tp->tempinst->tempdecl);
1465 if (!tp->tempinst->tempdecl) 1510 if (!tp->tempinst->tempdecl)
1466 { if (!tp->tempinst->name->equals(tempinst->name)) 1511 { //printf("tp->tempinst->name = '%s'\n", tp->tempinst->name->toChars());
1467 goto Lnomatch; 1512 if (!tp->tempinst->name->equals(tempinst->name))
1513 {
1514 /* Handle case of:
1515 * template Foo(T : sa!(T), alias sa)
1516 */
1517 int i = templateIdentifierLookup(tp->tempinst->name, parameters);
1518 if (i == -1)
1519 goto Lnomatch;
1520 TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
1521 // This logic duplicates tpx->matchArg()
1522 TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
1523 if (!ta)
1524 goto Lnomatch;
1525 Dsymbol *sa = tempinst->tempdecl;
1526 if (!sa)
1527 goto Lnomatch;
1528 if (ta->specAlias && sa != ta->specAlias)
1529 goto Lnomatch;
1530 if (dedtypes->data[i])
1531 { // Must match already deduced symbol
1532 Dsymbol *s = (Dsymbol *)dedtypes->data[i];
1533
1534 if (s != sa)
1535 goto Lnomatch;
1536 }
1537 dedtypes->data[i] = sa;
1538 }
1468 } 1539 }
1469 else if (tempinst->tempdecl != tp->tempinst->tempdecl) 1540 else if (tempinst->tempdecl != tp->tempinst->tempdecl)
1470 goto Lnomatch; 1541 goto Lnomatch;
1471 1542
1472 for (int i = 0; i < tempinst->tiargs->dim; i++) 1543 for (int i = 0; i < tempinst->tiargs->dim; i++)
1828 { 1899 {
1829 m = MATCHconvert; 1900 m = MATCHconvert;
1830 if (t) 1901 if (t)
1831 { // Must match already deduced type 1902 { // Must match already deduced type
1832 1903
1904 m = MATCHexact;
1833 if (!t->equals(ta)) 1905 if (!t->equals(ta))
1834 goto Lnomatch; 1906 goto Lnomatch;
1835 } 1907 }
1836 } 1908 }
1837 1909
2985 { error("identifier '%s' is not defined", id->toChars()); 3057 { error("identifier '%s' is not defined", id->toChars());
2986 return NULL; 3058 return NULL;
2987 } 3059 }
2988 #if LOG 3060 #if LOG
2989 printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind()); 3061 printf("It's an instance of '%s' kind '%s'\n", s->toChars(), s->kind());
2990 printf("s->parent = '%s'\n", s->parent->toChars()); 3062 if (s->parent)
3063 printf("s->parent = '%s'\n", s->parent->toChars());
2991 #endif 3064 #endif
2992 withsym = scopesym->isWithScopeSymbol(); 3065 withsym = scopesym->isWithScopeSymbol();
2993 3066
2994 /* We might have found an alias within a template when 3067 /* We might have found an alias within a template when
2995 * we really want the template. 3068 * we really want the template.
3090 if (!td->isVariadic()) 3163 if (!td->isVariadic())
3091 continue; 3164 continue;
3092 } 3165 }
3093 3166
3094 dedtypes.setDim(td->parameters->dim); 3167 dedtypes.setDim(td->parameters->dim);
3168 dedtypes.zero();
3095 if (!td->scope) 3169 if (!td->scope)
3096 { 3170 {
3097 error("forward reference to template declaration %s", td->toChars()); 3171 error("forward reference to template declaration %s", td->toChars());
3098 return NULL; 3172 return NULL;
3099 } 3173 }
3100 m = td->matchWithInstance(this, &dedtypes, 0); 3174 m = td->matchWithInstance(this, &dedtypes, 0);
3175 //printf("m = %d\n", m);
3101 if (!m) // no match at all 3176 if (!m) // no match at all
3102 continue; 3177 continue;
3103 3178
3104 #if 1 3179 #if 1
3105 if (m < m_best) 3180 if (m < m_best)
3755 3830
3756 argsym = new ScopeDsymbol(); 3831 argsym = new ScopeDsymbol();
3757 argsym->parent = scy->parent; 3832 argsym->parent = scy->parent;
3758 Scope *scope = scy->push(argsym); 3833 Scope *scope = scy->push(argsym);
3759 3834
3835 unsigned errorsave = global.errors;
3836
3760 // Declare each template parameter as an alias for the argument type 3837 // Declare each template parameter as an alias for the argument type
3761 declareParameters(scope); 3838 declareParameters(scope);
3762 3839
3763 // Add members to enclosing scope, as well as this scope 3840 // Add members to enclosing scope, as well as this scope
3764 for (unsigned i = 0; i < members->dim; i++) 3841 for (unsigned i = 0; i < members->dim; i++)
3794 semantic2(sc2); 3871 semantic2(sc2);
3795 3872
3796 if (sc->func) 3873 if (sc->func)
3797 { 3874 {
3798 semantic3(sc2); 3875 semantic3(sc2);
3876 }
3877
3878 // Give additional context info if error occurred during instantiation
3879 if (global.errors != errorsave)
3880 {
3881 error("error instantiating");
3799 } 3882 }
3800 3883
3801 sc2->pop(); 3884 sc2->pop();
3802 3885
3803 scope->pop(); 3886 scope->pop();