diff gen/toir.cpp @ 1137:45d73f0a9b43

Automated merge with http://hg.dsource.org/projects/ldc
author Christian Kamm <kamm incasoftware de>
date Tue, 24 Mar 2009 14:34:16 +0100
parents 9d308feaec27
children f99a3b393c03
line wrap: on
line diff
--- a/gen/toir.cpp	Tue Mar 24 03:14:22 2009 +0100
+++ b/gen/toir.cpp	Tue Mar 24 14:34:16 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 {