mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-03 00:20:40 +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
23
dmd/mtype.c
23
dmd/mtype.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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
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