mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user