Mercurial > projects > ddmd
comparison dmd/Parameter.d @ 130:60bb0fe4563e
dmdfe 2.037 first main iteration
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 09 Sep 2010 22:51:44 +0100 |
parents | dmd/Argument.d@1765f3ef917d |
children | 206db751bd4c |
comparison
equal
deleted
inserted
replaced
129:010eb8f0e18d | 130:60bb0fe4563e |
---|---|
1 module dmd.Parameter; | |
2 | |
3 import dmd.common; | |
4 import dmd.Type; | |
5 import dmd.Identifier; | |
6 import dmd.TypeArray; | |
7 import dmd.TypeFunction; | |
8 import dmd.TypeDelegate; | |
9 import dmd.TypeTuple; | |
10 import dmd.TY; | |
11 import dmd.Expression; | |
12 import dmd.OutBuffer; | |
13 import dmd.HdrGenState; | |
14 import dmd.ArrayTypes; | |
15 import dmd.StorageClassDeclaration; | |
16 import dmd.Global; | |
17 import dmd.MOD; | |
18 import dmd.CppMangleState; | |
19 import dmd.STC; | |
20 | |
21 class Parameter | |
22 { | |
23 //enum InOut inout; | |
24 STC storageClass; | |
25 Type type; | |
26 Identifier ident; | |
27 Expression defaultArg; | |
28 | |
29 this(STC storageClass, Type type, Identifier ident, Expression defaultArg) | |
30 { | |
31 this.type = type; | |
32 this.ident = ident; | |
33 this.storageClass = storageClass; | |
34 this.defaultArg = defaultArg; | |
35 } | |
36 | |
37 Parameter clone() | |
38 { | |
39 return new Parameter(storageClass, type, ident, defaultArg); | |
40 } | |
41 | |
42 Parameter syntaxCopy() | |
43 { | |
44 return new Parameter(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null); | |
45 } | |
46 | |
47 /**************************************************** | |
48 * Determine if parameter is a lazy array of delegates. | |
49 * If so, return the return type of those delegates. | |
50 * If not, return null. | |
51 */ | |
52 Type isLazyArray() | |
53 { | |
54 // if (inout == Lazy) | |
55 { | |
56 Type tb = type.toBasetype(); | |
57 if (tb.ty == Tsarray || tb.ty == Tarray) | |
58 { | |
59 Type tel = (cast(TypeArray)tb).next.toBasetype(); | |
60 if (tel.ty == Tdelegate) | |
61 { | |
62 TypeDelegate td = cast(TypeDelegate)tel; | |
63 TypeFunction tf = cast(TypeFunction)td.next; | |
64 | |
65 if (!tf.varargs && Parameter.dim(tf.parameters) == 0) | |
66 { | |
67 return tf.next; // return type of delegate | |
68 } | |
69 } | |
70 } | |
71 } | |
72 return null; | |
73 } | |
74 | |
75 void toDecoBuffer(OutBuffer buf) | |
76 { | |
77 if (storageClass & STC.STCscope) | |
78 buf.writeByte('M'); | |
79 switch (storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STClazy)) | |
80 { | |
81 case STC.STCundefined: | |
82 case STC.STCin: | |
83 break; | |
84 case STC.STCout: | |
85 buf.writeByte('J'); | |
86 break; | |
87 case STC.STCref: | |
88 buf.writeByte('K'); | |
89 break; | |
90 case STC.STClazy: | |
91 buf.writeByte('L'); | |
92 break; | |
93 } | |
94 static if (false) { | |
95 int mod = 0x100; | |
96 if (type.toBasetype().ty == TY.Tclass) | |
97 mod = 0; | |
98 type.toDecoBuffer(buf, mod); | |
99 } else { | |
100 //type.toHeadMutable().toDecoBuffer(buf, 0); | |
101 type.toDecoBuffer(buf, 0); | |
102 } | |
103 } | |
104 | |
105 static Parameters arraySyntaxCopy(Parameters args) | |
106 { | |
107 typeof(return) a = null; | |
108 | |
109 if (args) | |
110 { | |
111 a = new Parameters(); | |
112 a.setDim(args.dim); | |
113 | |
114 for (size_t i = 0; i < a.dim; i++) | |
115 { | |
116 auto arg = args[i]; | |
117 | |
118 arg = arg.syntaxCopy(); | |
119 a[i] = arg; | |
120 } | |
121 } | |
122 | |
123 return a; | |
124 } | |
125 | |
126 static string argsTypesToChars(Parameters args, int varargs) | |
127 { | |
128 scope OutBuffer buf = new OutBuffer(); | |
129 | |
130 static if (true) { | |
131 HdrGenState hgs; | |
132 argsToCBuffer(buf, &hgs, args, varargs); | |
133 } else { | |
134 buf.writeByte('('); | |
135 if (args) | |
136 { | |
137 OutBuffer argbuf = new OutBuffer(); | |
138 HdrGenState hgs; | |
139 | |
140 for (int i = 0; i < args.dim; i++) | |
141 { | |
142 if (i) | |
143 buf.writeByte(','); | |
144 auto arg = cast(Parameter)args.data[i]; | |
145 argbuf.reset(); | |
146 arg.type.toCBuffer2(&argbuf, &hgs, 0); | |
147 buf.write(&argbuf); | |
148 } | |
149 if (varargs) | |
150 { | |
151 if (i && varargs == 1) | |
152 buf.writeByte(','); | |
153 buf.writestring("..."); | |
154 } | |
155 } | |
156 buf.writeByte(')'); | |
157 } | |
158 return buf.toChars(); | |
159 } | |
160 | |
161 static void argsCppMangle(OutBuffer buf, CppMangleState* cms, Parameters arguments, int varargs) | |
162 { | |
163 assert(false); | |
164 } | |
165 | |
166 static void argsToCBuffer(OutBuffer buf, HdrGenState* hgs, Parameters arguments, int varargs) | |
167 { | |
168 buf.writeByte('('); | |
169 if (arguments) | |
170 { | |
171 int i; | |
172 scope OutBuffer argbuf = new OutBuffer(); | |
173 | |
174 for (i = 0; i < arguments.dim; i++) | |
175 { | |
176 if (i) | |
177 buf.writestring(", "); | |
178 auto arg = arguments[i]; | |
179 | |
180 if (arg.storageClass & STCout) | |
181 buf.writestring("out "); | |
182 else if (arg.storageClass & STCref) | |
183 buf.writestring((global.params.Dversion == 1) ? "inout " : "ref "); | |
184 else if (arg.storageClass & STCin) | |
185 buf.writestring("in "); | |
186 else if (arg.storageClass & STClazy) | |
187 buf.writestring("lazy "); | |
188 else if (arg.storageClass & STCalias) | |
189 buf.writestring("alias "); | |
190 else if (arg.storageClass & STCauto) | |
191 buf.writestring("auto "); | |
192 | |
193 uint stc = arg.storageClass; | |
194 if (arg.type && arg.type.mod & MODshared) | |
195 stc &= ~STCshared; | |
196 | |
197 StorageClassDeclaration.stcToCBuffer(buf, stc & (STCconst | STCimmutable | STCshared | STCscope)); | |
198 | |
199 argbuf.reset(); | |
200 if (arg.storageClass & STCalias) | |
201 { | |
202 if (arg.ident) | |
203 argbuf.writestring(arg.ident.toChars()); | |
204 } | |
205 else | |
206 arg.type.toCBuffer(argbuf, arg.ident, hgs); | |
207 if (arg.defaultArg) | |
208 { | |
209 argbuf.writestring(" = "); | |
210 arg.defaultArg.toCBuffer(argbuf, hgs); | |
211 } | |
212 buf.write(argbuf); | |
213 } | |
214 if (varargs) | |
215 { | |
216 if (i && varargs == 1) | |
217 buf.writeByte(','); | |
218 buf.writestring("..."); | |
219 } | |
220 } | |
221 buf.writeByte(')'); | |
222 } | |
223 | |
224 static void argsToDecoBuffer(OutBuffer buf, Parameters arguments) | |
225 { | |
226 //printf("Parameter::argsToDecoBuffer()\n"); | |
227 | |
228 // Write argument types | |
229 if (arguments) | |
230 { | |
231 size_t dim = Parameter.dim(arguments); | |
232 for (size_t i = 0; i < dim; i++) | |
233 { | |
234 auto arg = Parameter.getNth(arguments, i); | |
235 arg.toDecoBuffer(buf); | |
236 } | |
237 } | |
238 } | |
239 | |
240 static int isTPL(Parameters arguments) | |
241 { | |
242 assert(false); | |
243 } | |
244 | |
245 /*************************************** | |
246 * Determine number of arguments, folding in tuples. | |
247 */ | |
248 static size_t dim(Parameters args) | |
249 { | |
250 size_t n = 0; | |
251 if (args) | |
252 { | |
253 foreach (arg; args) | |
254 { | |
255 Type t = arg.type.toBasetype(); | |
256 | |
257 if (t.ty == TY.Ttuple) | |
258 { | |
259 auto tu = cast(TypeTuple)t; | |
260 n += dim(tu.arguments); | |
261 } | |
262 else | |
263 n++; | |
264 } | |
265 } | |
266 return n; | |
267 } | |
268 | |
269 /*************************************** | |
270 * Get nth Parameter, folding in tuples. | |
271 * Returns: | |
272 * Parameter nth Parameter | |
273 * null not found, *pn gets incremented by the number | |
274 * of Parameters | |
275 */ | |
276 static Parameter getNth(Parameters args, size_t nth, size_t* pn = null) | |
277 { | |
278 if (!args) | |
279 return null; | |
280 | |
281 size_t n = 0; | |
282 foreach (arg; args) | |
283 { | |
284 Type t = arg.type.toBasetype(); | |
285 | |
286 if (t.ty == TY.Ttuple) | |
287 { TypeTuple tu = cast(TypeTuple)t; | |
288 arg = getNth(tu.arguments, nth - n, &n); | |
289 if (arg) | |
290 return arg; | |
291 } | |
292 else if (n == nth) | |
293 return arg; | |
294 else | |
295 n++; | |
296 } | |
297 | |
298 if (pn) | |
299 *pn += n; | |
300 | |
301 return null; | |
302 } | |
303 } |