mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 16:11:08 +03:00
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
This commit is contained in:
parent
c99938debf
commit
6da09c01b3
8 changed files with 84 additions and 32 deletions
19
dmd/mtype.c
19
dmd/mtype.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -56,7 +56,6 @@ struct IRStruct : Object
|
|||
typedef std::vector<VarDeclaration*> VarDeclVector;
|
||||
|
||||
public:
|
||||
IRStruct();
|
||||
IRStruct(Type*);
|
||||
|
||||
Type* type;
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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
17
test/classinfo2.d
Normal 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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue