comparison gen/classes.cpp @ 133:44a95ac7368a trunk

[svn r137] Many fixes towards tango.io.Console working, but not quite there yet... In particular, assertions has been fixed to include file/line info, and much more!
author lindquist
date Mon, 14 Jan 2008 05:11:54 +0100
parents 1700239cab2e
children 0e28624814e8
comparison
equal deleted inserted replaced
132:1700239cab2e 133:44a95ac7368a
54 void DtoResolveClass(ClassDeclaration* cd) 54 void DtoResolveClass(ClassDeclaration* cd)
55 { 55 {
56 if (cd->llvmResolved) return; 56 if (cd->llvmResolved) return;
57 cd->llvmResolved = true; 57 cd->llvmResolved = true;
58 58
59 // first resolve the base class 59 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
60 LOG_SCOPE;
61
62 // get the TypeClass
63 assert(cd->type->ty == Tclass);
64 TypeClass* ts = (TypeClass*)cd->type;
65
66 // make sure the IRStruct is created
67 IRStruct* irstruct = cd->llvmIRStruct;
68 if (!irstruct) {
69 irstruct = new IRStruct(ts);
70 cd->llvmIRStruct = irstruct;
71 }
72
73 // resolve the base class
60 if (cd->baseClass) { 74 if (cd->baseClass) {
61 DtoResolveClass(cd->baseClass); 75 DtoResolveClass(cd->baseClass);
62 } 76 }
63 77
64 // resolve interfaces 78 // resolve interfaces
70 // Fill in vtbl[] 84 // Fill in vtbl[]
71 b->fillVtbl(cd, &b->vtbl, 1); 85 b->fillVtbl(cd, &b->vtbl, 1);
72 } 86 }
73 } 87 }
74 88
75 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
76 LOG_SCOPE;
77
78 assert(cd->type->ty == Tclass);
79 TypeClass* ts = (TypeClass*)cd->type;
80
81 assert(!cd->llvmIRStruct);
82 IRStruct* irstruct = new IRStruct(ts);
83 cd->llvmIRStruct = irstruct;
84
85 gIR->structs.push_back(irstruct); 89 gIR->structs.push_back(irstruct);
86 gIR->classes.push_back(cd); 90 gIR->classes.push_back(cd);
87 91
88 // add vtable 92 // add vtable
89 ts->llvmVtblType = new llvm::PATypeHolder(llvm::OpaqueType::get()); 93 ts->llvmVtblType = new llvm::PATypeHolder(llvm::OpaqueType::get());
90 const llvm::Type* vtabty = llvm::PointerType::get(ts->llvmVtblType->get()); 94 const llvm::Type* vtabty = getPtrToType(ts->llvmVtblType->get());
91 95
92 std::vector<const llvm::Type*> fieldtypes; 96 std::vector<const llvm::Type*> fieldtypes;
93 fieldtypes.push_back(vtabty); 97 fieldtypes.push_back(vtabty);
94 98
95 // add monitor 99 // add monitor
96 fieldtypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty)); 100 fieldtypes.push_back(getPtrToType(llvm::Type::Int8Ty));
97 101
98 // add interface vtables 102 // add interface vtables
99 if (cd->vtblInterfaces) 103 if (cd->vtblInterfaces)
100 for (size_t i = 0; i < cd->vtblInterfaces->dim; i++) 104 for (size_t i = 0; i < cd->vtblInterfaces->dim; i++)
101 { 105 {
102 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; 106 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
103 ClassDeclaration *id = b->base; 107 ClassDeclaration *id = b->base;
104 assert(id->type->ty == Tclass); 108 assert(id->type->ty == Tclass);
105 TypeClass* itc = (TypeClass*)id->type; 109 TypeClass* itc = (TypeClass*)id->type;
106 const llvm::Type* ivtblTy = llvm::PointerType::get(itc->llvmVtblType->get()); 110 const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get());
107 fieldtypes.push_back(ivtblTy); 111 fieldtypes.push_back(ivtblTy);
108 112
109 // add this interface to the map 113 // add this interface to the map
110 IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get())); 114 IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get()));
111 irstruct->interfaces.insert(std::make_pair(id, iri)); 115 irstruct->interfaces.insert(std::make_pair(id, iri));
140 // first iteration 144 // first iteration
141 if (lastoffset == (unsigned)-1) { 145 if (lastoffset == (unsigned)-1) {
142 lastoffset = i->first; 146 lastoffset = i->first;
143 fieldtype = i->second.type; 147 fieldtype = i->second.type;
144 fieldinit = i->second.var; 148 fieldinit = i->second.var;
145 prevsize = gTargetData->getTypeSize(fieldtype); 149 prevsize = getABITypeSize(fieldtype);
146 i->second.var->llvmFieldIndex = idx; 150 i->second.var->llvmFieldIndex = idx;
147 } 151 }
148 // colliding offset? 152 // colliding offset?
149 else if (lastoffset == i->first) { 153 else if (lastoffset == i->first) {
150 size_t s = gTargetData->getTypeSize(i->second.type); 154 size_t s = getABITypeSize(i->second.type);
151 if (s > prevsize) { 155 if (s > prevsize) {
152 fieldpad += s - prevsize; 156 fieldpad += s - prevsize;
153 prevsize = s; 157 prevsize = s;
154 } 158 }
155 cd->llvmHasUnions = true; 159 cd->llvmHasUnions = true;
156 i->second.var->llvmFieldIndex = idx; 160 i->second.var->llvmFieldIndex = idx;
157 } 161 }
158 // intersecting offset? 162 // intersecting offset?
159 else if (i->first < (lastoffset + prevsize)) { 163 else if (i->first < (lastoffset + prevsize)) {
160 size_t s = gTargetData->getTypeSize(i->second.type); 164 size_t s = getABITypeSize(i->second.type);
161 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size 165 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
162 cd->llvmHasUnions = true; 166 cd->llvmHasUnions = true;
163 i->second.var->llvmFieldIndex = idx; 167 i->second.var->llvmFieldIndex = idx;
164 i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s; 168 i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
165 } 169 }
178 182
179 // start new 183 // start new
180 lastoffset = i->first; 184 lastoffset = i->first;
181 fieldtype = i->second.type; 185 fieldtype = i->second.type;
182 fieldinit = i->second.var; 186 fieldinit = i->second.var;
183 prevsize = gTargetData->getTypeSize(fieldtype); 187 prevsize = getABITypeSize(fieldtype);
184 i->second.var->llvmFieldIndex = idx; 188 i->second.var->llvmFieldIndex = idx;
185 fieldpad = 0; 189 fieldpad = 0;
186 } 190 }
187 } 191 }
188 fieldtypes.push_back(fieldtype); 192 fieldtypes.push_back(fieldtype);
210 214
211 if (!ts->llvmType) 215 if (!ts->llvmType)
212 ts->llvmType = new llvm::PATypeHolder(structtype); 216 ts->llvmType = new llvm::PATypeHolder(structtype);
213 else 217 else
214 *ts->llvmType = structtype; 218 *ts->llvmType = structtype;
219 spa = *ts->llvmType;
215 220
216 // name the type 221 // name the type
217 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get()); 222 gIR->module->addTypeName(cd->mangle(), ts->llvmType->get());
218 223
219 // build interface info type 224 // build interface info type
220 std::vector<const llvm::Type*> infoTypes; 225 std::vector<const llvm::Type*> infoTypes;
221 // ClassInfo classinfo 226 // ClassInfo classinfo
222 ClassDeclaration* cinfod = ClassDeclaration::classinfo; 227 ClassDeclaration* cinfod = ClassDeclaration::classinfo;
223 DtoResolveClass(cinfod); 228 DtoResolveClass(cinfod);
224 infoTypes.push_back(llvm::PointerType::get(cinfod->type->llvmType->get())); 229 infoTypes.push_back(getPtrToType(cinfod->type->llvmType->get()));
225 // void*[] vtbl 230 // void*[] vtbl
226 std::vector<const llvm::Type*> infoVtbltypes; 231 std::vector<const llvm::Type*> infoVtbltypes;
227 infoVtbltypes.push_back(DtoSize_t()); 232 infoVtbltypes.push_back(DtoSize_t());
228 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty)); 233 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
229 infoVtbltypes.push_back(byteptrptrty); 234 infoVtbltypes.push_back(byteptrptrty);
230 infoTypes.push_back(llvm::StructType::get(infoVtbltypes)); 235 infoTypes.push_back(llvm::StructType::get(infoVtbltypes));
231 // int offset 236 // int offset
232 infoTypes.push_back(llvm::Type::Int32Ty); 237 infoTypes.push_back(llvm::Type::Int32Ty);
233 // create type 238 // create type
245 250
246 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { 251 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
247 DtoResolveFunction(fd); 252 DtoResolveFunction(fd);
248 //assert(fd->type->ty == Tfunction); 253 //assert(fd->type->ty == Tfunction);
249 //TypeFunction* tf = (TypeFunction*)fd->type; 254 //TypeFunction* tf = (TypeFunction*)fd->type;
250 //const llvm::Type* fpty = llvm::PointerType::get(tf->llvmType->get()); 255 //const llvm::Type* fpty = getPtrToType(tf->llvmType->get());
251 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd); 256 const llvm::FunctionType* vfty = DtoBaseFunctionType(fd);
252 const llvm::Type* vfpty = llvm::PointerType::get(vfty); 257 const llvm::Type* vfpty = getPtrToType(vfty);
253 sinits_ty.push_back(vfpty); 258 sinits_ty.push_back(vfpty);
254 } 259 }
255 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { 260 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
256 Logger::println("*** ClassDeclaration in vtable: %s", cd2->toChars()); 261 Logger::println("*** ClassDeclaration in vtable: %s", cd2->toChars());
257 const llvm::Type* cinfoty; 262 const llvm::Type* cinfoty;
264 } 269 }
265 else { 270 else {
266 // this is the ClassInfo class, the type is this type 271 // this is the ClassInfo class, the type is this type
267 cinfoty = ts->llvmType->get(); 272 cinfoty = ts->llvmType->get();
268 } 273 }
269 const llvm::Type* cty = llvm::PointerType::get(cinfoty); 274 const llvm::Type* cty = getPtrToType(cinfoty);
270 sinits_ty.push_back(cty); 275 sinits_ty.push_back(cty);
271 } 276 }
272 else 277 else
273 assert(0); 278 assert(0);
274 } 279 }
312 if (cd->getModule() == gIR->dmodule) { 317 if (cd->getModule() == gIR->dmodule) {
313 needs_definition = true; 318 needs_definition = true;
314 } 319 }
315 320
316 // interface vtables are emitted by the class implementing them 321 // interface vtables are emitted by the class implementing them
317 // also interfaces have no static initializer 322 // also, interfaces have no static initializer
318 if (!cd->isInterfaceDeclaration()) { 323 // also, abstract classes have no vtable
324 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
319 // vtable 325 // vtable
320 std::string varname("_D"); 326 std::string varname("_D");
321 varname.append(cd->mangle()); 327 varname.append(cd->mangle());
322 varname.append("6__vtblZ"); 328 varname.append("6__vtblZ");
323 329
329 // build interface info type 335 // build interface info type
330 std::vector<const llvm::Type*> types; 336 std::vector<const llvm::Type*> types;
331 // ClassInfo classinfo 337 // ClassInfo classinfo
332 ClassDeclaration* cd2 = ClassDeclaration::classinfo; 338 ClassDeclaration* cd2 = ClassDeclaration::classinfo;
333 DtoResolveClass(cd2); 339 DtoResolveClass(cd2);
334 types.push_back(llvm::PointerType::get(cd2->type->llvmType->get())); 340 types.push_back(getPtrToType(cd2->type->llvmType->get()));
335 // void*[] vtbl 341 // void*[] vtbl
336 std::vector<const llvm::Type*> vtbltypes; 342 std::vector<const llvm::Type*> vtbltypes;
337 vtbltypes.push_back(DtoSize_t()); 343 vtbltypes.push_back(DtoSize_t());
338 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty)); 344 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
339 vtbltypes.push_back(byteptrptrty); 345 vtbltypes.push_back(byteptrptrty);
340 types.push_back(llvm::StructType::get(vtbltypes)); 346 types.push_back(llvm::StructType::get(vtbltypes));
341 // int offset 347 // int offset
342 types.push_back(llvm::Type::Int32Ty); 348 types.push_back(llvm::Type::Int32Ty);
343 // create type 349 // create type
416 422
417 IRStruct* irstruct = cd->llvmIRStruct; 423 IRStruct* irstruct = cd->llvmIRStruct;
418 gIR->structs.push_back(irstruct); 424 gIR->structs.push_back(irstruct);
419 gIR->classes.push_back(cd); 425 gIR->classes.push_back(cd);
420 426
427 // get the struct (class) type
428 assert(cd->type->ty == Tclass);
429 TypeClass* ts = (TypeClass*)cd->type;
430 const llvm::StructType* structtype = isaStruct(ts->llvmType->get());
431 const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get());
432
421 // make sure each offset knows its default initializer 433 // make sure each offset knows its default initializer
422 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) 434 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
423 { 435 {
424 IRStruct::Offset* so = &i->second; 436 IRStruct::Offset* so = &i->second;
425 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); 437 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
429 441
430 // fill out fieldtypes/inits 442 // fill out fieldtypes/inits
431 std::vector<llvm::Constant*> fieldinits; 443 std::vector<llvm::Constant*> fieldinits;
432 444
433 // first field is always the vtable 445 // first field is always the vtable
434 assert(cd->llvmVtbl != 0); 446 if (cd->isAbstract())
435 fieldinits.push_back(cd->llvmVtbl); 447 {
448 fieldinits.push_back(
449 llvm::ConstantPointerNull::get(
450 getPtrToType(
451 ts->llvmVtblType->get()
452 )
453 )
454 );
455 }
456 else
457 {
458 assert(cd->llvmVtbl != 0);
459 fieldinits.push_back(cd->llvmVtbl);
460 }
436 461
437 // then comes monitor 462 // then comes monitor
438 fieldinits.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty))); 463 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
439 464
440 size_t dataoffset = 2; 465 size_t dataoffset = 2;
441 466
442 // next comes interface vtables 467 // next comes interface vtables
443 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) 468 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
444 { 469 {
445 IRInterface* iri = i->second; 470 IRInterface* iri = i->second;
446 assert(iri->vtbl); 471 if (cd->isAbstract())
447 fieldinits.push_back(iri->vtbl); 472 {
448 ++dataoffset; 473 fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy));
474 }
475 else
476 {
477 assert(iri->vtbl);
478 fieldinits.push_back(iri->vtbl);
479 ++dataoffset;
480 }
449 } 481 }
450 482
451 /* 483 /*
452 // rest 484 // rest
453 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 485 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
454 Logger::println("adding fieldinit for: %s", i->second.var->toChars()); 486 Logger::println("adding fieldinit for: %s", i->second.var->toChars());
455 fieldinits.push_back(i->second.init); 487 fieldinits.push_back(i->second.init);
456 } 488 }
457 */ 489 */
458
459 // get the struct (class) type
460 assert(cd->type->ty == Tclass);
461 TypeClass* ts = (TypeClass*)cd->type;
462 const llvm::StructType* structtype = isaStruct(ts->llvmType->get());
463 const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get());
464 490
465 // go through the field inits and build the default initializer 491 // go through the field inits and build the default initializer
466 size_t nfi = irstruct->defaultFields.size(); 492 size_t nfi = irstruct->defaultFields.size();
467 for (size_t i=0; i<nfi; ++i) { 493 for (size_t i=0; i<nfi; ++i) {
468 llvm::Constant* c; 494 llvm::Constant* c;
493 519
494 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); 520 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
495 assert(_init); 521 assert(_init);
496 cd->llvmConstInit = _init; 522 cd->llvmConstInit = _init;
497 523
498 // generate vtable initializer 524 // abstract classes have no static vtable
499 std::vector<llvm::Constant*> sinits; 525 if (!cd->isAbstract())
500 526 {
501 for (int k=0; k < cd->vtbl.dim; k++) 527 // generate vtable initializer
502 { 528 std::vector<llvm::Constant*> sinits;
503 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k]; 529
504 assert(dsym); 530 for (int k=0; k < cd->vtbl.dim; k++)
505 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; 531 {
506 532 Dsymbol* dsym = (Dsymbol*)cd->vtbl.data[k];
507 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { 533 assert(dsym);
508 DtoForceDeclareDsymbol(fd); 534 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
509 assert(fd->llvmValue); 535
510 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue); 536 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
511 // cast if necessary (overridden method) 537 DtoForceDeclareDsymbol(fd);
512 if (c->getType() != vtbltype->getElementType(k)) 538 assert(fd->llvmValue);
513 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k)); 539 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
514 sinits.push_back(c); 540 // cast if necessary (overridden method)
515 } 541 if (c->getType() != vtbltype->getElementType(k))
516 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { 542 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k));
517 assert(cd->llvmClass); 543 sinits.push_back(c);
518 llvm::Constant* c = cd->llvmClass; 544 }
519 sinits.push_back(c); 545 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
520 } 546 assert(cd->llvmClass);
521 else 547 llvm::Constant* c = cd->llvmClass;
522 assert(0); 548 sinits.push_back(c);
523 } 549 }
524 550 else
525 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); 551 assert(0);
552 }
553
554 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
526 555
527 #if 0 556 #if 0
528 for (size_t i=0; i< sinits.size(); ++i) 557 for (size_t i=0; i< sinits.size(); ++i)
529 { 558 {
530 Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n'; 559 Logger::cout() << "field[" << i << "] = " << *svtbl_ty->getElementType(i) << '\n';
531 Logger::cout() << "init [" << i << "] = " << *sinits[i]->getType() << '\n'; 560 Logger::cout() << "init [" << i << "] = " << *sinits[i]->getType() << '\n';
532 assert(svtbl_ty->getElementType(i) == sinits[i]->getType()); 561 assert(svtbl_ty->getElementType(i) == sinits[i]->getType());
533 } 562 }
534 #endif 563 #endif
535 564
536 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits); 565 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits);
537 cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); 566 cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
538 567
539 // create interface vtable const initalizers 568 // create interface vtable const initalizers
540 int idx = 2; 569 int idx = 2;
541 int idxScale = PTRSIZE; 570 int idxScale = PTRSIZE;
542 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) 571 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
543 {
544 ClassDeclaration* id = i->first;
545 assert(id->type->ty == Tclass);
546 TypeClass* its = (TypeClass*)id->type;
547
548 IRInterface* iri = i->second;
549 BaseClass* b = iri->base;
550
551 const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get());
552
553 // generate interface info initializer
554 std::vector<llvm::Constant*> infoInits;
555 // classinfo
556 assert(id->llvmClass);
557 llvm::Constant* c = id->llvmClass;
558 infoInits.push_back(c);
559 // vtbl
560 const llvm::Type* byteptrptrty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
561 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
562 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
563 infoInits.push_back(c);
564 // offset
565 infoInits.push_back(DtoConstInt(idx*idxScale));
566 // create interface info initializer constant
567 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
568
569 // generate vtable initializer
570 std::vector<llvm::Constant*> iinits;
571
572 // add interface info
573 iinits.push_back(iri->info);
574
575 for (int k=1; k < b->vtbl.dim; k++)
576 { 572 {
577 Logger::println("interface vtbl const init nr. %d", k); 573 ClassDeclaration* id = i->first;
578 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k]; 574 assert(id->type->ty == Tclass);
579 FuncDeclaration* fd = dsym->isFuncDeclaration(); 575 TypeClass* its = (TypeClass*)id->type;
580 assert(fd); 576
581 DtoForceDeclareDsymbol(fd); 577 IRInterface* iri = i->second;
582 assert(fd->llvmValue); 578 BaseClass* b = iri->base;
583 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue); 579
584 // we have to bitcast, as the type created in ResolveClass expects a different this type 580 const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get());
585 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k)); 581
586 iinits.push_back(c); 582 // generate interface info initializer
587 } 583 std::vector<llvm::Constant*> infoInits;
588 584 // classinfo
589 #if 1 585 assert(id->llvmClass);
590 for (size_t x=0; x< iinits.size(); ++x) 586 llvm::Constant* c = id->llvmClass;
591 { 587 infoInits.push_back(c);
592 Logger::cout() << "field[" << x << "] = " << *ivtbl_ty->getElementType(x) << "\n\n"; 588 // vtbl
593 Logger::cout() << "init [" << x << "] = " << *iinits[x] << "\n\n"; 589 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
594 assert(ivtbl_ty->getElementType(x) == iinits[x]->getType()); 590 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
595 } 591 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
596 #endif 592 infoInits.push_back(c);
597 593 // offset
598 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); 594 infoInits.push_back(DtoConstInt(idx*idxScale));
599 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); 595 // create interface info initializer constant
600 596 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
601 idx++; 597
602 } 598 // generate vtable initializer
599 std::vector<llvm::Constant*> iinits;
600
601 // add interface info
602 iinits.push_back(iri->info);
603
604 for (int k=1; k < b->vtbl.dim; k++)
605 {
606 Logger::println("interface vtbl const init nr. %d", k);
607 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k];
608 FuncDeclaration* fd = dsym->isFuncDeclaration();
609 assert(fd);
610 DtoForceDeclareDsymbol(fd);
611 assert(fd->llvmValue);
612 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
613 // we have to bitcast, as the type created in ResolveClass expects a different this type
614 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k));
615 iinits.push_back(c);
616 }
617
618 #if 1
619 for (size_t x=0; x< iinits.size(); ++x)
620 {
621 Logger::cout() << "field[" << x << "] = " << *ivtbl_ty->getElementType(x) << "\n\n";
622 Logger::cout() << "init [" << x << "] = " << *iinits[x] << "\n\n";
623 assert(ivtbl_ty->getElementType(x) == iinits[x]->getType());
624 }
625 #endif
626
627 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits);
628 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit);
629
630 idx++;
631 }
632 } // !abstract
603 633
604 gIR->classes.pop_back(); 634 gIR->classes.pop_back();
605 gIR->structs.pop_back(); 635 gIR->structs.pop_back();
606 } 636 }
607 637
619 assert(cd->type->ty == Tclass); 649 assert(cd->type->ty == Tclass);
620 TypeClass* ts = (TypeClass*)cd->type; 650 TypeClass* ts = (TypeClass*)cd->type;
621 651
622 if (cd->getModule() == gIR->dmodule) { 652 if (cd->getModule() == gIR->dmodule) {
623 // interfaces don't have initializers 653 // interfaces don't have initializers
624 if (!cd->isInterfaceDeclaration()) { 654 // neither do abstract classes
655 if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
656 {
625 cd->llvmInit->setInitializer(cd->llvmConstInit); 657 cd->llvmInit->setInitializer(cd->llvmConstInit);
626 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); 658 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
627 659
628 // initialize interface vtables 660 // initialize interface vtables
629 IRStruct* irstruct = cd->llvmIRStruct; 661 IRStruct* irstruct = cd->llvmIRStruct;
633 IRInterface* iri = i->second; 665 IRInterface* iri = i->second;
634 iri->vtbl->setInitializer(iri->vtblInit); 666 iri->vtbl->setInitializer(iri->vtblInit);
635 infoInits.push_back(iri->infoInit); 667 infoInits.push_back(iri->infoInit);
636 } 668 }
637 // initialize interface info array 669 // initialize interface info array
638 if (!infoInits.empty()) { 670 if (!infoInits.empty())
671 {
639 llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); 672 llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits);
640 irstruct->interfaceInfos->setInitializer(arrInit); 673 irstruct->interfaceInfos->setInitializer(arrInit);
641 } 674 }
642 } 675 }
643 676
644 // generate classinfo 677 // generate classinfo
645 DtoDefineClassInfo(cd); 678 DtoDefineClassInfo(cd);
646 } 679 }
680 }
681
682 //////////////////////////////////////////////////////////////////////////////////////////
683
684 DValue* DtoNewClass(TypeClass* tc, NewExp* newexp)
685 {
686 // resolve type
687 DtoForceDeclareDsymbol(tc->sym);
688
689 // allocate
690 llvm::Value* mem;
691 if (newexp->onstack)
692 {
693 mem = new llvm::AllocaInst(DtoType(tc)->getContainedType(0), "newclass_alloca", gIR->topallocapoint());
694 }
695 else
696 {
697 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass");
698 std::vector<llvm::Value*> args;
699 args.push_back(tc->sym->llvmClass);
700 mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc");
701 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc");
702 }
703
704 // init
705 DtoInitClass(tc, mem);
706
707 // init inner-class outer reference
708 if (newexp->thisexp)
709 {
710 Logger::println("Resolving outer class");
711 LOG_SCOPE;
712 DValue* thisval = newexp->thisexp->toElem(gIR);
713 size_t idx = 2;
714 idx += tc->sym->llvmIRStruct->interfaces.size();
715 llvm::Value* dst = thisval->getRVal();
716 llvm::Value* src = DtoGEPi(mem,0,idx,"tmp");
717 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
718 DtoStore(dst, src);
719 }
720 // set the context for nested classes
721 else if (tc->sym->isNested())
722 {
723 Logger::println("Resolving nested context");
724 LOG_SCOPE;
725 size_t idx = 2;
726 idx += tc->sym->llvmIRStruct->interfaces.size();
727 llvm::Value* nest = gIR->func()->decl->llvmNested;
728 if (!nest)
729 nest = gIR->func()->decl->llvmThisVar;
730 assert(nest);
731 llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp");
732 nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
733 DtoStore(nest, gep);
734 }
735
736 // call constructor
737 if (newexp->arguments)
738 return DtoCallClassCtor(tc, newexp->member, newexp->arguments, mem);
739
740 // return default constructed class
741 return new DImValue(tc, mem, false);
742 }
743
744 //////////////////////////////////////////////////////////////////////////////////////////
745
746 void DtoInitClass(TypeClass* tc, llvm::Value* dst)
747 {
748 size_t presz = 2*getABITypeSize(DtoSize_t());
749 uint64_t n = getABITypeSize(tc->llvmType->get()) - presz;
750
751 // set vtable field seperately, this might give better optimization
752 assert(tc->sym->llvmVtbl);
753 DtoStore(tc->sym->llvmVtbl, DtoGEPi(dst,0,0,"vtbl"));
754
755 // monitor always defaults to zero
756 llvm::Value* tmp = DtoGEPi(dst,0,1,"monitor");
757 DtoStore(llvm::Constant::getNullValue(tmp->getType()->getContainedType(0)), tmp);
758
759 // done?
760 if (n == 0)
761 return;
762
763 // copy the rest from the static initializer
764 assert(tc->sym->llvmInit);
765 assert(dst->getType() == tc->sym->llvmInit->getType());
766
767 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty);
768
769 llvm::Value* dstarr = DtoGEPi(dst,0,2,"tmp");
770 dstarr = DtoBitCast(dstarr, arrty);
771
772 llvm::Value* srcarr = DtoGEPi(tc->sym->llvmInit,0,2,"tmp");
773 srcarr = DtoBitCast(srcarr, arrty);
774
775 llvm::Function* fn = LLVM_DeclareMemCpy32();
776 std::vector<llvm::Value*> llargs;
777 llargs.resize(4);
778 llargs[0] = dstarr;
779 llargs[1] = srcarr;
780 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
781 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
782
783 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
784 }
785
786 //////////////////////////////////////////////////////////////////////////////////////////
787
788 DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* arguments, llvm::Value* mem)
789 {
790 Logger::println("Calling constructor");
791 LOG_SCOPE;
792
793 assert(ctor);
794 DtoForceDeclareDsymbol(ctor);
795 llvm::Function* fn = llvm::cast<llvm::Function>(ctor->llvmValue);
796 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type);
797
798 std::vector<llvm::Value*> ctorargs;
799 ctorargs.push_back(mem);
800 for (size_t i=0; i<arguments->dim; ++i)
801 {
802 Expression* ex = (Expression*)arguments->data[i];
803 Argument* fnarg = Argument::getNth(tf->parameters, i);
804 DValue* argval = DtoArgument(fnarg, ex);
805 llvm::Value* a = argval->getRVal();
806 const llvm::Type* aty = fn->getFunctionType()->getParamType(i+1);
807 if (a->getType() != aty)
808 a = DtoBitCast(a, aty);
809 ctorargs.push_back(a);
810 }
811 llvm::CallInst* call = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", gIR->scopebb());
812 call->setCallingConv(DtoCallingConv(LINKd));
813
814 return new DImValue(type, call, false);
647 } 815 }
648 816
649 ////////////////////////////////////////////////////////////////////////////////////////// 817 //////////////////////////////////////////////////////////////////////////////////////////
650 818
651 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance) 819 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
654 for (size_t i=0; i<arr->dim; i++) 822 for (size_t i=0; i<arr->dim; i++)
655 { 823 {
656 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; 824 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
657 assert(fd->llvmValue); 825 assert(fd->llvmValue);
658 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb()); 826 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
659 }
660 }
661
662 //////////////////////////////////////////////////////////////////////////////////////////
663
664 void DtoInitClass(TypeClass* tc, llvm::Value* dst)
665 {
666 assert(gIR);
667
668 assert(tc->llvmType);
669 uint64_t size_t_size = gTargetData->getTypeSize(DtoSize_t());
670 uint64_t n = gTargetData->getTypeSize(tc->llvmType->get()) - size_t_size;
671
672 // set vtable field
673 llvm::Value* vtblvar = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
674 assert(tc->sym->llvmVtbl);
675 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb());
676
677 // copy the static initializer
678 if (n > 0) {
679 assert(tc->sym->llvmInit);
680 assert(dst->getType() == tc->sym->llvmInit->getType());
681
682 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
683
684 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
685 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb());
686
687 llvm::Value* srcarr = new llvm::BitCastInst(tc->sym->llvmInit,arrty,"tmp",gIR->scopebb());
688 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb());
689
690 llvm::Function* fn = LLVM_DeclareMemCpy32();
691 std::vector<llvm::Value*> llargs;
692 llargs.resize(4);
693 llargs[0] = dstarr;
694 llargs[1] = srcarr;
695 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
696 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
697
698 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
699 } 827 }
700 } 828 }
701 829
702 ////////////////////////////////////////////////////////////////////////////////////////// 830 //////////////////////////////////////////////////////////////////////////////////////////
703 831
715 843
716 Type* from = DtoDType(val->getType()); 844 Type* from = DtoDType(val->getType());
717 TypeClass* fc = (TypeClass*)from; 845 TypeClass* fc = (TypeClass*)from;
718 846
719 if (tc->sym->isInterfaceDeclaration()) { 847 if (tc->sym->isInterfaceDeclaration()) {
720 assert(!fc->sym->isInterfaceDeclaration()); 848 if (fc->sym->isInterfaceDeclaration()) {
721 return DtoDynamicCastObject(val, _to); 849 return DtoDynamicCastInterface(val, _to);
850 }
851 else {
852 return DtoDynamicCastObject(val, _to);
853 }
722 } 854 }
723 else { 855 else {
724 int poffset; 856 int poffset;
725 if (fc->sym->isInterfaceDeclaration()) { 857 if (fc->sym->isInterfaceDeclaration()) {
726 return DtoCastInterfaceToObject(val, _to); 858 return DtoCastInterfaceToObject(val, _to);
803 return new DImValue(to, ret); 935 return new DImValue(to, ret);
804 } 936 }
805 937
806 ////////////////////////////////////////////////////////////////////////////////////////// 938 //////////////////////////////////////////////////////////////////////////////////////////
807 939
940 DValue* DtoDynamicCastInterface(DValue* val, Type* _to)
941 {
942 // call:
943 // Object _d_interface_cast(void* p, ClassInfo c)
944
945 DtoForceDeclareDsymbol(ClassDeclaration::object);
946 DtoForceDeclareDsymbol(ClassDeclaration::classinfo);
947
948 llvm::Function* func = LLVM_D_GetRuntimeFunction(gIR->module, "_d_interface_cast");
949 const llvm::FunctionType* funcTy = func->getFunctionType();
950
951 std::vector<llvm::Value*> args;
952
953 // void* p
954 llvm::Value* tmp = val->getRVal();
955 tmp = DtoBitCast(tmp, funcTy->getParamType(0));
956 args.push_back(tmp);
957
958 // ClassInfo c
959 TypeClass* to = (TypeClass*)DtoDType(_to);
960 DtoForceDeclareDsymbol(to->sym);
961 assert(to->sym->llvmClass);
962 tmp = to->sym->llvmClass;
963 // unfortunately this is needed as the implementation of object differs somehow from the declaration
964 // this could happen in user code as well :/
965 tmp = DtoBitCast(tmp, funcTy->getParamType(1));
966 args.push_back(tmp);
967
968 // call it
969 llvm::Value* ret = gIR->ir->CreateCall(func, args.begin(), args.end(), "tmp");
970
971 // cast return value
972 ret = DtoBitCast(ret, DtoType(_to));
973
974 return new DImValue(_to, ret);
975 }
976
977 //////////////////////////////////////////////////////////////////////////////////////////
978
808 static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx) 979 static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx)
809 { 980 {
810 // start at the bottom of the inheritance chain 981 // start at the bottom of the inheritance chain
811 if (cd->baseClass != 0) { 982 if (cd->baseClass != 0) {
812 unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx); 983 unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx);
849 LOG_SCOPE; 1020 LOG_SCOPE;
850 1021
851 if (idxs.empty()) 1022 if (idxs.empty())
852 idxs.push_back(0); 1023 idxs.push_back(0);
853 1024
854 const llvm::Type* llt = llvm::PointerType::get(DtoType(t)); 1025 const llvm::Type* llt = getPtrToType(DtoType(t));
855 const llvm::Type* st = DtoType(cd->type); 1026 const llvm::Type* st = DtoType(cd->type);
856 if (ptr->getType() != st) { 1027 if (ptr->getType() != st) {
857 assert(cd->llvmHasUnions); 1028 assert(cd->llvmHasUnions);
858 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); 1029 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp");
859 } 1030 }
893 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); 1064 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
894 std::vector<unsigned> tmp; 1065 std::vector<unsigned> tmp;
895 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 1066 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
896 } 1067 }
897 else { 1068 else {
898 const llvm::Type* sty = llvm::PointerType::get(DtoType(vd->type)); 1069 const llvm::Type* sty = getPtrToType(DtoType(vd->type));
899 if (ptr->getType() != sty) { 1070 if (ptr->getType() != sty) {
900 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); 1071 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp");
901 std::vector<unsigned> tmp; 1072 std::vector<unsigned> tmp;
902 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 1073 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
903 } 1074 }
908 } 1079 }
909 } 1080 }
910 1081
911 assert(0); 1082 assert(0);
912 1083
913 size_t llt_sz = gTargetData->getTypeSize(llt->getContainedType(0)); 1084 size_t llt_sz = getABITypeSize(llt->getContainedType(0));
914 assert(os % llt_sz == 0); 1085 assert(os % llt_sz == 0);
915 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 1086 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
916 return new llvm::GetElementPtrInst(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); 1087 return new llvm::GetElementPtrInst(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb());
1088 }
1089
1090 //////////////////////////////////////////////////////////////////////////////////////////
1091
1092 llvm::Value* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl)
1093 {
1094 assert(fdecl->isVirtual());//fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual()));
1095 assert(fdecl->vtblIndex > 0);
1096 assert(DtoDType(inst->getType())->ty == Tclass);
1097
1098 llvm::Value* vthis = inst->getRVal();
1099 //Logger::cout() << "vthis: " << *vthis << '\n';
1100
1101 llvm::Value* funcval;
1102 funcval = DtoGEPi(vthis, 0, 0, "tmp");
1103 funcval = DtoLoad(funcval);
1104 funcval = DtoGEPi(funcval, 0, fdecl->vtblIndex, fdecl->toPrettyChars());
1105 funcval = DtoLoad(funcval);
1106
1107 //assert(funcval->getType() == DtoType(fdecl->type));
1108 //cc = DtoCallingConv(fdecl->linkage);
1109
1110 return funcval;
917 } 1111 }
918 1112
919 ////////////////////////////////////////////////////////////////////////////////////////// 1113 //////////////////////////////////////////////////////////////////////////////////////////
920 1114
921 void DtoDeclareClassInfo(ClassDeclaration* cd) 1115 void DtoDeclareClassInfo(ClassDeclaration* cd)
959 vd->type->getTypeInfo(NULL); 1153 vd->type->getTypeInfo(NULL);
960 assert(vd->type->vtinfo); 1154 assert(vd->type->vtinfo);
961 DtoForceDeclareDsymbol(vd->type->vtinfo); 1155 DtoForceDeclareDsymbol(vd->type->vtinfo);
962 llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue); 1156 llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue);
963 1157
964 const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get()); 1158 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get());
965 //Logger::cout() << "tiTy = " << *tiTy << '\n'; 1159 //Logger::cout() << "tiTy = " << *tiTy << '\n';
966 1160
967 types.push_back(tiTy); 1161 types.push_back(tiTy);
968 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy)); 1162 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy));
969 1163
1000 1194
1001 if (ninits > 0) { 1195 if (ninits > 0) {
1002 // OffsetTypeInfo type 1196 // OffsetTypeInfo type
1003 std::vector<const llvm::Type*> elemtypes; 1197 std::vector<const llvm::Type*> elemtypes;
1004 elemtypes.push_back(DtoSize_t()); 1198 elemtypes.push_back(DtoSize_t());
1005 const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get()); 1199 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get());
1006 elemtypes.push_back(tiTy); 1200 elemtypes.push_back(tiTy);
1007 const llvm::StructType* sTy = llvm::StructType::get(elemtypes); 1201 const llvm::StructType* sTy = llvm::StructType::get(elemtypes);
1008 1202
1009 // array type 1203 // array type
1010 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits); 1204 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits);
1011 llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits); 1205 llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits);
1012 1206
1013 std::string name(cd->type->vtinfo->toChars()); 1207 std::string name(cd->type->vtinfo->toChars());
1014 name.append("__OffsetTypeInfos"); 1208 name.append("__OffsetTypeInfos");
1015 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module); 1209 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module);
1016 ptr = llvm::ConstantExpr::getBitCast(gvar, llvm::PointerType::get(sTy)); 1210 ptr = llvm::ConstantExpr::getBitCast(gvar, getPtrToType(sTy));
1017 } 1211 }
1018 else { 1212 else {
1019 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1))); 1213 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1)));
1020 } 1214 }
1021 1215
1024 1218
1025 static llvm::Constant* build_class_dtor(ClassDeclaration* cd) 1219 static llvm::Constant* build_class_dtor(ClassDeclaration* cd)
1026 { 1220 {
1027 // construct the function 1221 // construct the function
1028 std::vector<const llvm::Type*> paramTypes; 1222 std::vector<const llvm::Type*> paramTypes;
1029 paramTypes.push_back(llvm::PointerType::get(cd->type->llvmType->get())); 1223 paramTypes.push_back(getPtrToType(cd->type->llvmType->get()));
1030 1224
1031 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false); 1225 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false);
1032 1226
1033 if (cd->dtors.dim == 0) { 1227 if (cd->dtors.dim == 0) {
1034 return llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); 1228 return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty));
1035 } 1229 }
1036 else if (cd->dtors.dim == 1) { 1230 else if (cd->dtors.dim == 1) {
1037 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0]; 1231 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
1038 DtoForceDeclareDsymbol(d); 1232 DtoForceDeclareDsymbol(d);
1039 assert(d->llvmValue); 1233 assert(d->llvmValue);
1040 return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), llvm::PointerType::get(llvm::Type::Int8Ty)); 1234 return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), getPtrToType(llvm::Type::Int8Ty));
1041 } 1235 }
1042 1236
1043 std::string gname("_D"); 1237 std::string gname("_D");
1044 gname.append(cd->mangle()); 1238 gname.append(cd->mangle());
1045 gname.append("12__destructorMFZv"); 1239 gname.append("12__destructorMFZv");
1058 assert(d->llvmValue); 1252 assert(d->llvmValue);
1059 builder.CreateCall(d->llvmValue, thisptr); 1253 builder.CreateCall(d->llvmValue, thisptr);
1060 } 1254 }
1061 builder.CreateRetVoid(); 1255 builder.CreateRetVoid();
1062 1256
1063 return llvm::ConstantExpr::getBitCast(func, llvm::PointerType::get(llvm::Type::Int8Ty)); 1257 return llvm::ConstantExpr::getBitCast(func, getPtrToType(llvm::Type::Int8Ty));
1064 } 1258 }
1065 1259
1066 static uint build_classinfo_flags(ClassDeclaration* cd) 1260 static uint build_classinfo_flags(ClassDeclaration* cd)
1067 { 1261 {
1068 // adapted from original dmd code 1262 // adapted from original dmd code
1119 1313
1120 assert(cd->type->ty == Tclass); 1314 assert(cd->type->ty == Tclass);
1121 assert(cd->llvmClass); 1315 assert(cd->llvmClass);
1122 1316
1123 TypeClass* cdty = (TypeClass*)cd->type; 1317 TypeClass* cdty = (TypeClass*)cd->type;
1124 if (!cd->isInterfaceDeclaration()) { 1318 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1125 assert(cd->llvmInit); 1319 assert(cd->llvmInit);
1126 assert(cd->llvmConstInit); 1320 assert(cd->llvmConstInit);
1127 assert(cd->llvmVtbl); 1321 assert(cd->llvmVtbl);
1128 assert(cd->llvmConstVtbl); 1322 assert(cd->llvmConstVtbl);
1129 } 1323 }
1145 // monitor 1339 // monitor
1146 c = cinfo->llvmConstInit->getOperand(1); 1340 c = cinfo->llvmConstInit->getOperand(1);
1147 inits.push_back(c); 1341 inits.push_back(c);
1148 1342
1149 // byte[] init 1343 // byte[] init
1150 const llvm::Type* byteptrty = llvm::PointerType::get(llvm::Type::Int8Ty); 1344 const llvm::Type* byteptrty = getPtrToType(llvm::Type::Int8Ty);
1151 if (cd->isInterfaceDeclaration()) { 1345 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1152 c = cinfo->llvmConstInit->getOperand(2); 1346 c = cinfo->llvmConstInit->getOperand(2);
1153 } 1347 }
1154 else { 1348 else {
1155 c = llvm::ConstantExpr::getBitCast(cd->llvmInit, byteptrty); 1349 c = llvm::ConstantExpr::getBitCast(cd->llvmInit, byteptrty);
1156 assert(!cd->llvmConstInit->getType()->isAbstract()); 1350 assert(!cd->llvmConstInit->getType()->isAbstract());
1157 size_t initsz = gTargetData->getTypeSize(cd->llvmConstInit->getType()); 1351 size_t initsz = getABITypeSize(cd->llvmConstInit->getType());
1158 c = DtoConstSlice(DtoConstSize_t(initsz), c); 1352 c = DtoConstSlice(DtoConstSize_t(initsz), c);
1159 } 1353 }
1160 inits.push_back(c); 1354 inits.push_back(c);
1161 1355
1162 // class name 1356 // class name
1170 } 1364 }
1171 c = DtoConstString(name); 1365 c = DtoConstString(name);
1172 inits.push_back(c); 1366 inits.push_back(c);
1173 1367
1174 // vtbl array 1368 // vtbl array
1175 if (cd->isInterfaceDeclaration()) { 1369 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1176 c = cinfo->llvmConstInit->getOperand(4); 1370 c = cinfo->llvmConstInit->getOperand(4);
1177 } 1371 }
1178 else { 1372 else {
1179 const llvm::Type* byteptrptrty = llvm::PointerType::get(byteptrty); 1373 const llvm::Type* byteptrptrty = getPtrToType(byteptrty);
1180 assert(!cd->llvmVtbl->getType()->isAbstract()); 1374 assert(!cd->llvmVtbl->getType()->isAbstract());
1181 c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty); 1375 c = llvm::ConstantExpr::getBitCast(cd->llvmVtbl, byteptrptrty);
1182 assert(!cd->llvmConstVtbl->getType()->isAbstract()); 1376 assert(!cd->llvmConstVtbl->getType()->isAbstract());
1183 size_t vtblsz = cd->llvmConstVtbl->getType()->getNumElements(); 1377 size_t vtblsz = cd->llvmConstVtbl->getType()->getNumElements();
1184 c = DtoConstSlice(DtoConstSize_t(vtblsz), c); 1378 c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
1185 } 1379 }
1186 inits.push_back(c); 1380 inits.push_back(c);
1187 1381
1188 // interfaces array 1382 // interfaces array
1189 IRStruct* irstruct = cd->llvmIRStruct; 1383 IRStruct* irstruct = cd->llvmIRStruct;
1190 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos) { 1384 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) {
1191 c = cinfo->llvmConstInit->getOperand(5); 1385 c = cinfo->llvmConstInit->getOperand(5);
1192 } 1386 }
1193 else { 1387 else {
1194 const llvm::Type* t = cinfo->llvmConstInit->getOperand(5)->getType()->getContainedType(1); 1388 const llvm::Type* t = cinfo->llvmConstInit->getOperand(5)->getType()->getContainedType(1);
1195 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); 1389 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t);
1197 c = DtoConstSlice(DtoConstSize_t(iisz), c); 1391 c = DtoConstSlice(DtoConstSize_t(iisz), c);
1198 } 1392 }
1199 inits.push_back(c); 1393 inits.push_back(c);
1200 1394
1201 // base classinfo 1395 // base classinfo
1202 if (cd->baseClass && !cd->isInterfaceDeclaration()) { 1396 if (cd->baseClass && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1203 DtoDeclareClassInfo(cd->baseClass); 1397 DtoDeclareClassInfo(cd->baseClass);
1204 c = cd->baseClass->llvmClass; 1398 c = cd->baseClass->llvmClass;
1205 assert(c); 1399 assert(c);
1206 inits.push_back(c); 1400 inits.push_back(c);
1207 } 1401 }
1210 c = cinfo->llvmConstInit->getOperand(6); 1404 c = cinfo->llvmConstInit->getOperand(6);
1211 inits.push_back(c); 1405 inits.push_back(c);
1212 } 1406 }
1213 1407
1214 // destructor 1408 // destructor
1215 if (cd->isInterfaceDeclaration()) { 1409 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1216 c = cinfo->llvmConstInit->getOperand(7); 1410 c = cinfo->llvmConstInit->getOperand(7);
1217 } 1411 }
1218 else { 1412 else {
1219 c = build_class_dtor(cd); 1413 c = build_class_dtor(cd);
1220 } 1414 }
1224 // TODO 1418 // TODO
1225 c = cinfo->llvmConstInit->getOperand(8); 1419 c = cinfo->llvmConstInit->getOperand(8);
1226 inits.push_back(c); 1420 inits.push_back(c);
1227 1421
1228 // uint flags 1422 // uint flags
1229 if (cd->isInterfaceDeclaration()) { 1423 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1230 c = cinfo->llvmConstInit->getOperand(9); 1424 c = cinfo->llvmConstInit->getOperand(9);
1231 } 1425 }
1232 else { 1426 else {
1233 uint flags = build_classinfo_flags(cd); 1427 uint flags = build_classinfo_flags(cd);
1234 c = DtoConstUint(flags); 1428 c = DtoConstUint(flags);
1239 // TODO 1433 // TODO
1240 c = cinfo->llvmConstInit->getOperand(10); 1434 c = cinfo->llvmConstInit->getOperand(10);
1241 inits.push_back(c); 1435 inits.push_back(c);
1242 1436
1243 // offset typeinfo 1437 // offset typeinfo
1244 if (cd->isInterfaceDeclaration()) { 1438 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1245 c = cinfo->llvmConstInit->getOperand(11); 1439 c = cinfo->llvmConstInit->getOperand(11);
1246 } 1440 }
1247 else { 1441 else {
1248 c = build_offti_array(cd, cinfo->llvmConstInit->getOperand(11)); 1442 c = build_offti_array(cd, cinfo->llvmConstInit->getOperand(11));
1249 } 1443 }
1250 inits.push_back(c); 1444 inits.push_back(c);
1251 1445
1252 // default constructor 1446 // default constructor
1253 if (cd->defaultCtor && !cd->isInterfaceDeclaration()) { 1447 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1254 DtoForceDeclareDsymbol(cd->defaultCtor); 1448 DtoForceDeclareDsymbol(cd->defaultCtor);
1255 c = isaConstant(cd->defaultCtor->llvmValue); 1449 c = isaConstant(cd->defaultCtor->llvmValue);
1256 const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType(); 1450 const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType();
1257 c = llvm::ConstantExpr::getBitCast(c, toTy); 1451 c = llvm::ConstantExpr::getBitCast(c, toTy);
1258 } 1452 }