Mercurial > projects > ldc
comparison dmd/template.c @ 336:aaade6ded589 trunk
[svn r357] Merged DMD 1.033
author | lindquist |
---|---|
date | Sat, 12 Jul 2008 19:38:31 +0200 |
parents | 2b72433d5c8c |
children | cecfee2d01a8 |
comparison
equal
deleted
inserted
replaced
335:17b844102023 | 336:aaade6ded589 |
---|---|
128 Expression *e2 = isExpression(o2); | 128 Expression *e2 = isExpression(o2); |
129 Dsymbol *s1 = isDsymbol(o1); | 129 Dsymbol *s1 = isDsymbol(o1); |
130 Dsymbol *s2 = isDsymbol(o2); | 130 Dsymbol *s2 = isDsymbol(o2); |
131 Tuple *v1 = isTuple(o1); | 131 Tuple *v1 = isTuple(o1); |
132 Tuple *v2 = isTuple(o2); | 132 Tuple *v2 = isTuple(o2); |
133 | |
133 //printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, v1 %p v2 %p\n", t1,t2,e1,e2,s1,s2,v1,v2); | 134 //printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, v1 %p v2 %p\n", t1,t2,e1,e2,s1,s2,v1,v2); |
134 | 135 |
135 /* A proper implementation of the various equals() overrides | 136 /* A proper implementation of the various equals() overrides |
136 * should make it possible to just do o1->equals(o2), but | 137 * should make it possible to just do o1->equals(o2), but |
137 * we'll do that another day. | 138 * we'll do that another day. |
389 /* BUG: should check: | 390 /* BUG: should check: |
390 * o no virtual functions or non-static data members of classes | 391 * o no virtual functions or non-static data members of classes |
391 */ | 392 */ |
392 } | 393 } |
393 | 394 |
394 char *TemplateDeclaration::kind() | 395 const char *TemplateDeclaration::kind() |
395 { | 396 { |
396 return (onemember && onemember->isAggregateDeclaration()) | 397 return (onemember && onemember->isAggregateDeclaration()) |
397 ? onemember->kind() | 398 ? onemember->kind() |
398 : (char *)"template"; | 399 : (char *)"template"; |
399 } | 400 } |
517 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter(); | 518 TemplateTypeParameter *ttp = tp->isTemplateTypeParameter(); |
518 if (ttp) | 519 if (ttp) |
519 printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : ""); | 520 printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : ""); |
520 #endif | 521 #endif |
521 | 522 |
523 #if DMDV1 | |
522 m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam); | 524 m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam); |
525 #else | |
526 m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam, (flag & 2) ? 1 : 0); | |
527 | |
528 #endif | |
523 //printf("\tm2 = %d\n", m2); | 529 //printf("\tm2 = %d\n", m2); |
524 | 530 |
525 if (m2 == MATCHnomatch) | 531 if (m2 == MATCHnomatch) |
526 { | 532 { |
527 #if 0 | 533 #if 0 |
869 { if (m < match) | 875 { if (m < match) |
870 match = m; // pick worst match | 876 match = m; // pick worst match |
871 continue; | 877 continue; |
872 } | 878 } |
873 } | 879 } |
880 | |
881 /* The following code for variadic arguments closely | |
882 * matches TypeFunction::callMatch() | |
883 */ | |
874 if (!(fdtype->varargs == 2 && i + 1 == nfparams)) | 884 if (!(fdtype->varargs == 2 && i + 1 == nfparams)) |
875 goto Lnomatch; | 885 goto Lnomatch; |
876 | 886 |
877 /* Check for match with function parameter T... | 887 /* Check for match with function parameter T... |
878 */ | 888 */ |
879 Type *t = fparam->type; | 889 Type *tb = fparam->type->toBasetype(); |
880 switch (t->ty) | 890 switch (tb->ty) |
881 { | 891 { |
882 // Perhaps we can do better with this, see TypeFunction::callMatch() | 892 // Perhaps we can do better with this, see TypeFunction::callMatch() |
883 case Tsarray: | 893 case Tsarray: |
894 { TypeSArray *tsa = (TypeSArray *)tb; | |
895 integer_t sz = tsa->dim->toInteger(); | |
896 if (sz != nfargs - i) | |
897 goto Lnomatch; | |
898 } | |
884 case Tarray: | 899 case Tarray: |
900 { TypeArray *ta = (TypeArray *)tb; | |
901 for (; i < nfargs; i++) | |
902 { | |
903 Expression *arg = (Expression *)fargs->data[i]; | |
904 assert(arg); | |
905 MATCH m; | |
906 /* If lazy array of delegates, | |
907 * convert arg(s) to delegate(s) | |
908 */ | |
909 Type *tret = fparam->isLazyArray(); | |
910 if (tret) | |
911 { | |
912 if (ta->next->equals(arg->type)) | |
913 { m = MATCHexact; | |
914 } | |
915 else | |
916 { | |
917 m = arg->implicitConvTo(tret); | |
918 if (m == MATCHnomatch) | |
919 { | |
920 if (tret->toBasetype()->ty == Tvoid) | |
921 m = MATCHconvert; | |
922 } | |
923 } | |
924 } | |
925 else | |
926 { | |
927 m = arg->type->deduceType(scope, ta->next, parameters, &dedtypes); | |
928 //m = arg->implicitConvTo(ta->next); | |
929 } | |
930 if (m == MATCHnomatch) | |
931 goto Lnomatch; | |
932 if (m < match) | |
933 match = m; | |
934 } | |
935 goto Lmatch; | |
936 } | |
885 case Tclass: | 937 case Tclass: |
886 case Tident: | 938 case Tident: |
887 goto Lmatch; | 939 goto Lmatch; |
888 | 940 |
889 default: | 941 default: |
982 // tdtypes.data[i] always matches ea here | 1034 // tdtypes.data[i] always matches ea here |
983 Initializer *init = new ExpInitializer(loc, ea); | 1035 Initializer *init = new ExpInitializer(loc, ea); |
984 TemplateValueParameter *tvp = tp->isTemplateValueParameter(); | 1036 TemplateValueParameter *tvp = tp->isTemplateValueParameter(); |
985 assert(tvp); | 1037 assert(tvp); |
986 | 1038 |
987 VarDeclaration *v = new VarDeclaration(0, tvp->valType, tp->ident, init); | 1039 VarDeclaration *v = new VarDeclaration(loc, tvp->valType, tp->ident, init); |
988 v->storage_class = STCconst; | 1040 v->storage_class = STCconst; |
989 s = v; | 1041 s = v; |
990 } | 1042 } |
991 else if (va) | 1043 else if (va) |
992 { | 1044 { |
1035 /************************************************* | 1087 /************************************************* |
1036 * Given function arguments, figure out which template function | 1088 * Given function arguments, figure out which template function |
1037 * to expand, and return that function. | 1089 * to expand, and return that function. |
1038 * If no match, give error message and return NULL. | 1090 * If no match, give error message and return NULL. |
1039 * Input: | 1091 * Input: |
1092 * sc instantiation scope | |
1093 * loc instantiation location | |
1040 * targsi initial list of template arguments | 1094 * targsi initial list of template arguments |
1041 * fargs arguments to function | 1095 * fargs arguments to function |
1042 */ | 1096 */ |
1043 | 1097 |
1044 FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, | 1098 FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc, |
1280 int i = templateParameterLookup(tparam, parameters); | 1334 int i = templateParameterLookup(tparam, parameters); |
1281 if (i == -1) | 1335 if (i == -1) |
1282 { | 1336 { |
1283 if (!sc) | 1337 if (!sc) |
1284 goto Lnomatch; | 1338 goto Lnomatch; |
1339 | |
1340 /* Need a loc to go with the semantic routine. | |
1341 */ | |
1342 Loc loc; | |
1343 if (parameters->dim) | |
1344 { | |
1345 TemplateParameter *tp = (TemplateParameter *)parameters->data[0]; | |
1346 loc = tp->loc; | |
1347 } | |
1348 | |
1285 /* BUG: what if tparam is a template instance, that | 1349 /* BUG: what if tparam is a template instance, that |
1286 * has as an argument another Tident? | 1350 * has as an argument another Tident? |
1287 */ | 1351 */ |
1288 tparam = tparam->semantic(0, sc); | 1352 tparam = tparam->semantic(loc, sc); |
1289 assert(tparam->ty != Tident); | 1353 assert(tparam->ty != Tident); |
1290 return deduceType(sc, tparam, parameters, dedtypes); | 1354 return deduceType(sc, tparam, parameters, dedtypes); |
1291 } | 1355 } |
1292 | 1356 |
1293 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; | 1357 TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; |
1315 else | 1379 else |
1316 goto Lnomatch; | 1380 goto Lnomatch; |
1317 } | 1381 } |
1318 | 1382 |
1319 if (ty != tparam->ty) | 1383 if (ty != tparam->ty) |
1320 goto Lnomatch; | 1384 return implicitConvTo(tparam); |
1385 // goto Lnomatch; | |
1321 | 1386 |
1322 if (nextOf()) | 1387 if (nextOf()) |
1323 return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes); | 1388 return nextOf()->deduceType(sc, tparam->nextOf(), parameters, dedtypes); |
1324 | 1389 |
1325 Lexact: | 1390 Lexact: |
1846 TemplateTupleParameter *TemplateParameter::isTemplateTupleParameter() | 1911 TemplateTupleParameter *TemplateParameter::isTemplateTupleParameter() |
1847 { | 1912 { |
1848 return NULL; | 1913 return NULL; |
1849 } | 1914 } |
1850 | 1915 |
1916 #if DMDV2 | |
1917 TemplateThisParameter *TemplateParameter::isTemplateThisParameter() | |
1918 { | |
1919 return NULL; | |
1920 } | |
1921 #endif | |
1922 | |
1851 /* ======================== TemplateTypeParameter =========================== */ | 1923 /* ======================== TemplateTypeParameter =========================== */ |
1852 | 1924 |
1853 // type-parameter | 1925 // type-parameter |
1854 | 1926 |
1855 TemplateTypeParameter::TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, | 1927 TemplateTypeParameter::TemplateTypeParameter(Loc loc, Identifier *ident, Type *specType, |
1968 | 2040 |
1969 t = (Type *)dedtypes->data[i]; | 2041 t = (Type *)dedtypes->data[i]; |
1970 | 2042 |
1971 if (specType) | 2043 if (specType) |
1972 { | 2044 { |
1973 //printf("\tcalling deduceType(), specType is %s\n", specType->toChars()); | 2045 //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta->toChars(), specType->toChars()); |
1974 MATCH m2 = ta->deduceType(sc, specType, parameters, dedtypes); | 2046 MATCH m2 = ta->deduceType(sc, specType, parameters, dedtypes); |
1975 if (m2 == MATCHnomatch) | 2047 if (m2 == MATCHnomatch) |
1976 { //printf("\tfailed deduceType\n"); | 2048 { //printf("\tfailed deduceType\n"); |
1977 goto Lnomatch; | 2049 goto Lnomatch; |
1978 } | 2050 } |
1981 m = m2; | 2053 m = m2; |
1982 t = (Type *)dedtypes->data[i]; | 2054 t = (Type *)dedtypes->data[i]; |
1983 } | 2055 } |
1984 else | 2056 else |
1985 { | 2057 { |
2058 // So that matches with specializations are better | |
1986 m = MATCHconvert; | 2059 m = MATCHconvert; |
1987 if (t) | 2060 if (t) |
1988 { // Must match already deduced type | 2061 { // Must match already deduced type |
1989 | 2062 |
1990 m = MATCHexact; | 2063 m = MATCHexact; |
1991 if (!t->equals(ta)) | 2064 if (!t->equals(ta)) |
2065 { //printf("t = %s ta = %s\n", t->toChars(), ta->toChars()); | |
1992 goto Lnomatch; | 2066 goto Lnomatch; |
2067 } | |
1993 } | 2068 } |
1994 } | 2069 } |
1995 | 2070 |
1996 if (!t) | 2071 if (!t) |
1997 { | 2072 { |
2073 t = t->semantic(loc, sc); | 2148 t = t->semantic(loc, sc); |
2074 } | 2149 } |
2075 return t; | 2150 return t; |
2076 } | 2151 } |
2077 | 2152 |
2153 /* ======================== TemplateThisParameter =========================== */ | |
2154 | |
2155 #if DMDV2 | |
2156 // this-parameter | |
2157 | |
2158 TemplateThisParameter::TemplateThisParameter(Loc loc, Identifier *ident, | |
2159 Type *specType, | |
2160 Type *defaultType) | |
2161 : TemplateTypeParameter(loc, ident, specType, defaultType) | |
2162 { | |
2163 } | |
2164 | |
2165 TemplateThisParameter *TemplateThisParameter::isTemplateThisParameter() | |
2166 { | |
2167 return this; | |
2168 } | |
2169 | |
2170 TemplateParameter *TemplateThisParameter::syntaxCopy() | |
2171 { | |
2172 TemplateThisParameter *tp = new TemplateThisParameter(loc, ident, specType, defaultType); | |
2173 if (tp->specType) | |
2174 tp->specType = specType->syntaxCopy(); | |
2175 if (defaultType) | |
2176 tp->defaultType = defaultType->syntaxCopy(); | |
2177 return tp; | |
2178 } | |
2179 | |
2180 void TemplateThisParameter::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | |
2181 { | |
2182 buf->writestring("this "); | |
2183 TemplateTypeParameter::toCBuffer(buf, hgs); | |
2184 } | |
2185 #endif | |
2186 | |
2078 /* ======================== TemplateAliasParameter ========================== */ | 2187 /* ======================== TemplateAliasParameter ========================== */ |
2079 | 2188 |
2080 // alias-parameter | 2189 // alias-parameter |
2081 | 2190 |
2082 Dsymbol *TemplateAliasParameter::sdummy = NULL; | 2191 Dsymbol *TemplateAliasParameter::sdummy = NULL; |
2118 { | 2227 { |
2119 if (specAliasT) | 2228 if (specAliasT) |
2120 { | 2229 { |
2121 specAlias = specAliasT->toDsymbol(sc); | 2230 specAlias = specAliasT->toDsymbol(sc); |
2122 if (!specAlias) | 2231 if (!specAlias) |
2123 error("%s is not a symbol", specAliasT->toChars()); | 2232 error(loc, "%s is not a symbol", specAliasT->toChars()); |
2124 } | 2233 } |
2125 #if 0 // Don't do semantic() until instantiation | 2234 #if 0 // Don't do semantic() until instantiation |
2126 if (defaultAlias) | 2235 if (defaultAlias) |
2127 defaultAlias = defaultAlias->semantic(loc, sc); | 2236 defaultAlias = defaultAlias->semantic(loc, sc); |
2128 #endif | 2237 #endif |
2489 } | 2598 } |
2490 | 2599 |
2491 | 2600 |
2492 Object *TemplateValueParameter::defaultArg(Scope *sc) | 2601 Object *TemplateValueParameter::defaultArg(Scope *sc) |
2493 { | 2602 { |
2494 Expression *e; | 2603 Expression *e = defaultValue; |
2495 | |
2496 e = defaultValue; | |
2497 if (e) | 2604 if (e) |
2498 { | 2605 { |
2499 e = e->syntaxCopy(); | 2606 e = e->syntaxCopy(); |
2500 e = e->semantic(sc); | 2607 e = e->semantic(sc); |
2608 #if DMDV2 | |
2609 if (e->op == TOKdefault) | |
2610 { DefaultInitExp *de = (DefaultInitExp *)e; | |
2611 e = de->resolve(loc, sc); | |
2612 } | |
2613 #endif | |
2501 } | 2614 } |
2502 return e; | 2615 return e; |
2503 } | 2616 } |
2504 | 2617 |
2505 /* ======================== TemplateTupleParameter ========================== */ | 2618 /* ======================== TemplateTupleParameter ========================== */ |
2650 this->tempdecl = NULL; | 2763 this->tempdecl = NULL; |
2651 this->inst = NULL; | 2764 this->inst = NULL; |
2652 this->argsym = NULL; | 2765 this->argsym = NULL; |
2653 this->aliasdecl = NULL; | 2766 this->aliasdecl = NULL; |
2654 this->semanticdone = 0; | 2767 this->semanticdone = 0; |
2768 this->semantictiargsdone = 0; | |
2655 this->withsym = NULL; | 2769 this->withsym = NULL; |
2656 this->nest = 0; | 2770 this->nest = 0; |
2657 this->havetempdecl = 0; | 2771 this->havetempdecl = 0; |
2658 this->isnested = NULL; | 2772 this->isnested = NULL; |
2659 this->errors = 0; | 2773 this->errors = 0; |
2672 this->tempdecl = td; | 2786 this->tempdecl = td; |
2673 this->inst = NULL; | 2787 this->inst = NULL; |
2674 this->argsym = NULL; | 2788 this->argsym = NULL; |
2675 this->aliasdecl = NULL; | 2789 this->aliasdecl = NULL; |
2676 this->semanticdone = 0; | 2790 this->semanticdone = 0; |
2791 this->semantictiargsdone = 1; | |
2677 this->withsym = NULL; | 2792 this->withsym = NULL; |
2678 this->nest = 0; | 2793 this->nest = 0; |
2679 this->havetempdecl = 1; | 2794 this->havetempdecl = 1; |
2680 this->isnested = NULL; | 2795 this->isnested = NULL; |
2681 this->errors = 0; | 2796 this->errors = 0; |
2857 //printf("\t1: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars()); | 2972 //printf("\t1: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars()); |
2858 a = sc->scopesym->members; | 2973 a = sc->scopesym->members; |
2859 } | 2974 } |
2860 else | 2975 else |
2861 { Module *m = sc->module->importedFrom; | 2976 { Module *m = sc->module->importedFrom; |
2862 //printf("\t2: adding to module %s\n", m->toChars()); | 2977 //printf("\t2: adding to module %s instead of module %s\n", m->toChars(), sc->module->toChars()); |
2863 a = m->members; | 2978 a = m->members; |
2864 if (m->semanticdone >= 3) | 2979 if (m->semanticdone >= 3) |
2865 dosemantic3 = 1; | 2980 dosemantic3 = 1; |
2866 } | 2981 } |
2867 for (int i = 0; 1; i++) | 2982 for (int i = 0; 1; i++) |
3023 | 3138 |
3024 | 3139 |
3025 void TemplateInstance::semanticTiargs(Scope *sc) | 3140 void TemplateInstance::semanticTiargs(Scope *sc) |
3026 { | 3141 { |
3027 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); | 3142 //printf("+TemplateInstance::semanticTiargs() %s\n", toChars()); |
3143 if (semantictiargsdone) | |
3144 return; | |
3145 semantictiargsdone = 1; | |
3028 semanticTiargs(loc, sc, tiargs); | 3146 semanticTiargs(loc, sc, tiargs); |
3029 } | 3147 } |
3030 | 3148 |
3031 void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs) | 3149 void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs) |
3032 { | 3150 { |
3383 else if (sa) | 3501 else if (sa) |
3384 { | 3502 { |
3385 Lsa: | 3503 Lsa: |
3386 Declaration *d = sa->isDeclaration(); | 3504 Declaration *d = sa->isDeclaration(); |
3387 if (d && !d->isDataseg() && | 3505 if (d && !d->isDataseg() && |
3388 #if V2 | 3506 #if DMDV2 |
3389 !(d->storage_class & STCmanifest) && | 3507 !(d->storage_class & STCmanifest) && |
3390 #endif | 3508 #endif |
3391 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) && | 3509 (!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) && |
3392 !isTemplateMixin()) | 3510 !isTemplateMixin()) |
3393 { | 3511 { |
3580 printf("-TemplateInstance::semantic2('%s')\n", toChars()); | 3698 printf("-TemplateInstance::semantic2('%s')\n", toChars()); |
3581 #endif | 3699 #endif |
3582 } | 3700 } |
3583 | 3701 |
3584 void TemplateInstance::semantic3(Scope *sc) | 3702 void TemplateInstance::semantic3(Scope *sc) |
3585 { int i; | 3703 { |
3586 | |
3587 #if LOG | 3704 #if LOG |
3588 printf("TemplateInstance::semantic3('%s'), semanticdone = %d\n", toChars(), semanticdone); | 3705 printf("TemplateInstance::semantic3('%s'), semanticdone = %d\n", toChars(), semanticdone); |
3589 #endif | 3706 #endif |
3590 //if (toChars()[0] == 'D') *(char*)0=0; | 3707 //if (toChars()[0] == 'D') *(char*)0=0; |
3591 if (semanticdone >= 3) | 3708 if (semanticdone >= 3) |
3594 if (!errors && members) | 3711 if (!errors && members) |
3595 { | 3712 { |
3596 sc = tempdecl->scope; | 3713 sc = tempdecl->scope; |
3597 sc = sc->push(argsym); | 3714 sc = sc->push(argsym); |
3598 sc = sc->push(this); | 3715 sc = sc->push(this); |
3599 for (i = 0; i < members->dim; i++) | 3716 for (int i = 0; i < members->dim; i++) |
3600 { | 3717 { |
3601 Dsymbol *s = (Dsymbol *)members->data[i]; | 3718 Dsymbol *s = (Dsymbol *)members->data[i]; |
3602 s->semantic3(sc); | 3719 s->semantic3(sc); |
3603 } | 3720 } |
3604 sc = sc->pop(); | 3721 sc = sc->pop(); |
3605 sc->pop(); | 3722 sc->pop(); |
3606 } | 3723 } |
3607 } | 3724 } |
3608 | 3725 |
3609 void TemplateInstance::toObjFile() | 3726 void TemplateInstance::toObjFile(int multiobj) |
3610 { int i; | 3727 { |
3611 | |
3612 #if LOG | 3728 #if LOG |
3613 printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); | 3729 printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this); |
3614 #endif | 3730 #endif |
3615 if (!errors && members) | 3731 if (!errors && members) |
3616 { | 3732 { |
3617 for (i = 0; i < members->dim; i++) | 3733 if (multiobj) |
3618 { | 3734 // Append to list of object files to be written later |
3619 Dsymbol *s = (Dsymbol *)members->data[i]; | 3735 //obj_append(this); |
3620 s->toObjFile(); | 3736 assert(0 && "multiobj"); |
3737 else | |
3738 { | |
3739 for (int i = 0; i < members->dim; i++) | |
3740 { | |
3741 Dsymbol *s = (Dsymbol *)members->data[i]; | |
3742 s->toObjFile(multiobj); | |
3743 } | |
3621 } | 3744 } |
3622 } | 3745 } |
3623 } | 3746 } |
3624 | 3747 |
3625 void TemplateInstance::inlineScan() | 3748 void TemplateInstance::inlineScan() |
3626 { int i; | 3749 { |
3627 | |
3628 #if LOG | 3750 #if LOG |
3629 printf("TemplateInstance::inlineScan('%s')\n", toChars()); | 3751 printf("TemplateInstance::inlineScan('%s')\n", toChars()); |
3630 #endif | 3752 #endif |
3631 if (!errors && members) | 3753 if (!errors && members) |
3632 { | 3754 { |
3633 for (i = 0; i < members->dim; i++) | 3755 for (int i = 0; i < members->dim; i++) |
3634 { | 3756 { |
3635 Dsymbol *s = (Dsymbol *)members->data[i]; | 3757 Dsymbol *s = (Dsymbol *)members->data[i]; |
3636 s->inlineScan(); | 3758 s->inlineScan(); |
3637 } | 3759 } |
3638 } | 3760 } |
3686 AliasDeclaration *TemplateInstance::isAliasDeclaration() | 3808 AliasDeclaration *TemplateInstance::isAliasDeclaration() |
3687 { | 3809 { |
3688 return aliasdecl; | 3810 return aliasdecl; |
3689 } | 3811 } |
3690 | 3812 |
3691 char *TemplateInstance::kind() | 3813 const char *TemplateInstance::kind() |
3692 { | 3814 { |
3693 return "template instance"; | 3815 return "template instance"; |
3694 } | 3816 } |
3695 | 3817 |
3696 int TemplateInstance::oneMember(Dsymbol **ps) | 3818 int TemplateInstance::oneMember(Dsymbol **ps) |
3768 } | 3890 } |
3769 if (!semanticdone) | 3891 if (!semanticdone) |
3770 semanticdone = 1; | 3892 semanticdone = 1; |
3771 #if LOG | 3893 #if LOG |
3772 printf("\tdo semantic\n"); | 3894 printf("\tdo semantic\n"); |
3895 #endif | |
3896 | |
3897 #if !IN_LLVM | |
3898 // dont know what this is | |
3899 util_progress(); | |
3773 #endif | 3900 #endif |
3774 | 3901 |
3775 Scope *scx = NULL; | 3902 Scope *scx = NULL; |
3776 if (scope) | 3903 if (scope) |
3777 { sc = scope; | 3904 { sc = scope; |
3883 //printf("\ts = '%s'\n", s->toChars()); | 4010 //printf("\ts = '%s'\n", s->toChars()); |
3884 TemplateMixin *tm = s->isTemplateMixin(); | 4011 TemplateMixin *tm = s->isTemplateMixin(); |
3885 if (!tm || tempdecl != tm->tempdecl) | 4012 if (!tm || tempdecl != tm->tempdecl) |
3886 continue; | 4013 continue; |
3887 | 4014 |
4015 /* Different argument list lengths happen with variadic args | |
4016 */ | |
4017 if (tiargs->dim != tm->tiargs->dim) | |
4018 continue; | |
4019 | |
3888 for (int i = 0; i < tiargs->dim; i++) | 4020 for (int i = 0; i < tiargs->dim; i++) |
3889 { Object *o = (Object *)tiargs->data[i]; | 4021 { Object *o = (Object *)tiargs->data[i]; |
3890 Type *ta = isType(o); | 4022 Type *ta = isType(o); |
3891 Expression *ea = isExpression(o); | 4023 Expression *ea = isExpression(o); |
3892 Dsymbol *sa = isDsymbol(o); | 4024 Dsymbol *sa = isDsymbol(o); |
4066 void TemplateMixin::inlineScan() | 4198 void TemplateMixin::inlineScan() |
4067 { | 4199 { |
4068 TemplateInstance::inlineScan(); | 4200 TemplateInstance::inlineScan(); |
4069 } | 4201 } |
4070 | 4202 |
4071 char *TemplateMixin::kind() | 4203 const char *TemplateMixin::kind() |
4072 { | 4204 { |
4073 return "mixin"; | 4205 return "mixin"; |
4074 } | 4206 } |
4075 | 4207 |
4076 int TemplateMixin::oneMember(Dsymbol **ps) | 4208 int TemplateMixin::oneMember(Dsymbol **ps) |
4106 } | 4238 } |
4107 | 4239 |
4108 void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 4240 void TemplateMixin::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
4109 { | 4241 { |
4110 buf->writestring("mixin "); | 4242 buf->writestring("mixin "); |
4111 int i; | 4243 |
4112 for (i = 0; i < idents->dim; i++) | 4244 for (int i = 0; i < idents->dim; i++) |
4113 { Identifier *id = (Identifier *)idents->data[i]; | 4245 { Identifier *id = (Identifier *)idents->data[i]; |
4114 | 4246 |
4115 if (i) | 4247 if (i) |
4116 buf->writeByte('.'); | 4248 buf->writeByte('.'); |
4117 buf->writestring(id->toChars()); | 4249 buf->writestring(id->toChars()); |
4118 } | 4250 } |
4119 buf->writestring("!("); | 4251 buf->writestring("!("); |
4120 if (tiargs) | 4252 if (tiargs) |
4121 { | 4253 { |
4122 for (i = 0; i < tiargs->dim; i++) | 4254 for (int i = 0; i < tiargs->dim; i++) |
4123 { if (i) | 4255 { if (i) |
4124 buf->writebyte(','); | 4256 buf->writebyte(','); |
4125 Object *oarg = (Object *)tiargs->data[i]; | 4257 Object *oarg = (Object *)tiargs->data[i]; |
4126 Type *t = isType(oarg); | 4258 Type *t = isType(oarg); |
4127 Expression *e = isExpression(oarg); | 4259 Expression *e = isExpression(oarg); |
4144 assert(0); | 4276 assert(0); |
4145 } | 4277 } |
4146 } | 4278 } |
4147 } | 4279 } |
4148 buf->writebyte(')'); | 4280 buf->writebyte(')'); |
4281 if (ident) | |
4282 { | |
4283 buf->writebyte(' '); | |
4284 buf->writestring(ident->toChars()); | |
4285 } | |
4149 buf->writebyte(';'); | 4286 buf->writebyte(';'); |
4150 buf->writenl(); | 4287 buf->writenl(); |
4151 } | 4288 } |
4152 | 4289 |
4153 | 4290 |
4154 void TemplateMixin::toObjFile() | 4291 void TemplateMixin::toObjFile(int multiobj) |
4155 { | 4292 { |
4156 //printf("TemplateMixin::toObjFile('%s')\n", toChars()); | 4293 //printf("TemplateMixin::toObjFile('%s')\n", toChars()); |
4157 TemplateInstance::toObjFile(); | 4294 TemplateInstance::toObjFile(multiobj); |
4158 } | 4295 } |
4159 | 4296 |