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