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