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