changeset 103:855adfdb8d38 trunk

[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
author lindquist
date Sun, 18 Nov 2007 08:25:07 +0100
parents 027b8d8b71ec
children 4d1e9eb001e0
files dmd/mtype.c gen/classes.cpp gen/irstate.cpp gen/irstate.h gen/tollvm.cpp gen/toobj.cpp llvmdc.kdevelop.filelist test/classinfo2.d
diffstat 8 files changed, 84 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/mtype.c	Sun Nov 18 06:52:57 2007 +0100
+++ b/dmd/mtype.c	Sun Nov 18 08:25:07 2007 +0100
@@ -4502,9 +4502,24 @@
 		e->type = t;	// do this so we don't get redundant dereference
 	    }
 	    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->type = t->pointerTo();
 		if (sym->isInterfaceDeclaration())
@@ -4526,6 +4541,8 @@
 		    e->type = t->pointerTo();
 		}
 		e = new PtrExp(e->loc, e, t);
+
+#endif
 	    }
 	    return e;
 	}
--- a/gen/classes.cpp	Sun Nov 18 06:52:57 2007 +0100
+++ b/gen/classes.cpp	Sun Nov 18 08:25:07 2007 +0100
@@ -46,6 +46,10 @@
     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 @@
     llvm::cast<llvm::OpaqueType>(spa.get())->refineAbstractTypeTo(structtype);
     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;
     if (cd->parent->isModule()) {
@@ -118,7 +125,17 @@
             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 @@
     gIR->constInitList.push_back(cd);
     if (needs_definition)
         gIR->defineList.push_back(cd);
+
+    // classinfo
+    DtoDeclareClassInfo(cd);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -236,7 +256,7 @@
     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 @@
 
     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 @@
             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 @@
 
     gIR->classes.pop_back();
     gIR->structs.pop_back();
-
-    DtoDeclareClassInfo(cd);
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
--- a/gen/irstate.cpp	Sun Nov 18 06:52:57 2007 +0100
+++ b/gen/irstate.cpp	Sun Nov 18 08:25:07 2007 +0100
@@ -105,16 +105,8 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-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;
--- a/gen/irstate.h	Sun Nov 18 06:52:57 2007 +0100
+++ b/gen/irstate.h	Sun Nov 18 08:25:07 2007 +0100
@@ -56,7 +56,6 @@
     typedef std::vector<VarDeclaration*> VarDeclVector;
 
 public:
-    IRStruct();
     IRStruct(Type*);
 
     Type* type;
--- a/gen/tollvm.cpp	Sun Nov 18 06:52:57 2007 +0100
+++ b/gen/tollvm.cpp	Sun Nov 18 08:25:07 2007 +0100
@@ -111,12 +111,11 @@
                     }
                 }
             }
+        }
 
-            // 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();
     }
 
@@ -134,12 +133,11 @@
                     }
                 }
             }
+        }
 
-            // 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());
     }
 
--- a/gen/toobj.cpp	Sun Nov 18 06:52:57 2007 +0100
+++ b/gen/toobj.cpp	Sun Nov 18 08:25:07 2007 +0100
@@ -85,6 +85,16 @@
         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]);
--- a/llvmdc.kdevelop.filelist	Sun Nov 18 06:52:57 2007 +0100
+++ b/llvmdc.kdevelop.filelist	Sun Nov 18 08:25:07 2007 +0100
@@ -314,6 +314,7 @@
 test/classes7.d
 test/classes8.d
 test/classinfo1.d
+test/classinfo2.d
 test/comma.d
 test/complex1.d
 test/cond.d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classinfo2.d	Sun Nov 18 08:25:07 2007 +0100
@@ -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);
+}