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(&paramtypes,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: