# HG changeset patch # User lindquist # Date 1210128351 -7200 # Node ID cea8dcfa76dfd5ae426a01684e0a7faa18e1c405 # Parent a074a5ff709cfc055c440c0d1c3b4f335b21679a [svn r193] Fixed: abstract classes implementing interfaces now output proper Interface info arrays. (null vtables). Did a little renaming of delegate utils. diff -r a074a5ff709c -r cea8dcfa76df gen/classes.cpp --- a/gen/classes.cpp Wed May 07 00:58:36 2008 +0200 +++ b/gen/classes.cpp Wed May 07 04:45:51 2008 +0200 @@ -610,11 +610,6 @@ infoInits.push_back(c); // offset - // generate target independent offset with constGEP - /*llvm::Value* cidx = DtoConstInt(iri->index); - Logger::cout() << "offset to interface in class type: " << *cd->type->ir.type->get() << '\n'; - size_t ioff = gTargetData->getIndexedOffset(cd->type->ir.type->get(), &cidx, 1); - infoInits.push_back(DtoConstUint(ioff));*/ assert(iri->index >= 0); size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index); infoInits.push_back(DtoConstUint(ioff)); @@ -658,17 +653,19 @@ } } // we always generate interfaceinfos as best we can - /*else + else { - for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i) + // TODO: this is duplicated code from right above... I'm just too lazy to generalise it right now :/ + // create interface vtable const initalizers + for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) { - ClassDeclaration* id = i->first; + IrInterface* iri = *i; + BaseClass* b = iri->base; + + ClassDeclaration* id = iri->decl; assert(id->type->ty == Tclass); TypeClass* its = (TypeClass*)id->type; - IrInterface* iri = i->second; - BaseClass* b = iri->base; - // generate interface info initializer std::vector infoInits; @@ -683,12 +680,14 @@ infoInits.push_back(c); // offset - infoInits.push_back(DtoConstInt(0)); + assert(iri->index >= 0); + size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index); + infoInits.push_back(DtoConstUint(ioff)); // create interface info initializer constant iri->infoInit = llvm::cast(llvm::ConstantStruct::get(iri->infoTy, infoInits)); } - }*/ + } gIR->classes.pop_back(); gIR->structs.pop_back(); @@ -709,7 +708,8 @@ TypeClass* ts = (TypeClass*)cd->type; if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) { - // interfaces don't have initializers + + // interfaces don't have static initializer/vtable // neither do abstract classes if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) { @@ -718,19 +718,30 @@ // initialize interface vtables IrStruct* irstruct = cd->ir.irStruct; - std::vector infoInits; for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) { IrInterface* iri = *i; iri->vtbl->setInitializer(iri->vtblInit); - infoInits.push_back(iri->infoInit); } - // initialize interface info array - if (!infoInits.empty()) - { - llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); - irstruct->interfaceInfos->setInitializer(arrInit); - } + } + + // always do interface info array when possible + IrStruct* irstruct = cd->ir.irStruct; + std::vector infoInits; + for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i) + { + IrInterface* iri = *i; + infoInits.push_back(iri->infoInit); + } + // set initializer + if (!infoInits.empty()) + { + llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits); + irstruct->interfaceInfos->setInitializer(arrInit); + } + else + { + assert(irstruct->interfaceInfos == NULL); } // generate classinfo diff -r a074a5ff709c -r cea8dcfa76df gen/toir.cpp --- a/gen/toir.cpp Wed May 07 00:58:36 2008 +0200 +++ b/gen/toir.cpp Wed May 07 04:45:51 2008 +0200 @@ -1841,7 +1841,7 @@ else if (t->ty == Tdelegate) { Logger::println("delegate"); - eval = DtoCompareDelegate(op,l->getRVal(),r->getRVal()); + eval = DtoDelegateCompare(op,l->getRVal(),r->getRVal()); } else { @@ -2333,7 +2333,7 @@ else { assert(l->getType() == r->getType()); } - eval = DtoDynArrayIs(op,l,r); + eval = DtoDelegateCompare(op,l,r); } else if (t1->isfloating()) { diff -r a074a5ff709c -r cea8dcfa76df gen/tollvm.cpp --- a/gen/tollvm.cpp Wed May 07 00:58:36 2008 +0200 +++ b/gen/tollvm.cpp Wed May 07 04:45:51 2008 +0200 @@ -278,7 +278,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -llvm::Value* DtoNullDelegate(llvm::Value* v) +llvm::Value* DtoDelegateToNull(llvm::Value* v) { assert(gIR); d_uns64 n = (global.params.is64bit) ? 16 : 8; @@ -327,17 +327,31 @@ ////////////////////////////////////////////////////////////////////////////////////////// -llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs) +llvm::Value* DtoDelegateCompare(TOK op, llvm::Value* lhs, llvm::Value* rhs) { - llvm::ICmpInst::Predicate pred = (op == TOKequal) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; - llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); - llvm::Value* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp"); - llvm::Value* b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); - l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); - r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp"); - llvm::Value* b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); + Logger::println("Doing delegate compare"); + llvm::ICmpInst::Predicate pred = (op == TOKequal || op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; + llvm::Value *b1, *b2; + if (rhs == NULL) + { + llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); + llvm::Value* r = llvm::Constant::getNullValue(l->getType()); + b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); + l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); + r = llvm::Constant::getNullValue(l->getType()); + b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); + } + else + { + llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); + llvm::Value* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp"); + b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); + l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); + r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp"); + b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); + } llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); - if (op == TOKnotequal) + if (op == TOKnotequal || op == TOKnotidentity) return gIR->ir->CreateNot(b,"tmp"); return b; } @@ -949,7 +963,7 @@ } else if (t->ty == Tdelegate) { if (rhs->isNull()) - DtoNullDelegate(lhs->getLVal()); + DtoDelegateToNull(lhs->getLVal()); else if (!rhs->inPlace()) { llvm::Value* l = lhs->getLVal(); llvm::Value* r = rhs->getRVal(); diff -r a074a5ff709c -r cea8dcfa76df gen/tollvm.h --- a/gen/tollvm.h Wed May 07 00:58:36 2008 +0200 +++ b/gen/tollvm.h Wed May 07 04:45:51 2008 +0200 @@ -17,9 +17,9 @@ // delegate helpers const llvm::StructType* DtoDelegateType(Type* t); -llvm::Value* DtoNullDelegate(llvm::Value* v); +llvm::Value* DtoDelegateToNull(llvm::Value* v); llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src); -llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs); +llvm::Value* DtoDelegateCompare(TOK op, llvm::Value* lhs, llvm::Value* rhs); // return linkage type for symbol using the current ir state for context llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym); diff -r a074a5ff709c -r cea8dcfa76df ir/irsymbol.cpp --- a/ir/irsymbol.cpp Wed May 07 00:58:36 2008 +0200 +++ b/ir/irsymbol.cpp Wed May 07 04:45:51 2008 +0200 @@ -3,10 +3,13 @@ #include "ir/irsymbol.h" #include "ir/irvar.h" +#include "gen/logger.h" + std::set IrDsymbol::list; void IrDsymbol::resetAll() { + Logger::println("resetting %u Dsymbols", list.size()); std::set::iterator it; for(it = list.begin(); it != list.end(); ++it) (*it)->reset(); diff -r a074a5ff709c -r cea8dcfa76df llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Wed May 07 00:58:36 2008 +0200 +++ b/llvmdc.kdevelop.filelist Wed May 07 04:45:51 2008 +0200 @@ -121,6 +121,7 @@ gen/logger.cpp gen/logger.h gen/optimizer.cpp +gen/pairtype.h gen/runtime.cpp gen/runtime.h gen/statements.cpp @@ -748,17 +749,13 @@ tangotests tangotests/a.d tangotests/aa1.d -tangotests/abc.d -tangotests/abcd.d tangotests/b.d tangotests/c.d tangotests/classes1.d tangotests/constructors.d -tangotests/d.d tangotests/e.d tangotests/f.d tangotests/files1.d -tangotests/g.d tangotests/h.d tangotests/i.d tangotests/j.d @@ -767,8 +764,6 @@ tangotests/m.d tangotests/n.d tangotests/o.d -tangotests/p.d -tangotests/q.d tangotests/r.d tangotests/s.d tangotests/stdout1.d