]> granicus.if.org Git - clang/commitdiff
Change CodeGenFunction::GetAddressOfDerivedClass to take a BasePath.
authorAnders Carlsson <andersca@mac.com>
Sat, 24 Apr 2010 21:23:59 +0000 (21:23 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 24 Apr 2010 21:23:59 +0000 (21:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102273 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGClass.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/CodeGenModule.h

index b8f7df927ce641248ba602c071ce2cc5e9d23ace..6dea9f77ae984a8fd78b2f94ce692144848b6671 100644 (file)
@@ -73,6 +73,23 @@ ComputeNonVirtualBaseClassOffset(ASTContext &Context,
   return Offset;
 }
 
+llvm::Constant *
+CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
+                                        const CXXBaseSpecifierArray &BasePath) {
+  assert(!BasePath.empty() && "Base path should not be empty!");
+
+  uint64_t Offset = 
+    ComputeNonVirtualBaseClassOffset(getContext(), ClassDecl, 
+                                     BasePath.begin(), BasePath.end());
+  if (!Offset)
+    return 0;
+  
+  const llvm::Type *PtrDiffTy = 
+  Types.ConvertType(getContext().getPointerDiffType());
+  
+  return llvm::ConstantInt::get(PtrDiffTy, Offset);
+}  
+
 llvm::Constant *
 CodeGenModule::GetNonVirtualBaseClassOffset(const CXXRecordDecl *Class,
                                             const CXXRecordDecl *BaseClass) {
@@ -336,21 +353,18 @@ CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
 
 llvm::Value *
 CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
-                                          const CXXRecordDecl *Class,
                                           const CXXRecordDecl *DerivedClass,
+                                          const CXXBaseSpecifierArray &BasePath,
                                           bool NullCheckValue) {
+  assert(!BasePath.empty() && "Base path should not be empty!");
+
   QualType DerivedTy =
     getContext().getCanonicalType(
     getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(DerivedClass)));
   const llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
   
-  if (Class == DerivedClass) {
-    // Just cast back.
-    return Builder.CreateBitCast(Value, DerivedPtrTy);
-  }
-
   llvm::Value *NonVirtualOffset =
-    CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class);
+    CGM.GetNonVirtualBaseClassOffset(DerivedClass, BasePath);
   
   if (!NonVirtualOffset) {
     // No offset, we can just cast back.
index 62b5a3dbee675b1b106ff11847eeec6c384a0253..5c9374dd2958475f0e51292e077ab677bfe4ab29 100644 (file)
@@ -1693,11 +1693,6 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
   case CastExpr::CK_ToUnion:
     return EmitAggExprToLValue(E);
   case CastExpr::CK_BaseToDerived: {
-    const RecordType *BaseClassTy = 
-      E->getSubExpr()->getType()->getAs<RecordType>();
-    CXXRecordDecl *BaseClassDecl = 
-      cast<CXXRecordDecl>(BaseClassTy->getDecl());
-    
     const RecordType *DerivedClassTy = E->getType()->getAs<RecordType>();
     CXXRecordDecl *DerivedClassDecl = 
       cast<CXXRecordDecl>(DerivedClassTy->getDecl());
@@ -1706,8 +1701,8 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
     
     // Perform the base-to-derived conversion
     llvm::Value *Derived = 
-      GetAddressOfDerivedClass(LV.getAddress(), BaseClassDecl, 
-                               DerivedClassDecl, /*NullCheckValue=*/false);
+      GetAddressOfDerivedClass(LV.getAddress(), DerivedClassDecl, 
+                               E->getBasePath(),/*NullCheckValue=*/false);
     
     return LValue::MakeAddr(Derived, MakeQualifiers(E->getType()));
   }
index f38126b8e7a8b2c62c7a1fa50e4d2b07a712d822..ad072c6d01b51e152576ca6dd5866d2578e6fb24 100644 (file)
@@ -822,16 +822,12 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
     return Visit(const_cast<Expr*>(E));
 
   case CastExpr::CK_BaseToDerived: {
-    const CXXRecordDecl *BaseClassDecl = 
-      E->getType()->getCXXRecordDeclForPointerType();
     const CXXRecordDecl *DerivedClassDecl = 
       DestTy->getCXXRecordDeclForPointerType();
     
-    Value *Src = Visit(const_cast<Expr*>(E));
-    
-    bool NullCheckValue = ShouldNullCheckClassCastValue(CE);
-    return CGF.GetAddressOfDerivedClass(Src, BaseClassDecl, DerivedClassDecl, 
-                                        NullCheckValue);
+    return CGF.GetAddressOfDerivedClass(Visit(E), DerivedClassDecl, 
+                                        CE->getBasePath(), 
+                                        ShouldNullCheckClassCastValue(CE));
   }
   case CastExpr::CK_UncheckedDerivedToBase:
   case CastExpr::CK_DerivedToBase: {
index 0707ada38c53fbd7511b5e58f2bfd641ce148404..c0786b8c3ebd3ce9229ed41937166d609a00094d 100644 (file)
@@ -793,8 +793,8 @@ public:
                                      bool NullCheckValue);
 
   llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value,
-                                        const CXXRecordDecl *ClassDecl,
                                         const CXXRecordDecl *DerivedClassDecl,
+                                        const CXXBaseSpecifierArray &BasePath,
                                         bool NullCheckValue);
 
   llvm::Value *GetVirtualBaseClassOffset(llvm::Value *This,
index 238b36d3d2c3cac149f0982c854875938af5160f..c324d61a5d782cee681aeb05b9a5c27fee5050bf 100644 (file)
@@ -245,7 +245,10 @@ public:
   llvm::Constant *
   GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
                                const CXXRecordDecl *BaseClassDecl);
-
+  llvm::Constant *
+  GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
+                               const CXXBaseSpecifierArray &BasePath);
+  
   /// GetStringForStringLiteral - Return the appropriate bytes for a string
   /// literal, properly padded to match the literal type. If only the address of
   /// a constant is needed consider using GetAddrOfConstantStringLiteral.