Mercurial > projects > ddmd
comparison dmd/TemplateTypeParameter.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | b7d29f613539 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
1 module dmd.TemplateTypeParameter; | |
2 | |
3 import dmd.TemplateParameter; | |
4 import dmd.Type; | |
5 import dmd.Loc; | |
6 import dmd.Identifier; | |
7 import dmd.Scope; | |
8 import dmd.OutBuffer; | |
9 import dmd.HdrGenState; | |
10 import dmd.Declaration; | |
11 import dmd.ArrayTypes; | |
12 import dmd.TypeIdentifier; | |
13 import dmd.AliasDeclaration; | |
14 import dmd.Util; | |
15 import dmd.MATCH; | |
16 import dmd.Dsymbol; | |
17 | |
18 class TemplateTypeParameter : TemplateParameter | |
19 { | |
20 /* Syntax: | |
21 * ident : specType = defaultType | |
22 */ | |
23 Type specType; // type parameter: if !=null, this is the type specialization | |
24 Type defaultType; | |
25 | |
26 this(Loc loc, Identifier ident, Type specType, Type defaultType) | |
27 { | |
28 super(loc, ident); | |
29 this.ident = ident; | |
30 this.specType = specType; | |
31 this.defaultType = defaultType; | |
32 } | |
33 | |
34 TemplateTypeParameter isTemplateTypeParameter() | |
35 { | |
36 return this; | |
37 } | |
38 | |
39 TemplateParameter syntaxCopy() | |
40 { | |
41 assert(false); | |
42 } | |
43 | |
44 void declareParameter(Scope sc) | |
45 { | |
46 //printf("TemplateTypeParameter.declareParameter('%s')\n", ident.toChars()); | |
47 TypeIdentifier ti = new TypeIdentifier(loc, ident); | |
48 sparam = new AliasDeclaration(loc, ident, ti); | |
49 if (!sc.insert(sparam)) | |
50 error(loc, "parameter '%s' multiply defined", ident.toChars()); | |
51 } | |
52 | |
53 void semantic(Scope sc) | |
54 { | |
55 //printf("TemplateTypeParameter.semantic('%s')\n", ident.toChars()); | |
56 if (specType) | |
57 { | |
58 specType = specType.semantic(loc, sc); | |
59 } | |
60 static if (false) { // Don't do semantic() until instantiation | |
61 if (defaultType) | |
62 { | |
63 defaultType = defaultType.semantic(loc, sc); | |
64 } | |
65 } | |
66 } | |
67 | |
68 void print(Object oarg, Object oded) | |
69 { | |
70 assert(false); | |
71 } | |
72 | |
73 void toCBuffer(OutBuffer buf, HdrGenState* hgs) | |
74 { | |
75 buf.writestring(ident.toChars()); | |
76 if (specType) | |
77 { | |
78 buf.writestring(" : "); | |
79 specType.toCBuffer(buf, null, hgs); | |
80 } | |
81 if (defaultType) | |
82 { | |
83 buf.writestring(" = "); | |
84 defaultType.toCBuffer(buf, null, hgs); | |
85 } | |
86 } | |
87 | |
88 Object specialization() | |
89 { | |
90 return specType; | |
91 } | |
92 | |
93 Object defaultArg(Loc loc, Scope sc) | |
94 { | |
95 Type t; | |
96 | |
97 t = defaultType; | |
98 if (t) | |
99 { | |
100 t = t.syntaxCopy(); | |
101 t = t.semantic(loc, sc); | |
102 } | |
103 return t; | |
104 } | |
105 | |
106 bool overloadMatch(TemplateParameter) | |
107 { | |
108 assert(false); | |
109 } | |
110 | |
111 /******************************************* | |
112 * Match to a particular TemplateParameter. | |
113 * Input: | |
114 * i i'th argument | |
115 * tiargs[] actual arguments to template instance | |
116 * parameters[] template parameters | |
117 * dedtypes[] deduced arguments to template instance | |
118 * *psparam set to symbol declared and initialized to dedtypes[i] | |
119 * flags 1: don't do 'toHeadMutable()' | |
120 */ | |
121 MATCH matchArg(Scope sc, Objects tiargs, int i, TemplateParameters parameters, Objects dedtypes, Declaration* psparam, int flags) | |
122 { | |
123 //printf("TemplateTypeParameter.matchArg()\n"); | |
124 Type t; | |
125 Object oarg; | |
126 MATCH m = MATCHexact; | |
127 Type ta; | |
128 | |
129 if (i < tiargs.dim) | |
130 oarg = cast(Object)tiargs.data[i]; | |
131 else | |
132 { | |
133 // Get default argument instead | |
134 oarg = defaultArg(loc, sc); | |
135 if (!oarg) | |
136 { | |
137 assert(i < dedtypes.dim); | |
138 // It might have already been deduced | |
139 oarg = cast(Object)dedtypes.data[i]; | |
140 if (!oarg) | |
141 { | |
142 goto Lnomatch; | |
143 } | |
144 flags |= 1; // already deduced, so don't to toHeadMutable() | |
145 } | |
146 } | |
147 | |
148 ta = isType(oarg); | |
149 if (!ta) | |
150 { | |
151 //printf("%s %p %p %p\n", oarg.toChars(), isExpression(oarg), isDsymbol(oarg), isTuple(oarg)); | |
152 goto Lnomatch; | |
153 } | |
154 //printf("ta is %s\n", ta.toChars()); | |
155 | |
156 t = cast(Type)dedtypes.data[i]; | |
157 | |
158 if (specType) | |
159 { | |
160 //printf("\tcalling deduceType(): ta is %s, specType is %s\n", ta.toChars(), specType.toChars()); | |
161 MATCH m2 = ta.deduceType(sc, specType, parameters, dedtypes); | |
162 if (m2 == MATCHnomatch) | |
163 { | |
164 //printf("\tfailed deduceType\n"); | |
165 goto Lnomatch; | |
166 } | |
167 | |
168 if (m2 < m) | |
169 m = m2; | |
170 t = cast(Type)dedtypes.data[i]; | |
171 } | |
172 else | |
173 { | |
174 // So that matches with specializations are better | |
175 m = MATCHconvert; | |
176 | |
177 /* This is so that: | |
178 * template Foo(T), Foo!(const int), => ta == int | |
179 */ | |
180 // if (!(flags & 1)) | |
181 // ta = ta.toHeadMutable(); | |
182 | |
183 if (t) | |
184 { // Must match already deduced type | |
185 | |
186 m = MATCHexact; | |
187 if (!t.equals(ta)) | |
188 { | |
189 //printf("t = %s ta = %s\n", t.toChars(), ta.toChars()); | |
190 goto Lnomatch; | |
191 } | |
192 } | |
193 } | |
194 | |
195 if (!t) | |
196 { | |
197 dedtypes.data[i] = cast(void*)ta; | |
198 t = ta; | |
199 } | |
200 | |
201 *psparam = new AliasDeclaration(loc, ident, t); | |
202 //printf("\tm = %d\n", m); | |
203 return m; | |
204 | |
205 Lnomatch: | |
206 *psparam = null; | |
207 //printf("\tm = %d\n", MATCHnomatch); | |
208 return MATCHnomatch; | |
209 } | |
210 | |
211 void* dummyArg() | |
212 { | |
213 assert(false); | |
214 } | |
215 } |