[cfe-commits] r95985 - /cfe/trunk/lib/CodeGen/CGVtable.cpp

Anders Carlsson andersca at mac.com
Fri Feb 12 09:13:24 PST 2010


Author: andersca
Date: Fri Feb 12 11:13:23 2010
New Revision: 95985

URL: http://llvm.org/viewvc/llvm-project?rev=95985&view=rev
Log:
Keep track of whether a final overrider needs a return type adjustment.

Modified:
    cfe/trunk/lib/CodeGen/CGVtable.cpp

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=95985&r1=95984&r2=95985&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Fri Feb 12 11:13:23 2010
@@ -125,7 +125,11 @@
     /// Method - The method decl of the overrider.
     const CXXMethodDecl *Method;
     
-    OverriderInfo() : Method(0) { }
+    /// NeedsReturnAdjustment - Whether this overrider needs to adjust its
+    /// return type.
+    bool NeedsReturnAdjustment;
+    
+    OverriderInfo() : Method(0), NeedsReturnAdjustment(false) { }
   };
 
 private:
@@ -273,9 +277,23 @@
                                        OverriddenMD)];
       assert(Overrider.Method && "Did not find existing overrider!");
 
-      assert(!ReturnTypeConversionRequiresAdjustment(Context, NewMD, 
-                                                     OverriddenMD) &&
-             "FIXME: Covariant return types not handled yet!");
+      /// We only need to do the return type check if the overrider doesn't
+      /// already need a return adjustment. Consider:
+      ///
+      /// struct A { virtual V1 *f(); }
+      /// struct B : A { virtual V2 *f(); }
+      /// struct C : B { virtual V2 *f(); }
+      ///
+      /// If we assume that that V2->V1 needs an adjustment, then when we
+      /// know that since A::f -> B::f needs an adjustment, then all classes
+      /// that eventually override B::f (and by transitivity A::f) are going to
+      /// need to have their return types adjusted.
+      if (!Overrider.NeedsReturnAdjustment) {
+        Overrider.NeedsReturnAdjustment = 
+          ReturnTypeConversionRequiresAdjustment(Context, NewMD, 
+                                                 OverriddenMD);
+      }
+
       // Set the new overrider.
       Overrider.Method = NewMD;
       
@@ -369,7 +387,10 @@
     OverriderInfo Overrider = getOverrider(Base, MD);
 
     Out << "  " << MD->getQualifiedNameAsString() << " - ";
-    Out << Overrider.Method->getQualifiedNameAsString() << "\n";
+    Out << Overrider.Method->getQualifiedNameAsString();
+    if (Overrider.NeedsReturnAdjustment)
+      Out << " [ret-adj]";
+    Out << "\n";
   }  
 }
 





More information about the cfe-commits mailing list