[svn r193] Fixed: abstract classes implementing interfaces now output proper Interface info arrays. (null vtables).

Did a little renaming of delegate utils.
This commit is contained in:
Tomas Lindquist Olsen
2008-05-07 04:45:51 +02:00
parent 50db9be203
commit 24bd9034c3
6 changed files with 66 additions and 43 deletions

View File

@@ -610,11 +610,6 @@ void DtoConstInitClass(ClassDeclaration* cd)
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 @@ void DtoConstInitClass(ClassDeclaration* cd)
}
}
// 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<llvm::Constant*> infoInits;
@@ -683,12 +680,14 @@ void DtoConstInitClass(ClassDeclaration* cd)
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>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
}
}*/
}
gIR->classes.pop_back();
gIR->structs.pop_back();
@@ -709,7 +708,8 @@ void DtoDefineClass(ClassDeclaration* cd)
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,21 +718,32 @@ void DtoDefineClass(ClassDeclaration* cd)
// initialize interface vtables
IrStruct* irstruct = cd->ir.irStruct;
std::vector<llvm::Constant*> 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<llvm::Constant*> 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
DtoDefineClassInfo(cd);
}

View File

@@ -1841,7 +1841,7 @@ DValue* EqualExp::toElem(IRState* p)
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 @@ DValue* IdentityExp::toElem(IRState* p)
else {
assert(l->getType() == r->getType());
}
eval = DtoDynArrayIs(op,l,r);
eval = DtoDelegateCompare(op,l,r);
}
else if (t1->isfloating())
{

View File

@@ -278,7 +278,7 @@ llvm::Function* LLVM_DeclareMemCpy64()
//////////////////////////////////////////////////////////////////////////////////////////
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* 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)
{
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 @@ void DtoAssign(DValue* lhs, DValue* rhs)
}
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();

View File

@@ -17,9 +17,9 @@ Type* DtoDType(Type* t);
// 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);

View File

@@ -3,10 +3,13 @@
#include "ir/irsymbol.h"
#include "ir/irvar.h"
#include "gen/logger.h"
std::set<IrDsymbol*> IrDsymbol::list;
void IrDsymbol::resetAll()
{
Logger::println("resetting %u Dsymbols", list.size());
std::set<IrDsymbol*>::iterator it;
for(it = list.begin(); it != list.end(); ++it)
(*it)->reset();

View File

@@ -121,6 +121,7 @@ gen/llvm.h
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 @@ tango/tango/util/log/model/ILevel.d
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/l.d
tangotests/m.d
tangotests/n.d
tangotests/o.d
tangotests/p.d
tangotests/q.d
tangotests/r.d
tangotests/s.d
tangotests/stdout1.d