]> granicus.if.org Git - clang/commitdiff
Refine handling for non-virtual bases in return value adjustments for
authorMike Stump <mrs@apple.com>
Tue, 13 Oct 2009 22:54:56 +0000 (22:54 +0000)
committerMike Stump <mrs@apple.com>
Tue, 13 Oct 2009 22:54:56 +0000 (22:54 +0000)
covariant thunks.  WIP.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84046 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGVtable.cpp
lib/CodeGen/CGVtable.h

index f3612a39d35f9118b7ed62f8c7c2b099957e93a1..41f7eefbe82be5acbac91d77fc540c58c43adcda 100644 (file)
@@ -83,22 +83,30 @@ public:
 
   void GenerateVBaseOffsets(std::vector<llvm::Constant *> &offsets,
                             const CXXRecordDecl *RD, uint64_t Offset,
-                            bool updateVBIndex) {
+                            bool updateVBIndex, Index_t current_vbindex) {
     for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
            e = RD->bases_end(); i != e; ++i) {
       const CXXRecordDecl *Base =
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+      Index_t next_vbindex = current_vbindex;
       if (i->isVirtual() && !SeenVBase.count(Base)) {
         SeenVBase.insert(Base);
         int64_t BaseOffset = -(Offset/8) + BLayout.getVBaseClassOffset(Base)/8;
         llvm::Constant *m = wrap(BaseOffset);
         m = wrap((0?700:0) + BaseOffset);
-        if (updateVBIndex)
-          VBIndex[Base] = (ssize_t)(-(offsets.size()*LLVMPointerWidth/8)
-                                    - 3*LLVMPointerWidth/8);
+        if (updateVBIndex) {
+          next_vbindex = (ssize_t)(-(offsets.size()*LLVMPointerWidth/8)
+                                   - 3*LLVMPointerWidth/8);
+          VBIndex[Base] = next_vbindex;
+        }
         offsets.push_back(m);
       }
-      GenerateVBaseOffsets(offsets, Base, Offset, updateVBIndex);
+      // We also record offsets for non-virtual bases to closest enclosing
+      // virtual base.  We do this so that we don't have to search
+      // for the nearst virtual base class when generating thunks.
+      if (updateVBIndex && VBIndex.count(Base) == 0)
+        VBIndex[Base] = next_vbindex;
+      GenerateVBaseOffsets(offsets, Base, Offset, updateVBIndex, next_vbindex);
     }
   }
 
@@ -122,7 +130,7 @@ public:
     if (i != VBIndex.end())
       return i->second;
 
-    assert(false && "FIXME: Locate the containing virtual base first");
+    assert(false && "FIXME: Base not found");
     return 0;
   }
 
@@ -188,13 +196,19 @@ public:
             Thunks[MD] = ThisOffset;
           return true;
         }
-#if 0
+
         // FIXME: finish off
         int64_t O = VCallOffset[OMD] - Offset/8;
-        if (O) {
-          Thunks[MD] = std::make_pair(O, 0);
+        if (O || ReturnOffset.first || ReturnOffset.second) {
+          CallOffset ThisOffset = std::make_pair(O, 0);
+          
+          if (ReturnOffset.first || ReturnOffset.second)
+            CovariantThunks[MD] = std::make_pair(std::make_pair(ThisOffset,
+                                                                ReturnOffset),
+                                                 oret);
+          else
+            Thunks[MD] = ThisOffset;
         }
-#endif
         return true;
       }
     }
@@ -394,7 +408,7 @@ public:
 
     std::vector<llvm::Constant *> offsets;
     extra = 0;
-    GenerateVBaseOffsets(offsets, RD, Offset, !ForVirtualBase);
+    GenerateVBaseOffsets(offsets, RD, Offset, !ForVirtualBase, 0);
     if (ForVirtualBase)
       extra = offsets.size();
 
index 6adc6e63b082a5eb1ce41b24f7d123bb79f3e086..69fb1f1005996e25ed8697c216fa8e3d6d9d6705 100644 (file)
@@ -47,9 +47,11 @@ public:
   /// stored.
   int64_t getMethodVtableIndex(const CXXMethodDecl *MD);
   
-  /// getVirtualBaseOffsetIndex - Return the index (relative to the vtable address 
-  /// point) where the offset of the  given virtual base of the given class is 
-  // stored.
+  /// getVirtualBaseOffsetIndex - Return the index (relative to the vtable
+  /// address point) where the offset of the virtual base that contains the
+  /// given Base is stored, otherwise, if no virtual base contains the given
+  /// class, return 0.  Base must be a virtual base class or an unambigious
+  /// base.
   int64_t getVirtualBaseOffsetIndex(const CXXRecordDecl *RD, 
                                     const CXXRecordDecl *VBase);
 };