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