[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 e->type = t; // do this so we don't get redundant dereference
} }
else else
{ /* For class objects, the classinfo reference is the first {
* entry in the vtbl[] /* 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 = new PtrExp(e->loc, e);
e->type = t->pointerTo(); e->type = t->pointerTo();
if (sym->isInterfaceDeclaration()) if (sym->isInterfaceDeclaration())
@ -4526,6 +4541,8 @@ L1:
e->type = t->pointerTo(); e->type = t->pointerTo();
} }
e = new PtrExp(e->loc, e, t); e = new PtrExp(e->loc, e, t);
#endif
} }
return e; return e;
} }

View file

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

View file

@ -56,7 +56,6 @@ struct IRStruct : Object
typedef std::vector<VarDeclaration*> VarDeclVector; typedef std::vector<VarDeclaration*> VarDeclVector;
public: public:
IRStruct();
IRStruct(Type*); IRStruct(Type*);
Type* 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);
} }
TypeStruct* ts = (TypeStruct*)t;
assert(ts->sym);
DtoResolveDsymbol(ts->sym);
return t->llvmType->get(); 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);
} }
TypeClass* tc = (TypeClass*)t;
assert(tc->sym);
DtoResolveDsymbol(tc->sym);
return llvm::PointerType::get(t->llvmType->get()); return llvm::PointerType::get(t->llvmType->get());
} }

View file

@ -85,6 +85,16 @@ Module::genobjfile()
ir.dmodule->llvmCompileUnit = DtoDwarfCompileUnit(this,true); 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 // process module members
for (int k=0; k < members->dim; k++) { for (int k=0; k < members->dim; k++) {
Dsymbol* dsym = (Dsymbol*)(members->data[k]); Dsymbol* dsym = (Dsymbol*)(members->data[k]);

View file

@ -314,6 +314,7 @@ test/classes6.d
test/classes7.d test/classes7.d
test/classes8.d test/classes8.d
test/classinfo1.d test/classinfo1.d
test/classinfo2.d
test/comma.d test/comma.d
test/complex1.d test/complex1.d
test/cond.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);
}