Mercurial > projects > ddmd
annotate dmd/TemplateDeclaration.d @ 192:eb38fdcb3e62 default tip
updated to compile with dmd2.062
author | korDen |
---|---|
date | Sat, 02 Mar 2013 01:25:52 -0800 |
parents | b0d41ff5e0df |
children |
rev | line source |
---|---|
0 | 1 module dmd.TemplateDeclaration; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Loc; |
5 import dmd.ScopeDsymbol; | |
6 import dmd.ArrayTypes; | |
7 import dmd.Dsymbol; | |
8 import dmd.STC; | |
9 import dmd.TemplateThisParameter; | |
10 import dmd.Global; | |
11 import dmd.Array; | |
12 import dmd.Identifier; | |
13 import dmd.TypeArray; | |
14 import dmd.Expression; | |
15 import dmd.Scope; | |
16 import dmd.TypeIdentifier; | |
17 import dmd.TypeDelegate; | |
18 import dmd.IntegerExp; | |
19 import dmd.TypeSArray; | |
20 import dmd.StringExp; | |
21 import dmd.TOK; | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
22 import dmd.Parameter; |
0 | 23 import dmd.CtorDeclaration; |
24 import dmd.TypeFunction; | |
25 import dmd.TY; | |
26 import dmd.OutBuffer; | |
27 import dmd.Declaration; | |
28 import dmd.HdrGenState; | |
29 import dmd.TemplateInstance; | |
30 import dmd.WANT; | |
31 import dmd.FuncDeclaration; | |
32 import dmd.TemplateTupleParameter; | |
33 import dmd.MATCH; | |
34 import dmd.Type; | |
35 import dmd.Tuple; | |
36 import dmd.TupleDeclaration; | |
37 import dmd.Initializer; | |
79 | 38 import dmd.Json; |
0 | 39 import dmd.ExpInitializer; |
40 import dmd.TemplateValueParameter; | |
41 import dmd.AliasDeclaration; | |
42 import dmd.VarDeclaration; | |
43 import dmd.TemplateParameter; | |
44 import dmd.TemplateTypeParameter; | |
131
206db751bd4c
dmdfe 2.037 compiles now
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
130
diff
changeset
|
45 import dmd.MOD; |
0 | 46 |
47 import dmd.expression.Util; | |
48 | |
49 import std.stdio; | |
50 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
179
diff
changeset
|
51 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
179
diff
changeset
|
52 |
0 | 53 /************************************** |
54 * Determine if TemplateDeclaration is variadic. | |
55 */ | |
56 | |
57 TemplateTupleParameter isVariadic(TemplateParameters parameters) | |
58 { | |
59 size_t dim = parameters.dim; | |
104 | 60 TemplateTupleParameter tp = null; |
0 | 61 |
104 | 62 if (dim) |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
63 tp = parameters[dim - 1].isTemplateTupleParameter(); |
0 | 64 |
104 | 65 return tp; |
0 | 66 } |
67 | |
68 void ObjectToCBuffer(OutBuffer buf, HdrGenState* hgs, Object oarg) | |
69 { | |
104 | 70 //printf("ObjectToCBuffer()\n"); |
71 Type t = isType(oarg); | |
72 Expression e = isExpression(oarg); | |
73 Dsymbol s = isDsymbol(oarg); | |
74 Tuple v = isTuple(oarg); | |
75 if (t) | |
76 { | |
0 | 77 //printf("\tt: %s ty = %d\n", t.toChars(), t.ty); |
78 t.toCBuffer(buf, null, hgs); | |
104 | 79 } |
80 else if (e) | |
0 | 81 e.toCBuffer(buf, hgs); |
104 | 82 else if (s) |
83 { | |
0 | 84 string p = s.ident ? s.ident.toChars() : s.toChars(); |
85 buf.writestring(p); | |
104 | 86 } |
87 else if (v) | |
88 { | |
0 | 89 Objects args = v.objects; |
90 for (size_t i = 0; i < args.dim; i++) | |
91 { | |
92 if (i) | |
93 buf.writeByte(','); | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
94 Object o = args[i]; |
0 | 95 ObjectToCBuffer(buf, hgs, o); |
96 } | |
104 | 97 } |
98 else if (!oarg) | |
99 { | |
0 | 100 buf.writestring("null"); |
104 | 101 } |
102 else | |
103 { | |
0 | 104 debug writef("bad Object = %p\n", oarg); |
105 assert(0); | |
104 | 106 } |
0 | 107 } |
108 | |
109 class TemplateDeclaration : ScopeDsymbol | |
110 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
179
diff
changeset
|
111 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
179
diff
changeset
|
112 |
104 | 113 TemplateParameters parameters; // array of TemplateParameter's |
0 | 114 |
104 | 115 TemplateParameters origParameters; // originals for Ddoc |
116 Expression constraint; | |
128
e6e542f37b94
Some more Array -> Vector conversions
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
117 Vector!TemplateInstance instances; // array of TemplateInstance's |
0 | 118 |
104 | 119 TemplateDeclaration overnext; // next overloaded TemplateDeclaration |
120 TemplateDeclaration overroot; // first in overnext list | |
0 | 121 |
104 | 122 int semanticRun; // 1 semantic() run |
0 | 123 |
104 | 124 Dsymbol onemember; // if !=NULL then one member of this template |
0 | 125 |
104 | 126 int literal; // this template declaration is a literal |
0 | 127 |
104 | 128 this(Loc loc, Identifier id, TemplateParameters parameters, Expression constraint, Dsymbols decldefs) |
0 | 129 { |
178 | 130 register(); |
0 | 131 super(id); |
132 | |
133 version (LOG) { | |
134 printf("TemplateDeclaration(this = %p, id = '%s')\n", this, id.toChars()); | |
135 } | |
136 static if (false) { | |
137 if (parameters) | |
138 for (int i = 0; i < parameters.dim; i++) | |
139 { | |
140 TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; | |
141 //printf("\tparameter[%d] = %p\n", i, tp); | |
142 TemplateTypeParameter ttp = tp.isTemplateTypeParameter(); | |
143 | |
144 if (ttp) | |
145 { | |
146 printf("\tparameter[%d] = %s : %s\n", i, tp.ident.toChars(), ttp.specType ? ttp.specType.toChars() : ""); | |
147 } | |
148 } | |
149 } | |
150 | |
151 this.loc = loc; | |
152 this.parameters = parameters; | |
153 this.origParameters = parameters; | |
154 this.constraint = constraint; | |
155 this.members = decldefs; | |
156 | |
128
e6e542f37b94
Some more Array -> Vector conversions
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
126
diff
changeset
|
157 instances = new Vector!TemplateInstance(); |
0 | 158 } |
159 | |
104 | 160 override Dsymbol syntaxCopy(Dsymbol) |
0 | 161 { |
51 | 162 //printf("TemplateDeclaration.syntaxCopy()\n"); |
163 TemplateDeclaration td; | |
164 TemplateParameters p; | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
72
diff
changeset
|
165 Dsymbols d; |
51 | 166 |
167 p = null; | |
168 if (parameters) | |
169 { | |
170 p = new TemplateParameters(); | |
171 p.setDim(parameters.dim); | |
172 for (int i = 0; i < p.dim; i++) | |
173 { | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
174 auto tp = parameters[i]; |
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
175 p[i] = tp.syntaxCopy(); |
51 | 176 } |
177 } | |
178 | |
179 Expression e = null; | |
180 if (constraint) | |
181 e = constraint.syntaxCopy(); | |
182 d = Dsymbol.arraySyntaxCopy(members); | |
183 td = new TemplateDeclaration(loc, ident, p, e, d); | |
184 return td; | |
0 | 185 } |
186 | |
104 | 187 override void semantic(Scope sc) |
0 | 188 { |
189 version (LOG) { | |
179 | 190 writef("TemplateDeclaration.semantic(this = %p, id = '%s')\n", this, ident.toChars()); |
191 writef("sc.stc = %llx\n", sc.stc); | |
0 | 192 } |
193 if (semanticRun) | |
194 return; // semantic() already run | |
195 semanticRun = 1; | |
196 | |
197 if (sc.func) | |
198 { | |
199 version (DMDV1) { | |
200 error("cannot declare template at function scope %s", sc.func.toChars()); | |
201 } | |
202 } | |
203 | |
204 if (/*global.params.useArrayBounds &&*/ sc.module_) | |
205 { | |
206 // Generate this function as it may be used | |
207 // when template is instantiated in other modules | |
208 sc.module_.toModuleArray(); | |
209 } | |
210 | |
211 if (/*global.params.useAssert &&*/ sc.module_) | |
212 { | |
213 // Generate this function as it may be used | |
214 // when template is instantiated in other modules | |
215 sc.module_.toModuleAssert(); | |
216 } | |
217 | |
218 /* Remember Scope for later instantiations, but make | |
219 * a copy since attributes can change. | |
220 */ | |
87
b17640f0e4e8
Fixed a bug with a Scope.this(Scope enclosing) being called instead of Scope.clone() method (as a copy ctor replacement)
korDen
parents:
79
diff
changeset
|
221 this.scope_ = sc.clone(); |
0 | 222 this.scope_.setNoFree(); |
223 | |
224 // Set up scope for parameters | |
225 ScopeDsymbol paramsym = new ScopeDsymbol(); | |
226 paramsym.parent = sc.parent; | |
227 Scope paramscope = sc.push(paramsym); | |
228 paramscope.parameterSpecialization = 1; | |
229 paramscope.stc = STCundefined; | |
230 | |
231 if (!parent) | |
232 parent = sc.parent; | |
233 | |
234 if (global.params.doDocComments) | |
235 { | |
236 origParameters = new TemplateParameters(); | |
237 origParameters.setDim(parameters.dim); | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
238 foreach (size_t i, TemplateParameter tp; parameters) |
0 | 239 { |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
240 origParameters[i] = tp.syntaxCopy(); |
0 | 241 } |
242 } | |
243 | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
244 foreach (tp; parameters) |
0 | 245 { |
246 tp.declareParameter(paramscope); | |
247 } | |
248 | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
249 foreach (size_t i, TemplateParameter tp; parameters) |
0 | 250 { |
251 tp.semantic(paramscope); | |
252 if (i + 1 != parameters.dim && tp.isTemplateTupleParameter()) | |
253 error("template tuple parameter must be last one"); | |
254 } | |
255 | |
256 paramscope.pop(); | |
257 | |
258 if (members) | |
259 { | |
260 Dsymbol s; | |
261 if (Dsymbol.oneMembers(members, &s)) | |
262 { | |
263 if (s && s.ident && s.ident.equals(ident)) | |
264 { | |
265 onemember = s; | |
266 s.parent = this; | |
267 } | |
268 } | |
269 } | |
270 | |
271 /* BUG: should check: | |
272 * o no virtual functions or non-static data members of classes | |
273 */ | |
274 } | |
275 | |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
276 /********************************** |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
277 * Overload existing TemplateDeclaration 'this' with the new one 's'. |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
278 * Return !=0 if successful; i.e. no conflict. |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
279 */ |
104 | 280 override bool overloadInsert(Dsymbol s) |
0 | 281 { |
50 | 282 TemplateDeclaration *pf; |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
283 TemplateDeclaration f; |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
284 |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
285 version (LOG) { |
50 | 286 printf("TemplateDeclaration.overloadInsert('%.*s')\n", s.toChars()); |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
287 } |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
288 f = s.isTemplateDeclaration(); |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
289 if (!f) |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
290 return false; |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
291 |
50 | 292 TemplateDeclaration pthis = this; |
293 for (pf = &pthis; *pf; pf = &(*pf).overnext) | |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
294 { |
50 | 295 static if (false) { |
296 // Conflict if TemplateParameter's match | |
297 // Will get caught anyway later with TemplateInstance, but | |
298 // should check it now. | |
299 if (f.parameters.dim != f2.parameters.dim) | |
300 goto Lcontinue; | |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
301 |
50 | 302 for (int i = 0; i < f.parameters.dim; i++) |
303 { | |
304 TemplateParameter p1 = cast(TemplateParameter)f.parameters.data[i]; | |
305 TemplateParameter p2 = cast(TemplateParameter)f2.parameters.data[i]; | |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
306 |
50 | 307 if (!p1.overloadMatch(p2)) |
308 goto Lcontinue; | |
309 } | |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
310 |
50 | 311 version (LOG) { |
312 printf("\tfalse: conflict\n"); | |
313 } | |
314 return false; | |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
315 |
50 | 316 Lcontinue: |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
317 ; |
50 | 318 } |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
319 } |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
320 |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
321 f.overroot = this; |
50 | 322 *pf = f; |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
323 version (LOG) { |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
324 printf("\ttrue: no conflict\n"); |
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
325 } |
50 | 326 |
8
d42cd5917df4
wysiwyg strings, alias this, templates, TypeSlice implementation
dkoroskin <>
parents:
0
diff
changeset
|
327 return true; |
0 | 328 } |
329 | |
104 | 330 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 331 { |
104 | 332 static if (false) // Should handle template functions |
333 { | |
334 if (onemember && onemember.isFuncDeclaration()) | |
335 buf.writestring("foo "); | |
336 } | |
337 buf.writestring(kind()); | |
338 buf.writeByte(' '); | |
339 buf.writestring(ident.toChars()); | |
340 buf.writeByte('('); | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
341 foreach (size_t i, TemplateParameter tp; parameters) |
104 | 342 { |
343 if (hgs.ddoc) | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
344 tp = origParameters[i]; |
104 | 345 if (i) |
346 buf.writeByte(','); | |
347 tp.toCBuffer(buf, hgs); | |
348 } | |
349 buf.writeByte(')'); | |
350 version(DMDV2) | |
351 { | |
352 if (constraint) | |
353 { buf.writestring(" if ("); | |
354 constraint.toCBuffer(buf, hgs); | |
355 buf.writeByte(')'); | |
356 } | |
357 } | |
358 | |
359 if (hgs.hdrgen) | |
360 { | |
361 hgs.tpltMember++; | |
362 buf.writenl(); | |
363 buf.writebyte('{'); | |
364 buf.writenl(); | |
365 foreach (Dsymbol s; members) | |
366 s.toCBuffer(buf, hgs); | |
367 | |
368 buf.writebyte('}'); | |
369 buf.writenl(); | |
370 hgs.tpltMember--; | |
371 } | |
0 | 372 } |
373 | |
79 | 374 override void toJsonBuffer(OutBuffer buf) |
375 { | |
376 //writef("TemplateDeclaration.toJsonBuffer()\n"); | |
377 | |
378 buf.writestring("{\n"); | |
379 | |
380 JsonProperty(buf, Pname, toChars()); | |
381 JsonProperty(buf, Pkind, kind()); | |
382 if (comment) | |
383 JsonProperty(buf, Pcomment, comment); | |
384 | |
385 if (loc.linnum) | |
386 JsonProperty(buf, Pline, loc.linnum); | |
387 | |
388 JsonString(buf, Pmembers); | |
389 buf.writestring(" : [\n"); | |
390 size_t offset = buf.offset; | |
391 foreach (Dsymbol s; members) | |
392 { | |
393 if (offset != buf.offset) | |
96 | 394 { buf.writestring(",\n"); |
79 | 395 offset = buf.offset; |
396 } | |
397 s.toJsonBuffer(buf); | |
398 } | |
96 | 399 JsonRemoveComma(buf); |
79 | 400 buf.writestring("]\n"); |
401 | |
402 buf.writestring("}\n"); | |
403 } | |
404 | |
104 | 405 override string kind() |
0 | 406 { |
50 | 407 return (onemember && onemember.isAggregateDeclaration()) |
408 ? onemember.kind() | |
409 : "template"; | |
0 | 410 } |
411 | |
104 | 412 override string toChars() |
0 | 413 { |
49 | 414 OutBuffer buf = new OutBuffer(); |
415 HdrGenState hgs; | |
416 | |
417 /// memset(&hgs, 0, hgs.sizeof); | |
418 buf.writestring(ident.toChars()); | |
419 buf.writeByte('('); | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
420 foreach (size_t i, TemplateParameter tp; parameters) |
49 | 421 { |
422 if (i) | |
423 buf.writeByte(','); | |
424 tp.toCBuffer(buf, &hgs); | |
425 } | |
426 buf.writeByte(')'); | |
427 version (DMDV2) { | |
428 if (constraint) | |
429 { | |
430 buf.writestring(" if ("); | |
431 constraint.toCBuffer(buf, &hgs); | |
432 buf.writeByte(')'); | |
433 } | |
434 } | |
435 buf.writeByte(0); | |
436 return buf.extractString(); | |
0 | 437 } |
438 | |
104 | 439 override void emitComment(Scope sc) |
0 | 440 { |
441 assert(false); | |
442 } | |
50 | 443 |
104 | 444 // void toDocBuffer(OutBuffer *buf); |
0 | 445 |
446 /*************************************** | |
447 * Given that ti is an instance of this TemplateDeclaration, | |
448 * deduce the types of the parameters to this, and store | |
449 * those deduced types in dedtypes[]. | |
450 * Input: | |
451 * flag 1: don't do semantic() because of dummy types | |
452 * 2: don't change types in matchArg() | |
453 * Output: | |
454 * dedtypes deduced arguments | |
455 * Return match level. | |
456 */ | |
104 | 457 MATCH matchWithInstance(TemplateInstance ti, Objects dedtypes, int flag) |
0 | 458 { |
459 MATCH m; | |
460 int dedtypes_dim = dedtypes.dim; | |
461 | |
462 version (LOGM) { | |
50 | 463 printf("\n+TemplateDeclaration.matchWithInstance(this = %.*s, ti = %.*s, flag = %d)\n", toChars(), ti.toChars(), flag); |
0 | 464 } |
465 | |
466 static if (false) { | |
467 printf("dedtypes.dim = %d, parameters.dim = %d\n", dedtypes_dim, parameters.dim); | |
468 if (ti.tiargs.dim) | |
469 printf("ti.tiargs.dim = %d, [0] = %p\n", ti.tiargs.dim, ti.tiargs.data[0]); | |
470 } | |
471 dedtypes.zero(); | |
472 | |
473 int parameters_dim = parameters.dim; | |
474 int variadic = isVariadic() !is null; | |
475 | |
476 // If more arguments than parameters, no match | |
477 if (ti.tiargs.dim > parameters_dim && !variadic) | |
478 { | |
479 version (LOGM) { | |
50 | 480 printf(" no match: more arguments than parameters\n"); |
0 | 481 } |
50 | 482 return MATCHnomatch; |
0 | 483 } |
484 | |
485 assert(dedtypes_dim == parameters_dim); | |
486 assert(dedtypes_dim >= ti.tiargs.dim || variadic); | |
487 | |
488 // Set up scope for parameters | |
489 assert(cast(size_t)cast(void*)scope_ > 0x10000); | |
490 ScopeDsymbol paramsym = new ScopeDsymbol(); | |
491 paramsym.parent = scope_.parent; | |
492 Scope paramscope = scope_.push(paramsym); | |
493 paramscope.stc = STCundefined; | |
494 | |
495 // Attempt type deduction | |
496 m = MATCHexact; | |
497 for (int i = 0; i < dedtypes_dim; i++) | |
498 { | |
499 MATCH m2; | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
500 auto tp = parameters[i]; |
0 | 501 Declaration sparam; |
502 | |
503 //printf("\targument [%d]\n", i); | |
504 version (LOGM) { | |
505 //printf("\targument [%d] is %s\n", i, oarg ? oarg.toChars() : "null"); | |
506 TemplateTypeParameter *ttp = tp.isTemplateTypeParameter(); | |
507 if (ttp) | |
508 printf("\tparameter[%d] is %s : %s\n", i, tp.ident.toChars(), ttp.specType ? ttp.specType.toChars() : ""); | |
509 } | |
510 | |
511 version (DMDV1) { | |
512 m2 = tp.matchArg(paramscope, ti.tiargs, i, parameters, dedtypes, &sparam); | |
513 } else { | |
514 m2 = tp.matchArg(paramscope, ti.tiargs, i, parameters, dedtypes, &sparam, (flag & 2) ? 1 : 0); | |
515 } | |
516 //printf("\tm2 = %d\n", m2); | |
517 | |
518 if (m2 == MATCHnomatch) | |
519 { | |
520 static if (false) { | |
521 printf("\tmatchArg() for parameter %i failed\n", i); | |
522 } | |
523 goto Lnomatch; | |
524 } | |
525 | |
526 if (m2 < m) | |
527 m = m2; | |
528 | |
529 if (!flag) | |
530 sparam.semantic(paramscope); | |
531 if (!paramscope.insert(sparam)) | |
532 goto Lnomatch; | |
533 } | |
534 | |
535 if (!flag) | |
536 { | |
537 /* Any parameter left without a type gets the type of | |
538 * its corresponding arg | |
539 */ | |
540 for (int i = 0; i < dedtypes_dim; i++) | |
541 { | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
542 if (!dedtypes[i]) |
0 | 543 { |
544 assert(i < ti.tiargs.dim); | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
545 dedtypes[i] = ti.tiargs[i]; |
0 | 546 } |
547 } | |
548 } | |
549 | |
550 version (DMDV2) { | |
551 if (m && constraint && !(flag & 1)) | |
552 { /* Check to see if constraint is satisfied. | |
553 */ | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
554 makeParamNamesVisibleInConstraint(paramscope); |
0 | 555 Expression e = constraint.syntaxCopy(); |
556 paramscope.flags |= SCOPE.SCOPEstaticif; | |
557 e = e.semantic(paramscope); | |
558 e = e.optimize(WANTvalue | WANTinterpret); | |
559 if (e.isBool(true)) { | |
560 ; | |
561 } else if (e.isBool(false)) | |
562 goto Lnomatch; | |
563 else | |
564 { | |
565 e.error("constraint %s is not constant or does not evaluate to a bool", e.toChars()); | |
566 } | |
567 } | |
568 } | |
569 | |
570 version (LOGM) { | |
571 // Print out the results | |
572 printf("--------------------------\n"); | |
573 printf("template %s\n", toChars()); | |
574 printf("instance %s\n", ti.toChars()); | |
575 if (m) | |
576 { | |
577 for (int i = 0; i < dedtypes_dim; i++) | |
578 { | |
579 TemplateParameter tp = cast(TemplateParameter)parameters.data[i]; | |
580 Object oarg; | |
581 | |
582 printf(" [%d]", i); | |
583 | |
584 if (i < ti.tiargs.dim) | |
585 oarg = cast(Object)ti.tiargs.data[i]; | |
586 else | |
587 oarg = null; | |
588 tp.print(oarg, cast(Object)dedtypes.data[i]); | |
589 } | |
590 } | |
591 else | |
592 goto Lnomatch; | |
593 } | |
594 | |
595 version (LOGM) { | |
596 printf(" match = %d\n", m); | |
597 } | |
598 goto Lret; | |
599 | |
600 Lnomatch: | |
601 version (LOGM) { | |
602 printf(" no match\n"); | |
603 } | |
604 m = MATCHnomatch; | |
605 | |
606 Lret: | |
607 paramscope.pop(); | |
608 version (LOGM) { | |
609 printf("-TemplateDeclaration.matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m); | |
610 } | |
611 return m; | |
612 } | |
613 | |
51 | 614 /******************************************** |
615 * Determine partial specialization order of 'this' vs td2. | |
616 * Returns: | |
617 * match this is at least as specialized as td2 | |
618 * 0 td2 is more specialized than this | |
619 */ | |
104 | 620 MATCH leastAsSpecialized(TemplateDeclaration td2) |
0 | 621 { |
104 | 622 /* This works by taking the template parameters to this template |
51 | 623 * declaration and feeding them to td2 as if it were a template |
624 * instance. | |
625 * If it works, then this template is at least as specialized | |
626 * as td2. | |
627 */ | |
628 | |
629 scope TemplateInstance ti = new TemplateInstance(Loc(0), ident); // create dummy template instance | |
630 scope Objects dedtypes = new Objects(); | |
631 | |
632 version (LOG_LEASTAS) { | |
633 printf("%s.leastAsSpecialized(%s)\n", toChars(), td2.toChars()); | |
634 } | |
635 | |
636 // Set type arguments to dummy template instance to be types | |
637 // generated from the parameters to this template declaration | |
638 ti.tiargs = new Objects(); | |
639 ti.tiargs.setDim(parameters.dim); | |
640 for (int i = 0; i < ti.tiargs.dim; i++) | |
641 { | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
642 auto tp = parameters[i]; |
51 | 643 |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
644 auto p = tp.dummyArg(); |
51 | 645 if (p) |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
646 ti.tiargs[i] = p; |
51 | 647 else |
648 ti.tiargs.setDim(i); | |
649 } | |
650 | |
651 // Temporary Array to hold deduced types | |
652 //dedtypes.setDim(parameters.dim); | |
653 dedtypes.setDim(td2.parameters.dim); | |
654 | |
655 // Attempt a type deduction | |
656 MATCH m = td2.matchWithInstance(ti, dedtypes, 1); | |
657 if (m) | |
658 { | |
659 /* A non-variadic template is more specialized than a | |
660 * variadic one. | |
661 */ | |
662 if (isVariadic() && !td2.isVariadic()) | |
663 goto L1; | |
664 | |
665 version (LOG_LEASTAS) { | |
666 printf(" matches %d, so is least as specialized\n", m); | |
667 } | |
668 return m; | |
669 } | |
670 L1: | |
671 version (LOG_LEASTAS) { | |
672 printf(" doesn't match, so is not as specialized\n"); | |
673 } | |
674 return MATCHnomatch; | |
0 | 675 } |
676 | |
677 /************************************************* | |
678 * Match function arguments against a specific template function. | |
679 * Input: | |
680 * loc instantiation location | |
681 * targsi Expression/Type initial list of template arguments | |
682 * ethis 'this' argument if !null | |
683 * fargs arguments to function | |
684 * Output: | |
685 * dedargs Expression/Type deduced template arguments | |
686 * Returns: | |
687 * match level | |
688 */ | |
104 | 689 MATCH deduceFunctionTemplateMatch(Loc loc, Objects targsi, Expression ethis, Expressions fargs, Objects dedargs) |
0 | 690 { |
691 size_t nfparams; | |
692 size_t nfargs; | |
693 size_t nargsi; // array size of targsi | |
694 int fptupindex = -1; | |
695 int tuple_dim = 0; | |
696 MATCH match = MATCHexact; | |
697 FuncDeclaration fd = onemember.toAlias().isFuncDeclaration(); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
698 Parameters fparameters; // function parameter list |
0 | 699 int fvarargs; // function varargs |
700 scope Objects dedtypes = new Objects(); // for T:T*, the dedargs is the T*, dedtypes is the T | |
701 | |
79 | 702 static if (false) |
703 { | |
0 | 704 printf("\nTemplateDeclaration.deduceFunctionTemplateMatch() %s\n", toChars()); |
705 for (i = 0; i < fargs.dim; i++) | |
706 { | |
707 Expression e = cast(Expression)fargs.data[i]; | |
708 printf("\tfarg[%d] is %s, type is %s\n", i, e.toChars(), e.type.toChars()); | |
709 } | |
710 printf("fd = %s\n", fd.toChars()); | |
179 | 711 printf("fd.type = %s\n", fd.type.toChars()); |
712 if (ethis) | |
713 printf("ethis.type = %s\n", ethis.type.toChars()); | |
0 | 714 } |
715 | |
716 assert(cast(size_t)cast(void*)scope_ > 0x10000); | |
717 | |
718 dedargs.setDim(parameters.dim); | |
719 dedargs.zero(); | |
720 | |
721 dedtypes.setDim(parameters.dim); | |
722 dedtypes.zero(); | |
723 | |
724 // Set up scope for parameters | |
725 ScopeDsymbol paramsym = new ScopeDsymbol(); | |
726 paramsym.parent = scope_.parent; | |
727 Scope paramscope = scope_.push(paramsym); | |
728 | |
729 TemplateTupleParameter tp = isVariadic(); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
730 int tp_is_declared = 0; |
0 | 731 |
79 | 732 static if (false) |
733 { | |
0 | 734 for (i = 0; i < dedargs.dim; i++) |
735 { | |
736 printf("\tdedarg[%d] = ", i); | |
737 Object oarg = cast(Object)dedargs.data[i]; | |
738 if (oarg) printf("%s", oarg.toChars()); | |
739 printf("\n"); | |
740 } | |
741 } | |
742 | |
743 | |
744 nargsi = 0; | |
745 if (targsi) | |
79 | 746 { |
747 // Set initial template arguments | |
0 | 748 nargsi = targsi.dim; |
79 | 749 size_t n = parameters.dim; |
0 | 750 if (tp) |
751 n--; | |
752 if (nargsi > n) | |
753 { | |
754 if (!tp) | |
755 goto Lnomatch; | |
756 | |
757 /* The extra initial template arguments | |
758 * now form the tuple argument. | |
759 */ | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
760 auto t = new Tuple(); |
0 | 761 assert(parameters.dim); |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
762 dedargs[parameters.dim - 1] = t; |
0 | 763 |
764 tuple_dim = nargsi - n; | |
765 t.objects.setDim(tuple_dim); | |
766 for (size_t i = 0; i < tuple_dim; i++) | |
767 { | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
768 t.objects[i] = targsi[n + i]; |
0 | 769 } |
770 declareParameter(paramscope, tp, t); | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
771 tp_is_declared = 1; |
0 | 772 } |
773 else | |
774 n = nargsi; | |
775 | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
776 memcpy(dedargs.ptr, targsi.ptr, n * (*dedargs.ptr).sizeof); |
0 | 777 |
778 for (size_t i = 0; i < n; i++) | |
779 { | |
780 assert(i < parameters.dim); | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
781 auto tp2 = parameters[i]; |
0 | 782 MATCH m; |
783 Declaration sparam = null; | |
784 | |
785 m = tp2.matchArg(paramscope, dedargs, i, parameters, dedtypes, &sparam); | |
786 //printf("\tdeduceType m = %d\n", m); | |
787 if (m == MATCHnomatch) | |
788 goto Lnomatch; | |
789 if (m < match) | |
790 match = m; | |
791 | |
792 sparam.semantic(paramscope); | |
793 if (!paramscope.insert(sparam)) | |
794 goto Lnomatch; | |
795 } | |
796 } | |
79 | 797 static if (false) |
798 { | |
0 | 799 for (i = 0; i < dedargs.dim; i++) |
800 { | |
801 printf("\tdedarg[%d] = ", i); | |
802 Object oarg = cast(Object)dedargs.data[i]; | |
803 if (oarg) printf("%s", oarg.toChars()); | |
804 printf("\n"); | |
805 } | |
806 } | |
807 | |
135 | 808 fparameters = fd.getParameters(&fvarargs); |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
809 nfparams = Parameter.dim(fparameters); // number of function parameters |
0 | 810 nfargs = fargs ? fargs.dim : 0; // number of function arguments |
811 | |
812 /* Check for match of function arguments with variadic template | |
813 * parameter, such as: | |
814 * | |
815 * template Foo(T, A...) { void Foo(T t, A a); } | |
816 * void main() { Foo(1,2,3); } | |
817 */ | |
818 if (tp) // if variadic | |
819 { | |
79 | 820 if (nfparams == 0 && nfargs != 0) // if no function parameters |
0 | 821 { |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
822 if (tp_is_declared) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
823 goto L2; |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
824 auto t = new Tuple(); |
0 | 825 //printf("t = %p\n", t); |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
826 dedargs[parameters.dim - 1] = t; |
0 | 827 declareParameter(paramscope, tp, t); |
828 goto L2; | |
829 } | |
830 else if (nfargs < nfparams - 1) | |
831 goto L1; | |
832 else | |
833 { | |
834 /* Figure out which of the function parameters matches | |
835 * the tuple template parameter. Do this by matching | |
836 * type identifiers. | |
837 * Set the index of this function parameter to fptupindex. | |
838 */ | |
839 for (fptupindex = 0; fptupindex < nfparams; fptupindex++) | |
840 { | |
126
1765f3ef917d
ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
121
diff
changeset
|
841 auto fparam = fparameters[fptupindex]; |
0 | 842 if (fparam.type.ty != Tident) |
843 continue; | |
126
1765f3ef917d
ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
121
diff
changeset
|
844 auto tid = cast(TypeIdentifier)fparam.type; |
0 | 845 if (!tp.ident.equals(tid.ident) || tid.idents.dim) |
846 continue; | |
847 | |
848 if (fvarargs) // variadic function doesn't | |
849 goto Lnomatch; // go with variadic template | |
850 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
851 if (tp_is_declared) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
852 goto L2; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
853 |
0 | 854 /* The types of the function arguments |
855 * now form the tuple argument. | |
856 */ | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
857 auto t = new Tuple(); |
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
858 dedargs[parameters.dim - 1] = t; |
0 | 859 |
860 tuple_dim = nfargs - (nfparams - 1); | |
861 t.objects.setDim(tuple_dim); | |
862 for (size_t i = 0; i < tuple_dim; i++) | |
863 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
87
diff
changeset
|
864 auto farg = fargs[fptupindex + i]; |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
865 t.objects[i] = farg.type; |
0 | 866 } |
867 declareParameter(paramscope, tp, t); | |
868 goto L2; | |
869 } | |
870 fptupindex = -1; | |
871 } | |
872 } | |
873 | |
874 L1: | |
875 if (nfparams == nfargs) { | |
876 ; | |
877 } else if (nfargs > nfparams) { | |
878 if (fvarargs == 0) | |
879 goto Lnomatch; // too many args, no match | |
880 match = MATCHconvert; // match ... with a conversion | |
881 } | |
882 | |
883 L2: | |
884 version (DMDV2) { | |
885 if (ethis) | |
886 { | |
179 | 887 // Match 'ethis' to any TemplateThisParameter's |
0 | 888 for (size_t i = 0; i < parameters.dim; i++) |
889 { | |
121
347de076ad34
TemplateParameters -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
114
diff
changeset
|
890 auto tp2 = parameters[i]; |
0 | 891 TemplateThisParameter ttp = tp2.isTemplateThisParameter(); |
892 if (ttp) | |
893 { | |
894 MATCH m; | |
895 | |
896 Type t = new TypeIdentifier(Loc(0), ttp.ident); | |
897 m = ethis.type.deduceType(paramscope, t, parameters, dedtypes); | |
898 if (!m) | |
899 goto Lnomatch; | |
900 if (m < match) | |
901 match = m; // pick worst match | |
902 } | |
903 } | |
179 | 904 |
905 // Match attributes of ethis against attributes of fd | |
906 if (fd.type) | |
907 { | |
908 Type tthis = ethis.type; | |
909 MOD mod = fd.type.mod; | |
910 StorageClass stc = scope_.stc; | |
911 if (stc & (STCshared | STCsynchronized)) | |
912 mod |= MODshared; | |
913 if (stc & STCimmutable) | |
914 mod |= MODimmutable; | |
915 if (stc & STCconst) | |
916 mod |= MODconst; | |
917 if (stc & STCwild) | |
918 mod |= MODwild; | |
919 // Fix mod | |
920 if (mod & MODimmutable) | |
921 mod = MODimmutable; | |
922 if (mod & MODconst) | |
923 mod &= ~STCwild; | |
924 if (tthis.mod != mod) | |
925 { | |
926 if (!MODimplicitConv(tthis.mod, mod)) | |
927 goto Lnomatch; | |
928 if (MATCHconst < match) | |
929 match = MATCHconst; | |
930 } | |
931 } | |
932 | |
0 | 933 } |
934 } | |
935 | |
936 // Loop through the function parameters | |
937 for (size_t i = 0; i < nfparams; i++) | |
938 { | |
939 /* Skip over function parameters which wound up | |
940 * as part of a template tuple parameter. | |
941 */ | |
942 if (i == fptupindex) | |
943 { | |
944 if (fptupindex == nfparams - 1) | |
945 break; | |
946 i += tuple_dim - 1; | |
947 continue; | |
948 } | |
949 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
950 auto fparam = Parameter.getNth(fparameters, i); |
0 | 951 |
952 if (i >= nfargs) // if not enough arguments | |
953 { | |
954 if (fparam.defaultArg) | |
955 { | |
956 /* Default arguments do not participate in template argument | |
957 * deduction. | |
958 */ | |
959 goto Lmatch; | |
960 } | |
961 } | |
962 else | |
963 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
87
diff
changeset
|
964 auto farg = fargs[i]; |
0 | 965 static if (false) { |
966 printf("\tfarg.type = %s\n", farg.type.toChars()); | |
967 printf("\tfparam.type = %s\n", fparam.type.toChars()); | |
968 } | |
969 Type argtype = farg.type; | |
970 | |
971 version (DMDV2) { | |
972 /* Allow string literals which are type [] to match with [dim] | |
973 */ | |
974 if (farg.op == TOKstring) | |
975 { | |
976 StringExp se = cast(StringExp)farg; | |
977 if (!se.committed && argtype.ty == Tarray && | |
978 fparam.type.toBasetype().ty == Tsarray) | |
979 { | |
980 argtype = new TypeSArray(argtype.nextOf(), new IntegerExp(se.loc, se.len, Type.tindex)); | |
981 argtype = argtype.semantic(se.loc, null); | |
982 argtype = argtype.invariantOf(); | |
983 } | |
984 } | |
985 } | |
986 | |
987 MATCH m; | |
988 m = argtype.deduceType(paramscope, fparam.type, parameters, dedtypes); | |
989 //printf("\tdeduceType m = %d\n", m); | |
990 | |
991 /* If no match, see if there's a conversion to a delegate | |
992 */ | |
993 if (!m && fparam.type.toBasetype().ty == Tdelegate) | |
994 { | |
995 TypeDelegate td = cast(TypeDelegate)fparam.type.toBasetype(); | |
996 TypeFunction tf = cast(TypeFunction)td.next; | |
997 | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
998 if (!tf.varargs && Parameter.dim(tf.parameters) == 0) |
0 | 999 { |
1000 m = farg.type.deduceType(paramscope, tf.next, parameters, dedtypes); | |
1001 if (!m && tf.next.toBasetype().ty == Tvoid) | |
1002 m = MATCHconvert; | |
1003 } | |
1004 //printf("\tm2 = %d\n", m); | |
1005 } | |
1006 | |
1007 if (m) | |
1008 { | |
1009 if (m < match) | |
1010 match = m; // pick worst match | |
1011 continue; | |
1012 } | |
1013 } | |
1014 | |
1015 /* The following code for variadic arguments closely | |
1016 * matches TypeFunction.callMatch() | |
1017 */ | |
1018 if (!(fvarargs == 2 && i + 1 == nfparams)) | |
1019 goto Lnomatch; | |
1020 | |
1021 /* Check for match with function parameter T... | |
1022 */ | |
1023 Type tb = fparam.type.toBasetype(); | |
1024 switch (tb.ty) | |
1025 { | |
1026 // Perhaps we can do better with this, see TypeFunction.callMatch() | |
1027 case Tsarray: | |
1028 { | |
1029 TypeSArray tsa = cast(TypeSArray)tb; | |
1030 ulong sz = tsa.dim.toInteger(); | |
1031 if (sz != nfargs - i) | |
1032 goto Lnomatch; | |
1033 } | |
1034 case Tarray: | |
1035 { | |
1036 TypeArray ta = cast(TypeArray)tb; | |
1037 for (; i < nfargs; i++) | |
1038 { | |
90
39648eb578f6
more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
87
diff
changeset
|
1039 auto arg = fargs[i]; |
0 | 1040 assert(arg); |
1041 MATCH m; | |
1042 /* If lazy array of delegates, | |
1043 * convert arg(s) to delegate(s) | |
1044 */ | |
1045 Type tret = fparam.isLazyArray(); | |
1046 if (tret) | |
1047 { | |
1048 if (ta.next.equals(arg.type)) | |
1049 { | |
1050 m = MATCHexact; | |
1051 } | |
1052 else | |
1053 { | |
1054 m = arg.implicitConvTo(tret); | |
1055 if (m == MATCHnomatch) | |
1056 { | |
1057 if (tret.toBasetype().ty == Tvoid) | |
1058 m = MATCHconvert; | |
1059 } | |
1060 } | |
1061 } | |
1062 else | |
1063 { | |
1064 m = arg.type.deduceType(paramscope, ta.next, parameters, dedtypes); | |
1065 //m = arg.implicitConvTo(ta.next); | |
1066 } | |
1067 if (m == MATCHnomatch) | |
1068 goto Lnomatch; | |
1069 if (m < match) | |
1070 match = m; | |
1071 } | |
1072 goto Lmatch; | |
1073 } | |
1074 case Tclass: | |
1075 case Tident: | |
1076 goto Lmatch; | |
1077 | |
1078 default: | |
1079 goto Lnomatch; | |
1080 } | |
1081 } | |
1082 | |
1083 Lmatch: | |
1084 | |
1085 /* Fill in any missing arguments with their defaults. | |
1086 */ | |
1087 for (size_t i = nargsi; i < dedargs.dim; i++) | |
1088 { | |
179 | 1089 auto tparam = parameters[i]; |
1090 //printf("tparam[%d] = %s\n", i, tparam.ident.toChars()); | |
0 | 1091 /* For T:T*, the dedargs is the T*, dedtypes is the T |
1092 * But for function templates, we really need them to match | |
1093 */ | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
1094 Object oarg = dedargs[i]; |
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
1095 Object oded = dedtypes[i]; |
0 | 1096 //printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded); |
1097 //if (oarg) printf("oarg: %s\n", oarg.toChars()); | |
1098 //if (oded) printf("oded: %s\n", oded.toChars()); | |
1099 if (!oarg) | |
1100 { | |
1101 if (oded) | |
1102 { | |
179 | 1103 if (tparam.specialization()) |
0 | 1104 { |
1105 /* The specialization can work as long as afterwards | |
1106 * the oded == oarg | |
1107 */ | |
1108 Declaration sparam; | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
1109 dedargs[i] = oded; |
179 | 1110 MATCH m2 = tparam.matchArg(paramscope, dedargs, i, parameters, dedtypes, &sparam, 0); |
0 | 1111 //printf("m2 = %d\n", m2); |
1112 if (!m2) | |
1113 goto Lnomatch; | |
1114 if (m2 < match) | |
1115 match = m2; // pick worst match | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
1116 if (dedtypes[i] !is oded) |
179 | 1117 error("specialization not allowed for deduced parameter %s", tparam.ident.toChars()); |
0 | 1118 } |
1119 } | |
1120 else | |
1121 { | |
1122 if (!oded) | |
179 | 1123 { |
1124 if (tp && // if tuple parameter and | |
1125 fptupindex < 0 && // tuple parameter was not in function parameter list and | |
1126 nargsi == dedargs.dim - 1) // we're one argument short (i.e. no tuple argument) | |
1127 { | |
1128 // make tuple argument an empty tuple | |
1129 oded = new Tuple(); | |
1130 } | |
1131 else | |
1132 goto Lnomatch; | |
1133 } | |
0 | 1134 } |
179 | 1135 declareParameter(paramscope, tparam, oded); |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
90
diff
changeset
|
1136 dedargs[i] = oded; |
0 | 1137 } |
1138 } | |
1139 | |
1140 version (DMDV2) { | |
1141 if (constraint) | |
1142 { /* Check to see if constraint is satisfied. | |
1143 */ | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1144 makeParamNamesVisibleInConstraint(paramscope); |
0 | 1145 Expression e = constraint.syntaxCopy(); |
1146 paramscope.flags |= SCOPE.SCOPEstaticif; | |
1147 e = e.semantic(paramscope); | |
1148 e = e.optimize(WANTvalue | WANTinterpret); | |
1149 if (e.isBool(true)) { | |
1150 ; | |
1151 } else if (e.isBool(false)) | |
1152 goto Lnomatch; | |
1153 else | |
1154 { | |
1155 e.error("constraint %s is not constant or does not evaluate to a bool", e.toChars()); | |
1156 } | |
1157 } | |
1158 } | |
1159 | |
1160 static if (false) { | |
1161 for (i = 0; i < dedargs.dim; i++) | |
1162 { | |
1163 Type t = cast(Type)dedargs.data[i]; | |
1164 printf("\tdedargs[%d] = %d, %s\n", i, t.dyncast(), t.toChars()); | |
1165 } | |
1166 } | |
1167 | |
1168 paramscope.pop(); | |
1169 //printf("\tmatch %d\n", match); | |
1170 return match; | |
1171 | |
1172 Lnomatch: | |
1173 paramscope.pop(); | |
1174 //printf("\tnomatch\n"); | |
1175 return MATCHnomatch; | |
1176 } | |
104 | 1177 |
0 | 1178 /************************************************* |
1179 * Given function arguments, figure out which template function | |
1180 * to expand, and return that function. | |
1181 * If no match, give error message and return null. | |
1182 * Input: | |
1183 * sc instantiation scope | |
1184 * loc instantiation location | |
1185 * targsi initial list of template arguments | |
1186 * ethis if !null, the 'this' pointer argument | |
1187 * fargs arguments to function | |
1188 * flags 1: do not issue error message on no match, just return null | |
1189 */ | |
1190 FuncDeclaration deduceFunctionTemplate(Scope sc, Loc loc, Objects targsi, Expression ethis, Expressions fargs, int flags = 0) | |
1191 { | |
1192 MATCH m_best = MATCHnomatch; | |
1193 TemplateDeclaration td_ambig = null; | |
1194 TemplateDeclaration td_best = null; | |
1195 Objects tdargs = new Objects(); | |
1196 TemplateInstance ti; | |
1197 FuncDeclaration fd; | |
1198 | |
1199 static if (false) { | |
1200 printf("TemplateDeclaration.deduceFunctionTemplate() %s\n", toChars()); | |
104 | 1201 printf(" targsi:\n"); |
0 | 1202 if (targsi) |
1203 { | |
1204 for (int i = 0; i < targsi.dim; i++) | |
1205 { | |
1206 Object arg = cast(Object)targsi.data[i]; | |
1207 printf("\t%s\n", arg.toChars()); | |
1208 } | |
1209 } | |
104 | 1210 printf(" fargs:\n"); |
0 | 1211 for (int i = 0; i < fargs.dim; i++) |
1212 { | |
1213 Expression arg = cast(Expression)fargs.data[i]; | |
1214 printf("\t%s %s\n", arg.type.toChars(), arg.toChars()); | |
1215 //printf("\tty = %d\n", arg.type.ty); | |
1216 } | |
179 | 1217 printf("stc = %llx\n", scope_.stc); |
0 | 1218 } |
1219 | |
1220 for (TemplateDeclaration td = this; td; td = td.overnext) | |
1221 { | |
1222 if (!td.semanticRun) | |
1223 { | |
1224 error("forward reference to template %s", td.toChars()); | |
1225 goto Lerror; | |
1226 } | |
1227 if (!td.onemember || !td.onemember.toAlias().isFuncDeclaration()) | |
1228 { | |
1229 error("is not a function template"); | |
1230 goto Lerror; | |
1231 } | |
1232 | |
1233 MATCH m; | |
1234 scope Objects dedargs = new Objects(); | |
1235 | |
1236 m = td.deduceFunctionTemplateMatch(loc, targsi, ethis, fargs, dedargs); | |
1237 //printf("deduceFunctionTemplateMatch = %d\n", m); | |
1238 if (!m) // if no match | |
1239 continue; | |
1240 | |
1241 if (m < m_best) | |
1242 goto Ltd_best; | |
1243 if (m > m_best) | |
1244 goto Ltd; | |
1245 | |
1246 { | |
1247 // Disambiguate by picking the most specialized TemplateDeclaration | |
1248 MATCH c1 = td.leastAsSpecialized(td_best); | |
1249 MATCH c2 = td_best.leastAsSpecialized(td); | |
1250 //printf("c1 = %d, c2 = %d\n", c1, c2); | |
1251 | |
1252 if (c1 > c2) | |
1253 goto Ltd; | |
1254 else if (c1 < c2) | |
1255 goto Ltd_best; | |
1256 else | |
1257 goto Lambig; | |
1258 } | |
1259 | |
1260 Lambig: // td_best and td are ambiguous | |
1261 td_ambig = td; | |
1262 continue; | |
1263 | |
1264 Ltd_best: // td_best is the best match so far | |
1265 td_ambig = null; | |
1266 continue; | |
1267 | |
1268 Ltd: // td is the new best match | |
1269 td_ambig = null; | |
1270 assert(cast(size_t)cast(void*)td.scope_ > 0x10000); | |
1271 td_best = td; | |
1272 m_best = m; | |
1273 tdargs.setDim(dedargs.dim); | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
1274 memcpy(tdargs.ptr, dedargs.ptr, tdargs.dim * (void*).sizeof); |
0 | 1275 continue; |
1276 } | |
1277 if (!td_best) | |
1278 { | |
1279 if (!(flags & 1)) | |
1280 error(loc, "does not match any function template declaration"); | |
1281 goto Lerror; | |
1282 } | |
1283 if (td_ambig) | |
1284 { | |
1285 error(loc, "matches more than one function template declaration:\n %s\nand:\n %s", | |
1286 td_best.toChars(), td_ambig.toChars()); | |
1287 } | |
1288 | |
1289 /* The best match is td_best with arguments tdargs. | |
1290 * Now instantiate the template. | |
1291 */ | |
1292 assert(cast(size_t)cast(void*)td_best.scope_ > 0x10000); | |
1293 ti = new TemplateInstance(loc, td_best, tdargs); | |
135 | 1294 ti.semantic(sc, fargs); |
0 | 1295 fd = ti.toAlias().isFuncDeclaration(); |
1296 if (!fd) | |
1297 goto Lerror; | |
1298 return fd; | |
1299 | |
1300 Lerror: | |
1301 /// version (DMDV2) { | |
1302 if (!(flags & 1)) | |
1303 /// } | |
1304 { | |
1305 HdrGenState hgs; | |
1306 | |
1307 scope OutBuffer bufa = new OutBuffer(); | |
1308 Objects args = targsi; | |
1309 if (args) | |
1310 { | |
1311 for (int i = 0; i < args.dim; i++) | |
1312 { | |
1313 if (i) | |
1314 bufa.writeByte(','); | |
113
3482c73a991b
More cleanup for arrays
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
110
diff
changeset
|
1315 Object oarg = args[i]; |
0 | 1316 ObjectToCBuffer(bufa, &hgs, oarg); |
1317 } | |
1318 } | |
1319 | |
1320 scope OutBuffer buf = new OutBuffer(); | |
1321 argExpTypesToCBuffer(buf, fargs, &hgs); | |
1322 error(loc, "cannot deduce template function from argument types !(%s)(%s)", bufa.toChars(), buf.toChars()); | |
1323 } | |
1324 return null; | |
1325 } | |
1326 | |
1327 /************************************************** | |
1328 * Declare template parameter tp with value o, and install it in the scope sc. | |
1329 */ | |
104 | 1330 void declareParameter(Scope sc, TemplateParameter tp, Object o) |
0 | 1331 { |
1332 //printf("TemplateDeclaration.declareParameter('%s', o = %p)\n", tp.ident.toChars(), o); | |
1333 | |
1334 Type targ = isType(o); | |
1335 Expression ea = isExpression(o); | |
1336 Dsymbol sa = isDsymbol(o); | |
1337 Tuple va = isTuple(o); | |
1338 | |
1339 Dsymbol s; | |
1340 | |
1341 // See if tp.ident already exists with a matching definition | |
1342 Dsymbol scopesym; | |
1343 s = sc.search(loc, tp.ident, &scopesym); | |
1344 if (s && scopesym == sc.scopesym) | |
1345 { | |
1346 TupleDeclaration td = s.isTupleDeclaration(); | |
1347 if (va && td) | |
1348 { | |
1349 Tuple tup = new Tuple(); | |
1350 assert(false); // < not implemented | |
1351 ///tup.objects = *td.objects; | |
1352 if (match(va, tup, this, sc)) | |
1353 { | |
1354 return; | |
1355 } | |
1356 } | |
1357 } | |
1358 | |
1359 if (targ) | |
1360 { | |
1361 //printf("type %s\n", targ.toChars()); | |
1362 s = new AliasDeclaration(Loc(0), tp.ident, targ); | |
1363 } | |
1364 else if (sa) | |
1365 { | |
1366 //printf("Alias %s %s;\n", sa.ident.toChars(), tp.ident.toChars()); | |
1367 s = new AliasDeclaration(Loc(0), tp.ident, sa); | |
1368 } | |
1369 else if (ea) | |
1370 { | |
1371 // tdtypes.data[i] always matches ea here | |
1372 Initializer init = new ExpInitializer(loc, ea); | |
1373 TemplateValueParameter tvp = tp.isTemplateValueParameter(); | |
1374 | |
1375 Type t = tvp ? tvp.valType : null; | |
1376 | |
1377 VarDeclaration v = new VarDeclaration(loc, t, tp.ident, init); | |
1378 v.storage_class = STCmanifest; | |
1379 s = v; | |
1380 } | |
1381 else if (va) | |
1382 { | |
1383 //printf("\ttuple\n"); | |
1384 s = new TupleDeclaration(loc, tp.ident, va.objects); | |
1385 } | |
1386 else | |
1387 { | |
1388 debug writefln(o.toString()); | |
1389 assert(0); | |
1390 } | |
1391 | |
1392 if (!sc.insert(s)) | |
1393 error("declaration %s is already defined", tp.ident.toChars()); | |
1394 | |
1395 s.semantic(sc); | |
1396 } | |
1397 | |
104 | 1398 override TemplateDeclaration isTemplateDeclaration() { return this; } |
0 | 1399 |
104 | 1400 TemplateTupleParameter isVariadic() |
0 | 1401 { |
1402 return .isVariadic(parameters); | |
1403 } | |
1404 | |
63 | 1405 /*********************************** |
1406 * We can overload templates. | |
1407 */ | |
104 | 1408 override bool isOverloadable() |
0 | 1409 { |
104 | 1410 return true; |
0 | 1411 } |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1412 |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1413 /**************************** |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1414 * Declare all the function parameters as variables |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1415 * and add them to the scope |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1416 */ |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1417 void makeParamNamesVisibleInConstraint(Scope paramscope) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1418 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1419 /* We do this ONLY if there is only one function in the template. |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1420 */ |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1421 FuncDeclaration fd = onemember && onemember.toAlias() ? |
131
206db751bd4c
dmdfe 2.037 compiles now
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
130
diff
changeset
|
1422 onemember.toAlias().isFuncDeclaration() : null; |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1423 if (fd) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1424 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1425 paramscope.parent = fd; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1426 int fvarargs; // function varargs |
135 | 1427 Parameters fparameters = fd.getParameters(&fvarargs); |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1428 size_t nfparams = Parameter.dim(fparameters); // Num function parameters |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1429 for (int i = 0; i < nfparams; i++) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1430 { |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1431 Parameter fparam = Parameter.getNth(fparameters, i).syntaxCopy(); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1432 if (!fparam.ident) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1433 continue; // don't add it, if it has no name |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1434 Type vtype = fparam.type.syntaxCopy(); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1435 // isPure will segfault if called on a ctor, because fd->type is null. |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1436 if (fd.type && fd.isPure()) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1437 vtype = vtype.addMod(MODconst); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1438 VarDeclaration v = new VarDeclaration(loc, vtype, fparam.ident, null); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1439 v.storage_class |= STCparameter; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1440 // Not sure if this condition is correct/necessary. |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1441 // It's from func.c |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1442 if (//fd->type && fd->type->ty == Tfunction && |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1443 fvarargs == 2 && i + 1 == nfparams) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1444 v.storage_class |= STCvariadic; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1445 |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1446 v.storage_class |= fparam.storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1447 v.semantic(paramscope); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1448 if (!paramscope.insert(v)) |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1449 error("parameter %s.%s is already defined", toChars(), v.toChars()); |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1450 else |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1451 v.parent = this; |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1452 } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1453 } |
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
128
diff
changeset
|
1454 } |
72 | 1455 } |