diff gen/toir.cpp @ 1136:9d308feaec27

Fix #239.
author Christian Kamm <kamm incasoftware de>
date Tue, 24 Mar 2009 14:33:57 +0100
parents b30fe7e1dbb9
children f99a3b393c03
line wrap: on
line diff
--- a/gen/toir.cpp	Mon Mar 23 14:47:51 2009 +0100
+++ b/gen/toir.cpp	Tue Mar 24 14:33:57 2009 +0100
@@ -1104,14 +1104,32 @@
         LLValue* vthis = l->getRVal();
         if (!vthis2) vthis2 = vthis;
 
-        // super call
-        if (e1->op == TOKsuper) {
+        //
+        // decide whether this function needs to be looked up in the vtable
+        //
+        bool vtbllookup = fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual());
+        
+        // even virtual functions are looked up directly if super or DotTypeExp
+        // are used, thus we need to walk through the this expression and check
+        Expression* e = e1;
+        while (e && vtbllookup) {
+            if (e->op == TOKsuper || e->op == TOKdottype)
+                vtbllookup = false;
+            else if (e->op == TOKcast)
+                e = ((CastExp*)e)->e1;
+            else
+                break;
+        }
+        
+        //
+        // look up function
+        //
+        if (!vtbllookup) {
             DtoForceDeclareDsymbol(fdecl);
             funcval = fdecl->ir.irFunc->func;
             assert(funcval);
         }
-        // normal virtual call
-        else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) {
+        else {
             assert(fdecl->vtblIndex > 0);
             assert(e1type->ty == Tclass);
 
@@ -1131,12 +1149,7 @@
             if (Logger::enabled())
                 Logger::cout() << "funcval casted: " << *funcval << '\n';
         }
-        // static call
-        else {
-            DtoForceDeclareDsymbol(fdecl);
-            funcval = fdecl->ir.irFunc->func;
-            assert(funcval);
-        }
+
         return new DFuncValue(fdecl, funcval, vthis2);
     }
     else {