Mercurial > projects > ldc
annotate gen/typinf.c @ 5:3d60e549b0c2 trunk
[svn r9] added a preliminary rebuild profile. llvmdc-posix - very handy :)
added readme.txt
added test/g.d - tests passing strings to functions
fixed test/dgs.d and test/funcptr, now all tests except those related to typeinfo should work.
author | lindquist |
---|---|
date | Wed, 05 Sep 2007 07:16:31 +0200 |
parents | e116aa1488e6 |
children | 0c77619e803b |
rev | line source |
---|---|
1 | 1 |
2 | |
3 // Copyright (c) 1999-2004 by Digital Mars | |
4 // All Rights Reserved | |
5 // written by Walter Bright | |
6 // www.digitalmars.com | |
7 // License for redistribution is by either the Artistic License | |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
9 // See the included readme.txt for details. | |
10 | |
11 #include <cstdio> | |
12 #include <cassert> | |
13 | |
14 #include "mars.h" | |
15 #include "module.h" | |
16 #include "mtype.h" | |
17 #include "scope.h" | |
18 #include "init.h" | |
19 #include "expression.h" | |
20 #include "attrib.h" | |
21 #include "declaration.h" | |
22 #include "template.h" | |
23 #include "id.h" | |
24 #include "enum.h" | |
25 #include "import.h" | |
26 #include "aggregate.h" | |
27 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
28 #include "gen/logger.h" |
1 | 29 |
30 /******************************************* | |
31 | |
32 * Get a canonicalized form of the TypeInfo for use with the internal | |
33 | |
34 * runtime library routines. Canonicalized in that static arrays are | |
35 | |
36 * represented as dynamic arrays, enums are represented by their | |
37 | |
38 * underlying type, etc. This reduces the number of TypeInfo's needed, | |
39 | |
40 * so we can use the custom internal ones more. | |
41 | |
42 */ | |
43 | |
44 | |
45 | |
46 Expression *Type::getInternalTypeInfo(Scope *sc) | |
47 | |
48 { TypeInfoDeclaration *tid; | |
49 | |
50 Expression *e; | |
51 | |
52 Type *t; | |
53 | |
54 static TypeInfoDeclaration *internalTI[TMAX]; | |
55 | |
56 | |
57 | |
58 //printf("Type::getInternalTypeInfo() %s\n", toChars()); | |
59 | |
60 t = toBasetype(); | |
61 | |
62 switch (t->ty) | |
63 | |
64 { | |
65 | |
66 case Tsarray: | |
67 | |
68 t = t->next->arrayOf(); // convert to corresponding dynamic array type | |
69 | |
70 break; | |
71 | |
72 | |
73 | |
74 case Tclass: | |
75 | |
76 if (((TypeClass *)t)->sym->isInterfaceDeclaration()) | |
77 | |
78 break; | |
79 | |
80 goto Linternal; | |
81 | |
82 | |
83 | |
84 case Tarray: | |
85 | |
86 if (t->next->ty != Tclass) | |
87 | |
88 break; | |
89 | |
90 goto Linternal; | |
91 | |
92 | |
93 | |
94 case Tfunction: | |
95 | |
96 case Tdelegate: | |
97 | |
98 case Tpointer: | |
99 | |
100 Linternal: | |
101 | |
102 tid = internalTI[t->ty]; | |
103 | |
104 if (!tid) | |
105 | |
106 { tid = new TypeInfoDeclaration(t, 1); | |
107 | |
108 internalTI[t->ty] = tid; | |
109 | |
110 } | |
111 | |
112 e = new VarExp(0, tid); | |
113 | |
114 e = e->addressOf(sc); | |
115 | |
116 e->type = tid->type; // do this so we don't get redundant dereference | |
117 | |
118 return e; | |
119 | |
120 | |
121 | |
122 default: | |
123 | |
124 break; | |
125 | |
126 } | |
127 | |
128 //printf("\tcalling getTypeInfo() %s\n", t->toChars()); | |
129 | |
130 return t->getTypeInfo(sc); | |
131 | |
132 } | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 /**************************************************** | |
139 | |
140 * Get the exact TypeInfo. | |
141 | |
142 */ | |
143 | |
144 | |
145 | |
146 Expression *Type::getTypeInfo(Scope *sc) | |
147 | |
148 { | |
149 | |
150 Expression *e; | |
151 | |
152 Type *t; | |
153 | |
154 | |
155 | |
156 //printf("Type::getTypeInfo() %p, %s\n", this, toChars()); | |
157 | |
158 t = merge(); // do this since not all Type's are merge'd | |
159 | |
160 if (!t->vtinfo) | |
161 | |
162 { t->vtinfo = t->getTypeInfoDeclaration(); | |
163 | |
164 assert(t->vtinfo); | |
165 | |
166 | |
167 | |
168 /* If this has a custom implementation in std/typeinfo, then | |
169 | |
170 * do not generate a COMDAT for it. | |
171 | |
172 */ | |
173 | |
174 if (!t->builtinTypeInfo()) | |
175 | |
176 { // Generate COMDAT | |
177 | |
178 if (sc) // if in semantic() pass | |
179 | |
180 { // Find module that will go all the way to an object file | |
181 | |
182 Module *m = sc->module->importedFrom; | |
183 | |
184 m->members->push(t->vtinfo); | |
185 | |
186 } | |
187 | |
188 else // if in obj generation pass | |
189 | |
190 { | |
191 | |
192 t->vtinfo->toObjFile(); | |
193 | |
194 } | |
195 | |
196 } | |
197 | |
198 } | |
199 | |
200 e = new VarExp(0, t->vtinfo); | |
201 | |
202 //e = e->addressOf(sc); | |
203 e->type = t->vtinfo->type; // do this so we don't get redundant dereference | |
204 | |
205 return e; | |
206 | |
207 } | |
208 | |
209 | |
210 | |
211 TypeInfoDeclaration *Type::getTypeInfoDeclaration() | |
212 | |
213 { | |
214 | |
215 //printf("Type::getTypeInfoDeclaration() %s\n", toChars()); | |
216 | |
217 return new TypeInfoDeclaration(this, 0); | |
218 | |
219 } | |
220 | |
221 | |
222 | |
223 TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration() | |
224 | |
225 { | |
226 | |
227 return new TypeInfoTypedefDeclaration(this); | |
228 | |
229 } | |
230 | |
231 | |
232 | |
233 TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration() | |
234 | |
235 { | |
236 | |
237 return new TypeInfoPointerDeclaration(this); | |
238 | |
239 } | |
240 | |
241 | |
242 | |
243 TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration() | |
244 | |
245 { | |
246 | |
247 return new TypeInfoArrayDeclaration(this); | |
248 | |
249 } | |
250 | |
251 | |
252 | |
253 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration() | |
254 | |
255 { | |
256 | |
257 return new TypeInfoStaticArrayDeclaration(this); | |
258 | |
259 } | |
260 | |
261 | |
262 | |
263 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration() | |
264 | |
265 { | |
266 | |
267 return new TypeInfoAssociativeArrayDeclaration(this); | |
268 | |
269 } | |
270 | |
271 | |
272 | |
273 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration() | |
274 | |
275 { | |
276 | |
277 return new TypeInfoStructDeclaration(this); | |
278 | |
279 } | |
280 | |
281 | |
282 | |
283 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration() | |
284 | |
285 { | |
286 | |
287 if (sym->isInterfaceDeclaration()) | |
288 | |
289 return new TypeInfoInterfaceDeclaration(this); | |
290 | |
291 else | |
292 | |
293 return new TypeInfoClassDeclaration(this); | |
294 | |
295 } | |
296 | |
297 | |
298 | |
299 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration() | |
300 | |
301 { | |
302 | |
303 return new TypeInfoEnumDeclaration(this); | |
304 | |
305 } | |
306 | |
307 | |
308 | |
309 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration() | |
310 | |
311 { | |
312 | |
313 return new TypeInfoFunctionDeclaration(this); | |
314 | |
315 } | |
316 enum RET TypeFunction::retStyle() | |
317 | |
318 { | |
319 | |
320 return RETstack; | |
321 | |
322 } | |
323 | |
324 | |
325 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration() | |
326 | |
327 { | |
328 | |
329 return new TypeInfoDelegateDeclaration(this); | |
330 | |
331 } | |
332 | |
333 | |
334 | |
335 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration() | |
336 | |
337 { | |
338 | |
339 return new TypeInfoTupleDeclaration(this); | |
340 | |
341 } | |
342 | |
343 | |
344 void TypeInfoDeclaration::toDt(dt_t **pdt) | |
345 { | |
346 } | |
347 | |
348 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) | |
349 { | |
350 } | |
351 | |
352 void TypeInfoStructDeclaration::toDt(dt_t **pdt) | |
353 { | |
354 } | |
355 | |
356 void TypeInfoClassDeclaration::toDt(dt_t **pdt) | |
357 { | |
358 } | |
359 | |
360 void TypeInfoDeclaration::toObjFile() | |
361 { | |
362 Logger::println("TypeInfoDeclaration::toObjFile()"); | |
363 LOG_SCOPE; | |
364 Logger::println("type = '%s'", tinfo->toChars()); | |
365 | |
366 | |
367 } | |
368 | |
369 /* ========================================================================= */ | |
370 | |
371 /* These decide if there's an instance for them already in std.typeinfo, | |
372 * because then the compiler doesn't need to build one. | |
373 */ | |
374 | |
375 int Type::builtinTypeInfo() | |
376 { | |
377 return 0; | |
378 } | |
379 | |
380 int TypeBasic::builtinTypeInfo() | |
381 { | |
382 return 1; | |
383 } | |
384 | |
385 int TypeDArray::builtinTypeInfo() | |
386 { | |
387 return 0; | |
388 } | |
389 | |
390 /* ========================================================================= */ | |
391 | |
392 /*************************************** | |
393 * Create a static array of TypeInfo references | |
394 * corresponding to an array of Expression's. | |
395 * Used to supply hidden _arguments[] value for variadic D functions. | |
396 */ | |
397 | |
398 Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim) | |
399 { | |
400 assert(0); | |
401 return 0; | |
402 } | |
403 |