diff gen/toir.cpp @ 113:27b9f749d9fe trunk

[svn r117] Initial working implementation of interfaces. Groundwork for all the different types of class/interface casts laid out.
author lindquist
date Sat, 24 Nov 2007 06:33:00 +0100
parents 5ab8e92611f9
children 5880c12dba83
line wrap: on
line diff
--- a/gen/toir.cpp	Thu Nov 22 22:30:10 2007 +0100
+++ b/gen/toir.cpp	Sat Nov 24 06:33:00 2007 +0100
@@ -1230,10 +1230,10 @@
 
     if (p->topexp() && p->topexp()->e1 == this) {
         Logger::println("lval PtrExp");
-        //if (a->isField()) return a;
         return new DVarValue(type, a->getRVal(), true);
     }
 
+    // this should be deterministic but right now lvalue casts don't propagate lvalueness !?!
     llvm::Value* lv = a->getRVal();
     llvm::Value* v = lv;
     if (DtoCanLoad(v))
@@ -1253,7 +1253,7 @@
     Type* t = DtoDType(type);
     Type* e1type = DtoDType(e1->type);
 
-    Logger::print("e1->type=%s\n", e1type->toChars());
+    Logger::print("e1type=%s\n", e1type->toChars());
 
     if (VarDeclaration* vd = var->isVarDeclaration()) {
         llvm::Value* arrptr;
@@ -1265,7 +1265,7 @@
             std::vector<unsigned> vdoffsets;
             arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets);
         }
-        else if (e1->type->ty == Tclass) {
+        else if (e1type->ty == Tclass) {
             TypeClass* tc = (TypeClass*)e1type;
             Logger::println("Class member offset: %d", vd->offset);
             std::vector<unsigned> vdoffsets(1,0);
@@ -1282,14 +1282,19 @@
     }
     else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
     {
-        if (fdecl->llvmValue == 0)
-        {
-            DtoForceDeclareDsymbol(fdecl);
+        DtoResolveDsymbol(fdecl);
+
+        llvm::Value* funcval;
+        llvm::Value* vthis2 = 0;
+        if (e1type->ty == Tclass) {
+            TypeClass* tc = (TypeClass*)e1type;
+            if (tc->sym->isInterfaceDeclaration()) {
+                vthis2 = DtoCastInterfaceToObject(l)->getRVal();
+            }
         }
-
-        llvm::Value* funcval = fdecl->llvmValue;
         llvm::Value* vthis = l->getRVal();
-        unsigned cc = (unsigned)-1;
+        if (!vthis2) vthis2 = vthis;
+        //unsigned cc = (unsigned)-1;
 
         // virtual call
         if (!fdecl->isFinal() && fdecl->isVirtual()) {
@@ -1303,10 +1308,17 @@
             funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
             funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb());
             funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
-            assert(funcval->getType() == fdecl->llvmValue->getType());
-            cc = DtoCallingConv(fdecl->linkage);
+            //assert(funcval->getType() == DtoType(fdecl->type));
+            //cc = DtoCallingConv(fdecl->linkage);
         }
-        return new DFuncValue(fdecl, funcval, vthis);
+        // static call
+        else {
+            DtoForceDeclareDsymbol(fdecl);
+            funcval = fdecl->llvmValue;
+            assert(funcval);
+            //assert(funcval->getType() == DtoType(fdecl->type));
+        }
+        return new DFuncValue(fdecl, funcval, vthis2);
     }
     else {
         printf("unknown: %s\n", var->toChars());
@@ -1829,15 +1841,14 @@
     //assert(e1->type->ty != Tclass);
 
     DValue* v = e1->toElem(p);
-    llvm::Value* val = v->getRVal();
+    const llvm::Type* t = DtoType(v->getType());
     llvm::Value* ldval = 0;
-
-    const llvm::Type* t = val->getType();
     llvm::Constant* z = llvm::Constant::getNullValue(t);
 
     Type* e1type = DtoDType(e1->type);
 
     if (e1type->ty == Tpointer) {
+        llvm::Value* val = v->getRVal();
         Logger::cout() << *z << '\n';
         Logger::cout() << *val << '\n';
         new llvm::FreeInst(val, p->scopebb());
@@ -1845,16 +1856,23 @@
     }
     else if (e1type->ty == Tclass) {
         TypeClass* tc = (TypeClass*)e1type;
-        DtoCallClassDtors(tc, val);
+        llvm::Value* val = 0;
+        if (tc->sym->dtors.dim > 0) {
+            val = v->getRVal();
+            DtoCallClassDtors(tc, val);
+        }
 
         if (DVarValue* vv = v->isVar()) {
-            if (vv->var && !vv->var->onstack)
+            if (vv->var && !vv->var->onstack) {
+                if (!val) val = v->getRVal();
                 new llvm::FreeInst(val, p->scopebb());
+            }
         }
         new llvm::StoreInst(z, v->getLVal(), p->scopebb());
     }
     else if (e1type->ty == Tarray) {
         // must be on the heap (correct?)
+        llvm::Value* val = v->getRVal();
         llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
         llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
         llvm::Value* ptr = DtoGEP(val,zero,one,"tmp",p->scopebb());