comparison dmd/template.c @ 1103:b30fe7e1dbb9

- Updated to DMD frontend 1.041. - Removed dmd/inifile.c , it's not under a free license, replaced with libconfig based config file.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Thu, 12 Mar 2009 20:37:27 +0100
parents d33b0d4b816a
children 1860414bf3b7
comparison
equal deleted inserted replaced
1102:ae950bd712d3 1103:b30fe7e1dbb9
1 1
2 // Compiler implementation of the D programming language 2 // Compiler implementation of the D programming language
3 // Copyright (c) 1999-2008 by Digital Mars 3 // Copyright (c) 1999-2009 by Digital Mars
4 // All Rights Reserved 4 // All Rights Reserved
5 // written by Walter Bright 5 // written by Walter Bright
6 // http://www.digitalmars.com 6 // http://www.digitalmars.com
7 // License for redistribution is by either the Artistic License 7 // License for redistribution is by either the Artistic License
8 // in artistic.txt, or the GNU General Public License in gnu.txt. 8 // in artistic.txt, or the GNU General Public License in gnu.txt.
19 long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep); 19 long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
20 #endif 20 #endif
21 #endif 21 #endif
22 22
23 #include "root.h" 23 #include "root.h"
24 #include "mem.h" 24 #include "rmem.h"
25 #include "stringtable.h" 25 #include "stringtable.h"
26 #include "mars.h" 26 #include "mars.h"
27 #include "identifier.h" 27 #include "identifier.h"
28 #include "mtype.h" 28 #include "mtype.h"
29 #include "template.h" 29 #include "template.h"
184 //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars()); 184 //printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars());
185 if (!s2 || !s1->equals(s2) || s1->parent != s2->parent) 185 if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
186 { 186 {
187 goto Lnomatch; 187 goto Lnomatch;
188 } 188 }
189 #if V2
190 VarDeclaration *v1 = s1->isVarDeclaration();
191 VarDeclaration *v2 = s2->isVarDeclaration();
192 if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest)
193 { ExpInitializer *ei1 = v1->init->isExpInitializer();
194 ExpInitializer *ei2 = v2->init->isExpInitializer();
195 if (ei1 && ei2 && !ei1->exp->equals(ei2->exp))
196 goto Lnomatch;
197 }
198 #endif
189 } 199 }
190 else if (v1) 200 else if (v1)
191 { 201 {
192 if (!v2) 202 if (!v2)
193 goto Lnomatch; 203 goto Lnomatch;
251 #endif 261 #endif
252 assert(0); 262 assert(0);
253 } 263 }
254 } 264 }
255 265
266 #if V2
267 Object *objectSyntaxCopy(Object *o)
268 {
269 if (!o)
270 return NULL;
271 Type *t = isType(o);
272 if (t)
273 return t->syntaxCopy();
274 Expression *e = isExpression(o);
275 if (e)
276 return e->syntaxCopy();
277 return o;
278 }
279 #endif
256 280
257 281
258 /* ======================== TemplateDeclaration ============================= */ 282 /* ======================== TemplateDeclaration ============================= */
259 283
260 TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs) 284 TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs)
277 } 301 }
278 #endif 302 #endif
279 this->loc = loc; 303 this->loc = loc;
280 this->parameters = parameters; 304 this->parameters = parameters;
281 this->origParameters = parameters; 305 this->origParameters = parameters;
306 #if V2
307 this->constraint = constraint;
308 #endif
282 this->members = decldefs; 309 this->members = decldefs;
283 this->overnext = NULL; 310 this->overnext = NULL;
284 this->overroot = NULL; 311 this->overroot = NULL;
285 this->scope = NULL; 312 this->scope = NULL;
286 this->onemember = NULL; 313 this->onemember = NULL;
301 for (int i = 0; i < p->dim; i++) 328 for (int i = 0; i < p->dim; i++)
302 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 329 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
303 p->data[i] = (void *)tp->syntaxCopy(); 330 p->data[i] = (void *)tp->syntaxCopy();
304 } 331 }
305 } 332 }
333 #if V2
334 Expression *e = NULL;
335 if (constraint)
336 e = constraint->syntaxCopy();
337 #endif
306 d = Dsymbol::arraySyntaxCopy(members); 338 d = Dsymbol::arraySyntaxCopy(members);
307 td = new TemplateDeclaration(loc, ident, p, d); 339 td = new TemplateDeclaration(loc, ident, p, d);
308 340
309 // LDC 341 // LDC
310 td->intrinsicName = intrinsicName; 342 td->intrinsicName = intrinsicName;
350 // Set up scope for parameters 382 // Set up scope for parameters
351 ScopeDsymbol *paramsym = new ScopeDsymbol(); 383 ScopeDsymbol *paramsym = new ScopeDsymbol();
352 paramsym->parent = sc->parent; 384 paramsym->parent = sc->parent;
353 Scope *paramscope = sc->push(paramsym); 385 Scope *paramscope = sc->push(paramsym);
354 paramscope->parameterSpecialization = 1; 386 paramscope->parameterSpecialization = 1;
387 paramscope->stc = 0;
355 388
356 if (global.params.doDocComments) 389 if (global.params.doDocComments)
357 { 390 {
358 origParameters = new TemplateParameters(); 391 origParameters = new TemplateParameters();
359 origParameters->setDim(parameters->dim); 392 origParameters->setDim(parameters->dim);
510 // Set up scope for parameters 543 // Set up scope for parameters
511 assert((size_t)scope > 0x10000); 544 assert((size_t)scope > 0x10000);
512 ScopeDsymbol *paramsym = new ScopeDsymbol(); 545 ScopeDsymbol *paramsym = new ScopeDsymbol();
513 paramsym->parent = scope->parent; 546 paramsym->parent = scope->parent;
514 Scope *paramscope = scope->push(paramsym); 547 Scope *paramscope = scope->push(paramsym);
548 paramscope->stc = 0;
515 549
516 // Attempt type deduction 550 // Attempt type deduction
517 m = MATCHexact; 551 m = MATCHexact;
518 for (int i = 0; i < dedtypes_dim; i++) 552 for (int i = 0; i < dedtypes_dim; i++)
519 { MATCH m2; 553 { MATCH m2;
761 } 795 }
762 796
763 memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data)); 797 memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
764 798
765 for (i = 0; i < nargsi; i++) 799 for (i = 0; i < nargsi; i++)
766 { TemplateParameter *tp = (TemplateParameter *)parameters->data[i]; 800 { assert(i < parameters->dim);
801 TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
767 MATCH m; 802 MATCH m;
768 Declaration *sparam; 803 Declaration *sparam;
769 804
770 m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); 805 m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
771 //printf("\tdeduceType m = %d\n", m); 806 //printf("\tdeduceType m = %d\n", m);
798 if (nfparams == 0) // if no function parameters 833 if (nfparams == 0) // if no function parameters
799 { 834 {
800 Tuple *t = new Tuple(); 835 Tuple *t = new Tuple();
801 //printf("t = %p\n", t); 836 //printf("t = %p\n", t);
802 dedargs->data[parameters->dim - 1] = (void *)t; 837 dedargs->data[parameters->dim - 1] = (void *)t;
838 declareParameter(paramscope, tp, t);
803 goto L2; 839 goto L2;
804 } 840 }
805 else if (nfargs < nfparams - 1) 841 else if (nfargs < nfparams - 1)
806 goto L1; 842 goto L1;
807 else 843 else
833 t->objects.setDim(tuple_dim); 869 t->objects.setDim(tuple_dim);
834 for (i = 0; i < tuple_dim; i++) 870 for (i = 0; i < tuple_dim; i++)
835 { Expression *farg = (Expression *)fargs->data[fptupindex + i]; 871 { Expression *farg = (Expression *)fargs->data[fptupindex + i];
836 t->objects.data[i] = (void *)farg->type; 872 t->objects.data[i] = (void *)farg->type;
837 } 873 }
874 declareParameter(paramscope, tp, t);
838 goto L2; 875 goto L2;
839 } 876 }
840 fptupindex = -1; 877 fptupindex = -1;
841 } 878 }
842 } 879 }
1018 { /* The specialization can work as long as afterwards 1055 { /* The specialization can work as long as afterwards
1019 * the oded == oarg 1056 * the oded == oarg
1020 */ 1057 */
1021 Declaration *sparam; 1058 Declaration *sparam;
1022 dedargs->data[i] = (void *)oded; 1059 dedargs->data[i] = (void *)oded;
1023 MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam); 1060 MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam, 0);
1024 //printf("m2 = %d\n", m2); 1061 //printf("m2 = %d\n", m2);
1025 if (!m2) 1062 if (!m2)
1026 goto Lnomatch; 1063 goto Lnomatch;
1027 if (m2 < match) 1064 if (m2 < match)
1028 match = m2; // pick worst match 1065 match = m2; // pick worst match
1075 //printf("\tnomatch\n"); 1112 //printf("\tnomatch\n");
1076 return MATCHnomatch; 1113 return MATCHnomatch;
1077 } 1114 }
1078 1115
1079 /************************************************** 1116 /**************************************************
1080 * Declare template parameter tp with value o. 1117 * Declare template parameter tp with value o, and install it in the scope sc.
1081 */ 1118 */
1082 1119
1083 void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Object *o) 1120 void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Object *o)
1084 { 1121 {
1085 //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o); 1122 //printf("TemplateDeclaration::declareParameter('%s', o = %p)\n", tp->ident->toChars(), o);
1258 error(loc, "does not match any template declaration"); 1295 error(loc, "does not match any template declaration");
1259 goto Lerror; 1296 goto Lerror;
1260 } 1297 }
1261 if (td_ambig) 1298 if (td_ambig)
1262 { 1299 {
1263 error(loc, "%s matches more than one function template declaration, %s and %s", 1300 error(loc, "matches more than one function template declaration:\n %s\nand:\n %s",
1264 toChars(), td_best->toChars(), td_ambig->toChars()); 1301 td_best->toChars(), td_ambig->toChars());
1265 } 1302 }
1266 1303
1267 /* The best match is td_best with arguments tdargs. 1304 /* The best match is td_best with arguments tdargs.
1268 * Now instantiate the template. 1305 * Now instantiate the template.
1269 */ 1306 */
1792 Type *t2 = isType(o2); 1829 Type *t2 = isType(o2);
1793 1830
1794 Expression *e1 = isExpression(o1); 1831 Expression *e1 = isExpression(o1);
1795 Expression *e2 = isExpression(o2); 1832 Expression *e2 = isExpression(o2);
1796 1833
1834 Dsymbol *s1 = isDsymbol(o1);
1835 Dsymbol *s2 = isDsymbol(o2);
1836
1837 Tuple *v1 = isTuple(o1);
1838 Tuple *v2 = isTuple(o2);
1797 #if 0 1839 #if 0
1798 if (t1) printf("t1 = %s\n", t1->toChars()); 1840 if (t1) printf("t1 = %s\n", t1->toChars());
1799 if (t2) printf("t2 = %s\n", t2->toChars()); 1841 if (t2) printf("t2 = %s\n", t2->toChars());
1800 if (e1) printf("e1 = %s\n", e1->toChars()); 1842 if (e1) printf("e1 = %s\n", e1->toChars());
1801 if (e2) printf("e2 = %s\n", e2->toChars()); 1843 if (e2) printf("e2 = %s\n", e2->toChars());
1844 if (s1) printf("s1 = %s\n", s1->toChars());
1845 if (s2) printf("s2 = %s\n", s2->toChars());
1846 if (v1) printf("v1 = %s\n", v1->toChars());
1847 if (v2) printf("v2 = %s\n", v2->toChars());
1802 #endif 1848 #endif
1803 1849
1804 if (t1 && t2) 1850 if (t1 && t2)
1805 { 1851 {
1806 if (!t1->deduceType(sc, t2, parameters, dedtypes)) 1852 if (!t1->deduceType(sc, t2, parameters, dedtypes))
1843 if (!m) 1889 if (!m)
1844 goto Lnomatch; 1890 goto Lnomatch;
1845 dedtypes->data[j] = e1; 1891 dedtypes->data[j] = e1;
1846 } 1892 }
1847 } 1893 }
1848 // BUG: Need to handle alias and tuple parameters 1894 else if (s1 && t2 && t2->ty == Tident)
1895 {
1896 j = templateParameterLookup(t2, parameters);
1897 if (j == -1)
1898 goto Lnomatch;
1899 TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
1900 // BUG: use tp->matchArg() instead of the following
1901 TemplateAliasParameter *ta = tp->isTemplateAliasParameter();
1902 if (!ta)
1903 goto Lnomatch;
1904 Dsymbol *s = (Dsymbol *)dedtypes->data[j];
1905 if (s)
1906 {
1907 if (!s1->equals(s))
1908 goto Lnomatch;
1909 }
1910 else
1911 {
1912 dedtypes->data[j] = s1;
1913 }
1914 }
1915 else if (s1 && s2)
1916 {
1917 if (!s1->equals(s2))
1918 goto Lnomatch;
1919 }
1920 // BUG: Need to handle tuple parameters
1849 else 1921 else
1850 goto Lnomatch; 1922 goto Lnomatch;
1851 } 1923 }
1852 } 1924 }
1853 return Type::deduceType(sc, tparam, parameters, dedtypes); 1925 return Type::deduceType(sc, tparam, parameters, dedtypes);
2111 * *psparam set to symbol declared and initialized to dedtypes[i] 2183 * *psparam set to symbol declared and initialized to dedtypes[i]
2112 */ 2184 */
2113 2185
2114 MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs, 2186 MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs,
2115 int i, TemplateParameters *parameters, Objects *dedtypes, 2187 int i, TemplateParameters *parameters, Objects *dedtypes,
2116 Declaration **psparam) 2188 Declaration **psparam, int flags)
2117 { 2189 {
2118 //printf("TemplateTypeParameter::matchArg()\n"); 2190 //printf("TemplateTypeParameter::matchArg()\n");
2119 Type *t; 2191 Type *t;
2120 Object *oarg; 2192 Object *oarg;
2121 MATCH m = MATCHexact; 2193 MATCH m = MATCHexact;
2355 return 0; 2427 return 0;
2356 } 2428 }
2357 2429
2358 MATCH TemplateAliasParameter::matchArg(Scope *sc, 2430 MATCH TemplateAliasParameter::matchArg(Scope *sc,
2359 Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, 2431 Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
2360 Declaration **psparam) 2432 Declaration **psparam, int flags)
2361 { 2433 {
2362 Dsymbol *sa; 2434 Dsymbol *sa;
2363 Object *oarg; 2435 Object *oarg;
2364 Expression *ea; 2436 Expression *ea;
2365 2437
2567 } 2639 }
2568 2640
2569 2641
2570 MATCH TemplateValueParameter::matchArg(Scope *sc, 2642 MATCH TemplateValueParameter::matchArg(Scope *sc,
2571 Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, 2643 Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes,
2572 Declaration **psparam) 2644 Declaration **psparam, int flags)
2573 { 2645 {
2574 //printf("TemplateValueParameter::matchArg()\n"); 2646 //printf("TemplateValueParameter::matchArg()\n");
2575 2647
2576 Initializer *init; 2648 Initializer *init;
2577 Declaration *sparam; 2649 Declaration *sparam;
2764 } 2836 }
2765 2837
2766 MATCH TemplateTupleParameter::matchArg(Scope *sc, 2838 MATCH TemplateTupleParameter::matchArg(Scope *sc,
2767 Objects *tiargs, int i, TemplateParameters *parameters, 2839 Objects *tiargs, int i, TemplateParameters *parameters,
2768 Objects *dedtypes, 2840 Objects *dedtypes,
2769 Declaration **psparam) 2841 Declaration **psparam, int flags)
2770 { 2842 {
2771 //printf("TemplateTupleParameter::matchArg()\n"); 2843 //printf("TemplateTupleParameter::matchArg()\n");
2772 2844
2773 /* The rest of the actual arguments (tiargs[]) form the match 2845 /* The rest of the actual arguments (tiargs[]) form the match
2774 * for the variadic parameter. 2846 * for the variadic parameter.
3024 //printf("error return %p, %d\n", tempdecl, global.errors); 3096 //printf("error return %p, %d\n", tempdecl, global.errors);
3025 return; // error recovery 3097 return; // error recovery
3026 } 3098 }
3027 } 3099 }
3028 3100
3029 isNested(tiargs); 3101 hasNestedArgs(tiargs);
3030 3102
3031 /* See if there is an existing TemplateInstantiation that already 3103 /* See if there is an existing TemplateInstantiation that already
3032 * implements the typeargs. If so, just refer to that one instead. 3104 * implements the typeargs. If so, just refer to that one instead.
3033 */ 3105 */
3034 3106
3099 break; 3171 break;
3100 #endif 3172 #endif
3101 3173
3102 //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); 3174 //if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
3103 if (scx && scx->scopesym && 3175 if (scx && scx->scopesym &&
3104 scx->scopesym->members && !scx->scopesym->isTemplateMixin() && 3176 scx->scopesym->members && !scx->scopesym->isTemplateMixin()
3105 /* The following test should really be if scx->module recursively 3177 #if 1 // removed because it bloated compile times
3106 * imports itself. Because if it does, see bugzilla 2500. 3178 /* The problem is if A imports B, and B imports A, and both A
3179 * and B instantiate the same template, does the compilation of A
3180 * or the compilation of B do the actual instantiation?
3181 *
3182 * see bugzilla 2500.
3107 */ 3183 */
3108 //scx->module == tempdecl->getModule() 3184 && !scx->module->selfImports()
3109 !scx->module->imports(scx->module) 3185 #endif
3110 ) 3186 )
3111 { 3187 {
3112 //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars()); 3188 //printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
3113 a = scx->scopesym->members; 3189 a = scx->scopesym->members;
3114 } 3190 }
3149 argsym = new ScopeDsymbol(); 3225 argsym = new ScopeDsymbol();
3150 argsym->parent = scope->parent; 3226 argsym->parent = scope->parent;
3151 scope = scope->push(argsym); 3227 scope = scope->push(argsym);
3152 3228
3153 // Declare each template parameter as an alias for the argument type 3229 // Declare each template parameter as an alias for the argument type
3154 declareParameters(scope); 3230 Scope *paramscope = scope->push();
3231 paramscope->stc = 0;
3232 declareParameters(paramscope);
3233 paramscope->pop();
3155 3234
3156 // Add members of template instance to template instance symbol table 3235 // Add members of template instance to template instance symbol table
3157 // parent = scope->scopesym; 3236 // parent = scope->scopesym;
3158 symtab = new DsymbolTable(); 3237 symtab = new DsymbolTable();
3159 int memnum = 0; 3238 int memnum = 0;
3618 /***************************************** 3697 /*****************************************
3619 * Determines if a TemplateInstance will need a nested 3698 * Determines if a TemplateInstance will need a nested
3620 * generation of the TemplateDeclaration. 3699 * generation of the TemplateDeclaration.
3621 */ 3700 */
3622 3701
3623 int TemplateInstance::isNested(Objects *args) 3702 int TemplateInstance::hasNestedArgs(Objects *args)
3624 { int nested = 0; 3703 { int nested = 0;
3625 //printf("TemplateInstance::isNested('%s')\n", tempdecl->ident->toChars()); 3704 //printf("TemplateInstance::hasNestedArgs('%s')\n", tempdecl->ident->toChars());
3626 3705
3627 /* A nested instance happens when an argument references a local 3706 /* A nested instance happens when an argument references a local
3628 * symbol that is on the stack. 3707 * symbol that is on the stack.
3629 */ 3708 */
3630 for (size_t i = 0; i < args->dim; i++) 3709 for (size_t i = 0; i < args->dim; i++)
3689 error("cannot use local '%s' as template parameter", d->toChars()); 3768 error("cannot use local '%s' as template parameter", d->toChars());
3690 } 3769 }
3691 } 3770 }
3692 else if (va) 3771 else if (va)
3693 { 3772 {
3694 nested |= isNested(&va->objects); 3773 nested |= hasNestedArgs(&va->objects);
3695 } 3774 }
3696 } 3775 }
3697 return nested; 3776 return nested;
3698 } 3777 }
3699 3778
3708 char *id; 3787 char *id;
3709 Objects *args; 3788 Objects *args;
3710 3789
3711 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); 3790 //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars());
3712 id = tempdecl->ident->toChars(); 3791 id = tempdecl->ident->toChars();
3713 buf.printf("__T%"PRIuSIZE"%s", strlen(id), id); 3792 buf.printf("__T%zu%s", strlen(id), id);
3714 args = tiargs; 3793 args = tiargs;
3715 for (int i = 0; i < args->dim; i++) 3794 for (int i = 0; i < args->dim; i++)
3716 { Object *o = (Object *)args->data[i]; 3795 { Object *o = (Object *)args->data[i];
3717 Type *ta = isType(o); 3796 Type *ta = isType(o);
3718 Expression *ea = isExpression(o); 3797 Expression *ea = isExpression(o);
3775 if (d && !d->type->deco) 3854 if (d && !d->type->deco)
3776 error("forward reference of %s", d->toChars()); 3855 error("forward reference of %s", d->toChars());
3777 else 3856 else
3778 { 3857 {
3779 char *p = sa->mangle(); 3858 char *p = sa->mangle();
3780 buf.printf("%"PRIuSIZE"%s", strlen(p), p); 3859 buf.printf("%zu%s", strlen(p), p);
3781 } 3860 }
3782 } 3861 }
3783 else if (va) 3862 else if (va)
3784 { 3863 {
3785 assert(i + 1 == args->dim); // must be last one 3864 assert(i + 1 == args->dim); // must be last one