comparison gen/classes.cpp @ 102:027b8d8b71ec trunk

[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up. Basically it tries to do the following in order: Resolve types, Declare symbols, Create constant initializers, Apply initializers, Generate functions bodies. ClassInfo is now has the most useful(biased?) members working. Probably other stuf...
author lindquist
date Sun, 18 Nov 2007 06:52:57 +0100
parents 5071469303d4
children 855adfdb8d38
comparison
equal deleted inserted replaced
101:169fda3a77d4 102:027b8d8b71ec
8 #include "gen/irstate.h" 8 #include "gen/irstate.h"
9 #include "gen/tollvm.h" 9 #include "gen/tollvm.h"
10 #include "gen/arrays.h" 10 #include "gen/arrays.h"
11 #include "gen/logger.h" 11 #include "gen/logger.h"
12 #include "gen/classes.h" 12 #include "gen/classes.h"
13 #include "gen/functions.h"
13 14
14 ////////////////////////////////////////////////////////////////////////////////////////// 15 //////////////////////////////////////////////////////////////////////////////////////////
15 16
16 static void LLVM_AddBaseClassData(BaseClasses* bcs) 17 static void LLVM_AddBaseClassData(BaseClasses* bcs)
17 { 18 {
20 { 21 {
21 BaseClass* bc = (BaseClass*)(bcs->data[j]); 22 BaseClass* bc = (BaseClass*)(bcs->data[j]);
22 assert(bc); 23 assert(bc);
23 Logger::println("Adding base class members of %s", bc->base->toChars()); 24 Logger::println("Adding base class members of %s", bc->base->toChars());
24 LOG_SCOPE; 25 LOG_SCOPE;
25
26 bc->base->toObjFile();
27 26
28 LLVM_AddBaseClassData(&bc->base->baseclasses); 27 LLVM_AddBaseClassData(&bc->base->baseclasses);
29 for (int k=0; k < bc->base->members->dim; k++) { 28 for (int k=0; k < bc->base->members->dim; k++) {
30 Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]); 29 Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]);
31 if (dsym->isVarDeclaration()) 30 if (dsym->isVarDeclaration())
36 } 35 }
37 } 36 }
38 37
39 ////////////////////////////////////////////////////////////////////////////////////////// 38 //////////////////////////////////////////////////////////////////////////////////////////
40 39
41 void DtoDeclareClass(ClassDeclaration* cd) 40 void DtoResolveClass(ClassDeclaration* cd)
42 { 41 {
43 if (cd->llvmTouched) return; 42 if (cd->llvmResolved) return;
44 cd->llvmTouched = true; 43 cd->llvmResolved = true;
45 44
46 Logger::println("DtoDeclareClass(%s)\n", cd->toPrettyChars()); 45 // first resolve the base class
46 if (cd->baseClass) {
47 DtoResolveClass(cd->baseClass);
48 }
49
50 Logger::println("DtoResolveClass(%s)", cd->toPrettyChars());
47 LOG_SCOPE; 51 LOG_SCOPE;
48 52
49 assert(cd->type->ty == Tclass); 53 assert(cd->type->ty == Tclass);
50 TypeClass* ts = (TypeClass*)cd->type; 54 TypeClass* ts = (TypeClass*)cd->type;
51 55
55 59
56 gIR->structs.push_back(irstruct); 60 gIR->structs.push_back(irstruct);
57 gIR->classes.push_back(cd); 61 gIR->classes.push_back(cd);
58 62
59 // add vtable 63 // add vtable
60 llvm::PATypeHolder pa = llvm::OpaqueType::get(); 64 ts->llvmVtblType = new llvm::PATypeHolder(llvm::OpaqueType::get());
61 const llvm::Type* vtabty = llvm::PointerType::get(pa); 65 const llvm::Type* vtabty = llvm::PointerType::get(ts->llvmVtblType->get());
62 66
63 std::vector<const llvm::Type*> fieldtypes; 67 std::vector<const llvm::Type*> fieldtypes;
64 fieldtypes.push_back(vtabty); 68 fieldtypes.push_back(vtabty);
65 69
66 // base classes first 70 // base classes first
78 } 82 }
79 83
80 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); 84 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes);
81 // refine abstract types for stuff like: class C {C next;} 85 // refine abstract types for stuff like: class C {C next;}
82 assert(irstruct->recty != 0); 86 assert(irstruct->recty != 0);
83 { 87
84 llvm::PATypeHolder& spa = irstruct->recty; 88 llvm::PATypeHolder& spa = irstruct->recty;
85 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype); 89 llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype);
86 structtype = isaStruct(spa.get()); 90 structtype = isaStruct(spa.get());
87 } 91
88
89 // create the type
90 ts->llvmType = new llvm::PATypeHolder(structtype); 92 ts->llvmType = new llvm::PATypeHolder(structtype);
91 93
92 bool needs_definition = false; 94 bool needs_definition = false;
93 if (cd->parent->isModule()) { 95 if (cd->parent->isModule()) {
94 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); 96 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get());
98 assert(0 && "class parent is not a module"); 100 assert(0 && "class parent is not a module");
99 } 101 }
100 102
101 // generate vtable 103 // generate vtable
102 llvm::GlobalVariable* svtblVar = 0; 104 llvm::GlobalVariable* svtblVar = 0;
103 std::vector<llvm::Constant*> sinits;
104 std::vector<const llvm::Type*> sinits_ty; 105 std::vector<const llvm::Type*> sinits_ty;
105 sinits.reserve(cd->vtbl.dim);
106 sinits_ty.reserve(cd->vtbl.dim);
107 106
108 for (int k=0; k < cd->vtbl.dim; k++) 107 for (int k=0; k < cd->vtbl.dim; k++)
109 { 108 {
110 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; 109 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k];
111 assert(dsym); 110 assert(dsym);
112 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; 111 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
113 112
114 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { 113 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
115 fd->toObjFile(); 114 DtoResolveFunction(fd);
115 assert(fd->type->ty == Tfunction);
116 TypeFunction* tf = (TypeFunction*)fd->type;
117 const llvm::Type* fpty = llvm::PointerType::get(tf->llvmType->get());
118 sinits_ty.push_back(fpty);
119 }
120 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
121 const llvm::Type* cty = llvm::PointerType::get(llvm::Type::Int8Ty);
122 sinits_ty.push_back(cty);
123 }
124 else
125 assert(0);
126 }
127
128 assert(!sinits_ty.empty());
129 const llvm::StructType* svtbl_ty = llvm::StructType::get(sinits_ty);
130
131 std::string styname(cd->mangle());
132 styname.append("__vtblType");
133 gIR->module->addTypeName(styname, svtbl_ty);
134
135 // refine for final vtable type
136 llvm::cast<llvm::OpaqueType>(ts->llvmVtblType->get())->refineAbstractTypeTo(svtbl_ty);
137
138 gIR->classes.pop_back();
139 gIR->structs.pop_back();
140
141 gIR->declareList.push_back(cd);
142 }
143
144 //////////////////////////////////////////////////////////////////////////////////////////
145
146 void DtoDeclareClass(ClassDeclaration* cd)
147 {
148 if (cd->llvmDeclared) return;
149 cd->llvmDeclared = true;
150
151 Logger::println("DtoDeclareClass(%s)", cd->toPrettyChars());
152 LOG_SCOPE;
153
154 assert(cd->type->ty == Tclass);
155 TypeClass* ts = (TypeClass*)cd->type;
156
157 assert(cd->llvmIRStruct);
158 IRStruct* irstruct = cd->llvmIRStruct;
159
160 gIR->structs.push_back(irstruct);
161 gIR->classes.push_back(cd);
162
163 bool needs_definition = false;
164 if (cd->parent->isModule()) {
165 needs_definition = (cd->getModule() == gIR->dmodule);
166 }
167
168 // vtable
169 std::string varname("_D");
170 varname.append(cd->mangle());
171 varname.append("6__vtblZ");
172
173 std::string styname(cd->mangle());
174 styname.append("__vtblTy");
175
176 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
177
178 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
179 cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
180
181 // init
182 std::string initname("_D");
183 initname.append(cd->mangle());
184 initname.append("6__initZ");
185
186 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
187 ts->llvmInit = initvar;
188
189 gIR->classes.pop_back();
190 gIR->structs.pop_back();
191
192 gIR->constInitList.push_back(cd);
193 if (needs_definition)
194 gIR->defineList.push_back(cd);
195 }
196
197 //////////////////////////////////////////////////////////////////////////////////////////
198
199 void DtoConstInitClass(ClassDeclaration* cd)
200 {
201 if (cd->llvmInitialized) return;
202 cd->llvmInitialized = true;
203
204 Logger::println("DtoConstInitClass(%s)", cd->toPrettyChars());
205 LOG_SCOPE;
206
207 IRStruct* irstruct = cd->llvmIRStruct;
208 gIR->structs.push_back(irstruct);
209 gIR->classes.push_back(cd);
210
211 // make sure each offset knows its default initializer
212 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
213 {
214 IRStruct::Offset* so = &i->second;
215 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
216 so->init = finit;
217 so->var->llvmConstInit = finit;
218 }
219
220 // fill out fieldtypes/inits
221 std::vector<llvm::Constant*> fieldinits;
222
223 // first field is always the vtable
224 assert(cd->llvmVtbl != 0);
225 fieldinits.push_back(cd->llvmVtbl);
226
227 // rest
228 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
229 Logger::println("adding fieldinit for: %s", i->second.var->toChars());
230 fieldinits.push_back(i->second.init);
231 }
232
233 // get the struct (class) type
234 assert(cd->type->ty == Tclass);
235 TypeClass* ts = (TypeClass*)cd->type;
236 const llvm::StructType* structtype = isaStruct(ts->llvmType->get());
237
238 // generate initializer
239 Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
240
241 for(size_t i=0; i<structtype->getNumElements(); ++i) {
242 Logger::cout() << "s#" << i << " = " << *structtype->getElementType(i) << '\n';
243 }
244
245 for(size_t i=0; i<fieldinits.size(); ++i) {
246 Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n';
247 }
248
249 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
250 assert(_init);
251 cd->llvmInitZ = _init;
252
253 // generate vtable initializer
254 std::vector<llvm::Constant*> sinits;
255
256 for (int k=0; k < cd->vtbl.dim; k++)
257 {
258 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k];
259 assert(dsym);
260 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
261
262 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
263 DtoForceDeclareDsymbol(fd);
116 assert(fd->llvmValue); 264 assert(fd->llvmValue);
117 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue); 265 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
118 sinits.push_back(c); 266 sinits.push_back(c);
119 sinits_ty.push_back(c->getType());
120 } 267 }
121 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) { 268 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
122 const llvm::Type* cty = llvm::PointerType::get(llvm::Type::Int8Ty); 269 const llvm::Type* cty = llvm::PointerType::get(llvm::Type::Int8Ty);
123 llvm::Constant* c = llvm::Constant::getNullValue(cty); 270 llvm::Constant* c = llvm::Constant::getNullValue(cty);
124 sinits.push_back(c); 271 sinits.push_back(c);
125 sinits_ty.push_back(cty);
126 } 272 }
127 else 273 else
128 assert(0); 274 assert(0);
129 } 275 }
130 276
131 const llvm::StructType* svtbl_ty = 0; 277 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
132 if (!sinits.empty()) 278
133 { 279 /*for (size_t i=0; i< sinits.size(); ++i)
134 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; 280 {
135 281 Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n';
136 std::string varname("_D"); 282 Logger::cout() << "init [" << i << "] = " << *sinits[i]->getType() << '\n';
137 varname.append(cd->mangle()); 283 assert(svtbl_ty->getElementType(i) == sinits[i]->getType());
138 varname.append("6__vtblZ"); 284 }*/
139 285
140 std::string styname(cd->mangle()); 286 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits);
141 styname.append("__vtblTy"); 287 cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
142
143 svtbl_ty = llvm::StructType::get(sinits_ty);
144 gIR->module->addTypeName(styname, svtbl_ty);
145 svtblVar = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
146
147 cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(svtbl_ty, sinits));
148 if (needs_definition)
149 svtblVar->setInitializer(cd->llvmConstVtbl);
150 cd->llvmVtbl = svtblVar;
151 }
152
153 // refine for final vtable type
154 llvm::cast<llvm::OpaqueType>(pa.get())->refineAbstractTypeTo(svtbl_ty);
155
156 std::string initname("_D");
157 initname.append(cd->mangle());
158 initname.append("6__initZ");
159 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
160 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
161 ts->llvmInit = initvar;
162 288
163 gIR->classes.pop_back(); 289 gIR->classes.pop_back();
164 gIR->structs.pop_back(); 290 gIR->structs.pop_back();
165 291
166 gIR->constInitQueue.push_back(cd); 292 DtoDeclareClassInfo(cd);
167 if (needs_definition) 293 }
168 gIR->defineQueue.push_back(cd); 294
169 } 295 //////////////////////////////////////////////////////////////////////////////////////////
170 296
171 ////////////////////////////////////////////////////////////////////////////////////////// 297 void DtoDefineClass(ClassDeclaration* cd)
172 298 {
173 void DtoConstInitClass(ClassDeclaration* cd) 299 if (cd->llvmDefined) return;
174 { 300 cd->llvmDefined = true;
175 IRStruct* irstruct = cd->llvmIRStruct; 301
176 if (irstruct->constinited) return; 302 Logger::println("DtoDefineClass(%s)", cd->toPrettyChars());
177 irstruct->constinited = true;
178
179 Logger::println("DtoConstInitClass(%s)\n", cd->toPrettyChars());
180 LOG_SCOPE; 303 LOG_SCOPE;
181
182 gIR->structs.push_back(irstruct);
183 gIR->classes.push_back(cd);
184
185 // make sure each offset knows its default initializer
186 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
187 {
188 IRStruct::Offset* so = &i->second;
189 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
190 so->init = finit;
191 so->var->llvmConstInit = finit;
192 }
193
194 // fill out fieldtypes/inits
195 std::vector<llvm::Constant*> fieldinits;
196
197 // first field is always the vtable
198 assert(cd->llvmVtbl != 0);
199 fieldinits.push_back(cd->llvmVtbl);
200
201 // rest
202 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
203 fieldinits.push_back(i->second.init);
204 }
205 304
206 // get the struct (class) type 305 // get the struct (class) type
207 assert(cd->type->ty == Tclass); 306 assert(cd->type->ty == Tclass);
208 TypeClass* ts = (TypeClass*)cd->type; 307 TypeClass* ts = (TypeClass*)cd->type;
209 const llvm::StructType* structtype = isaStruct(ts->llvmType->get());
210
211 // generate initializer
212 Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
213 Logger::println("%u %u fields", structtype->getNumElements(), fieldinits.size());
214 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
215 assert(_init);
216 cd->llvmInitZ = _init;
217
218 gIR->classes.pop_back();
219 gIR->structs.pop_back();
220 }
221
222 //////////////////////////////////////////////////////////////////////////////////////////
223
224 void DtoDefineClass(ClassDeclaration* cd)
225 {
226 IRStruct* irstruct = cd->llvmIRStruct;
227 if (irstruct->defined) return;
228 irstruct->defined = true;
229
230 Logger::println("DtoDefineClass(%s)\n", cd->toPrettyChars());
231 LOG_SCOPE;
232
233 // get the struct (class) type
234 assert(cd->type->ty == Tclass);
235 TypeClass* ts = (TypeClass*)cd->type;
236 308
237 bool def = false; 309 bool def = false;
238 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) { 310 if (cd->parent->isModule() && cd->getModule() == gIR->dmodule) {
239 ts->llvmInit->setInitializer(cd->llvmInitZ); 311 ts->llvmInit->setInitializer(cd->llvmInitZ);
312 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
240 def = true; 313 def = true;
241 } 314 }
242 315
243 // generate classinfo 316 // generate classinfo
244 DtoDeclareClassInfo(cd);
245 if (def) DtoDefineClassInfo(cd); 317 if (def) DtoDefineClassInfo(cd);
246 } 318 }
247 319
248 ////////////////////////////////////////////////////////////////////////////////////////// 320 //////////////////////////////////////////////////////////////////////////////////////////
249 321
300 372
301 ////////////////////////////////////////////////////////////////////////////////////////// 373 //////////////////////////////////////////////////////////////////////////////////////////
302 374
303 void DtoDeclareClassInfo(ClassDeclaration* cd) 375 void DtoDeclareClassInfo(ClassDeclaration* cd)
304 { 376 {
305 if (cd->llvmClass) 377 if (cd->llvmClassDeclared) return;
306 return; 378 cd->llvmClassDeclared = true;
307 379
308 Logger::println("CLASS INFO DECLARATION: %s", cd->toChars()); 380 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars());
309 LOG_SCOPE; 381 LOG_SCOPE;
310 382
311 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 383 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
312 cinfo->toObjFile(); 384 DtoResolveClass(cinfo);
313
314 const llvm::Type* st = cinfo->type->llvmType->get();
315 385
316 std::string gname("_D"); 386 std::string gname("_D");
317 gname.append(cd->mangle()); 387 gname.append(cd->mangle());
318 gname.append("7__ClassZ"); 388 gname.append("7__ClassZ");
389
390 const llvm::Type* st = cinfo->type->llvmType->get();
319 391
320 cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module); 392 cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module);
321 } 393 }
322 394
323 void DtoDefineClassInfo(ClassDeclaration* cd) 395 void DtoDefineClassInfo(ClassDeclaration* cd)
337 // void *deallocator; 409 // void *deallocator;
338 // OffsetTypeInfo[] offTi; 410 // OffsetTypeInfo[] offTi;
339 // void *defaultConstructor; 411 // void *defaultConstructor;
340 // } 412 // }
341 413
342 if (cd->llvmClassZ) 414 if (cd->llvmClassDefined) return;
343 return; 415 cd->llvmClassDefined = true;
344 416
345 Logger::println("CLASS INFO DEFINITION: %s", cd->toChars()); 417 Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
346 LOG_SCOPE; 418 LOG_SCOPE;
419
420 assert(cd->type->ty == Tclass);
347 assert(cd->llvmClass); 421 assert(cd->llvmClass);
422 assert(cd->llvmInitZ);
423 assert(cd->llvmVtbl);
424 assert(cd->llvmConstVtbl);
425
426 TypeClass* cdty = (TypeClass*)cd->type;
427 assert(cdty->llvmInit);
348 428
349 // holds the list of initializers for llvm 429 // holds the list of initializers for llvm
350 std::vector<llvm::Constant*> inits; 430 std::vector<llvm::Constant*> inits;
351 431
352 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 432 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
353 DtoConstInitClass(cinfo); 433 DtoForceConstInitDsymbol(cinfo);
354 assert(cinfo->llvmInitZ); 434 assert(cinfo->llvmInitZ);
355 435
356 llvm::Constant* c; 436 llvm::Constant* c;
357 437
358 // own vtable 438 // own vtable
361 inits.push_back(c); 441 inits.push_back(c);
362 442
363 // monitor 443 // monitor
364 // TODO no monitors yet 444 // TODO no monitors yet
365 445
366 // initializer 446 // byte[] init
367 c = cinfo->llvmInitZ->getOperand(1); 447 const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty);
448 c = llvm::ConstantExpr::getBitCast(cdty->llvmInit, byteptrty);
449 assert(!cd->llvmInitZ->getType()->isAbstract());
450 size_t initsz = gTargetData->getTypeSize(cd->llvmInitZ->getType());
451 c = DtoConstSlice(DtoConstSize_t(initsz), c);
368 inits.push_back(c); 452 inits.push_back(c);
369 453
370 // class name 454 // class name
371 // from dmd 455 // from dmd
372 char *name = cd->ident->toChars(); 456 char *name = cd->ident->toChars();
378 } 462 }
379 c = DtoConstString(name); 463 c = DtoConstString(name);
380 inits.push_back(c); 464 inits.push_back(c);
381 465
382 // vtbl array 466 // vtbl array
383 c = cinfo->llvmInitZ->getOperand(3); 467 const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty);
468 assert(!cd->llvmVtbl->getType()->isAbstract());
469 c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty);
470 assert(!cd->llvmConstVtbl->getType()->isAbstract());
471 size_t vtblsz = gTargetData->getTypeSize(cd->llvmConstVtbl->getType());
472 c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
384 inits.push_back(c); 473 inits.push_back(c);
385 474
386 // interfaces array 475 // interfaces array
476 // TODO
387 c = cinfo->llvmInitZ->getOperand(4); 477 c = cinfo->llvmInitZ->getOperand(4);
388 inits.push_back(c); 478 inits.push_back(c);
389 479
390 // base classinfo 480 // base classinfo
391 c = cinfo->llvmInitZ->getOperand(5); 481 if (cd->baseClass) {
392 inits.push_back(c); 482 DtoDeclareClassInfo(cd->baseClass);
483 c = cd->baseClass->llvmClass;
484 assert(c);
485 inits.push_back(c);
486 }
487 else {
488 // null
489 c = cinfo->llvmInitZ->getOperand(5);
490 inits.push_back(c);
491 }
393 492
394 // destructor 493 // destructor
494 // TODO
395 c = cinfo->llvmInitZ->getOperand(6); 495 c = cinfo->llvmInitZ->getOperand(6);
396 inits.push_back(c); 496 inits.push_back(c);
397 497
398 // invariant 498 // invariant
499 // TODO
399 c = cinfo->llvmInitZ->getOperand(7); 500 c = cinfo->llvmInitZ->getOperand(7);
400 inits.push_back(c); 501 inits.push_back(c);
401 502
402 // flags 503 // uint flags, adapted from original dmd code
403 c = cinfo->llvmInitZ->getOperand(8); 504 uint flags = 0;
505 //flags |= 4; // has offTi
506 //flags |= isCOMclass(); // IUnknown
507 if (cd->ctor) flags |= 8;
508 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass)
509 {
510 if (cd2->members)
511 {
512 for (size_t i = 0; i < cd2->members->dim; i++)
513 {
514 Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
515 //printf("sm = %s %s\n", sm->kind(), sm->toChars());
516 if (sm->hasPointers())
517 goto L2;
518 }
519 }
520 }
521 flags |= 2; // no pointers
522 L2:
523 c = DtoConstUint(flags);
404 inits.push_back(c); 524 inits.push_back(c);
405 525
406 // allocator 526 // allocator
527 // TODO
407 c = cinfo->llvmInitZ->getOperand(9); 528 c = cinfo->llvmInitZ->getOperand(9);
408 inits.push_back(c); 529 inits.push_back(c);
409 530
410 // offset typeinfo 531 // offset typeinfo
532 // TODO
411 c = cinfo->llvmInitZ->getOperand(10); 533 c = cinfo->llvmInitZ->getOperand(10);
412 inits.push_back(c); 534 inits.push_back(c);
413 535
414 // default constructor 536 // default constructor
537 // TODO
415 c = cinfo->llvmInitZ->getOperand(11); 538 c = cinfo->llvmInitZ->getOperand(11);
416 inits.push_back(c); 539 inits.push_back(c);
417 540
418 /*size_t n = inits.size(); 541 /*size_t n = inits.size();
419 for (size_t i=0; i<n; ++i) 542 for (size_t i=0; i<n; ++i)