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