[svn r114] Implemented the ClassInfo.offTi member.

This commit is contained in:
Tomas Lindquist Olsen
2007-11-22 21:01:01 +01:00
parent d51e392b8d
commit be1fcd6a24
4 changed files with 114 additions and 6 deletions

View File

@@ -414,6 +414,87 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
cd->llvmClass = new llvm::GlobalVariable(st, true, llvm::GlobalValue::ExternalLinkage, NULL, gname, gIR->module);
}
static llvm::Constant* build_offti_entry(VarDeclaration* vd)
{
std::vector<const llvm::Type*> types;
std::vector<llvm::Constant*> inits;
types.push_back(DtoSize_t());
size_t offset = vd->offset; // TODO might not be the true offset
// dmd only accounts for the vtable, not classinfo or monitor
if (global.params.is64bit)
offset += 8;
else
offset += 4;
inits.push_back(DtoConstSize_t(offset));
vd->type->getTypeInfo(NULL);
assert(vd->type->vtinfo);
DtoForceDeclareDsymbol(vd->type->vtinfo);
llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue);
const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get());
Logger::cout() << "tiTy = " << *tiTy << '\n';
types.push_back(tiTy);
inits.push_back(llvm::ConstantExpr::getBitCast(c, tiTy));
const llvm::StructType* sTy = llvm::StructType::get(types);
return llvm::ConstantStruct::get(sTy, inits);
}
static llvm::Constant* build_offti_array(ClassDeclaration* cd, llvm::Constant* init)
{
const llvm::StructType* initTy = isaStruct(init->getType());
assert(initTy);
std::vector<llvm::Constant*> arrayInits;
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 (VarDeclaration* vd = sm->isVarDeclaration())
{
llvm::Constant* c = build_offti_entry(vd);
assert(c);
arrayInits.push_back(c);
}
}
}
}
size_t ninits = arrayInits.size();
llvm::Constant* size = DtoConstSize_t(ninits);
llvm::Constant* ptr;
if (ninits > 0) {
// OffsetTypeInfo type
std::vector<const llvm::Type*> elemtypes;
elemtypes.push_back(DtoSize_t());
const llvm::Type* tiTy = llvm::PointerType::get(Type::typeinfo->type->llvmType->get());
elemtypes.push_back(tiTy);
const llvm::StructType* sTy = llvm::StructType::get(elemtypes);
// array type
const llvm::ArrayType* arrTy = llvm::ArrayType::get(sTy, ninits);
llvm::Constant* arrInit = llvm::ConstantArray::get(arrTy, arrayInits);
std::string name(cd->type->vtinfo->toChars());
name.append("__OffsetTypeInfos");
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(arrTy,true,llvm::GlobalValue::InternalLinkage,arrInit,name,gIR->module);
ptr = llvm::ConstantExpr::getBitCast(gvar, llvm::PointerType::get(sTy));
}
else {
ptr = llvm::ConstantPointerNull::get(isaPointer(initTy->getElementType(1)));
}
return DtoConstSlice(size, ptr);
}
void DtoDefineClassInfo(ClassDeclaration* cd)
{
// The layout is:
@@ -552,7 +633,7 @@ L2:
// offset typeinfo
// TODO
c = cinfo->llvmInitZ->getOperand(10);
c = build_offti_array(cd, cinfo->llvmInitZ->getOperand(10));
inits.push_back(c);
// default constructor

View File

@@ -819,7 +819,7 @@ void TypeInfoStructDeclaration::llvmDefine()
// char[] name
char *name = sd->toPrettyChars();
sinits.push_back(DtoConstString(name));
Logger::println("************** A");
//Logger::println("************** A");
assert(sinits.back()->getType() == stype->getElementType(1));
// void[] init
@@ -881,7 +881,7 @@ void TypeInfoStructDeclaration::llvmDefine()
}
#endif
Logger::println("************** B");
//Logger::println("************** B");
const llvm::PointerType* ptty = isaPointer(stype->getElementType(3));
s = search_function(sd, Id::tohash);
@@ -909,7 +909,7 @@ void TypeInfoStructDeclaration::llvmDefine()
fdx = s ? s->isFuncDeclaration() : NULL;
for (int i = 0; i < 2; i++)
{
Logger::println("************** C %d", i);
//Logger::println("************** C %d", i);
ptty = isaPointer(stype->getElementType(4+i));
if (fdx)
{
@@ -934,7 +934,7 @@ void TypeInfoStructDeclaration::llvmDefine()
fdx = s ? s->isFuncDeclaration() : NULL;
}
Logger::println("************** D");
//Logger::println("************** D");
ptty = isaPointer(stype->getElementType(6));
s = search_function(sd, Id::tostring);
fdx = s ? s->isFuncDeclaration() : NULL;

View File

@@ -323,7 +323,6 @@ test/bug70.d
test/bug71.d
test/bug72.d
test/bug73.d
test/bug74.d
test/bug8.d
test/bug9.d
test/c.d
@@ -337,6 +336,7 @@ test/classes7.d
test/classes8.d
test/classinfo1.d
test/classinfo2.d
test/classinfo3.d
test/comma.d
test/complex1.d
test/complex2.d

27
test/classinfo3.d Normal file
View File

@@ -0,0 +1,27 @@
module classinfo3;
class C
{
int i;
float f;
long l;
int j;
}
void main()
{
auto c = C.classinfo;
assert(c.offTi !is null);
assert(c.offTi.length == 4);
size_t base = 2*size_t.sizeof;
assert(c.offTi[0].offset == base);
assert(c.offTi[0].ti == typeid(int));
assert(c.offTi[1].offset == base+4);
assert(c.offTi[1].ti == typeid(float));
assert(c.offTi[2].offset == base+8);
assert(c.offTi[2].ti == typeid(long));
assert(c.offTi[3].offset == base+16);
assert(c.offTi[3].ti == typeid(int));
}