comparison dmd/IsExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 427f8aa74d28
comparison
equal deleted inserted replaced
-1:000000000000 0:10317f0c89a5
1 module dmd.IsExp;
2
3 import dmd.Expression;
4 import dmd.Identifier;
5 import dmd.ArrayTypes;
6 import dmd.Type;
7 import dmd.TOK;
8 import dmd.OutBuffer;
9 import dmd.Loc;
10 import dmd.Scope;
11 import dmd.HdrGenState;
12 import dmd.TY;
13 import dmd.TypeEnum;
14 import dmd.STC;
15 import dmd.TypeClass;
16 import dmd.TemplateParameter;
17 import dmd.BaseClass;
18 import dmd.ClassDeclaration;
19 import dmd.TypeStruct;
20 import dmd.TypeTypedef;
21 import dmd.IntegerExp;
22 import dmd.AliasDeclaration;
23 import dmd.Dsymbol;
24 import dmd.TypeTuple;
25 import dmd.TypeDelegate;
26 import dmd.Declaration;
27 import dmd.TypeFunction;
28 import dmd.MATCH;
29 import dmd.TypePointer;
30 import dmd.Argument;
31
32 class IsExp : Expression
33 {
34 /* is(targ id tok tspec)
35 * is(targ id == tok2)
36 */
37 Type targ;
38 Identifier id; // can be null
39 TOK tok; // ':' or '=='
40 Type tspec; // can be null
41 TOK tok2; // 'struct', 'union', 'typedef', etc.
42 TemplateParameters parameters;
43
44 this(Loc loc, Type targ, Identifier id, TOK tok, Type tspec, TOK tok2, TemplateParameters parameters)
45 {
46 super(loc, TOK.TOKis, IsExp.sizeof);
47
48 this.targ = targ;
49 this.id = id;
50 this.tok = tok;
51 this.tspec = tspec;
52 this.tok2 = tok2;
53 this.parameters = parameters;
54 }
55
56 Expression syntaxCopy()
57 {
58 assert(false);
59 }
60
61 Expression semantic(Scope sc)
62 {
63 Type tded;
64
65 /* is(targ id tok tspec)
66 * is(targ id == tok2)
67 */
68
69 //printf("IsExp.semantic(%s)\n", toChars());
70 if (id && !(sc.flags & SCOPE.SCOPEstaticif))
71 error("can only declare type aliases within static if conditionals");
72
73 Type t = targ.trySemantic(loc, sc);
74 if (!t)
75 goto Lno; // errors, so condition is false
76 targ = t;
77 if (tok2 != TOK.TOKreserved)
78 {
79 switch (tok2)
80 {
81 case TOKtypedef:
82 if (targ.ty != Ttypedef)
83 goto Lno;
84 tded = (cast(TypeTypedef)targ).sym.basetype;
85 break;
86
87 case TOKstruct:
88 if (targ.ty != Tstruct)
89 goto Lno;
90 if ((cast(TypeStruct)targ).sym.isUnionDeclaration())
91 goto Lno;
92 tded = targ;
93 break;
94
95 case TOKunion:
96 if (targ.ty != Tstruct)
97 goto Lno;
98 if (!(cast(TypeStruct)targ).sym.isUnionDeclaration())
99 goto Lno;
100 tded = targ;
101 break;
102
103 case TOKclass:
104 if (targ.ty != Tclass)
105 goto Lno;
106 if ((cast(TypeClass)targ).sym.isInterfaceDeclaration())
107 goto Lno;
108 tded = targ;
109 break;
110
111 case TOKinterface:
112 if (targ.ty != Tclass)
113 goto Lno;
114 if (!(cast(TypeClass)targ).sym.isInterfaceDeclaration())
115 goto Lno;
116 tded = targ;
117 break;
118 version (DMDV2) {
119 case TOKconst:
120 if (!targ.isConst())
121 goto Lno;
122 tded = targ;
123 break;
124
125 case TOKinvariant:
126 case TOKimmutable:
127 if (!targ.isInvariant())
128 goto Lno;
129 tded = targ;
130 break;
131
132 case TOKshared:
133 if (!targ.isShared())
134 goto Lno;
135 tded = targ;
136 break;
137 }
138
139 case TOKsuper:
140 // If class or interface, get the base class and interfaces
141 if (targ.ty != Tclass)
142 goto Lno;
143 else
144 { ClassDeclaration cd = (cast(TypeClass)targ).sym;
145 Arguments args = new Arguments;
146 args.reserve(cd.baseclasses.dim);
147 for (size_t i = 0; i < cd.baseclasses.dim; i++)
148 {
149 BaseClass b = cast(BaseClass)cd.baseclasses.data[i];
150 args.push(cast(void*)new Argument(STCin, b.type, null, null));
151 }
152 tded = new TypeTuple(args);
153 }
154 break;
155
156 case TOKenum:
157 if (targ.ty != Tenum)
158 goto Lno;
159 tded = (cast(TypeEnum)targ).sym.memtype;
160 break;
161
162 case TOKdelegate:
163 if (targ.ty != Tdelegate)
164 goto Lno;
165 tded = (cast(TypeDelegate)targ).next; // the underlying function type
166 break;
167
168 case TOKfunction:
169 {
170 if (targ.ty != Tfunction)
171 goto Lno;
172 tded = targ;
173
174 /* Generate tuple from function parameter types.
175 */
176 assert(tded.ty == Tfunction);
177 Arguments params = (cast(TypeFunction)tded).parameters;
178 size_t dim = Argument.dim(params);
179 Arguments args = new Arguments;
180 args.reserve(dim);
181 for (size_t i = 0; i < dim; i++)
182 {
183 Argument arg = Argument.getNth(params, i);
184 assert(arg && arg.type);
185 args.push(cast(void*)new Argument(arg.storageClass, arg.type, null, null));
186 }
187 tded = new TypeTuple(args);
188 break;
189 }
190
191 case TOKreturn:
192 /* Get the 'return type' for the function,
193 * delegate, or pointer to function.
194 */
195 if (targ.ty == Tfunction)
196 tded = (cast(TypeFunction)targ).next;
197 else if (targ.ty == Tdelegate)
198 { tded = (cast(TypeDelegate)targ).next;
199 tded = (cast(TypeFunction)tded).next;
200 }
201 else if (targ.ty == Tpointer &&
202 (cast(TypePointer)targ).next.ty == Tfunction)
203 { tded = (cast(TypePointer)targ).next;
204 tded = (cast(TypeFunction)tded).next;
205 }
206 else
207 goto Lno;
208 break;
209
210 default:
211 assert(0);
212 }
213 goto Lyes;
214 }
215 else if (id && tspec)
216 {
217 /* Evaluate to true if targ matches tspec.
218 * If true, declare id as an alias for the specialized type.
219 */
220
221 MATCH m;
222 assert(parameters && parameters.dim);
223
224 scope Objects dedtypes = new Objects();
225 dedtypes.setDim(parameters.dim);
226 dedtypes.zero();
227
228 m = targ.deduceType(null, tspec, parameters, dedtypes);
229 if (m == MATCHnomatch ||
230 (m != MATCHexact && tok == TOKequal))
231 {
232 goto Lno;
233 }
234 else
235 {
236 tded = cast(Type)dedtypes.data[0];
237 if (!tded)
238 tded = targ;
239
240 scope Objects tiargs = new Objects();
241 tiargs.setDim(1);
242 tiargs.data[0] = cast(void*)targ;
243
244 /* Declare trailing parameters
245 */
246 for (int i = 1; i < parameters.dim; i++)
247 {
248 TemplateParameter tp = cast(TemplateParameter)parameters.data[i];
249 Declaration s = null;
250
251 m = tp.matchArg(sc, tiargs, i, parameters, dedtypes, &s);
252 if (m == MATCHnomatch)
253 goto Lno;
254 s.semantic(sc);
255 if (!sc.insert(s))
256 error("declaration %s is already defined", s.toChars());
257 static if (false) {
258 Object o = cast(Object)dedtypes.data[i];
259 Dsymbol s = TemplateDeclaration.declareParameter(loc, sc, tp, o);
260 }
261 if (sc.sd)
262 s.addMember(sc, sc.sd, 1);
263 }
264
265 goto Lyes;
266 }
267 }
268 else if (id)
269 {
270 /* Declare id as an alias for type targ. Evaluate to true
271 */
272 tded = targ;
273 goto Lyes;
274 }
275 else if (tspec)
276 {
277 /* Evaluate to true if targ matches tspec
278 * is(targ == tspec)
279 * is(targ : tspec)
280 */
281 tspec = tspec.semantic(loc, sc);
282 //printf("targ = %s\n", targ.toChars());
283 //printf("tspec = %s\n", tspec.toChars());
284 if (tok == TOKcolon)
285 {
286 if (targ.implicitConvTo(tspec))
287 goto Lyes;
288 else
289 goto Lno;
290 }
291 else /* == */
292 {
293 if (targ.equals(tspec))
294 goto Lyes;
295 else
296 goto Lno;
297 }
298 }
299
300 Lyes:
301 if (id)
302 {
303 Dsymbol s = new AliasDeclaration(loc, id, tded);
304 s.semantic(sc);
305 if (!sc.insert(s))
306 error("declaration %s is already defined", s.toChars());
307 if (sc.sd)
308 s.addMember(sc, sc.sd, 1);
309 }
310 //printf("Lyes\n");
311 return new IntegerExp(loc, 1, Type.tbool);
312
313 Lno:
314 //printf("Lno\n");
315 return new IntegerExp(loc, 0, Type.tbool);
316 }
317
318 void toCBuffer(OutBuffer buf, HdrGenState* hgs)
319 {
320 assert(false);
321 }
322 }
323