comparison gen/classes.cpp @ 112:368547b1cbe6 trunk

[svn r116] Implemented the ClassInfo.destructor field.
author lindquist
date Thu, 22 Nov 2007 22:30:10 +0100
parents a7ae554ce4f4
children 27b9f749d9fe
comparison
equal deleted inserted replaced
111:a7ae554ce4f4 112:368547b1cbe6
455 if (cd2->members) 455 if (cd2->members)
456 { 456 {
457 for (size_t i = 0; i < cd2->members->dim; i++) 457 for (size_t i = 0; i < cd2->members->dim; i++)
458 { 458 {
459 Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; 459 Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
460 if (VarDeclaration* vd = sm->isVarDeclaration()) 460 if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough?
461 { 461 {
462 llvm::Constant* c = build_offti_entry(vd); 462 llvm::Constant* c = build_offti_entry(vd);
463 assert(c); 463 assert(c);
464 arrayInits.push_back(c); 464 arrayInits.push_back(c);
465 } 465 }
491 else { 491 else {
492 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1))); 492 ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1)));
493 } 493 }
494 494
495 return DtoConstSlice(size, ptr); 495 return DtoConstSlice(size, ptr);
496 }
497
498 static llvm::Constant* build_class_dtor(ClassDeclaration* cd)
499 {
500 // construct the function
501 std::vector<const llvm::Type*> paramTypes;
502 paramTypes.push_back(llvm::PointerType::get(cd->type->llvmType->get()));
503
504 const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false);
505
506 if (cd->dtors.dim == 0) {
507 return llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty));
508 }
509 else if (cd->dtors.dim == 1) {
510 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
511 DtoForceDeclareDsymbol(d);
512 assert(d->llvmValue);
513 return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), llvm::PointerType::get(llvm::Type::Int8Ty));
514 }
515
516 std::string gname("_D");
517 gname.append(cd->mangle());
518 gname.append("12__destructorMFZv");
519
520 llvm::Function* func = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, gname, gIR->module);
521 llvm::Value* thisptr = func->arg_begin();
522 thisptr->setName("this");
523
524 llvm::BasicBlock* bb = new llvm::BasicBlock("entry", func);
525 LLVMBuilder builder(bb);
526
527 for (size_t i = 0; i < cd->dtors.dim; i++)
528 {
529 DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
530 DtoForceDeclareDsymbol(d);
531 assert(d->llvmValue);
532 builder.CreateCall(d->llvmValue, thisptr);
533 }
534 builder.CreateRetVoid();
535
536 return llvm::ConstantExpr::getBitCast(func, llvm::PointerType::get(llvm::Type::Int8Ty));
537 }
538
539 static uint build_classinfo_flags(ClassDeclaration* cd)
540 {
541 uint flags = 0;
542 //flags |= isCOMclass(); // IUnknown
543 bool hasOffTi = false;
544 if (cd->ctor) flags |= 8;
545 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass)
546 {
547 if (cd2->members)
548 {
549 for (size_t i = 0; i < cd2->members->dim; i++)
550 {
551 Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
552 if (sm->isVarDeclaration()) // is this enough?
553 hasOffTi = true;
554 //printf("sm = %s %s\n", sm->kind(), sm->toChars());
555 if (sm->hasPointers())
556 goto L2;
557 }
558 }
559 }
560 flags |= 2; // no pointers
561 L2:
562 if (hasOffTi)
563 flags |= 4;
564 return flags;
496 } 565 }
497 566
498 void DtoDefineClassInfo(ClassDeclaration* cd) 567 void DtoDefineClassInfo(ClassDeclaration* cd)
499 { 568 {
500 // The layout is: 569 // The layout is:
592 c = cinfo->llvmInitZ->getOperand(5); 661 c = cinfo->llvmInitZ->getOperand(5);
593 inits.push_back(c); 662 inits.push_back(c);
594 } 663 }
595 664
596 // destructor 665 // destructor
597 // TODO 666 c = build_class_dtor(cd);
598 c = cinfo->llvmInitZ->getOperand(6);
599 inits.push_back(c); 667 inits.push_back(c);
600 668
601 // invariant 669 // invariant
602 // TODO 670 // TODO
603 c = cinfo->llvmInitZ->getOperand(7); 671 c = cinfo->llvmInitZ->getOperand(7);
604 inits.push_back(c); 672 inits.push_back(c);
605 673
606 // uint flags, adapted from original dmd code 674 // uint flags, adapted from original dmd code
607 uint flags = 0; 675 uint flags = build_classinfo_flags(cd);
608 //flags |= 4; // has offTi
609 //flags |= isCOMclass(); // IUnknown
610 if (cd->ctor) flags |= 8;
611 for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass)
612 {
613 if (cd2->members)
614 {
615 for (size_t i = 0; i < cd2->members->dim; i++)
616 {
617 Dsymbol *sm = (Dsymbol *)cd2->members->data[i];
618 //printf("sm = %s %s\n", sm->kind(), sm->toChars());
619 if (sm->hasPointers())
620 goto L2;
621 }
622 }
623 }
624 flags |= 2; // no pointers
625 L2:
626 c = DtoConstUint(flags); 676 c = DtoConstUint(flags);
627 inits.push_back(c); 677 inits.push_back(c);
628 678
629 // allocator 679 // allocator
630 // TODO 680 // TODO