changeset 1253:752bed475b75

Fixed classinfo.interfaces for .. interfaces!
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Tue, 21 Apr 2009 20:19:53 +0200
parents 7c1b55db4ff3
children 747fdd9245d7
files gen/classes.cpp ir/irclass.cpp ir/irstruct.cpp ir/irstruct.h ir/irtypeclass.cpp
diffstat 5 files changed, 54 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/gen/classes.cpp	Tue Apr 21 19:32:22 2009 +0200
+++ b/gen/classes.cpp	Tue Apr 21 20:19:53 2009 +0200
@@ -58,18 +58,22 @@
     // emit the ClassZ symbol
     LLGlobalVariable* ClassZ = irstruct->getClassInfoSymbol();
 
+    // emit the interfaceInfosZ symbol if necessary
+    if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0)
+        irstruct->getInterfaceArraySymbol(); // initializer is applied when it's built
+
     // interface only emit typeinfo and classinfo
-    if (!cd->isInterfaceDeclaration())
+    if (cd->isInterfaceDeclaration())
+    {
+        irstruct->initializeInterface();
+    }
+    else
     {
         // emit the initZ symbol
         LLGlobalVariable* initZ = irstruct->getInitSymbol();
         // emit the vtblZ symbol
         LLGlobalVariable* vtblZ = irstruct->getVtblSymbol();
 
-        // emit the interfaceInfosZ symbol if necessary
-        if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0)
-            irstruct->getInterfaceArraySymbol(); // initializer is applied when it's built
-
         // perform definition
         if (needs_def)
         {
--- a/ir/irclass.cpp	Tue Apr 21 19:32:22 2009 +0200
+++ b/ir/irclass.cpp	Tue Apr 21 20:19:53 2009 +0200
@@ -424,11 +424,20 @@
         ci = DtoBitCast(ci, classinfo_type);
 
         // vtbl
-        ClassGlobalMap::iterator itv = interfaceVtblMap.find(it->base);
-        assert(itv != interfaceVtblMap.end() && "interface vtbl not found");
-        LLConstant* vtb = itv->second;
-        vtb = DtoBitCast(vtb, voidptrptr_type);
-        vtb = DtoConstSlice(DtoConstSize_t(itc->getVtblSize()), vtb);
+        LLConstant* vtb;
+        // interface get a null
+        if (cd->isInterfaceDeclaration())
+        {
+            vtb = DtoConstSlice(DtoConstSize_t(0), getNullValue(voidptrptr_type));
+        }
+        else
+        {
+            ClassGlobalMap::iterator itv = interfaceVtblMap.find(it->base);
+            assert(itv != interfaceVtblMap.end() && "interface vtbl not found");
+            vtb = itv->second;
+            vtb = DtoBitCast(vtb, voidptrptr_type);
+            vtb = DtoConstSlice(DtoConstSize_t(itc->getVtblSize()), vtb);
+        }
 
         // offset
         LLConstant* off = DtoConstSize_t(it->offset);
@@ -473,3 +482,22 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
+
+void IrStruct::initializeInterface()
+{
+    InterfaceDeclaration* base = aggrdecl->isInterfaceDeclaration();
+    assert(base && "not interface");
+
+    // has interface vtbls?
+    if (!base->vtblInterfaces)
+        return;
+
+    ArrayIter<BaseClass> it(*base->vtblInterfaces);
+    for (; !it.done(); it.next())
+    {
+        // add to the interface list
+        interfacesWithVtbls.push_back(it.get());
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
--- a/ir/irstruct.cpp	Tue Apr 21 19:32:22 2009 +0200
+++ b/ir/irstruct.cpp	Tue Apr 21 20:19:53 2009 +0200
@@ -371,4 +371,3 @@
     IF_LOG Logger::cout() << "final struct initializer: " << *c << std::endl;
     return c;
 }
-
--- a/ir/irstruct.h	Tue Apr 21 19:32:22 2009 +0200
+++ b/ir/irstruct.h	Tue Apr 21 20:19:53 2009 +0200
@@ -58,6 +58,11 @@
     LLConstant* createStructInitializer(StructInitializer* si);
 
     //////////////////////////////////////////////////////////////////////////
+
+    /// Initialize interface.
+    void initializeInterface();
+
+    //////////////////////////////////////////////////////////////////////////
 protected:
     /// Static default initializer global.
     llvm::GlobalVariable* init;
--- a/ir/irtypeclass.cpp	Tue Apr 21 19:32:22 2009 +0200
+++ b/ir/irtypeclass.cpp	Tue Apr 21 20:19:53 2009 +0200
@@ -142,8 +142,13 @@
     // add vtbl
     defaultTypes.push_back(llvm::PointerType::get(vtbl_pa.get(), 0));
 
-    // interface are just a vtable
-    if (!cd->isInterfaceDeclaration())
+    // interfaces are just a vtable
+    if (cd->isInterfaceDeclaration())
+    {
+        num_interface_vtbls = cd->vtblInterfaces ? cd->vtblInterfaces->dim : 0;
+    }
+    // classes have monitor and fields
+    else
     {
         // add monitor
         defaultTypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty, 0));