changeset 177:cea8dcfa76df trunk

[svn r193] Fixed: abstract classes implementing interfaces now output proper Interface info arrays. (null vtables). Did a little renaming of delegate utils.
author lindquist
date Wed, 07 May 2008 04:45:51 +0200
parents a074a5ff709c
children 8873b7f1457e
files gen/classes.cpp gen/toir.cpp gen/tollvm.cpp gen/tollvm.h ir/irsymbol.cpp llvmdc.kdevelop.filelist
diffstat 6 files changed, 66 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/gen/classes.cpp	Wed May 07 00:58:36 2008 +0200
+++ b/gen/classes.cpp	Wed May 07 04:45:51 2008 +0200
@@ -610,11 +610,6 @@
             infoInits.push_back(c);
 
             // offset
-            // generate target independent offset with constGEP
-            /*llvm::Value* cidx = DtoConstInt(iri->index);
-            Logger::cout() << "offset to interface in class type: " << *cd->type->ir.type->get() << '\n';
-            size_t ioff = gTargetData->getIndexedOffset(cd->type->ir.type->get(), &cidx, 1);
-            infoInits.push_back(DtoConstUint(ioff));*/
             assert(iri->index >= 0);
             size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index);
             infoInits.push_back(DtoConstUint(ioff));
@@ -658,17 +653,19 @@
         }
     }
     // we always generate interfaceinfos as best we can
-    /*else
+    else
     {
-        for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
+        // TODO: this is duplicated code from right above... I'm just too lazy to generalise it right now :/
+        // create interface vtable const initalizers
+        for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
         {
-            ClassDeclaration* id = i->first;
+            IrInterface* iri = *i;
+            BaseClass* b = iri->base;
+
+            ClassDeclaration* id = iri->decl;
             assert(id->type->ty == Tclass);
             TypeClass* its = (TypeClass*)id->type;
 
-            IrInterface* iri = i->second;
-            BaseClass* b = iri->base;
-
             // generate interface info initializer
             std::vector<llvm::Constant*> infoInits;
 
@@ -683,12 +680,14 @@
             infoInits.push_back(c);
 
             // offset
-            infoInits.push_back(DtoConstInt(0));
+            assert(iri->index >= 0);
+            size_t ioff = gTargetData->getStructLayout(isaStruct(cd->type->ir.type->get()))->getElementOffset(iri->index);
+            infoInits.push_back(DtoConstUint(ioff));
 
             // create interface info initializer constant
             iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
         }
-    }*/
+    }
 
     gIR->classes.pop_back();
     gIR->structs.pop_back();
@@ -709,7 +708,8 @@
     TypeClass* ts = (TypeClass*)cd->type;
 
     if (cd->getModule() == gIR->dmodule || DtoIsTemplateInstance(cd)) {
-        // interfaces don't have initializers
+
+        // interfaces don't have static initializer/vtable
         // neither do abstract classes
         if (!cd->isInterfaceDeclaration() && !cd->isAbstract())
         {
@@ -718,19 +718,30 @@
 
             // initialize interface vtables
             IrStruct* irstruct = cd->ir.irStruct;
-            std::vector<llvm::Constant*> infoInits;
             for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
             {
                 IrInterface* iri = *i;
                 iri->vtbl->setInitializer(iri->vtblInit);
-                infoInits.push_back(iri->infoInit);
             }
-            // initialize interface info array
-            if (!infoInits.empty())
-            {
-                llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits);
-                irstruct->interfaceInfos->setInitializer(arrInit);
-            }
+        }
+
+        // always do interface info array when possible
+        IrStruct* irstruct = cd->ir.irStruct;
+        std::vector<llvm::Constant*> infoInits;
+        for (IrStruct::InterfaceVectorIter i=irstruct->interfaceVec.begin(); i!=irstruct->interfaceVec.end(); ++i)
+        {
+            IrInterface* iri = *i;
+            infoInits.push_back(iri->infoInit);
+        }
+        // set initializer
+        if (!infoInits.empty())
+        {
+            llvm::Constant* arrInit = llvm::ConstantArray::get(irstruct->interfaceInfosTy, infoInits);
+            irstruct->interfaceInfos->setInitializer(arrInit);
+        }
+        else
+        {
+            assert(irstruct->interfaceInfos == NULL);
         }
 
         // generate classinfo
--- a/gen/toir.cpp	Wed May 07 00:58:36 2008 +0200
+++ b/gen/toir.cpp	Wed May 07 04:45:51 2008 +0200
@@ -1841,7 +1841,7 @@
     else if (t->ty == Tdelegate)
     {
         Logger::println("delegate");
-        eval = DtoCompareDelegate(op,l->getRVal(),r->getRVal());
+        eval = DtoDelegateCompare(op,l->getRVal(),r->getRVal());
     }
     else
     {
@@ -2333,7 +2333,7 @@
         else {
             assert(l->getType() == r->getType());
         }
-        eval = DtoDynArrayIs(op,l,r);
+        eval = DtoDelegateCompare(op,l,r);
     }
     else if (t1->isfloating())
     {
--- a/gen/tollvm.cpp	Wed May 07 00:58:36 2008 +0200
+++ b/gen/tollvm.cpp	Wed May 07 04:45:51 2008 +0200
@@ -278,7 +278,7 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::Value* DtoNullDelegate(llvm::Value* v)
+llvm::Value* DtoDelegateToNull(llvm::Value* v)
 {
     assert(gIR);
     d_uns64 n = (global.params.is64bit) ? 16 : 8;
@@ -327,17 +327,31 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
-llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs)
+llvm::Value* DtoDelegateCompare(TOK op, llvm::Value* lhs, llvm::Value* rhs)
 {
-    llvm::ICmpInst::Predicate pred = (op == TOKequal) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
-    llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp");
-    llvm::Value* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp");
-    llvm::Value* b1 = gIR->ir->CreateICmp(pred,l,r,"tmp");
-    l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp");
-    r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp");
-    llvm::Value* b2 = gIR->ir->CreateICmp(pred,l,r,"tmp");
+    Logger::println("Doing delegate compare");
+    llvm::ICmpInst::Predicate pred = (op == TOKequal || op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE;
+    llvm::Value *b1, *b2;
+    if (rhs == NULL)
+    {
+        llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp");
+        llvm::Value* r = llvm::Constant::getNullValue(l->getType());
+        b1 = gIR->ir->CreateICmp(pred,l,r,"tmp");
+        l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp");
+        r = llvm::Constant::getNullValue(l->getType());
+        b2 = gIR->ir->CreateICmp(pred,l,r,"tmp");
+    }
+    else
+    {
+        llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp");
+        llvm::Value* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp");
+        b1 = gIR->ir->CreateICmp(pred,l,r,"tmp");
+        l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp");
+        r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp");
+        b2 = gIR->ir->CreateICmp(pred,l,r,"tmp");
+    }
     llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp");
-    if (op == TOKnotequal)
+    if (op == TOKnotequal || op == TOKnotidentity)
         return gIR->ir->CreateNot(b,"tmp");
     return b;
 }
@@ -949,7 +963,7 @@
     }
     else if (t->ty == Tdelegate) {
         if (rhs->isNull())
-            DtoNullDelegate(lhs->getLVal());
+            DtoDelegateToNull(lhs->getLVal());
         else if (!rhs->inPlace()) {
             llvm::Value* l = lhs->getLVal();
             llvm::Value* r = rhs->getRVal();
--- a/gen/tollvm.h	Wed May 07 00:58:36 2008 +0200
+++ b/gen/tollvm.h	Wed May 07 04:45:51 2008 +0200
@@ -17,9 +17,9 @@
 
 // delegate helpers
 const llvm::StructType* DtoDelegateType(Type* t);
-llvm::Value* DtoNullDelegate(llvm::Value* v);
+llvm::Value* DtoDelegateToNull(llvm::Value* v);
 llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src);
-llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs);
+llvm::Value* DtoDelegateCompare(TOK op, llvm::Value* lhs, llvm::Value* rhs);
 
 // return linkage type for symbol using the current ir state for context
 llvm::GlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym);
--- a/ir/irsymbol.cpp	Wed May 07 00:58:36 2008 +0200
+++ b/ir/irsymbol.cpp	Wed May 07 04:45:51 2008 +0200
@@ -3,10 +3,13 @@
 #include "ir/irsymbol.h"
 #include "ir/irvar.h"
 
+#include "gen/logger.h"
+
 std::set<IrDsymbol*> IrDsymbol::list;
 
 void IrDsymbol::resetAll()
 {
+    Logger::println("resetting %u Dsymbols", list.size());
     std::set<IrDsymbol*>::iterator it;
     for(it = list.begin(); it != list.end(); ++it)
         (*it)->reset();
--- a/llvmdc.kdevelop.filelist	Wed May 07 00:58:36 2008 +0200
+++ b/llvmdc.kdevelop.filelist	Wed May 07 04:45:51 2008 +0200
@@ -121,6 +121,7 @@
 gen/logger.cpp
 gen/logger.h
 gen/optimizer.cpp
+gen/pairtype.h
 gen/runtime.cpp
 gen/runtime.h
 gen/statements.cpp
@@ -748,17 +749,13 @@
 tangotests
 tangotests/a.d
 tangotests/aa1.d
-tangotests/abc.d
-tangotests/abcd.d
 tangotests/b.d
 tangotests/c.d
 tangotests/classes1.d
 tangotests/constructors.d
-tangotests/d.d
 tangotests/e.d
 tangotests/f.d
 tangotests/files1.d
-tangotests/g.d
 tangotests/h.d
 tangotests/i.d
 tangotests/j.d
@@ -767,8 +764,6 @@
 tangotests/m.d
 tangotests/n.d
 tangotests/o.d
-tangotests/p.d
-tangotests/q.d
 tangotests/r.d
 tangotests/s.d
 tangotests/stdout1.d