Mercurial > projects > ldc
changeset 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 |
files | gen/classes.cpp llvmdc.kdevelop.filelist test/classinfo1.d test/classinfo4.d |
diffstat | 4 files changed, 101 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/classes.cpp Thu Nov 22 21:17:54 2007 +0100 +++ b/gen/classes.cpp Thu Nov 22 22:30:10 2007 +0100 @@ -457,7 +457,7 @@ for (size_t i = 0; i < cd2->members->dim; i++) { Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; - if (VarDeclaration* vd = sm->isVarDeclaration()) + if (VarDeclaration* vd = sm->isVarDeclaration()) // is this enough? { llvm::Constant* c = build_offti_entry(vd); assert(c); @@ -495,6 +495,75 @@ return DtoConstSlice(size, ptr); } +static llvm::Constant* build_class_dtor(ClassDeclaration* cd) +{ + // construct the function + std::vector<const llvm::Type*> paramTypes; + paramTypes.push_back(llvm::PointerType::get(cd->type->llvmType->get())); + + const llvm::FunctionType* fnTy = llvm::FunctionType::get(llvm::Type::VoidTy, paramTypes, false); + + if (cd->dtors.dim == 0) { + return llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); + } + else if (cd->dtors.dim == 1) { + DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0]; + DtoForceDeclareDsymbol(d); + assert(d->llvmValue); + return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), llvm::PointerType::get(llvm::Type::Int8Ty)); + } + + std::string gname("_D"); + gname.append(cd->mangle()); + gname.append("12__destructorMFZv"); + + llvm::Function* func = new llvm::Function(fnTy, llvm::GlobalValue::InternalLinkage, gname, gIR->module); + llvm::Value* thisptr = func->arg_begin(); + thisptr->setName("this"); + + llvm::BasicBlock* bb = new llvm::BasicBlock("entry", func); + LLVMBuilder builder(bb); + + for (size_t i = 0; i < cd->dtors.dim; i++) + { + DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i]; + DtoForceDeclareDsymbol(d); + assert(d->llvmValue); + builder.CreateCall(d->llvmValue, thisptr); + } + builder.CreateRetVoid(); + + return llvm::ConstantExpr::getBitCast(func, llvm::PointerType::get(llvm::Type::Int8Ty)); +} + +static uint build_classinfo_flags(ClassDeclaration* cd) +{ + uint flags = 0; + //flags |= isCOMclass(); // IUnknown + bool hasOffTi = false; + if (cd->ctor) flags |= 8; + for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) + { + if (cd2->members) + { + for (size_t i = 0; i < cd2->members->dim; i++) + { + Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; + if (sm->isVarDeclaration()) // is this enough? + hasOffTi = true; + //printf("sm = %s %s\n", sm->kind(), sm->toChars()); + if (sm->hasPointers()) + goto L2; + } + } + } + flags |= 2; // no pointers +L2: + if (hasOffTi) + flags |= 4; + return flags; +} + void DtoDefineClassInfo(ClassDeclaration* cd) { // The layout is: @@ -594,8 +663,7 @@ } // destructor - // TODO - c = cinfo->llvmInitZ->getOperand(6); + c = build_class_dtor(cd); inits.push_back(c); // invariant @@ -604,25 +672,7 @@ inits.push_back(c); // uint flags, adapted from original dmd code - uint flags = 0; - //flags |= 4; // has offTi - //flags |= isCOMclass(); // IUnknown - if (cd->ctor) flags |= 8; - for (ClassDeclaration *cd2 = cd; cd2; cd2 = cd2->baseClass) - { - if (cd2->members) - { - for (size_t i = 0; i < cd2->members->dim; i++) - { - Dsymbol *sm = (Dsymbol *)cd2->members->data[i]; - //printf("sm = %s %s\n", sm->kind(), sm->toChars()); - if (sm->hasPointers()) - goto L2; - } - } - } - flags |= 2; // no pointers -L2: + uint flags = build_classinfo_flags(cd); c = DtoConstUint(flags); inits.push_back(c);
--- a/llvmdc.kdevelop.filelist Thu Nov 22 21:17:54 2007 +0100 +++ b/llvmdc.kdevelop.filelist Thu Nov 22 22:30:10 2007 +0100 @@ -338,6 +338,7 @@ test/classinfo2.d test/classinfo3.d test/classinfo4.d +test/classinfo5.d test/comma.d test/complex1.d test/complex2.d
--- a/test/classinfo1.d Thu Nov 22 21:17:54 2007 +0100 +++ b/test/classinfo1.d Thu Nov 22 22:30:10 2007 +0100 @@ -16,13 +16,13 @@ char[] name = ci.name; printf("%.*s\n", name.length, name.ptr); assert(ci.name == "classinfo1.NoPtrs"); - assert(ci.flags == 2); + assert(ci.flags & 2); } { ClassInfo ci = HasPtrs.classinfo; char[] name = ci.name; printf("%.*s\n", name.length, name.ptr); assert(ci.name == "classinfo1.HasPtrs"); - assert(ci.flags == 0); + assert(!(ci.flags & 2)); } }
--- a/test/classinfo4.d Thu Nov 22 21:17:54 2007 +0100 +++ b/test/classinfo4.d Thu Nov 22 22:30:10 2007 +0100 @@ -4,15 +4,40 @@ { } -class D +class D : C { this() { } + ~this() + { + } +} + +template T() +{ + ~this() + { + } +} + +class E : D +{ + this() + { + } + ~this() + { + } + mixin T; } void main() { assert(C.classinfo.defaultConstructor is null); + assert(C.classinfo.destructor is null); assert(D.classinfo.defaultConstructor !is null); + assert(D.classinfo.destructor !is null); + assert(E.classinfo.defaultConstructor !is null); + assert(E.classinfo.destructor !is null); }