]> granicus.if.org Git - clang/commitdiff
Factor vtable pointer setting code out into a separate function.
authorAnders Carlsson <andersca@mac.com>
Sun, 28 Mar 2010 19:40:00 +0000 (19:40 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 28 Mar 2010 19:40:00 +0000 (19:40 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99773 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGClass.cpp
lib/CodeGen/CodeGenFunction.h

index 8a084926e76a5df0e07b6a7d4ca8b47205b4942e..2fa583728953f3e6079e59d890da2d8fa4b87485 100644 (file)
@@ -139,7 +139,7 @@ CodeGenFunction::GetAddressOfBaseOfCompleteClass(llvm::Value *This,
   V = Builder.CreateBitCast(V, ConvertType(Base)->getPointerTo());
 
   return V;
-}                                      
+}
 
 llvm::Value *
 CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
@@ -1556,6 +1556,34 @@ CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,
   return VBaseOffset;
 }
 
+void
+CodeGenFunction::InitializeVTablePointer(BaseSubobject Base, 
+                                         bool BaseIsMorallyVirtual,
+                                         llvm::Constant *VTable,
+                                         const CXXRecordDecl *VTableClass) {
+  
+  // Compute the address point.
+  const CodeGenVTables::AddrSubMap_t& AddressPoints =
+    CGM.getVTables().getAddressPoints(VTableClass);
+  
+  uint64_t AddressPoint = 
+    AddressPoints.lookup(std::make_pair(Base.getBase(), Base.getBaseOffset()));
+  llvm::Value *VTableAddressPoint =
+      Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);
+
+  // Compute where to store the address point.
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
+  llvm::Value *VTableField = Builder.CreateBitCast(LoadCXXThis(), Int8PtrTy);
+  VTableField = 
+    Builder.CreateConstInBoundsGEP1_64(VTableField, Base.getBaseOffset() / 8);  
+  
+  // Finally, store the address point.
+  const llvm::Type *AddressPointPtrTy =
+    VTableAddressPoint->getType()->getPointerTo();
+  VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy);
+  Builder.CreateStore(VTableAddressPoint, VTableField);
+}
+
 void CodeGenFunction::InitializeVtablePtrs(const CXXRecordDecl *RD) {
   if (!RD->isDynamicClass())
     return;
@@ -1607,25 +1635,8 @@ void CodeGenFunction::InitializeVtablePtrs(BaseSubobject Base,
     InitializeVtablePtrs(BaseSubobject(BaseDecl, BaseOffset), 
                          VTable, VTableClass);
   }
-  
-  // Compute the address point.
-  const CodeGenVTables::AddrSubMap_t& AddressPoints =
-    CGM.getVTables().getAddressPoints(VTableClass);
-  
-  uint64_t AddressPoint = 
-    AddressPoints.lookup(std::make_pair(Base.getBase(), Base.getBaseOffset()));
-  llvm::Value *VTableAddressPoint =
-      Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);
 
-  // Compute where to store the address point.
-  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
-  llvm::Value *VTableField = Builder.CreateBitCast(LoadCXXThis(), Int8PtrTy);
-  VTableField = 
-    Builder.CreateConstInBoundsGEP1_64(VTableField, Base.getBaseOffset() / 8);  
-  
-  // Finally, store the address point.
-  const llvm::Type *AddressPointPtrTy =
-    VTableAddressPoint->getType()->getPointerTo();
-  VTableField = Builder.CreateBitCast(VTableField, AddressPointPtrTy);
-  Builder.CreateStore(VTableAddressPoint, VTableField);
+  // FIXME: BaseIsMorallyVirtual is not correct here.
+  InitializeVTablePointer(Base, /*BaseIsMorallyVirtual=*/false, VTable, 
+                          VTableClass);
 }
index 4ecb03dca05d920a558ddb639b5dfe8a2c6a673a..3d7165b0a977c6a56700553280211f4469d7ace9 100644 (file)
@@ -509,11 +509,23 @@ public:
   
   void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type);
 
-  void InitializeVtablePtrs(const CXXRecordDecl *ClassDecl);
+  /// InitializeVTablePointer - Initialize the vtable pointer of the given
+  /// subobject.
+  ///
+  /// \param BaseIsMorallyVirtual - Whether the base subobject is a virtual base
+  /// or a direct or indirect base of a virtual base.
+  void InitializeVTablePointer(BaseSubobject Base, bool BaseIsMorallyVirtual,
+                               llvm::Constant *VTable,
+                               const CXXRecordDecl *VTableClass);
+
+  typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;
 
   void InitializeVtablePtrs(BaseSubobject Base, llvm::Constant *VTable,
                             const CXXRecordDecl *VTableClass);
 
+  void InitializeVtablePtrs(const CXXRecordDecl *ClassDecl);
+
+
   void SynthesizeCXXCopyConstructor(const FunctionArgList &Args);
   void SynthesizeCXXCopyAssignment(const FunctionArgList &Args);