comparison gen/classes.cpp @ 156:ccd07d9f2ce9 trunk

[svn r172] moving all IR state previously stored in Dsymbol into IrDsymbol and a Dsymbol->IrDsymbol map
author ChristianK
date Thu, 01 May 2008 13:05:53 +0200
parents 7f92f477ff53
children 5c17f81fc1c1
comparison
equal deleted inserted replaced
155:7f92f477ff53 156:ccd07d9f2ce9
33 33
34 // resolve interfaces while we're at it 34 // resolve interfaces while we're at it
35 if (bc->base->isInterfaceDeclaration()) 35 if (bc->base->isInterfaceDeclaration())
36 { 36 {
37 // don't add twice 37 // don't add twice
38 if (target->irStruct->interfaceMap.find(bc->base) == target->irStruct->interfaceMap.end()) 38 if (gIR->irDsymbol[target].irStruct->interfaceMap.find(bc->base) == gIR->irDsymbol[target].irStruct->interfaceMap.end())
39 { 39 {
40 Logger::println("adding interface '%s'", bc->base->toPrettyChars()); 40 Logger::println("adding interface '%s'", bc->base->toPrettyChars());
41 IrInterface* iri = new IrInterface(bc, NULL); 41 IrInterface* iri = new IrInterface(bc, NULL);
42 42
43 // add to map 43 // add to map
44 target->irStruct->interfaceMap.insert(std::make_pair(bc->base, iri)); 44 gIR->irDsymbol[target].irStruct->interfaceMap.insert(std::make_pair(bc->base, iri));
45 // add to ordered list 45 // add to ordered list
46 target->irStruct->interfaceVec.push_back(iri); 46 gIR->irDsymbol[target].irStruct->interfaceVec.push_back(iri);
47 47
48 // Fill in vtbl[] 48 // Fill in vtbl[]
49 if (!target->isAbstract()) { 49 if (!target->isAbstract()) {
50 bc->fillVtbl(target, &bc->vtbl, 0); 50 bc->fillVtbl(target, &bc->vtbl, 0);
51 } 51 }
86 86
87 ////////////////////////////////////////////////////////////////////////////////////////// 87 //////////////////////////////////////////////////////////////////////////////////////////
88 88
89 void DtoResolveClass(ClassDeclaration* cd) 89 void DtoResolveClass(ClassDeclaration* cd)
90 { 90 {
91 if (cd->llvmResolved) return; 91 if (gIR->irDsymbol[cd].resolved) return;
92 cd->llvmResolved = true; 92 gIR->irDsymbol[cd].resolved = true;
93 93
94 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 94 Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
95 LOG_SCOPE; 95 LOG_SCOPE;
96 96
97 // get the TypeClass 97 // get the TypeClass
98 assert(cd->type->ty == Tclass); 98 assert(cd->type->ty == Tclass);
99 TypeClass* ts = (TypeClass*)cd->type; 99 TypeClass* ts = (TypeClass*)cd->type;
100 100
101 // make sure the IrStruct is created 101 // make sure the IrStruct is created
102 IrStruct* irstruct = cd->irStruct; 102 IrStruct* irstruct = gIR->irDsymbol[cd].irStruct;
103 if (!irstruct) { 103 if (!irstruct) {
104 irstruct = new IrStruct(ts); 104 irstruct = new IrStruct(ts);
105 cd->irStruct = irstruct; 105 gIR->irDsymbol[cd].irStruct = irstruct;
106 } 106 }
107 107
108 // resolve the base class 108 // resolve the base class
109 if (cd->baseClass) { 109 if (cd->baseClass) {
110 DtoResolveClass(cd->baseClass); 110 DtoResolveClass(cd->baseClass);
167 if (lastoffset == (unsigned)-1) { 167 if (lastoffset == (unsigned)-1) {
168 lastoffset = i->first; 168 lastoffset = i->first;
169 fieldtype = i->second.type; 169 fieldtype = i->second.type;
170 fieldinit = i->second.var; 170 fieldinit = i->second.var;
171 prevsize = getABITypeSize(fieldtype); 171 prevsize = getABITypeSize(fieldtype);
172 i->second.var->irField->index = idx; 172 gIR->irDsymbol[i->second.var].irField->index = idx;
173 } 173 }
174 // colliding offset? 174 // colliding offset?
175 else if (lastoffset == i->first) { 175 else if (lastoffset == i->first) {
176 size_t s = getABITypeSize(i->second.type); 176 size_t s = getABITypeSize(i->second.type);
177 if (s > prevsize) { 177 if (s > prevsize) {
178 fieldpad += s - prevsize; 178 fieldpad += s - prevsize;
179 prevsize = s; 179 prevsize = s;
180 } 180 }
181 cd->irStruct->hasUnions = true; 181 gIR->irDsymbol[cd].irStruct->hasUnions = true;
182 i->second.var->irField->index = idx; 182 gIR->irDsymbol[i->second.var].irField->index = idx;
183 } 183 }
184 // intersecting offset? 184 // intersecting offset?
185 else if (i->first < (lastoffset + prevsize)) { 185 else if (i->first < (lastoffset + prevsize)) {
186 size_t s = getABITypeSize(i->second.type); 186 size_t s = getABITypeSize(i->second.type);
187 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size 187 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
188 cd->irStruct->hasUnions = true; 188 gIR->irDsymbol[cd].irStruct->hasUnions = true;
189 i->second.var->irField->index = idx; 189 gIR->irDsymbol[i->second.var].irField->index = idx;
190 i->second.var->irField->indexOffset = (i->first - lastoffset) / s; 190 gIR->irDsymbol[i->second.var].irField->indexOffset = (i->first - lastoffset) / s;
191 } 191 }
192 // fresh offset 192 // fresh offset
193 else { 193 else {
194 // commit the field 194 // commit the field
195 fieldtypes.push_back(fieldtype); 195 fieldtypes.push_back(fieldtype);
205 // start new 205 // start new
206 lastoffset = i->first; 206 lastoffset = i->first;
207 fieldtype = i->second.type; 207 fieldtype = i->second.type;
208 fieldinit = i->second.var; 208 fieldinit = i->second.var;
209 prevsize = getABITypeSize(fieldtype); 209 prevsize = getABITypeSize(fieldtype);
210 i->second.var->irField->index = idx; 210 gIR->irDsymbol[i->second.var].irField->index = idx;
211 fieldpad = 0; 211 fieldpad = 0;
212 } 212 }
213 } 213 }
214 fieldtypes.push_back(fieldtype); 214 fieldtypes.push_back(fieldtype);
215 irstruct->defaultFields.push_back(fieldinit); 215 irstruct->defaultFields.push_back(fieldinit);
222 // populate interface map 222 // populate interface map
223 { 223 {
224 Logger::println("Adding interfaces to '%s'", cd->toPrettyChars()); 224 Logger::println("Adding interfaces to '%s'", cd->toPrettyChars());
225 LOG_SCOPE; 225 LOG_SCOPE;
226 LLVM_AddBaseClassInterfaces(cd, &cd->baseclasses); 226 LLVM_AddBaseClassInterfaces(cd, &cd->baseclasses);
227 Logger::println("%d interfaces added", cd->irStruct->interfaceVec.size()); 227 Logger::println("%d interfaces added", gIR->irDsymbol[cd].irStruct->interfaceVec.size());
228 assert(cd->irStruct->interfaceVec.size() == cd->irStruct->interfaceMap.size()); 228 assert(gIR->irDsymbol[cd].irStruct->interfaceVec.size() == gIR->irDsymbol[cd].irStruct->interfaceMap.size());
229 } 229 }
230 230
231 // add interface vtables at the end 231 // add interface vtables at the end
232 int interIdx = (int)fieldtypes.size(); 232 int interIdx = (int)fieldtypes.size();
233 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) 233 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
244 iri->vtblTy = isaStruct(itc->llvmVtblType->get()); 244 iri->vtblTy = isaStruct(itc->llvmVtblType->get());
245 245
246 // set index 246 // set index
247 iri->index = interIdx++; 247 iri->index = interIdx++;
248 } 248 }
249 Logger::println("%d interface vtables added", cd->irStruct->interfaceVec.size()); 249 Logger::println("%d interface vtables added", gIR->irDsymbol[cd].irStruct->interfaceVec.size());
250 assert(cd->irStruct->interfaceVec.size() == cd->irStruct->interfaceMap.size()); 250 assert(gIR->irDsymbol[cd].irStruct->interfaceVec.size() == gIR->irDsymbol[cd].irStruct->interfaceMap.size());
251 251
252 // create type 252 // create type
253 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes); 253 const llvm::StructType* structtype = llvm::StructType::get(fieldtypes);
254 254
255 // refine abstract types for stuff like: class C {C next;} 255 // refine abstract types for stuff like: class C {C next;}
328 328
329 ////////////////////////////////////////////////////////////////////////////////////////// 329 //////////////////////////////////////////////////////////////////////////////////////////
330 330
331 void DtoDeclareClass(ClassDeclaration* cd) 331 void DtoDeclareClass(ClassDeclaration* cd)
332 { 332 {
333 if (cd->llvmDeclared) return; 333 if (gIR->irDsymbol[cd].declared) return;
334 cd->llvmDeclared = true; 334 gIR->irDsymbol[cd].declared = true;
335 335
336 Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 336 Logger::println("DtoDeclareClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
337 LOG_SCOPE; 337 LOG_SCOPE;
338 338
339 assert(cd->type->ty == Tclass); 339 assert(cd->type->ty == Tclass);
340 TypeClass* ts = (TypeClass*)cd->type; 340 TypeClass* ts = (TypeClass*)cd->type;
341 341
342 assert(cd->irStruct); 342 assert(gIR->irDsymbol[cd].irStruct);
343 IrStruct* irstruct = cd->irStruct; 343 IrStruct* irstruct = gIR->irDsymbol[cd].irStruct;
344 344
345 gIR->structs.push_back(irstruct); 345 gIR->structs.push_back(irstruct);
346 gIR->classes.push_back(cd); 346 gIR->classes.push_back(cd);
347 347
348 bool needs_definition = false; 348 bool needs_definition = false;
359 std::string varname("_D"); 359 std::string varname("_D");
360 varname.append(cd->mangle()); 360 varname.append(cd->mangle());
361 varname.append("6__vtblZ"); 361 varname.append("6__vtblZ");
362 362
363 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get()); 363 const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
364 cd->irStruct->vtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module); 364 gIR->irDsymbol[cd].irStruct->vtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
365 } 365 }
366 366
367 // get interface info type 367 // get interface info type
368 const llvm::StructType* infoTy = DtoInterfaceInfoType(); 368 const llvm::StructType* infoTy = DtoInterfaceInfoType();
369 369
370 // interface info array 370 // interface info array
371 if (!cd->irStruct->interfaceVec.empty()) { 371 if (!gIR->irDsymbol[cd].irStruct->interfaceVec.empty()) {
372 // symbol name 372 // symbol name
373 std::string nam = "_D"; 373 std::string nam = "_D";
374 nam.append(cd->mangle()); 374 nam.append(cd->mangle());
375 nam.append("16__interfaceInfosZ"); 375 nam.append("16__interfaceInfosZ");
376 // resolve array type 376 // resolve array type
377 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->irStruct->interfaceVec.size()); 377 const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, gIR->irDsymbol[cd].irStruct->interfaceVec.size());
378 // declare global 378 // declare global
379 irstruct->interfaceInfosTy = arrTy; 379 irstruct->interfaceInfosTy = arrTy;
380 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module); 380 irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
381 } 381 }
382 382
407 std::string initname("_D"); 407 std::string initname("_D");
408 initname.append(cd->mangle()); 408 initname.append(cd->mangle());
409 initname.append("6__initZ"); 409 initname.append("6__initZ");
410 410
411 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module); 411 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType->get(), true, _linkage, NULL, initname, gIR->module);
412 cd->irStruct->init = initvar; 412 gIR->irDsymbol[cd].irStruct->init = initvar;
413 } 413 }
414 414
415 gIR->classes.pop_back(); 415 gIR->classes.pop_back();
416 gIR->structs.pop_back(); 416 gIR->structs.pop_back();
417 417
429 429
430 ////////////////////////////////////////////////////////////////////////////////////////// 430 //////////////////////////////////////////////////////////////////////////////////////////
431 431
432 void DtoConstInitClass(ClassDeclaration* cd) 432 void DtoConstInitClass(ClassDeclaration* cd)
433 { 433 {
434 if (cd->llvmInitialized) return; 434 if (gIR->irDsymbol[cd].initialized) return;
435 cd->llvmInitialized = true; 435 gIR->irDsymbol[cd].initialized = true;
436 436
437 if (cd->isInterfaceDeclaration()) 437 if (cd->isInterfaceDeclaration())
438 return; // nothing to do 438 return; // nothing to do
439 439
440 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 440 Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
441 LOG_SCOPE; 441 LOG_SCOPE;
442 442
443 IrStruct* irstruct = cd->irStruct; 443 IrStruct* irstruct = gIR->irDsymbol[cd].irStruct;
444 gIR->structs.push_back(irstruct); 444 gIR->structs.push_back(irstruct);
445 gIR->classes.push_back(cd); 445 gIR->classes.push_back(cd);
446 446
447 // get the struct (class) type 447 // get the struct (class) type
448 assert(cd->type->ty == Tclass); 448 assert(cd->type->ty == Tclass);
454 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) 454 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
455 { 455 {
456 IrStruct::Offset* so = &i->second; 456 IrStruct::Offset* so = &i->second;
457 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init); 457 llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
458 so->init = finit; 458 so->init = finit;
459 so->var->irField->constInit = finit; 459 gIR->irDsymbol[so->var].irField->constInit = finit;
460 } 460 }
461 461
462 // fill out fieldtypes/inits 462 // fill out fieldtypes/inits
463 std::vector<llvm::Constant*> fieldinits; 463 std::vector<llvm::Constant*> fieldinits;
464 464
473 ) 473 )
474 ); 474 );
475 } 475 }
476 else 476 else
477 { 477 {
478 assert(cd->irStruct->vtbl != 0); 478 assert(gIR->irDsymbol[cd].irStruct->vtbl != 0);
479 fieldinits.push_back(cd->irStruct->vtbl); 479 fieldinits.push_back(gIR->irDsymbol[cd].irStruct->vtbl);
480 } 480 }
481 481
482 // then comes monitor 482 // then comes monitor
483 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty))); 483 fieldinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)));
484 484
485 // go through the field inits and build the default initializer 485 // go through the field inits and build the default initializer
486 size_t nfi = irstruct->defaultFields.size(); 486 size_t nfi = irstruct->defaultFields.size();
487 for (size_t i=0; i<nfi; ++i) { 487 for (size_t i=0; i<nfi; ++i) {
488 llvm::Constant* c; 488 llvm::Constant* c;
489 if (irstruct->defaultFields[i]) { 489 if (irstruct->defaultFields[i]) {
490 c = irstruct->defaultFields[i]->irField->constInit; 490 c = gIR->irDsymbol[irstruct->defaultFields[i]].irField->constInit;
491 assert(c); 491 assert(c);
492 } 492 }
493 else { 493 else {
494 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2)); 494 const llvm::ArrayType* arrty = isaArray(structtype->getElementType(i+2));
495 assert(arrty); 495 assert(arrty);
534 } 534 }
535 #endif 535 #endif
536 536
537 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits); 537 llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
538 assert(_init); 538 assert(_init);
539 cd->irStruct->constInit = _init; 539 gIR->irDsymbol[cd].irStruct->constInit = _init;
540 540
541 // abstract classes have no static vtable 541 // abstract classes have no static vtable
542 // neither do interfaces (on their own, the implementing class supplies the vtable) 542 // neither do interfaces (on their own, the implementing class supplies the vtable)
543 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) 543 if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
544 { 544 {
551 assert(dsym); 551 assert(dsym);
552 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n'; 552 //Logger::cout() << "vtblsym: " << dsym->toChars() << '\n';
553 553
554 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) { 554 if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
555 DtoForceDeclareDsymbol(fd); 555 DtoForceDeclareDsymbol(fd);
556 assert(gIR->irFunc[fd]->func); 556 assert(gIR->irDsymbol[fd].irFunc->func);
557 llvm::Constant* c = llvm::cast<llvm::Constant>(gIR->irFunc[fd]->func); 557 llvm::Constant* c = llvm::cast<llvm::Constant>(gIR->irDsymbol[fd].irFunc->func);
558 // cast if necessary (overridden method) 558 // cast if necessary (overridden method)
559 if (c->getType() != vtbltype->getElementType(k)) 559 if (c->getType() != vtbltype->getElementType(k))
560 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k)); 560 c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k));
561 sinits.push_back(c); 561 sinits.push_back(c);
562 } 562 }
563 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) { 563 else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
564 assert(cd->irStruct->classInfo); 564 assert(gIR->irDsymbol[cd].irStruct->classInfo);
565 llvm::Constant* c = cd->irStruct->classInfo; 565 llvm::Constant* c = gIR->irDsymbol[cd].irStruct->classInfo;
566 sinits.push_back(c); 566 sinits.push_back(c);
567 } 567 }
568 else 568 else
569 assert(0); 569 assert(0);
570 } 570 }
579 assert(svtbl_ty->getElementType(i) == sinits[i]->getType()); 579 assert(svtbl_ty->getElementType(i) == sinits[i]->getType());
580 } 580 }
581 #endif 581 #endif
582 582
583 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits); 583 llvm::Constant* cvtblInit = llvm::ConstantStruct::get(svtbl_ty, sinits);
584 cd->irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit); 584 gIR->irDsymbol[cd].irStruct->constVtbl = llvm::cast<llvm::ConstantStruct>(cvtblInit);
585 585
586 // create interface vtable const initalizers 586 // create interface vtable const initalizers
587 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) 587 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
588 { 588 {
589 IrInterface* iri = *i; 589 IrInterface* iri = *i;
597 597
598 // generate interface info initializer 598 // generate interface info initializer
599 std::vector<llvm::Constant*> infoInits; 599 std::vector<llvm::Constant*> infoInits;
600 600
601 // classinfo 601 // classinfo
602 assert(id->irStruct->classInfo); 602 assert(gIR->irDsymbol[id].irStruct->classInfo);
603 llvm::Constant* c = id->irStruct->classInfo; 603 llvm::Constant* c = gIR->irDsymbol[id].irStruct->classInfo;
604 infoInits.push_back(c); 604 infoInits.push_back(c);
605 605
606 // vtbl 606 // vtbl
607 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); 607 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
608 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty); 608 c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
634 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k]; 634 Dsymbol* dsym = (Dsymbol*)b->vtbl.data[k];
635 assert(dsym); 635 assert(dsym);
636 FuncDeclaration* fd = dsym->isFuncDeclaration(); 636 FuncDeclaration* fd = dsym->isFuncDeclaration();
637 assert(fd); 637 assert(fd);
638 DtoForceDeclareDsymbol(fd); 638 DtoForceDeclareDsymbol(fd);
639 assert(gIR->irFunc[fd]->func); 639 assert(gIR->irDsymbol[fd].irFunc->func);
640 llvm::Constant* c = llvm::cast<llvm::Constant>(gIR->irFunc[fd]->func); 640 llvm::Constant* c = llvm::cast<llvm::Constant>(gIR->irDsymbol[fd].irFunc->func);
641 641
642 // we have to bitcast, as the type created in ResolveClass expects a different this type 642 // we have to bitcast, as the type created in ResolveClass expects a different this type
643 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k)); 643 c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k));
644 iinits.push_back(c); 644 iinits.push_back(c);
645 } 645 }
671 671
672 // generate interface info initializer 672 // generate interface info initializer
673 std::vector<llvm::Constant*> infoInits; 673 std::vector<llvm::Constant*> infoInits;
674 674
675 // classinfo 675 // classinfo
676 assert(id->irStruct->classInfo); 676 assert(gIR->irDsymbol[id].irStruct->classInfo);
677 llvm::Constant* c = id->irStruct->classInfo; 677 llvm::Constant* c = gIR->irDsymbol[id].irStruct->classInfo;
678 infoInits.push_back(c); 678 infoInits.push_back(c);
679 679
680 // vtbl 680 // vtbl
681 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty)); 681 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
682 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty)); 682 c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
696 696
697 ////////////////////////////////////////////////////////////////////////////////////////// 697 //////////////////////////////////////////////////////////////////////////////////////////
698 698
699 void DtoDefineClass(ClassDeclaration* cd) 699 void DtoDefineClass(ClassDeclaration* cd)
700 { 700 {
701 if (cd->llvmDefined) return; 701 if (gIR->irDsymbol[cd].defined) return;
702 cd->llvmDefined = true; 702 gIR->irDsymbol[cd].defined = true;
703 703
704 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars()); 704 Logger::println("DtoDefineClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
705 LOG_SCOPE; 705 LOG_SCOPE;
706 706
707 // get the struct (class) type 707 // get the struct (class) type
711 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) { 711 if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) {
712 // interfaces don't have initializers 712 // interfaces don't have initializers
713 // neither do abstract classes 713 // neither do abstract classes
714 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) 714 if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
715 { 715 {
716 cd->irStruct->init->setInitializer(cd->irStruct->constInit); 716 gIR->irDsymbol[cd].irStruct->init->setInitializer(gIR->irDsymbol[cd].irStruct->constInit);
717 cd->irStruct->vtbl->setInitializer(cd->irStruct->constVtbl); 717 gIR->irDsymbol[cd].irStruct->vtbl->setInitializer(gIR->irDsymbol[cd].irStruct->constVtbl);
718 718
719 // initialize interface vtables 719 // initialize interface vtables
720 IrStruct* irstruct = cd->irStruct; 720 IrStruct* irstruct = gIR->irDsymbol[cd].irStruct;
721 std::vector<llvm::Constant*> infoInits; 721 std::vector<llvm::Constant*> infoInits;
722 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) 722 for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
723 { 723 {
724 IrInterface* iri = *i; 724 IrInterface* iri = *i;
725 iri->vtbl->setInitializer(iri->vtblInit); 725 iri->vtbl->setInitializer(iri->vtblInit);
753 } 753 }
754 else 754 else
755 { 755 {
756 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass"); 756 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_newclass");
757 std::vector<llvm::Value*> args; 757 std::vector<llvm::Value*> args;
758 args.push_back(tc->sym->irStruct->classInfo); 758 args.push_back(gIR->irDsymbol[tc->sym].irStruct->classInfo);
759 mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc"); 759 mem = gIR->ir->CreateCall(fn, args.begin(), args.end(), "newclass_gc_alloc");
760 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc"); 760 mem = DtoBitCast(mem, DtoType(tc), "newclass_gc");
761 } 761 }
762 762
763 // init 763 // init
768 { 768 {
769 Logger::println("Resolving outer class"); 769 Logger::println("Resolving outer class");
770 LOG_SCOPE; 770 LOG_SCOPE;
771 DValue* thisval = newexp->thisexp->toElem(gIR); 771 DValue* thisval = newexp->thisexp->toElem(gIR);
772 size_t idx = 2; 772 size_t idx = 2;
773 //idx += tc->sym->irStruct->interfaces.size(); 773 //idx += gIR->irDsymbol[tc->sym].irStruct->interfaces.size();
774 llvm::Value* dst = thisval->getRVal(); 774 llvm::Value* dst = thisval->getRVal();
775 llvm::Value* src = DtoGEPi(mem,0,idx,"tmp"); 775 llvm::Value* src = DtoGEPi(mem,0,idx,"tmp");
776 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n'; 776 Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
777 DtoStore(dst, src); 777 DtoStore(dst, src);
778 } 778 }
780 else if (tc->sym->isNested()) 780 else if (tc->sym->isNested())
781 { 781 {
782 Logger::println("Resolving nested context"); 782 Logger::println("Resolving nested context");
783 LOG_SCOPE; 783 LOG_SCOPE;
784 size_t idx = 2; 784 size_t idx = 2;
785 //idx += tc->sym->irStruct->interfaces.size(); 785 //idx += gIR->irDsymbol[tc->sym].irStruct->interfaces.size();
786 llvm::Value* nest = gIR->irFunc[gIR->func()->decl]->nestedVar; 786 llvm::Value* nest = gIR->irDsymbol[gIR->func()->decl].irFunc->nestedVar;
787 if (!nest) 787 if (!nest)
788 nest = gIR->irFunc[gIR->func()->decl]->thisVar; 788 nest = gIR->irDsymbol[gIR->func()->decl].irFunc->thisVar;
789 assert(nest); 789 assert(nest);
790 llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp"); 790 llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp");
791 nest = DtoBitCast(nest, gep->getType()->getContainedType(0)); 791 nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
792 DtoStore(nest, gep); 792 DtoStore(nest, gep);
793 } 793 }
806 { 806 {
807 size_t presz = 2*getABITypeSize(DtoSize_t()); 807 size_t presz = 2*getABITypeSize(DtoSize_t());
808 uint64_t n = getABITypeSize(tc->llvmType->get()) - presz; 808 uint64_t n = getABITypeSize(tc->llvmType->get()) - presz;
809 809
810 // set vtable field seperately, this might give better optimization 810 // set vtable field seperately, this might give better optimization
811 assert(tc->sym->irStruct->vtbl); 811 assert(gIR->irDsymbol[tc->sym].irStruct->vtbl);
812 DtoStore(tc->sym->irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl")); 812 DtoStore(gIR->irDsymbol[tc->sym].irStruct->vtbl, DtoGEPi(dst,0,0,"vtbl"));
813 813
814 // monitor always defaults to zero 814 // monitor always defaults to zero
815 llvm::Value* tmp = DtoGEPi(dst,0,1,"monitor"); 815 llvm::Value* tmp = DtoGEPi(dst,0,1,"monitor");
816 DtoStore(llvm::Constant::getNullValue(tmp->getType()->getContainedType(0)), tmp); 816 DtoStore(llvm::Constant::getNullValue(tmp->getType()->getContainedType(0)), tmp);
817 817
818 // done? 818 // done?
819 if (n == 0) 819 if (n == 0)
820 return; 820 return;
821 821
822 // copy the rest from the static initializer 822 // copy the rest from the static initializer
823 assert(tc->sym->irStruct->init); 823 assert(gIR->irDsymbol[tc->sym].irStruct->init);
824 assert(dst->getType() == tc->sym->irStruct->init->getType()); 824 assert(dst->getType() == gIR->irDsymbol[tc->sym].irStruct->init->getType());
825 825
826 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty); 826 const llvm::Type* arrty = getPtrToType(llvm::Type::Int8Ty);
827 827
828 llvm::Value* dstarr = DtoGEPi(dst,0,2,"tmp"); 828 llvm::Value* dstarr = DtoGEPi(dst,0,2,"tmp");
829 dstarr = DtoBitCast(dstarr, arrty); 829 dstarr = DtoBitCast(dstarr, arrty);
830 830
831 llvm::Value* srcarr = DtoGEPi(tc->sym->irStruct->init,0,2,"tmp"); 831 llvm::Value* srcarr = DtoGEPi(gIR->irDsymbol[tc->sym].irStruct->init,0,2,"tmp");
832 srcarr = DtoBitCast(srcarr, arrty); 832 srcarr = DtoBitCast(srcarr, arrty);
833 833
834 llvm::Function* fn = LLVM_DeclareMemCpy32(); 834 llvm::Function* fn = LLVM_DeclareMemCpy32();
835 std::vector<llvm::Value*> llargs; 835 std::vector<llvm::Value*> llargs;
836 llargs.resize(4); 836 llargs.resize(4);
849 Logger::println("Calling constructor"); 849 Logger::println("Calling constructor");
850 LOG_SCOPE; 850 LOG_SCOPE;
851 851
852 assert(ctor); 852 assert(ctor);
853 DtoForceDeclareDsymbol(ctor); 853 DtoForceDeclareDsymbol(ctor);
854 llvm::Function* fn = gIR->irFunc[ctor]->func; 854 llvm::Function* fn = gIR->irDsymbol[ctor].irFunc->func;
855 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type); 855 TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type);
856 856
857 std::vector<llvm::Value*> ctorargs; 857 std::vector<llvm::Value*> ctorargs;
858 ctorargs.push_back(mem); 858 ctorargs.push_back(mem);
859 for (size_t i=0; i<arguments->dim; ++i) 859 for (size_t i=0; i<arguments->dim; ++i)
879 { 879 {
880 Array* arr = &tc->sym->dtors; 880 Array* arr = &tc->sym->dtors;
881 for (size_t i=0; i<arr->dim; i++) 881 for (size_t i=0; i<arr->dim; i++)
882 { 882 {
883 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; 883 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
884 assert(gIR->irFunc[fd]->func); 884 assert(gIR->irDsymbol[fd].irFunc->func);
885 new llvm::CallInst(gIR->irFunc[fd]->func, instance, "", gIR->scopebb()); 885 new llvm::CallInst(gIR->irDsymbol[fd].irFunc->func, instance, "", gIR->scopebb());
886 } 886 }
887 } 887 }
888 888
889 ////////////////////////////////////////////////////////////////////////////////////////// 889 //////////////////////////////////////////////////////////////////////////////////////////
890 890
959 assert(funcTy->getParamType(0) == tmp->getType()); 959 assert(funcTy->getParamType(0) == tmp->getType());
960 960
961 // ClassInfo c 961 // ClassInfo c
962 TypeClass* to = (TypeClass*)DtoDType(_to); 962 TypeClass* to = (TypeClass*)DtoDType(_to);
963 DtoForceDeclareDsymbol(to->sym); 963 DtoForceDeclareDsymbol(to->sym);
964 assert(to->sym->irStruct->classInfo); 964 assert(gIR->irDsymbol[to->sym].irStruct->classInfo);
965 tmp = to->sym->irStruct->classInfo; 965 tmp = gIR->irDsymbol[to->sym].irStruct->classInfo;
966 // unfortunately this is needed as the implementation of object differs somehow from the declaration 966 // unfortunately this is needed as the implementation of object differs somehow from the declaration
967 // this could happen in user code as well :/ 967 // this could happen in user code as well :/
968 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); 968 tmp = DtoBitCast(tmp, funcTy->getParamType(1));
969 args.push_back(tmp); 969 args.push_back(tmp);
970 assert(funcTy->getParamType(1) == tmp->getType()); 970 assert(funcTy->getParamType(1) == tmp->getType());
1025 args.push_back(tmp); 1025 args.push_back(tmp);
1026 1026
1027 // ClassInfo c 1027 // ClassInfo c
1028 TypeClass* to = (TypeClass*)DtoDType(_to); 1028 TypeClass* to = (TypeClass*)DtoDType(_to);
1029 DtoForceDeclareDsymbol(to->sym); 1029 DtoForceDeclareDsymbol(to->sym);
1030 assert(to->sym->irStruct->classInfo); 1030 assert(gIR->irDsymbol[to->sym].irStruct->classInfo);
1031 tmp = to->sym->irStruct->classInfo; 1031 tmp = gIR->irDsymbol[to->sym].irStruct->classInfo;
1032 // unfortunately this is needed as the implementation of object differs somehow from the declaration 1032 // unfortunately this is needed as the implementation of object differs somehow from the declaration
1033 // this could happen in user code as well :/ 1033 // this could happen in user code as well :/
1034 tmp = DtoBitCast(tmp, funcTy->getParamType(1)); 1034 tmp = DtoBitCast(tmp, funcTy->getParamType(1));
1035 args.push_back(tmp); 1035 args.push_back(tmp);
1036 1036
1092 idxs.push_back(0); 1092 idxs.push_back(0);
1093 1093
1094 const llvm::Type* llt = getPtrToType(DtoType(t)); 1094 const llvm::Type* llt = getPtrToType(DtoType(t));
1095 const llvm::Type* st = DtoType(cd->type); 1095 const llvm::Type* st = DtoType(cd->type);
1096 if (ptr->getType() != st) { 1096 if (ptr->getType() != st) {
1097 assert(cd->irStruct->hasUnions); 1097 assert(gIR->irDsymbol[cd].irStruct->hasUnions);
1098 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp"); 1098 ptr = gIR->ir->CreateBitCast(ptr, st, "tmp");
1099 } 1099 }
1100 1100
1101 unsigned dataoffset = 2; 1101 unsigned dataoffset = 2;
1102 1102
1103 IrStruct* irstruct = cd->irStruct; 1103 IrStruct* irstruct = gIR->irDsymbol[cd].irStruct;
1104 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) { 1104 for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
1105 //for (unsigned i=0; i<cd->fields.dim; ++i) { 1105 //for (unsigned i=0; i<cd->fields.dim; ++i) {
1106 //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; 1106 //VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
1107 VarDeclaration* vd = i->second.var; 1107 VarDeclaration* vd = i->second.var;
1108 assert(vd); 1108 assert(vd);
1109 Type* vdtype = DtoDType(vd->type); 1109 Type* vdtype = DtoDType(vd->type);
1110 Logger::println("found %u type %s", vd->offset, vdtype->toChars()); 1110 Logger::println("found %u type %s", vd->offset, vdtype->toChars());
1111 assert(vd->irField->index >= 0); 1111 assert(gIR->irDsymbol[vd].irField->index >= 0);
1112 if (os == vd->offset && vdtype == t) { 1112 if (os == vd->offset && vdtype == t) {
1113 idxs.push_back(vd->irField->index + dataoffset); 1113 idxs.push_back(gIR->irDsymbol[vd].irField->index + dataoffset);
1114 Logger::cout() << "indexing: " << *ptr << '\n'; 1114 Logger::cout() << "indexing: " << *ptr << '\n';
1115 ptr = DtoGEP(ptr, idxs, "tmp"); 1115 ptr = DtoGEP(ptr, idxs, "tmp");
1116 if (ptr->getType() != llt) 1116 if (ptr->getType() != llt)
1117 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 1117 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1118 Logger::cout() << "indexing: " << *ptr << '\n'; 1118 Logger::cout() << "indexing: " << *ptr << '\n';
1119 if (vd->irField->indexOffset) 1119 if (gIR->irDsymbol[vd].irField->indexOffset)
1120 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); 1120 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(gIR->irDsymbol[vd].irField->indexOffset), "tmp", gIR->scopebb());
1121 Logger::cout() << "indexing: " << *ptr << '\n'; 1121 Logger::cout() << "indexing: " << *ptr << '\n';
1122 return ptr; 1122 return ptr;
1123 } 1123 }
1124 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { 1124 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
1125 TypeStruct* ts = (TypeStruct*)vdtype; 1125 TypeStruct* ts = (TypeStruct*)vdtype;
1126 StructDeclaration* ssd = ts->sym; 1126 StructDeclaration* ssd = ts->sym;
1127 idxs.push_back(vd->irField->index + dataoffset); 1127 idxs.push_back(gIR->irDsymbol[vd].irField->index + dataoffset);
1128 if (vd->irField->indexOffset) { 1128 if (gIR->irDsymbol[vd].irField->indexOffset) {
1129 Logger::println("has union field offset"); 1129 Logger::println("has union field offset");
1130 ptr = DtoGEP(ptr, idxs, "tmp"); 1130 ptr = DtoGEP(ptr, idxs, "tmp");
1131 if (ptr->getType() != llt) 1131 if (ptr->getType() != llt)
1132 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); 1132 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
1133 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb()); 1133 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(gIR->irDsymbol[vd].irField->indexOffset), "tmp", gIR->scopebb());
1134 std::vector<unsigned> tmp; 1134 std::vector<unsigned> tmp;
1135 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); 1135 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
1136 } 1136 }
1137 else { 1137 else {
1138 const llvm::Type* sty = getPtrToType(DtoType(vd->type)); 1138 const llvm::Type* sty = getPtrToType(DtoType(vd->type));
1181 1181
1182 ////////////////////////////////////////////////////////////////////////////////////////// 1182 //////////////////////////////////////////////////////////////////////////////////////////
1183 1183
1184 void DtoDeclareClassInfo(ClassDeclaration* cd) 1184 void DtoDeclareClassInfo(ClassDeclaration* cd)
1185 { 1185 {
1186 if (cd->irStruct->classDeclared) return; 1186 if (gIR->irDsymbol[cd].irStruct->classDeclared) return;
1187 cd->irStruct->classDeclared = true; 1187 gIR->irDsymbol[cd].irStruct->classDeclared = true;
1188 1188
1189 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars()); 1189 Logger::println("DtoDeclareClassInfo(%s)", cd->toChars());
1190 LOG_SCOPE; 1190 LOG_SCOPE;
1191 1191
1192 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 1192 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
1199 else 1199 else
1200 gname.append("11__InterfaceZ"); 1200 gname.append("11__InterfaceZ");
1201 1201
1202 const llvm::Type* st = cinfo->type->llvmType->get(); 1202 const llvm::Type* st = cinfo->type->llvmType->get();
1203 1203
1204 cd->irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module); 1204 gIR->irDsymbol[cd].irStruct->classInfo = new llvm::GlobalVariable(st, true, DtoLinkage(cd), NULL, gname, gIR->module);
1205 } 1205 }
1206 1206
1207 static llvm::Constant* build_offti_entry(VarDeclaration* vd) 1207 static llvm::Constant* build_offti_entry(VarDeclaration* vd)
1208 { 1208 {
1209 std::vector<const llvm::Type*> types; 1209 std::vector<const llvm::Type*> types;
1220 inits.push_back(DtoConstSize_t(offset)); 1220 inits.push_back(DtoConstSize_t(offset));
1221 1221
1222 vd->type->getTypeInfo(NULL); 1222 vd->type->getTypeInfo(NULL);
1223 assert(vd->type->vtinfo); 1223 assert(vd->type->vtinfo);
1224 DtoForceDeclareDsymbol(vd->type->vtinfo); 1224 DtoForceDeclareDsymbol(vd->type->vtinfo);
1225 llvm::Constant* c = isaConstant(vd->type->vtinfo->getIrValue()); 1225 llvm::Constant* c = isaConstant(gIR->irDsymbol[vd->type->vtinfo].getIrValue());
1226 1226
1227 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get()); 1227 const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get());
1228 //Logger::cout() << "tiTy = " << *tiTy << '\n'; 1228 //Logger::cout() << "tiTy = " << *tiTy << '\n';
1229 1229
1230 types.push_back(tiTy); 1230 types.push_back(tiTy);
1298 return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); 1298 return llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty));
1299 } 1299 }
1300 else if (cd->dtors.dim == 1) { 1300 else if (cd->dtors.dim == 1) {
1301 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0]; 1301 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
1302 DtoForceDeclareDsymbol(d); 1302 DtoForceDeclareDsymbol(d);
1303 assert(gIR->irFunc[d]->func); 1303 assert(gIR->irDsymbol[d].irFunc->func);
1304 return llvm::ConstantExpr::getBitCast(isaConstant(gIR->irFunc[d]->func), getPtrToType(llvm::Type::Int8Ty)); 1304 return llvm::ConstantExpr::getBitCast(isaConstant(gIR->irDsymbol[d].irFunc->func), getPtrToType(llvm::Type::Int8Ty));
1305 } 1305 }
1306 1306
1307 std::string gname("_D"); 1307 std::string gname("_D");
1308 gname.append(cd->mangle()); 1308 gname.append(cd->mangle());
1309 gname.append("12__destructorMFZv"); 1309 gname.append("12__destructorMFZv");
1317 1317
1318 for (size_t i = 0; i < cd->dtors.dim; i++) 1318 for (size_t i = 0; i < cd->dtors.dim; i++)
1319 { 1319 {
1320 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i]; 1320 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
1321 DtoForceDeclareDsymbol(d); 1321 DtoForceDeclareDsymbol(d);
1322 assert(gIR->irFunc[d]->func); 1322 assert(gIR->irDsymbol[d].irFunc->func);
1323 builder.CreateCall(gIR->irFunc[d]->func, thisptr); 1323 builder.CreateCall(gIR->irDsymbol[d].irFunc->func, thisptr);
1324 } 1324 }
1325 builder.CreateRetVoid(); 1325 builder.CreateRetVoid();
1326 1326
1327 return llvm::ConstantExpr::getBitCast(func, getPtrToType(llvm::Type::Int8Ty)); 1327 return llvm::ConstantExpr::getBitCast(func, getPtrToType(llvm::Type::Int8Ty));
1328 } 1328 }
1373 // void *deallocator; 1373 // void *deallocator;
1374 // OffsetTypeInfo[] offTi; 1374 // OffsetTypeInfo[] offTi;
1375 // void *defaultConstructor; 1375 // void *defaultConstructor;
1376 // } 1376 // }
1377 1377
1378 if (cd->irStruct->classDefined) return; 1378 if (gIR->irDsymbol[cd].irStruct->classDefined) return;
1379 cd->irStruct->classDefined = true; 1379 gIR->irDsymbol[cd].irStruct->classDefined = true;
1380 1380
1381 Logger::println("DtoDefineClassInfo(%s)", cd->toChars()); 1381 Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
1382 LOG_SCOPE; 1382 LOG_SCOPE;
1383 1383
1384 assert(cd->type->ty == Tclass); 1384 assert(cd->type->ty == Tclass);
1385 assert(cd->irStruct->classInfo); 1385 assert(gIR->irDsymbol[cd].irStruct->classInfo);
1386 1386
1387 TypeClass* cdty = (TypeClass*)cd->type; 1387 TypeClass* cdty = (TypeClass*)cd->type;
1388 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1388 if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1389 assert(cd->irStruct->init); 1389 assert(gIR->irDsymbol[cd].irStruct->init);
1390 assert(cd->irStruct->constInit); 1390 assert(gIR->irDsymbol[cd].irStruct->constInit);
1391 assert(cd->irStruct->vtbl); 1391 assert(gIR->irDsymbol[cd].irStruct->vtbl);
1392 assert(cd->irStruct->constVtbl); 1392 assert(gIR->irDsymbol[cd].irStruct->constVtbl);
1393 } 1393 }
1394 1394
1395 // holds the list of initializers for llvm 1395 // holds the list of initializers for llvm
1396 std::vector<llvm::Constant*> inits; 1396 std::vector<llvm::Constant*> inits;
1397 1397
1398 ClassDeclaration* cinfo = ClassDeclaration::classinfo; 1398 ClassDeclaration* cinfo = ClassDeclaration::classinfo;
1399 DtoForceConstInitDsymbol(cinfo); 1399 DtoForceConstInitDsymbol(cinfo);
1400 assert(cinfo->irStruct->constInit); 1400 assert(gIR->irDsymbol[cinfo].irStruct->constInit);
1401 1401
1402 llvm::Constant* c; 1402 llvm::Constant* c;
1403 1403
1404 // own vtable 1404 // own vtable
1405 c = cinfo->irStruct->constInit->getOperand(0); 1405 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(0);
1406 assert(c); 1406 assert(c);
1407 inits.push_back(c); 1407 inits.push_back(c);
1408 1408
1409 // monitor 1409 // monitor
1410 c = cinfo->irStruct->constInit->getOperand(1); 1410 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(1);
1411 inits.push_back(c); 1411 inits.push_back(c);
1412 1412
1413 // byte[] init 1413 // byte[] init
1414 const llvm::Type* byteptrty = getPtrToType(llvm::Type::Int8Ty); 1414 const llvm::Type* byteptrty = getPtrToType(llvm::Type::Int8Ty);
1415 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1415 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1416 c = cinfo->irStruct->constInit->getOperand(2); 1416 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(2);
1417 } 1417 }
1418 else { 1418 else {
1419 c = llvm::ConstantExpr::getBitCast(cd->irStruct->init, byteptrty); 1419 c = llvm::ConstantExpr::getBitCast(gIR->irDsymbol[cd].irStruct->init, byteptrty);
1420 assert(!cd->irStruct->constInit->getType()->isAbstract()); 1420 assert(!gIR->irDsymbol[cd].irStruct->constInit->getType()->isAbstract());
1421 size_t initsz = getABITypeSize(cd->irStruct->constInit->getType()); 1421 size_t initsz = getABITypeSize(gIR->irDsymbol[cd].irStruct->constInit->getType());
1422 c = DtoConstSlice(DtoConstSize_t(initsz), c); 1422 c = DtoConstSlice(DtoConstSize_t(initsz), c);
1423 } 1423 }
1424 inits.push_back(c); 1424 inits.push_back(c);
1425 1425
1426 // class name 1426 // class name
1435 c = DtoConstString(name); 1435 c = DtoConstString(name);
1436 inits.push_back(c); 1436 inits.push_back(c);
1437 1437
1438 // vtbl array 1438 // vtbl array
1439 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1439 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1440 c = cinfo->irStruct->constInit->getOperand(4); 1440 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(4);
1441 } 1441 }
1442 else { 1442 else {
1443 const llvm::Type* byteptrptrty = getPtrToType(byteptrty); 1443 const llvm::Type* byteptrptrty = getPtrToType(byteptrty);
1444 assert(!cd->irStruct->vtbl->getType()->isAbstract()); 1444 assert(!gIR->irDsymbol[cd].irStruct->vtbl->getType()->isAbstract());
1445 c = llvm::ConstantExpr::getBitCast(cd->irStruct->vtbl, byteptrptrty); 1445 c = llvm::ConstantExpr::getBitCast(gIR->irDsymbol[cd].irStruct->vtbl, byteptrptrty);
1446 assert(!cd->irStruct->constVtbl->getType()->isAbstract()); 1446 assert(!gIR->irDsymbol[cd].irStruct->constVtbl->getType()->isAbstract());
1447 size_t vtblsz = cd->irStruct->constVtbl->getType()->getNumElements(); 1447 size_t vtblsz = gIR->irDsymbol[cd].irStruct->constVtbl->getType()->getNumElements();
1448 c = DtoConstSlice(DtoConstSize_t(vtblsz), c); 1448 c = DtoConstSlice(DtoConstSize_t(vtblsz), c);
1449 } 1449 }
1450 inits.push_back(c); 1450 inits.push_back(c);
1451 1451
1452 // interfaces array 1452 // interfaces array
1453 IrStruct* irstruct = cd->irStruct; 1453 IrStruct* irstruct = gIR->irDsymbol[cd].irStruct;
1454 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) { 1454 if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) {
1455 c = cinfo->irStruct->constInit->getOperand(5); 1455 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(5);
1456 } 1456 }
1457 else { 1457 else {
1458 const llvm::Type* t = cinfo->irStruct->constInit->getOperand(5)->getType()->getContainedType(1); 1458 const llvm::Type* t = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(5)->getType()->getContainedType(1);
1459 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t); 1459 c = llvm::ConstantExpr::getBitCast(irstruct->interfaceInfos, t);
1460 size_t iisz = irstruct->interfaceInfosTy->getNumElements(); 1460 size_t iisz = irstruct->interfaceInfosTy->getNumElements();
1461 c = DtoConstSlice(DtoConstSize_t(iisz), c); 1461 c = DtoConstSlice(DtoConstSize_t(iisz), c);
1462 } 1462 }
1463 inits.push_back(c); 1463 inits.push_back(c);
1464 1464
1465 // base classinfo 1465 // base classinfo
1466 if (cd->baseClass && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1466 if (cd->baseClass && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1467 DtoDeclareClassInfo(cd->baseClass); 1467 DtoDeclareClassInfo(cd->baseClass);
1468 c = cd->baseClass->irStruct->classInfo; 1468 c = gIR->irDsymbol[cd->baseClass].irStruct->classInfo;
1469 assert(c); 1469 assert(c);
1470 inits.push_back(c); 1470 inits.push_back(c);
1471 } 1471 }
1472 else { 1472 else {
1473 // null 1473 // null
1474 c = cinfo->irStruct->constInit->getOperand(6); 1474 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(6);
1475 inits.push_back(c); 1475 inits.push_back(c);
1476 } 1476 }
1477 1477
1478 // destructor 1478 // destructor
1479 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1479 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1480 c = cinfo->irStruct->constInit->getOperand(7); 1480 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(7);
1481 } 1481 }
1482 else { 1482 else {
1483 c = build_class_dtor(cd); 1483 c = build_class_dtor(cd);
1484 } 1484 }
1485 inits.push_back(c); 1485 inits.push_back(c);
1486 1486
1487 // invariant 1487 // invariant
1488 // TODO 1488 // TODO
1489 c = cinfo->irStruct->constInit->getOperand(8); 1489 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(8);
1490 inits.push_back(c); 1490 inits.push_back(c);
1491 1491
1492 // uint flags 1492 // uint flags
1493 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1493 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1494 c = cinfo->irStruct->constInit->getOperand(9); 1494 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(9);
1495 } 1495 }
1496 else { 1496 else {
1497 uint flags = build_classinfo_flags(cd); 1497 uint flags = build_classinfo_flags(cd);
1498 c = DtoConstUint(flags); 1498 c = DtoConstUint(flags);
1499 } 1499 }
1500 inits.push_back(c); 1500 inits.push_back(c);
1501 1501
1502 // allocator 1502 // allocator
1503 // TODO 1503 // TODO
1504 c = cinfo->irStruct->constInit->getOperand(10); 1504 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(10);
1505 inits.push_back(c); 1505 inits.push_back(c);
1506 1506
1507 // offset typeinfo 1507 // offset typeinfo
1508 if (cd->isInterfaceDeclaration() || cd->isAbstract()) { 1508 if (cd->isInterfaceDeclaration() || cd->isAbstract()) {
1509 c = cinfo->irStruct->constInit->getOperand(11); 1509 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(11);
1510 } 1510 }
1511 else { 1511 else {
1512 c = build_offti_array(cd, cinfo->irStruct->constInit->getOperand(11)); 1512 c = build_offti_array(cd, gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(11));
1513 } 1513 }
1514 inits.push_back(c); 1514 inits.push_back(c);
1515 1515
1516 // default constructor 1516 // default constructor
1517 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) { 1517 if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
1518 DtoForceDeclareDsymbol(cd->defaultCtor); 1518 DtoForceDeclareDsymbol(cd->defaultCtor);
1519 c = isaConstant(gIR->irFunc[cd->defaultCtor]->func); 1519 c = isaConstant(gIR->irDsymbol[cd->defaultCtor].irFunc->func);
1520 const llvm::Type* toTy = cinfo->irStruct->constInit->getOperand(12)->getType(); 1520 const llvm::Type* toTy = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(12)->getType();
1521 c = llvm::ConstantExpr::getBitCast(c, toTy); 1521 c = llvm::ConstantExpr::getBitCast(c, toTy);
1522 } 1522 }
1523 else { 1523 else {
1524 c = cinfo->irStruct->constInit->getOperand(12); 1524 c = gIR->irDsymbol[cinfo].irStruct->constInit->getOperand(12);
1525 } 1525 }
1526 inits.push_back(c); 1526 inits.push_back(c);
1527 1527
1528 /*size_t n = inits.size(); 1528 /*size_t n = inits.size();
1529 for (size_t i=0; i<n; ++i) 1529 for (size_t i=0; i<n; ++i)
1530 { 1530 {
1531 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n'; 1531 Logger::cout() << "inits[" << i << "]: " << *inits[i] << '\n';
1532 }*/ 1532 }*/
1533 1533
1534 // build the initializer 1534 // build the initializer
1535 const llvm::StructType* st = isaStruct(cinfo->irStruct->constInit->getType()); 1535 const llvm::StructType* st = isaStruct(gIR->irDsymbol[cinfo].irStruct->constInit->getType());
1536 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits); 1536 llvm::Constant* finalinit = llvm::ConstantStruct::get(st, inits);
1537 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n'; 1537 //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n';
1538 1538
1539 cd->irStruct->constClassInfo = finalinit; 1539 gIR->irDsymbol[cd].irStruct->constClassInfo = finalinit;
1540 cd->irStruct->classInfo->setInitializer(finalinit); 1540 gIR->irDsymbol[cd].irStruct->classInfo->setInitializer(finalinit);
1541 } 1541 }