Mercurial > projects > ldc
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(); |