Mercurial > projects > ldc
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 } |