1 /** 2 * Compiler implementation of the 3 * $(LINK2 http://www.dlang.org, D programming language). 4 * 5 * Copyright: Copyright (c) 1999-2016 by Digital Mars, All Rights Reserved 6 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright) 7 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 8 * Source: $(DMDSRC _toctype.d) 9 */ 10 11 module ddmd.toctype; 12 13 import core.stdc.stdlib; 14 15 import ddmd.backend.cc : Classsym, Symbol; 16 import ddmd.backend.ty; 17 import ddmd.backend.type; 18 19 import ddmd.declaration; 20 import ddmd.dstruct; 21 import ddmd.globals; 22 import ddmd.id; 23 import ddmd.mtype; 24 import ddmd.visitor; 25 26 extern extern (C++) uint totym(Type tx); 27 28 extern (C++) final class ToCtypeVisitor : Visitor 29 { 30 alias visit = super.visit; 31 public: 32 extern (D) this() 33 { 34 } 35 36 override void visit(Type t) 37 { 38 t.ctype = type_fake(totym(t)); 39 t.ctype.Tcount++; 40 } 41 42 override void visit(TypeSArray t) 43 { 44 t.ctype = type_static_array(t.dim.toInteger(), Type_toCtype(t.next)); 45 } 46 47 override void visit(TypeDArray t) 48 { 49 t.ctype = type_dyn_array(Type_toCtype(t.next)); 50 t.ctype.Tident = t.toPrettyChars(true); 51 } 52 53 override void visit(TypeAArray t) 54 { 55 t.ctype = type_assoc_array(Type_toCtype(t.index), Type_toCtype(t.next)); 56 } 57 58 override void visit(TypePointer t) 59 { 60 //printf("TypePointer::toCtype() %s\n", t->toChars()); 61 t.ctype = type_pointer(Type_toCtype(t.next)); 62 } 63 64 override void visit(TypeFunction t) 65 { 66 size_t nparams = Parameter.dim(t.parameters); 67 type*[10] tmp; 68 type** ptypes = tmp.ptr; 69 if (nparams > 10) 70 ptypes = cast(type**)malloc((type*).sizeof * nparams); 71 for (size_t i = 0; i < nparams; i++) 72 { 73 Parameter p = Parameter.getNth(t.parameters, i); 74 type* tp = Type_toCtype(p.type); 75 if (p.storageClass & (STCout | STCref)) 76 tp = type_allocn(TYnref, tp); 77 else if (p.storageClass & STClazy) 78 { 79 // Mangle as delegate 80 type* tf = type_function(TYnfunc, null, 0, false, tp); 81 tp = type_delegate(tf); 82 } 83 ptypes[i] = tp; 84 } 85 t.ctype = type_function(totym(t), ptypes, nparams, t.varargs == 1, Type_toCtype(t.next)); 86 if (nparams > 10) 87 free(ptypes); 88 } 89 90 override void visit(TypeDelegate t) 91 { 92 t.ctype = type_delegate(Type_toCtype(t.next)); 93 } 94 95 void addMod(Type t) 96 { 97 switch (t.mod) 98 { 99 case 0: 100 assert(0); 101 case MODconst: 102 case MODwild: 103 case MODwildconst: 104 t.ctype.Tty |= mTYconst; 105 break; 106 case MODshared: 107 t.ctype.Tty |= mTYshared; 108 break; 109 case MODshared | MODconst: 110 case MODshared | MODwild: 111 case MODshared | MODwildconst: 112 t.ctype.Tty |= mTYshared | mTYconst; 113 break; 114 case MODimmutable: 115 t.ctype.Tty |= mTYimmutable; 116 break; 117 default: 118 assert(0); 119 } 120 } 121 122 override void visit(TypeStruct t) 123 { 124 //printf("TypeStruct::toCtype() '%s'\n", t->sym->toChars()); 125 if (t.mod == 0) 126 { 127 // Create a new backend type 128 StructDeclaration sym = t.sym; 129 if (sym.ident == Id.__c_long_double) 130 { 131 t.ctype = type_fake(TYdouble); 132 t.ctype.Tcount++; 133 return; 134 } 135 t.ctype = type_struct_class(sym.toPrettyChars(true), sym.alignsize, sym.structsize, sym.arg1type ? Type_toCtype(sym.arg1type) : null, sym.arg2type ? Type_toCtype(sym.arg2type) : null, sym.isUnionDeclaration() !is null, false, sym.isPOD() != 0); 136 /* Add in fields of the struct 137 * (after setting ctype to avoid infinite recursion) 138 */ 139 if (global.params.symdebug) 140 { 141 for (size_t i = 0; i < sym.fields.dim; i++) 142 { 143 VarDeclaration v = sym.fields[i]; 144 symbol_struct_addField(cast(Symbol*)t.ctype.Ttag, v.ident.toChars(), Type_toCtype(v.type), v.offset); 145 } 146 } 147 return; 148 } 149 150 // Copy mutable version of backend type and add modifiers 151 type* mctype = Type_toCtype(t.castMod(0)); 152 t.ctype = type_alloc(tybasic(mctype.Tty)); 153 t.ctype.Tcount++; 154 if (t.ctype.Tty == TYstruct) 155 { 156 t.ctype.Ttag = mctype.Ttag; // structure tag name 157 } 158 addMod(t); 159 //printf("t = %p, Tflags = x%x\n", ctype, ctype->Tflags); 160 } 161 162 override void visit(TypeEnum t) 163 { 164 //printf("TypeEnum::toCtype() '%s'\n", t->sym->toChars()); 165 if (t.mod == 0) 166 { 167 if (!t.sym.memtype) 168 { 169 // Bugzilla 13792 170 t.ctype = Type_toCtype(Type.tvoid); 171 } 172 else if (t.sym.memtype.toBasetype().ty == Tint32) 173 { 174 t.ctype = type_enum(t.sym.toPrettyChars(true), Type_toCtype(t.sym.memtype)); 175 } 176 else 177 { 178 t.ctype = Type_toCtype(t.sym.memtype); 179 } 180 return; 181 } 182 183 // Copy mutable version of backend type and add modifiers 184 type* mctype = Type_toCtype(t.castMod(0)); 185 if (tybasic(mctype.Tty) == TYenum) 186 { 187 Classsym* s = mctype.Ttag; 188 assert(s); 189 t.ctype = type_alloc(TYenum); 190 t.ctype.Ttag = s; // enum tag name 191 t.ctype.Tcount++; 192 t.ctype.Tnext = mctype.Tnext; 193 t.ctype.Tnext.Tcount++; 194 addMod(t); 195 } 196 else 197 t.ctype = mctype; 198 //printf("t = %p, Tflags = x%x\n", t, t->Tflags); 199 } 200 201 override void visit(TypeClass t) 202 { 203 //printf("TypeClass::toCtype() %s\n", toChars()); 204 type* tc = type_struct_class(t.sym.toPrettyChars(true), t.sym.alignsize, t.sym.structsize, null, null, false, true, true); 205 t.ctype = type_pointer(tc); 206 /* Add in fields of the class 207 * (after setting ctype to avoid infinite recursion) 208 */ 209 if (global.params.symdebug) 210 { 211 for (size_t i = 0; i < t.sym.fields.dim; i++) 212 { 213 VarDeclaration v = t.sym.fields[i]; 214 symbol_struct_addField(cast(Symbol*)tc.Ttag, v.ident.toChars(), Type_toCtype(v.type), v.offset); 215 } 216 } 217 } 218 } 219 220 extern (C++) type* Type_toCtype(Type t) 221 { 222 if (!t.ctype) 223 { 224 scope ToCtypeVisitor v = new ToCtypeVisitor(); 225 t.accept(v); 226 } 227 return t.ctype; 228 }