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 }