comparison gen/classes.cpp @ 110:e8da7856a260 trunk

[svn r114] Implemented the ClassInfo.offTi member.
author lindquist
date Thu, 22 Nov 2007 21:01:01 +0100
parents 5b5194b25f33
children a7ae554ce4f4
comparison
equal deleted inserted replaced
109:5ab8e92611f9 110:e8da7856a260
410 gname.append("7__ClassZ"); 410 gname.append("7__ClassZ");
411 411
412 const llvm::Type* st = cinfo->type->llvmType->get(); 412 const llvm::Type* st = cinfo->type->llvmType->get();
413 413
414 cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module); 414 cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module);
415 }
416
417 static llvm::Constant* build_offti_entry(VarDeclaration* vd)
418 {
419 std::vector<const llvm::Type*> types;
420 std::vector<llvm::Constant*> inits;
421
422 types.push_back(DtoSize_t());
423
424 size_t offset = vd->offset; // TODO might not be the true offset
425 // dmd only accounts for the vtable, not classinfo or monitor
426 if (global.params.is64bit)
427 offset += 8;
428 else
429 offset += 4;
430 inits.push_back(DtoConstSize_t(offset));
431
432 vd->type->getTypeInfo(NULL);
433 assert(vd->type->vtinfo);
434 DtoForceDeclareDsymbol(vd->type->vtinfo);
435 llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue);
436
437 const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get());
438 Logger::cout() << "tiTy = " << *tiTy << '\n';
439
440 types.push_back(tiTy);
441 inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy));
442
443 const llvm::StructType* sTy = llvm::StructType::get(types);
444 return llvm::ConstantStruct::get(sTy, inits);
445 }
446
447 static llvm::Constant* build_offti_array(ClassDeclaration* cd, llvm::Constant* init)
448 {
449 const llvm::StructType* initTy = isaStruct(init->getType());
450 assert(initTy);
451
452 std::vector<llvm::Constant*> arrayInits;
453 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass)
454 {
455 if (cd2->members)
456 {
457 for (size_t i = 0; i < cd2->members->dim; i++)
458 {
459 Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
460 if (VarDeclaration* vd = sm->isVarDeclaration())
461 {
462 llvm::Constant* c = build_offti_entry(vd);
463 assert(c);
464 arrayInits.push_back(c);
465 }
466 }
467 }
468 }
469
470 size_t ninits = arrayInits.size();
471 llvm::Constant* size = DtoConstSize_t(ninits);
472 llvm::Constant* ptr;
473
474 if (ninits > 0) {
475 // OffsetTypeInfo type
476 std::vector<const llvm::Type*> elemtypes;
477 elemtypes.push_back(DtoSize_t());
478 const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get());
479 elemtypes.push_back(tiTy);
480 const llvm::StructType* sTy = llvm::StructType::get(elemtypes);
481
482 // array type
483 const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits);
484 llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits);
485
486 std::string name(cd->type->vtinfo->toChars());
487 name.append("__OffsetTypeInfos");
488 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module);
489 ptr = llvm::ConstantExpr::getBitCast(gvar, llvm::PointerType::get(sTy));
490 }
491 else {
492 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1)));
493 }
494
495 return DtoConstSlice(size, ptr);
415 } 496 }
416 497
417 void DtoDefineClassInfo(ClassDeclaration* cd) 498 void DtoDefineClassInfo(ClassDeclaration* cd)
418 { 499 {
419 // The layout is: 500 // The layout is:
550 c = cinfo->llvmInitZ->getOperand(9); 631 c = cinfo->llvmInitZ->getOperand(9);
551 inits.push_back(c); 632 inits.push_back(c);
552 633
553 // offset typeinfo 634 // offset typeinfo
554 // TODO 635 // TODO
555 c = cinfo->llvmInitZ->getOperand(10); 636 c = build_offti_array(cd, cinfo->llvmInitZ->getOperand(10));
556 inits.push_back(c); 637 inits.push_back(c);
557 638
558 // default constructor 639 // default constructor
559 // TODO 640 // TODO
560 c = cinfo->llvmInitZ->getOperand(11); 641 c = cinfo->llvmInitZ->getOperand(11);