comparison gen/classes.cpp @ 136:0e28624814e8 trunk

[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
author lindquist
date Thu, 17 Jan 2008 03:15:12 +0100
parents 44a95ac7368a
children ce7b81fb957f
comparison
equal deleted inserted replaced
135:176bd52b3cf5 136:0e28624814e8
14 #include "gen/structs.h" 14 #include "gen/structs.h"
15 #include "gen/functions.h" 15 #include "gen/functions.h"
16 #include "gen/runtime.h" 16 #include "gen/runtime.h"
17 #include "gen/dvalue.h" 17 #include "gen/dvalue.h"
18 18
19 #include "ir/irstruct.h"
20
19 ////////////////////////////////////////////////////////////////////////////////////////// 21 //////////////////////////////////////////////////////////////////////////////////////////
20 22
21 static void LLVM_AddBaseClassData(BaseClasses* bcs) 23 static void LLVM_AddBaseClassData(BaseClasses* bcs)
22 { 24 {
23 // add base class data members first 25 // add base class data members first
24 for (int j=0; j<bcs->dim; j++) 26 for (int j=0; j<bcs->dim; j++)
25 { 27 {
26 BaseClass* bc = (BaseClass*)(bcs->data[j]); 28 BaseClass* bc = (BaseClass*)(bcs->data[j]);
27 assert(bc);
28 if (bc->base->isInterfaceDeclaration()) 29 if (bc->base->isInterfaceDeclaration())
29 continue; // interfaces only has methods 30 continue; // interfaces only have methods
30 31
31 LLVM_AddBaseClassData(&bc->base->baseclasses); 32 LLVM_AddBaseClassData(&bc->base->baseclasses);
32 33
33 Logger::println("Adding base class members of %s", bc->base->toChars()); 34 Logger::println("Adding base class members of %s", bc->base->toChars());
34 LOG_SCOPE; 35 LOG_SCOPE;
36 Array* arr = &bc->base->fields; 37 Array* arr = &bc->base->fields;
37 for (int k=0; k < arr->dim; k++) { 38 for (int k=0; k < arr->dim; k++) {
38 VarDeclaration* v = (VarDeclaration*)(arr->data[k]); 39 VarDeclaration* v = (VarDeclaration*)(arr->data[k]);
39 v->toObjFile(); 40 v->toObjFile();
40 } 41 }
41
42 /*for (int k=0; k < bc->base->members->dim; k++) {
43 Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]);
44 if (dsym->isVarDeclaration())
45 {
46 dsym->toObjFile();
47 }
48 }*/
49 } 42 }
50 } 43 }
51 44
52 ////////////////////////////////////////////////////////////////////////////////////////// 45 //////////////////////////////////////////////////////////////////////////////////////////
53 46
61 54
62 // get the TypeClass 55 // get the TypeClass
63 assert(cd->type->ty == Tclass); 56 assert(cd->type->ty == Tclass);
64 TypeClass* ts = (TypeClass*)cd->type; 57 TypeClass* ts = (TypeClass*)cd->type;
65 58
66 // make sure the IRStruct is created 59 // make sure the IrStruct is created
67 IRStruct* irstruct = cd->llvmIRStruct; 60 IrStruct* irstruct = cd->llvmIrStruct;
68 if (!irstruct) { 61 if (!irstruct) {
69 irstruct = new IRStruct(ts); 62 irstruct = new IrStruct(ts);
70 cd->llvmIRStruct = irstruct; 63 cd->llvmIrStruct = irstruct;
71 } 64 }
72 65
73 // resolve the base class 66 // resolve the base class
74 if (cd->baseClass) { 67 if (cd->baseClass) {
75 DtoResolveClass(cd->baseClass); 68 DtoResolveClass(cd->baseClass);
76 } 69 }
77 70
78 // resolve interfaces 71 // resolve interface vtables
79 if (cd->vtblInterfaces) { 72 if (cd->vtblInterfaces) {
80 for (int i=0; i < cd->vtblInterfaces->dim; i++) { 73 for (int i=0; i < cd->vtblInterfaces->dim; i++) {
81 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i]; 74 BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
82 ClassDeclaration *id = b->base; 75 ClassDeclaration *id = b->base;
83 DtoResolveClass(id); 76 DtoResolveClass(id);
109 TypeClass* itc = (TypeClass*)id->type; 102 TypeClass* itc = (TypeClass*)id->type;
110 const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get()); 103 const llvm::Type* ivtblTy = getPtrToType(itc->llvmVtblType->get());
111 fieldtypes.push_back(ivtblTy); 104 fieldtypes.push_back(ivtblTy);
112 105
113 // add this interface to the map 106 // add this interface to the map
114 IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get())); 107 IrInterface* iri = new IrInterface(b, isaStruct(itc->llvmVtblType->get()));
115 irstruct->interfaces.insert(std::make_pair(id, iri)); 108 irstruct->interfaces.insert(std::make_pair(id, iri));
116 } 109 }
117 110
118 // base classes first 111 // base classes first
119 LLVM_AddBaseClassData(&cd->baseclasses); 112 LLVM_AddBaseClassData(&cd->baseclasses);
138 unsigned lastoffset = (unsigned)-1; 131 unsigned lastoffset = (unsigned)-1;
139 const llvm::Type* fieldtype = NULL; 132 const llvm::Type* fieldtype = NULL;
140 VarDeclaration* fieldinit = NULL; 133 VarDeclaration* fieldinit = NULL;
141 size_t fieldpad = 0; 134 size_t fieldpad = 0;
142 int idx = 0; 135 int idx = 0;
143 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 136 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
144 // first iteration 137 // first iteration
145 if (lastoffset == (unsigned)-1) { 138 if (lastoffset == (unsigned)-1) {
146 lastoffset = i->first; 139 lastoffset = i->first;
147 fieldtype = i->second.type; 140 fieldtype = i->second.type;
148 fieldinit = i->second.var; 141 fieldinit = i->second.var;
149 prevsize = getABITypeSize(fieldtype); 142 prevsize = getABITypeSize(fieldtype);
150 i->second.var->llvmFieldIndex = idx; 143 i->second.var->irField->index = idx;
151 } 144 }
152 // colliding offset? 145 // colliding offset?
153 else if (lastoffset == i->first) { 146 else if (lastoffset == i->first) {
154 size_t s = getABITypeSize(i->second.type); 147 size_t s = getABITypeSize(i->second.type);
155 if (s > prevsize) { 148 if (s > prevsize) {
156 fieldpad += s - prevsize; 149 fieldpad += s - prevsize;
157 prevsize = s; 150 prevsize = s;
158 } 151 }
159 cd->llvmHasUnions = true; 152 cd->llvmHasUnions = true;
160 i->second.var->llvmFieldIndex = idx; 153 i->second.var->irField->index = idx;
161 } 154 }
162 // intersecting offset? 155 // intersecting offset?
163 else if (i->first < (lastoffset + prevsize)) { 156 else if (i->first < (lastoffset + prevsize)) {
164 size_t s = getABITypeSize(i->second.type); 157 size_t s = getABITypeSize(i->second.type);
165 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size 158 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
166 cd->llvmHasUnions = true; 159 cd->llvmHasUnions = true;
167 i->second.var->llvmFieldIndex = idx; 160 i->second.var->irField->index = idx;
168 i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s; 161 i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
169 } 162 }
170 // fresh offset 163 // fresh offset
171 else { 164 else {
172 // commit the field 165 // commit the field
173 fieldtypes.push_back(fieldtype); 166 fieldtypes.push_back(fieldtype);
183 // start new 176 // start new
184 lastoffset = i->first; 177 lastoffset = i->first;
185 fieldtype = i->second.type; 178 fieldtype = i->second.type;
186 fieldinit = i->second.var; 179 fieldinit = i->second.var;
187 prevsize = getABITypeSize(fieldtype); 180 prevsize = getABITypeSize(fieldtype);
188 i->second.var->llvmFieldIndex = idx; 181 i->second.var->irField->index = idx;
189 fieldpad = 0; 182 fieldpad = 0;
190 } 183 }
191 } 184 }
192 fieldtypes.push_back(fieldtype); 185 fieldtypes.push_back(fieldtype);
193 irstruct->defaultFields.push_back(fieldinit); 186 irstruct->defaultFields.push_back(fieldinit);
197 } 190 }
198 } 191 }
199 192
200 /* 193 /*
201 // add field types 194 // add field types
202 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 195 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
203 fieldtypes.push_back(i->second.type); 196 fieldtypes.push_back(i->second.type);
204 } 197 }
205 */ 198 */
206 199
207 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); 200 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes);
305 LOG_SCOPE; 298 LOG_SCOPE;
306 299
307 assert(cd->type->ty == Tclass); 300 assert(cd->type->ty == Tclass);
308 TypeClass* ts = (TypeClass*)cd->type; 301 TypeClass* ts = (TypeClass*)cd->type;
309 302
310 assert(cd->llvmIRStruct); 303 assert(cd->llvmIrStruct);
311 IRStruct* irstruct = cd->llvmIRStruct; 304 IrStruct* irstruct = cd->llvmIrStruct;
312 305
313 gIR->structs.push_back(irstruct); 306 gIR->structs.push_back(irstruct);
314 gIR->classes.push_back(cd); 307 gIR->classes.push_back(cd);
315 308
316 bool needs_definition = false; 309 bool needs_definition = false;
317 if (cd->getModule() == gIR->dmodule) { 310 if (cd->getModule() == gIR->dmodule) {
318 needs_definition = true; 311 needs_definition = true;
319 } 312 }
320 313
321 // interface vtables are emitted by the class implementing them 314 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
322 // also, interfaces have no static initializer 315
323 // also, abstract classes have no vtable 316 // interfaces have no static initializer
317 // same goes for abstract classes
324 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { 318 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
325 // vtable 319 // vtable
326 std::string varname("_D"); 320 std::string varname("_D");
327 varname.append(cd->mangle()); 321 varname.append(cd->mangle());
328 varname.append("6__vtblZ"); 322 varname.append("6__vtblZ");
329 323
330 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
331
332 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); 324 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
333 cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); 325 cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
334 326 }
335 // build interface info type 327
336 std::vector<const llvm::Type*> types; 328 // get interface info type
337 // ClassInfo classinfo 329 const llvm::StructType* infoTy = DtoInterfaceInfoType();
338 ClassDeclaration* cd2 = ClassDeclaration::classinfo; 330
339 DtoResolveClass(cd2); 331 // interface info array
340 types.push_back(getPtrToType(cd2->type->llvmType->get())); 332 if (cd->vtblInterfaces->dim > 0) {
341 // void*[] vtbl 333 // symbol name
342 std::vector<const llvm::Type*> vtbltypes; 334 std::string nam = "_D";
343 vtbltypes.push_back(DtoSize_t()); 335 nam.append(cd->mangle());
344 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); 336 nam.append("16__interfaceInfosZ");
345 vtbltypes.push_back(byteptrptrty); 337 // resolve array type
346 types.push_back(llvm::StructType::get(vtbltypes)); 338 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
347 // int offset 339 // declare global
348 types.push_back(llvm::Type::Int32Ty); 340 irstruct->interfaceInfosTy = arrTy;
349 // create type 341 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
350 const llvm::StructType* infoTy = llvm::StructType::get(types); 342 }
351 343
352 // interface info array 344 // interfaces have no static initializer
353 if (cd->vtblInterfaces->dim > 0) { 345 // same goes for abstract classes
354 // symbol name 346 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
355 std::string nam = "_D";
356 nam.append(cd->mangle());
357 nam.append("16__interfaceInfosZ");
358 // resolve array type
359 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
360 // declare global
361 irstruct->interfaceInfosTy = arrTy;
362 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
363 }
364
365 // interface vtables 347 // interface vtables
366 unsigned idx = 0; 348 unsigned idx = 0;
367 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) 349 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
368 { 350 {
369 ClassDeclaration* id = i->first; 351 ClassDeclaration* id = i->first;
370 IRInterface* iri = i->second; 352 IrInterface* iri = i->second;
371 353
372 std::string nam("_D"); 354 std::string nam("_D");
373 nam.append(cd->mangle()); 355 nam.append(cd->mangle());
374 nam.append("11__interface"); 356 nam.append("11__interface");
375 nam.append(id->mangle()); 357 nam.append(id->mangle());
376 nam.append("6__vtblZ"); 358 nam.append("6__vtblZ");
377 359
378 assert(iri->vtblTy); 360 assert(iri->vtblTy);
379 iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module); 361 iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module);
380 iri->infoTy = infoTy;
381 llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)}; 362 llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)};
382 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2); 363 iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2);
383 idx++; 364 idx++;
384 } 365 }
385 366
418 return; // nothing to do 399 return; // nothing to do
419 400
420 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 401 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
421 LOG_SCOPE; 402 LOG_SCOPE;
422 403
423 IRStruct* irstruct = cd->llvmIRStruct; 404 IrStruct* irstruct = cd->llvmIrStruct;
424 gIR->structs.push_back(irstruct); 405 gIR->structs.push_back(irstruct);
425 gIR->classes.push_back(cd); 406 gIR->classes.push_back(cd);
426 407
427 // get the struct (class) type 408 // get the struct (class) type
428 assert(cd->type->ty == Tclass); 409 assert(cd->type->ty == Tclass);
429 TypeClass* ts = (TypeClass*)cd->type; 410 TypeClass* ts = (TypeClass*)cd->type;
430 const llvm::StructType* structtype = isaStruct(ts->llvmType->get()); 411 const llvm::StructType* structtype = isaStruct(ts->llvmType->get());
431 const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get()); 412 const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get());
432 413
433 // make sure each offset knows its default initializer 414 // make sure each offset knows its default initializer
434 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) 415 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
435 { 416 {
436 IRStruct::Offset* so = &i->second; 417 IrStruct::Offset* so = &i->second;
437 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); 418 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
438 so->init = finit; 419 so->init = finit;
439 so->var->llvmConstInit = finit; 420 so->var->irField->constInit = finit;
440 } 421 }
441 422
442 // fill out fieldtypes/inits 423 // fill out fieldtypes/inits
443 std::vector<llvm::Constant*> fieldinits; 424 std::vector<llvm::Constant*> fieldinits;
444 425
463 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); 444 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
464 445
465 size_t dataoffset = 2; 446 size_t dataoffset = 2;
466 447
467 // next comes interface vtables 448 // next comes interface vtables
468 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) 449 const llvm::StructType* infoTy = DtoInterfaceInfoType();
469 { 450 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
470 IRInterface* iri = i->second; 451 {
452 IrInterface* iri = i->second;
453 iri->infoTy = infoTy;
471 if (cd->isAbstract()) 454 if (cd->isAbstract())
472 { 455 {
473 fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy)); 456 fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy));
474 } 457 }
475 else 458 else
480 } 463 }
481 } 464 }
482 465
483 /* 466 /*
484 // rest 467 // rest
485 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 468 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
486 Logger::println("adding fieldinit for: %s", i->second.var->toChars()); 469 Logger::println("adding fieldinit for: %s", i->second.var->toChars());
487 fieldinits.push_back(i->second.init); 470 fieldinits.push_back(i->second.init);
488 } 471 }
489 */ 472 */
490 473
491 // go through the field inits and build the default initializer 474 // go through the field inits and build the default initializer
492 size_t nfi = irstruct->defaultFields.size(); 475 size_t nfi = irstruct->defaultFields.size();
493 for (size_t i=0; i<nfi; ++i) { 476 for (size_t i=0; i<nfi; ++i) {
494 llvm::Constant* c; 477 llvm::Constant* c;
495 if (irstruct->defaultFields[i] != NULL) { 478 if (irstruct->defaultFields[i] != NULL) {
496 c = irstruct->defaultFields[i]->llvmConstInit; 479 c = irstruct->defaultFields[i]->irField->constInit;
497 assert(c); 480 assert(c);
498 } 481 }
499 else { 482 else {
500 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+dataoffset)); 483 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+dataoffset));
501 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false)); 484 std::vector<llvm::Constant*> vals(arrty->getNumElements(), llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false));
533 assert(dsym); 516 assert(dsym);
534 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; 517 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
535 518
536 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { 519 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
537 DtoForceDeclareDsymbol(fd); 520 DtoForceDeclareDsymbol(fd);
538 assert(fd->llvmValue); 521 assert(fd->irFunc->func);
539 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue); 522 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func);
540 // cast if necessary (overridden method) 523 // cast if necessary (overridden method)
541 if (c->getType() != vtbltype->getElementType(k)) 524 if (c->getType() != vtbltype->getElementType(k))
542 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k)); 525 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k));
543 sinits.push_back(c); 526 sinits.push_back(c);
544 } 527 }
566 cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); 549 cd->llvmConstVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
567 550
568 // create interface vtable const initalizers 551 // create interface vtable const initalizers
569 int idx = 2; 552 int idx = 2;
570 int idxScale = PTRSIZE; 553 int idxScale = PTRSIZE;
571 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) 554 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
572 { 555 {
573 ClassDeclaration* id = i->first; 556 ClassDeclaration* id = i->first;
574 assert(id->type->ty == Tclass); 557 assert(id->type->ty == Tclass);
575 TypeClass* its = (TypeClass*)id->type; 558 TypeClass* its = (TypeClass*)id->type;
576 559
577 IRInterface* iri = i->second; 560 IrInterface* iri = i->second;
578 BaseClass* b = iri->base; 561 BaseClass* b = iri->base;
579 562
580 const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get()); 563 const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get());
581 564
582 // generate interface info initializer 565 // generate interface info initializer
583 std::vector<llvm::Constant*> infoInits; 566 std::vector<llvm::Constant*> infoInits;
567
584 // classinfo 568 // classinfo
585 assert(id->llvmClass); 569 assert(id->llvmClass);
586 llvm::Constant* c = id->llvmClass; 570 llvm::Constant* c = id->llvmClass;
587 infoInits.push_back(c); 571 infoInits.push_back(c);
572
588 // vtbl 573 // vtbl
589 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); 574 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
590 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); 575 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
591 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c); 576 c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
592 infoInits.push_back(c); 577 infoInits.push_back(c);
578
593 // offset 579 // offset
594 infoInits.push_back(DtoConstInt(idx*idxScale)); 580 infoInits.push_back(DtoConstInt(idx*idxScale));
581
595 // create interface info initializer constant 582 // create interface info initializer constant
596 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits)); 583 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
597 584
598 // generate vtable initializer 585 // generate vtable initializer
599 std::vector<llvm::Constant*> iinits; 586 std::vector<llvm::Constant*> iinits;
606 Logger::println("interface vtbl const init nr. %d", k); 593 Logger::println("interface vtbl const init nr. %d", k);
607 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k]; 594 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k];
608 FuncDeclaration* fd = dsym->isFuncDeclaration(); 595 FuncDeclaration* fd = dsym->isFuncDeclaration();
609 assert(fd); 596 assert(fd);
610 DtoForceDeclareDsymbol(fd); 597 DtoForceDeclareDsymbol(fd);
611 assert(fd->llvmValue); 598 assert(fd->irFunc->func);
612 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue); 599 llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func);
600
613 // we have to bitcast, as the type created in ResolveClass expects a different this type 601 // 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)); 602 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k));
615 iinits.push_back(c); 603 iinits.push_back(c);
616 } 604 }
617 605
627 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits); 615 llvm::Constant* civtblInit = llvm::ConstantStruct::get(ivtbl_ty, iinits);
628 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit); 616 iri->vtblInit = llvm::cast<llvm::ConstantStruct>(civtblInit);
629 617
630 idx++; 618 idx++;
631 } 619 }
632 } // !abstract 620 }
621 // we always generate interfaceinfos as best we can
622 else
623 {
624 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
625 {
626 ClassDeclaration* id = i->first;
627 assert(id->type->ty == Tclass);
628 TypeClass* its = (TypeClass*)id->type;
629
630 IrInterface* iri = i->second;
631 BaseClass* b = iri->base;
632
633 // generate interface info initializer
634 std::vector<llvm::Constant*> infoInits;
635
636 // classinfo
637 assert(id->llvmClass);
638 llvm::Constant* c = id->llvmClass;
639 infoInits.push_back(c);
640
641 // vtbl
642 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
643 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
644 infoInits.push_back(c);
645
646 // offset
647 infoInits.push_back(DtoConstInt(0));
648
649 // create interface info initializer constant
650 iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
651 }
652 }
633 653
634 gIR->classes.pop_back(); 654 gIR->classes.pop_back();
635 gIR->structs.pop_back(); 655 gIR->structs.pop_back();
636 } 656 }
637 657
656 { 676 {
657 cd->llvmInit->setInitializer(cd->llvmConstInit); 677 cd->llvmInit->setInitializer(cd->llvmConstInit);
658 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl); 678 cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
659 679
660 // initialize interface vtables 680 // initialize interface vtables
661 IRStruct* irstruct = cd->llvmIRStruct; 681 IrStruct* irstruct = cd->llvmIrStruct;
662 std::vector<llvm::Constant*> infoInits; 682 std::vector<llvm::Constant*> infoInits;
663 for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) 683 for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
664 { 684 {
665 IRInterface* iri = i->second; 685 IrInterface* iri = i->second;
666 iri->vtbl->setInitializer(iri->vtblInit); 686 iri->vtbl->setInitializer(iri->vtblInit);
667 infoInits.push_back(iri->infoInit); 687 infoInits.push_back(iri->infoInit);
668 } 688 }
669 // initialize interface info array 689 // initialize interface info array
670 if (!infoInits.empty()) 690 if (!infoInits.empty())
709 { 729 {
710 Logger::println("Resolving outer class"); 730 Logger::println("Resolving outer class");
711 LOG_SCOPE; 731 LOG_SCOPE;
712 DValue* thisval = newexp->thisexp->toElem(gIR); 732 DValue* thisval = newexp->thisexp->toElem(gIR);
713 size_t idx = 2; 733 size_t idx = 2;
714 idx += tc->sym->llvmIRStruct->interfaces.size(); 734 idx += tc->sym->llvmIrStruct->interfaces.size();
715 llvm::Value* dst = thisval->getRVal(); 735 llvm::Value* dst = thisval->getRVal();
716 llvm::Value* src = DtoGEPi(mem,0,idx,"tmp"); 736 llvm::Value* src = DtoGEPi(mem,0,idx,"tmp");
717 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; 737 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
718 DtoStore(dst, src); 738 DtoStore(dst, src);
719 } 739 }
721 else if (tc->sym->isNested()) 741 else if (tc->sym->isNested())
722 { 742 {
723 Logger::println("Resolving nested context"); 743 Logger::println("Resolving nested context");
724 LOG_SCOPE; 744 LOG_SCOPE;
725 size_t idx = 2; 745 size_t idx = 2;
726 idx += tc->sym->llvmIRStruct->interfaces.size(); 746 idx += tc->sym->llvmIrStruct->interfaces.size();
727 llvm::Value* nest = gIR->func()->decl->llvmNested; 747 llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar;
728 if (!nest) 748 if (!nest)
729 nest = gIR->func()->decl->llvmThisVar; 749 nest = gIR->func()->decl->irFunc->thisVar;
730 assert(nest); 750 assert(nest);
731 llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp"); 751 llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp");
732 nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); 752 nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
733 DtoStore(nest, gep); 753 DtoStore(nest, gep);
734 } 754 }
790 Logger::println("Calling constructor"); 810 Logger::println("Calling constructor");
791 LOG_SCOPE; 811 LOG_SCOPE;
792 812
793 assert(ctor); 813 assert(ctor);
794 DtoForceDeclareDsymbol(ctor); 814 DtoForceDeclareDsymbol(ctor);
795 llvm::Function* fn = llvm::cast<llvm::Function>(ctor->llvmValue); 815 llvm::Function* fn = ctor->irFunc->func;
796 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); 816 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type);
797 817
798 std::vector<llvm::Value*> ctorargs; 818 std::vector<llvm::Value*> ctorargs;
799 ctorargs.push_back(mem); 819 ctorargs.push_back(mem);
800 for (size_t i=0; i<arguments->dim; ++i) 820 for (size_t i=0; i<arguments->dim; ++i)
820 { 840 {
821 Array* arr = &tc->sym->dtors; 841 Array* arr = &tc->sym->dtors;
822 for (size_t i=0; i<arr->dim; i++) 842 for (size_t i=0; i<arr->dim; i++)
823 { 843 {
824 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; 844 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
825 assert(fd->llvmValue); 845 assert(fd->irFunc->func);
826 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb()); 846 new llvm::CallInst(fd->irFunc->func, instance, "", gIR->scopebb());
827 } 847 }
828 } 848 }
829 849
830 ////////////////////////////////////////////////////////////////////////////////////////// 850 //////////////////////////////////////////////////////////////////////////////////////////
831 851
1029 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); 1049 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp");
1030 } 1050 }
1031 1051
1032 unsigned dataoffset = 2 + cd->vtblInterfaces->dim; 1052 unsigned dataoffset = 2 + cd->vtblInterfaces->dim;
1033 1053
1034 IRStruct* irstruct = cd->llvmIRStruct; 1054 IrStruct* irstruct = cd->llvmIrStruct;
1035 for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 1055 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
1036 //for (unsigned i=0; i<cd->fields.dim; ++i) { 1056 //for (unsigned i=0; i<cd->fields.dim; ++i) {
1037 //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; 1057 //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
1038 VarDeclaration* vd = i->second.var; 1058 VarDeclaration* vd = i->second.var;
1039 assert(vd); 1059 assert(vd);
1040 Type* vdtype = DtoDType(vd->type); 1060 Type* vdtype = DtoDType(vd->type);
1041 Logger::println("found %u type %s", vd->offset, vdtype->toChars()); 1061 Logger::println("found %u type %s", vd->offset, vdtype->toChars());
1042 assert(vd->llvmFieldIndex >= 0); 1062 assert(vd->irField->index >= 0);
1043 if (os == vd->offset && vdtype == t) { 1063 if (os == vd->offset && vdtype == t) {
1044 idxs.push_back(vd->llvmFieldIndex + dataoffset); 1064 idxs.push_back(vd->irField->index + dataoffset);
1045 Logger::cout() << "indexing: " << *ptr << '\n'; 1065 Logger::cout() << "indexing: " << *ptr << '\n';
1046 ptr = DtoGEP(ptr, idxs, "tmp"); 1066 ptr = DtoGEP(ptr, idxs, "tmp");
1047 if (ptr->getType() != llt) 1067 if (ptr->getType() != llt)
1048 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 1068 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1049 Logger::cout() << "indexing: " << *ptr << '\n'; 1069 Logger::cout() << "indexing: " << *ptr << '\n';
1050 if (vd->llvmFieldIndexOffset) 1070 if (vd->irField->indexOffset)
1051 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); 1071 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
1052 Logger::cout() << "indexing: " << *ptr << '\n'; 1072 Logger::cout() << "indexing: " << *ptr << '\n';
1053 return ptr; 1073 return ptr;
1054 } 1074 }
1055 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { 1075 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
1056 TypeStruct* ts = (TypeStruct*)vdtype; 1076 TypeStruct* ts = (TypeStruct*)vdtype;
1057 StructDeclaration* ssd = ts->sym; 1077 StructDeclaration* ssd = ts->sym;
1058 idxs.push_back(vd->llvmFieldIndex + dataoffset); 1078 idxs.push_back(vd->irField->index + dataoffset);
1059 if (vd->llvmFieldIndexOffset) { 1079 if (vd->irField->indexOffset) {
1060 Logger::println("has union field offset"); 1080 Logger::println("has union field offset");
1061 ptr = DtoGEP(ptr, idxs, "tmp"); 1081 ptr = DtoGEP(ptr, idxs, "tmp");
1062 if (ptr->getType() != llt) 1082 if (ptr->getType() != llt)
1063 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 1083 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1064 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); 1084 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
1065 std::vector<unsigned> tmp; 1085 std::vector<unsigned> tmp;
1066 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 1086 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
1067 } 1087 }
1068 else { 1088 else {
1069 const llvm::Type* sty = getPtrToType(DtoType(vd->type)); 1089 const llvm::Type* sty = getPtrToType(DtoType(vd->type));
1151 inits.push_back(DtoConstSize_t(offset)); 1171 inits.push_back(DtoConstSize_t(offset));
1152 1172
1153 vd->type->getTypeInfo(NULL); 1173 vd->type->getTypeInfo(NULL);
1154 assert(vd->type->vtinfo); 1174 assert(vd->type->vtinfo);
1155 DtoForceDeclareDsymbol(vd->type->vtinfo); 1175 DtoForceDeclareDsymbol(vd->type->vtinfo);
1156 llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue); 1176 llvm::Constant* c = isaConstant(vd->type->vtinfo->getIrValue());
1157 1177
1158 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get()); 1178 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get());
1159 //Logger::cout() << "tiTy = " << *tiTy << '\n'; 1179 //Logger::cout() << "tiTy = " << *tiTy << '\n';
1160 1180
1161 types.push_back(tiTy); 1181 types.push_back(tiTy);
1228 return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); 1248 return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty));
1229 } 1249 }
1230 else if (cd->dtors.dim == 1) { 1250 else if (cd->dtors.dim == 1) {
1231 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0]; 1251 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
1232 DtoForceDeclareDsymbol(d); 1252 DtoForceDeclareDsymbol(d);
1233 assert(d->llvmValue); 1253 assert(d->irFunc->func);
1234 return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), getPtrToType(llvm::Type::Int8Ty)); 1254 return llvm::ConstantExpr::getBitCast(isaConstant(d->irFunc->func), getPtrToType(llvm::Type::Int8Ty));
1235 } 1255 }
1236 1256
1237 std::string gname("_D"); 1257 std::string gname("_D");
1238 gname.append(cd->mangle()); 1258 gname.append(cd->mangle());
1239 gname.append("12__destructorMFZv"); 1259 gname.append("12__destructorMFZv");
1247 1267
1248 for (size_t i = 0; i < cd->dtors.dim; i++) 1268 for (size_t i = 0; i < cd->dtors.dim; i++)
1249 { 1269 {
1250 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i]; 1270 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
1251 DtoForceDeclareDsymbol(d); 1271 DtoForceDeclareDsymbol(d);
1252 assert(d->llvmValue); 1272 assert(d->irFunc->func);
1253 builder.CreateCall(d->llvmValue, thisptr); 1273 builder.CreateCall(d->irFunc->func, thisptr);
1254 } 1274 }
1255 builder.CreateRetVoid(); 1275 builder.CreateRetVoid();
1256 1276
1257 return llvm::ConstantExpr::getBitCast(func, getPtrToType(llvm::Type::Int8Ty)); 1277 return llvm::ConstantExpr::getBitCast(func, getPtrToType(llvm::Type::Int8Ty));
1258 } 1278 }
1378 c = DtoConstSlice(DtoConstSize_t(vtblsz), c); 1398 c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
1379 } 1399 }
1380 inits.push_back(c); 1400 inits.push_back(c);
1381 1401
1382 // interfaces array 1402 // interfaces array
1383 IRStruct* irstruct = cd->llvmIRStruct; 1403 IrStruct* irstruct = cd->llvmIrStruct;
1384 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { 1404 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) {
1385 c = cinfo->llvmConstInit->getOperand(5); 1405 c = cinfo->llvmConstInit->getOperand(5);
1386 } 1406 }
1387 else { 1407 else {
1388 const llvm::Type* t = cinfo->llvmConstInit->getOperand(5)->getType()->getContainedType(1); 1408 const llvm::Type* t = cinfo->llvmConstInit->getOperand(5)->getType()->getContainedType(1);
1444 inits.push_back(c); 1464 inits.push_back(c);
1445 1465
1446 // default constructor 1466 // default constructor
1447 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1467 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1448 DtoForceDeclareDsymbol(cd->defaultCtor); 1468 DtoForceDeclareDsymbol(cd->defaultCtor);
1449 c = isaConstant(cd->defaultCtor->llvmValue); 1469 c = isaConstant(cd->defaultCtor->irFunc->func);
1450 const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType(); 1470 const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType();
1451 c = llvm::ConstantExpr::getBitCast(c, toTy); 1471 c = llvm::ConstantExpr::getBitCast(c, toTy);
1452 } 1472 }
1453 else { 1473 else {
1454 c = cinfo->llvmConstInit->getOperand(12); 1474 c = cinfo->llvmConstInit->getOperand(12);