[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)

This commit is contained in:
Tomas Lindquist Olsen 2007-11-18 08:25:07 +01:00
parent c99938debf
commit 6da09c01b3
8 changed files with 84 additions and 32 deletions

View file

@ -4502,9 +4502,24 @@ L1:
e->type = t; // do this so we don't get redundant dereference
}
else
{ /* For class objects, the classinfo reference is the first
{
/* For class objects, the classinfo reference is the first
* entry in the vtbl[]
*/
#if IN_LLVM
e = e->castTo(sc, t->pointerTo()->pointerTo());
e = new PtrExp(e->loc, e);
e->type = t->pointerTo();
e = new PtrExp(e->loc, e);
e->type = t;
if (sym->isInterfaceDeclaration())
{
assert(0 && "No interfaces yet!");
}
#else
e = new PtrExp(e->loc, e);
e->type = t->pointerTo();
if (sym->isInterfaceDeclaration())
@ -4526,6 +4541,8 @@ L1:
e->type = t->pointerTo();
}
e = new PtrExp(e->loc, e, t);
#endif
}
return e;
}

View file

@ -46,6 +46,10 @@ void DtoResolveClass(ClassDeclaration* cd)
if (cd->baseClass) {
DtoResolveClass(cd->baseClass);
}
// resolve typeinfo
//DtoResolveClass(ClassDeclaration::typeinfo);
// resolve classinfo
//DtoResolveClass(ClassDeclaration::classinfo);
Logger::println("DtoResolveClass(%s)", cd->toPrettyChars());
LOG_SCOPE;
@ -89,7 +93,10 @@ void DtoResolveClass(ClassDeclaration* cd)
llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype);
structtype = isaStruct(spa.get());
if (!ts->llvmType)
ts->llvmType = new llvm::PATypeHolder(structtype);
else
*ts->llvmType = structtype;
bool needs_definition = false;
if (cd->parent->isModule()) {
@ -118,7 +125,17 @@ void DtoResolveClass(ClassDeclaration* cd)
sinits_ty.push_back(fpty);
}
else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
const llvm::Type* cty = llvm::PointerType::get(llvm::Type::Int8Ty);
//Logger::println("*** ClassDeclaration in vtable: %s", cd->toChars());
const llvm::Type* cinfoty;
if (cd != ClassDeclaration::classinfo) {
cd = ClassDeclaration::classinfo;
DtoResolveClass(cd);
cinfoty = cd->type->llvmType->get();
}
else {
cinfoty = ts->llvmType->get();
}
const llvm::Type* cty = llvm::PointerType::get(cd->type->llvmType->get());
sinits_ty.push_back(cty);
}
else
@ -192,6 +209,9 @@ void DtoDeclareClass(ClassDeclaration* cd)
gIR->constInitList.push_back(cd);
if (needs_definition)
gIR->defineList.push_back(cd);
// classinfo
DtoDeclareClassInfo(cd);
}
//////////////////////////////////////////////////////////////////////////////////////////
@ -236,7 +256,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
const llvm::StructType* structtype = isaStruct(ts->llvmType->get());
// generate initializer
Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
/*Logger::cout() << cd->toPrettyChars() << " | " << *structtype << '\n';
for(size_t i=0; i<structtype->getNumElements(); ++i) {
Logger::cout() << "s#" << i << " = " << *structtype->getElementType(i) << '\n';
@ -244,7 +264,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
for(size_t i=0; i<fieldinits.size(); ++i) {
Logger::cout() << "i#" << i << " = " << *fieldinits[i]->getType() << '\n';
}
}*/
llvm::Constant* _init = llvm::ConstantStruct::get(structtype, fieldinits);
assert(_init);
@ -265,9 +285,9 @@ void DtoConstInitClass(ClassDeclaration* cd)
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
sinits.push_back(c);
}
else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
const llvm::Type* cty = llvm::PointerType::get(llvm::Type::Int8Ty);
llvm::Constant* c = llvm::Constant::getNullValue(cty);
else if (ClassDeclaration* cd2 = dsym->isClassDeclaration()) {
assert(cd->llvmClass);
llvm::Constant* c = cd->llvmClass;
sinits.push_back(c);
}
else
@ -288,8 +308,6 @@ void DtoConstInitClass(ClassDeclaration* cd)
gIR->classes.pop_back();
gIR->structs.pop_back();
DtoDeclareClassInfo(cd);
}
//////////////////////////////////////////////////////////////////////////////////////////

View file

@ -105,16 +105,8 @@ bool IRState::scopereturned()
//////////////////////////////////////////////////////////////////////////////////////////
IRStruct::IRStruct()
: recty(llvm::OpaqueType::get())
{
type = 0;
defined = false;
constinited = false;
}
IRStruct::IRStruct(Type* t)
: recty(llvm::OpaqueType::get())
: recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get())
{
type = t;
defined = false;

View file

@ -56,7 +56,6 @@ struct IRStruct : Object
typedef std::vector<VarDeclaration*> VarDeclVector;
public:
IRStruct();
IRStruct(Type*);
Type* type;

View file

@ -111,12 +111,11 @@ const llvm::Type* DtoType(Type* t)
}
}
}
}
// forward declaration
TypeStruct* ts = (TypeStruct*)t;
assert(ts->sym);
DtoResolveDsymbol(ts->sym);
}
return t->llvmType->get();
}
@ -134,12 +133,11 @@ const llvm::Type* DtoType(Type* t)
}
}
}
}
// forward declaration
TypeClass* tc = (TypeClass*)t;
assert(tc->sym);
DtoResolveDsymbol(tc->sym);
}
return llvm::PointerType::get(t->llvmType->get());
}

View file

@ -85,6 +85,16 @@ Module::genobjfile()
ir.dmodule->llvmCompileUnit = DtoDwarfCompileUnit(this,true);
}
// start out by providing opaque for the built-in class types
if (!ClassDeclaration::object->type->llvmType)
ClassDeclaration::object->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get());
if (!Type::typeinfo->type->llvmType)
Type::typeinfo->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get());
if (!ClassDeclaration::classinfo->type->llvmType)
ClassDeclaration::classinfo->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get());
// process module members
for (int k=0; k < members->dim; k++) {
Dsymbol* dsym = (Dsymbol*)(members->data[k]);

View file

@ -314,6 +314,7 @@ test/classes6.d
test/classes7.d
test/classes8.d
test/classinfo1.d
test/classinfo2.d
test/comma.d
test/complex1.d
test/cond.d

17
test/classinfo2.d Normal file
View file

@ -0,0 +1,17 @@
module classinfo2;
class C
{
}
class D : C
{
}
void main()
{
D d;
d = new D;
ClassInfo ci = d.classinfo;
assert(ci is D.classinfo);
}