root/trunk/src/toctype.c

Revision 798, 12.7 kB (checked in by walter, 1 year ago)

more 64

  • Property svn:eol-style set to native
Line 
1 // Copyright (c) 1999-2010 by Digital Mars
2 // All Rights Reserved
3 // written by Walter Bright
4 // http://www.digitalmars.com
5 // http://www.dsource.org/projects/dmd/browser/trunk/src/toctype.c
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <stddef.h>
12 #include <time.h>
13 #include <assert.h>
14
15 #if __sun&&__SVR4
16 #include <alloca.h>
17 #endif
18
19 #include "mars.h"
20 #include "module.h"
21 #include "mtype.h"
22 #include "declaration.h"
23 #include "statement.h"
24 #include "enum.h"
25 #include "aggregate.h"
26 #include "init.h"
27 #include "attrib.h"
28 #include "id.h"
29 #include "import.h"
30 #include "template.h"
31
32 #include "rmem.h"
33 #include "cc.h"
34 #include "global.h"
35 #include "oper.h"
36 #include "code.h"
37 #include "type.h"
38 #include "dt.h"
39 #include "cgcv.h"
40 #include "outbuf.h"
41 #include "irstate.h"
42
43 void out_config_init();
44 void slist_add(Symbol *s);
45 void slist_reset();
46
47
48 /***************************************
49  * Convert from D type to C type.
50  * This is done so C debug info can be generated.
51  */
52
53 type *Type::toCtype()
54 {
55     if (!ctype)
56     {   ctype = type_fake(totym());
57         ctype->Tcount++;
58     }
59     return ctype;
60 }
61
62 type *Type::toCParamtype()
63 {
64     return toCtype();
65 }
66
67 type *TypeSArray::toCParamtype()
68 {
69 #if SARRAYVALUE
70     return toCtype();
71 #else
72     // arrays are passed as pointers
73     return next->pointerTo()->toCtype();
74 #endif
75 }
76
77 type *TypeSArray::toCtype()
78 {
79     if (!ctype)
80     {   type *tn;
81
82         tn = next->toCtype();
83         ctype = type_allocn(TYarray, tn);
84         ctype->Tdim = dim->toInteger();
85     }
86     return ctype;
87 }
88
89 type *TypeDArray::toCtype()
90 {   type *t;
91
92     if (ctype)
93         return ctype;
94
95     if (0 && global.params.symdebug)
96     {
97         /* Create a C type out of:
98          *      struct _Array_T { size_t length; T* data; }
99          */
100         Symbol *s;
101         char *id;
102
103         assert(next->deco);
104         id = (char *) alloca(7 + strlen(next->deco) + 1);
105         sprintf(id, "_Array_%s", next->deco);
106         s = symbol_calloc(id);
107         s->Sclass = SCstruct;
108         s->Sstruct = struct_calloc();
109         s->Sstruct->Sflags |= 0;
110         s->Sstruct->Salignsize = alignsize();
111         s->Sstruct->Sstructalign = global.structalign;
112         s->Sstruct->Sstructsize = size(0);
113         slist_add(s);
114
115         Symbol *s1 = symbol_name("length", SCmember, Type::tsize_t->toCtype());
116         list_append(&s->Sstruct->Sfldlst, s1);
117
118         Symbol *s2 = symbol_name("data", SCmember, next->pointerTo()->toCtype());
119         s2->Smemoff = Type::tsize_t->size();
120         list_append(&s->Sstruct->Sfldlst, s2);
121
122         t = type_alloc(TYstruct);
123         t->Ttag = (Classsym *)s;                // structure tag name
124         t->Tcount++;
125         s->Stype = t;
126     }
127     else
128     {
129         if (global.params.symdebug == 1)
130         {
131             // Generate D symbolic debug info, rather than C
132             t = type_allocn(TYdarray, next->toCtype());
133         }
134         else
135             t = type_fake(TYdarray);
136     }
137     t->Tcount++;
138     ctype = t;
139     return t;
140 }
141
142
143 type *TypeAArray::toCtype()
144 {   type *t;
145
146     if (ctype)
147         return ctype;
148
149     if (0 && global.params.symdebug)
150     {
151         /* An associative array is represented by:
152          *      struct AArray { size_t length; void* ptr; }
153          */
154
155         static Symbol *s;
156
157         if (!s)
158         {
159             s = symbol_calloc("_AArray");
160             s->Sclass = SCstruct;
161             s->Sstruct = struct_calloc();
162             s->Sstruct->Sflags |= 0;
163             s->Sstruct->Salignsize = alignsize();
164             s->Sstruct->Sstructalign = global.structalign;
165             s->Sstruct->Sstructsize = size(0);
166             slist_add(s);
167
168             Symbol *s1 = symbol_name("length", SCmember, Type::tsize_t->toCtype());
169             list_append(&s->Sstruct->Sfldlst, s1);
170
171             Symbol *s2 = symbol_name("data", SCmember, Type::tvoidptr->toCtype());
172             s2->Smemoff = Type::tsize_t->size();
173             list_append(&s->Sstruct->Sfldlst, s2);
174         }
175
176         t = type_alloc(TYstruct);
177         t->Ttag = (Classsym *)s;                // structure tag name
178         t->Tcount++;
179         s->Stype = t;
180     }
181     else
182     {
183         if (global.params.symdebug == 1)
184         {
185             /* Generate D symbolic debug info, rather than C
186              *   Tnext: element type
187              *   Tkey: key type
188              */
189             t = type_allocn(TYaarray, next->toCtype());
190             t->Tkey = index->toCtype();
191             t->Tkey->Tcount++;
192         }
193         else
194             t = type_fake(TYaarray);
195     }
196     t->Tcount++;
197     ctype = t;
198     return t;
199 }
200
201
202 type *TypePointer::toCtype()
203 {   type *tn;
204     type *t;
205
206     //printf("TypePointer::toCtype() %s\n", toChars());
207     if (ctype)
208         return ctype;
209
210     if (1 || global.params.symdebug)
211     {   /* Need to always do this, otherwise C++ name mangling
212          * goes awry.
213          */
214         t = type_alloc(TYnptr);
215         ctype = t;
216         tn = next->toCtype();
217         t->Tnext = tn;
218         tn->Tcount++;
219     }
220     else
221         t = type_fake(totym());
222     t->Tcount++;
223     ctype = t;
224     return t;
225 }
226
227 type *TypeFunction::toCtype()
228 {   type *t;
229
230     if (ctype)
231         return ctype;
232
233     if (1)
234     {
235         param_t *paramtypes = NULL;
236         size_t nparams = Parameter::dim(parameters);
237         for (size_t i = 0; i < nparams; i++)
238         {   Parameter *arg = Parameter::getNth(parameters, i);
239             type *tp = arg->type->toCtype();
240             if (arg->storageClass & (STCout | STCref))
241             {   // C doesn't have reference types, so it's really a pointer
242                 // to the parameter type
243                 tp = type_allocn(TYref, tp);
244             }
245             param_append_type(&paramtypes,tp);
246         }
247         tym_t tyf = totym();
248         t = type_alloc(tyf);
249         t->Tflags |= TFprototype;
250         if (varargs != 1)
251             t->Tflags |= TFfixed;
252         ctype = t;
253         assert(next);           // function return type should exist
254         t->Tnext = next->toCtype();
255         t->Tnext->Tcount++;
256         t->Tparamtypes = paramtypes;
257     }
258     ctype = t;
259     return t;
260 }
261
262 type *TypeDelegate::toCtype()
263 {   type *t;
264
265     if (ctype)
266         return ctype;
267
268     if (0 && global.params.symdebug)
269     {
270         /* A delegate consists of:
271          *    _Delegate { void* frameptr; Function *funcptr; }
272          */
273
274         static Symbol *s;
275
276         if (!s)
277         {
278             s = symbol_calloc("_Delegate");
279             s->Sclass = SCstruct;
280             s->Sstruct = struct_calloc();
281             s->Sstruct->Sflags |= 0;
282             s->Sstruct->Salignsize = alignsize();
283             s->Sstruct->Sstructalign = global.structalign;
284             s->Sstruct->Sstructsize = size(0);
285             slist_add(s);
286
287             Symbol *s1 = symbol_name("frameptr", SCmember, Type::tvoidptr->toCtype());
288             list_append(&s->Sstruct->Sfldlst, s1);
289
290             Symbol *s2 = symbol_name("funcptr", SCmember, Type::tvoidptr->toCtype());
291             s2->Smemoff = Type::tvoidptr->size();
292             list_append(&s->Sstruct->Sfldlst, s2);
293         }
294
295         t = type_alloc(TYstruct);
296         t->Ttag = (Classsym *)s;                // structure tag name
297         t->Tcount++;
298         s->Stype = t;
299     }
300     else
301     {
302         if (global.params.symdebug == 1)
303         {
304             // Generate D symbolic debug info, rather than C
305             t = type_allocn(TYdelegate, next->toCtype());
306         }
307         else
308             t = type_fake(TYdelegate);
309     }
310
311     t->Tcount++;
312     ctype = t;
313     return t;
314 }
315
316
317 type *TypeStruct::toCtype()
318 {
319     if (ctype)
320         return ctype;
321
322     //printf("TypeStruct::toCtype() '%s'\n", sym->toChars());
323     type *t = type_alloc(TYstruct);
324     Type *tm = mutableOf();
325     if (tm->ctype)
326     {
327         Symbol *s = tm->ctype->Ttag;
328         t->Ttag = (Classsym *)s;            // structure tag name
329         t->Tcount++;
330         // Add modifiers
331         switch (mod)
332         {
333             case 0:
334                 assert(0);
335                 break;
336             case MODconst:
337             case MODwild:
338                 t->Tty |= mTYconst;
339                 break;
340             case MODimmutable:
341                 t->Tty |= mTYimmutable;
342                 break;
343             case MODshared:
344                 t->Tty |= mTYshared;
345                 break;
346             case MODshared | MODwild:
347             case MODshared | MODconst:
348                 t->Tty |= mTYshared | mTYconst;
349                 break;
350             default:
351                 assert(0);
352         }
353         ctype = t;
354     }
355     else
356     {
357         Symbol *s = symbol_calloc(sym->toPrettyChars());
358         s->Sclass = SCstruct;
359         s->Sstruct = struct_calloc();
360         s->Sstruct->Sflags |= 0;
361         s->Sstruct->Salignsize = sym->alignsize;
362         s->Sstruct->Sstructalign = sym->alignsize;
363         s->Sstruct->Sstructsize = sym->structsize;
364
365         if (sym->isUnionDeclaration())
366             s->Sstruct->Sflags |= STRunion;
367
368         t->Ttag = (Classsym *)s;            // structure tag name
369         t->Tcount++;
370         s->Stype = t;
371         slist_add(s);
372         tm->ctype = t;
373         ctype = t;
374
375         /* Add in fields of the struct
376          * (after setting ctype to avoid infinite recursion)
377          */
378         if (global.params.symdebug)
379             for (int i = 0; i < sym->fields.dim; i++)
380             {   VarDeclaration *v = (VarDeclaration *)sym->fields.data[i];
381
382                 Symbol *s2 = symbol_name(v->ident->toChars(), SCmember, v->type->toCtype());
383                 s2->Smemoff = v->offset;
384                 list_append(&s->Sstruct->Sfldlst, s2);
385             }
386     }
387
388     //printf("t = %p, Tflags = x%x\n", t, t->Tflags);
389     return t;
390 }
391
392 type *TypeEnum::toCtype()
393 {
394     if (ctype)
395         return ctype;
396
397     //printf("TypeEnum::toCtype() '%s'\n", sym->toChars());
398     type *t;
399     Type *tm = mutableOf();
400     if (tm->ctype && tybasic(tm->ctype->Tty) == TYenum)
401     {
402         Symbol *s = tm->ctype->Ttag;
403         assert(s);
404         t = type_alloc(TYenum);
405         t->Ttag = (Classsym *)s;            // enum tag name
406         t->Tcount++;
407         t->Tnext = tm->ctype->Tnext;
408         t->Tnext->Tcount++;
409         // Add modifiers
410         switch (mod)
411         {
412             case 0:
413                 assert(0);
414                 break;
415             case MODconst:
416             case MODwild:
417                 t->Tty |= mTYconst;
418                 break;
419             case MODimmutable:
420                 t->Tty |= mTYimmutable;
421                 break;
422             case MODshared:
423                 t->Tty |= mTYshared;
424                 break;
425             case MODshared | MODwild:
426             case MODshared | MODconst:
427                 t->Tty |= mTYshared | mTYconst;
428                 break;
429             default:
430                 assert(0);
431         }
432         ctype = t;
433     }
434     else if (sym->memtype->toBasetype()->ty == Tint32)
435     {
436         Symbol *s = symbol_calloc(sym->toPrettyChars());
437         s->Sclass = SCenum;
438         s->Senum = (enum_t *) MEM_PH_CALLOC(sizeof(enum_t));
439         s->Senum->SEflags |= SENforward;        // forward reference
440         slist_add(s);
441
442         t = type_alloc(TYenum);
443         t->Ttag = (Classsym *)s;            // enum tag name
444         t->Tcount++;
445         t->Tnext = sym->memtype->toCtype();
446         t->Tnext->Tcount++;
447         s->Stype = t;
448         slist_add(s);
449         tm->ctype = t;
450         ctype = t;
451     }
452     else
453     {
454         t = ctype = sym->memtype->toCtype();
455     }
456
457     //printf("t = %p, Tflags = x%x\n", t, t->Tflags);
458     return t;
459 }
460
461 type *TypeTypedef::toCtype()
462 {
463     return sym->basetype->toCtype();
464 }
465
466 type *TypeTypedef::toCParamtype()
467 {
468     return sym->basetype->toCParamtype();
469 }
470
471 type *TypeClass::toCtype()
472 {   type *t;
473     Symbol *s;
474
475     //printf("TypeClass::toCtype() %s\n", toChars());
476     if (ctype)
477         return ctype;
478
479     /* Need this symbol to do C++ name mangling
480      */
481     const char *name = sym->isCPPinterface() ? sym->ident->toChars()
482                                              : sym->toPrettyChars();
483     s = symbol_calloc(name);
484     s->Sclass = SCstruct;
485     s->Sstruct = struct_calloc();
486     s->Sstruct->Sflags |= STRclass;
487     s->Sstruct->Salignsize = sym->alignsize;
488     s->Sstruct->Sstructalign = sym->structalign;
489     s->Sstruct->Sstructsize = sym->structsize;
490
491     t = type_alloc(TYstruct);
492     t->Ttag = (Classsym *)s;            // structure tag name
493     t->Tcount++;
494     s->Stype = t;
495     slist_add(s);
496
497     t = type_allocn(TYnptr, t);
498
499     t->Tcount++;
500     ctype = t;
501
502     /* Add in fields of the class
503      * (after setting ctype to avoid infinite recursion)
504      */
505     if (global.params.symdebug)
506         for (int i = 0; i < sym->fields.dim; i++)
507         {   VarDeclaration *v = (VarDeclaration *)sym->fields.data[i];
508
509             Symbol *s2 = symbol_name(v->ident->toChars(), SCmember, v->type->toCtype());
510             s2->Smemoff = v->offset;
511             list_append(&s->Sstruct->Sfldlst, s2);
512         }
513
514     return t;
515 }
Note: See TracBrowser for help on using the browser.