[cfe-commits] r102270 - in /cfe/trunk/lib/CodeGen: CGClass.cpp CGExprScalar.cpp CodeGenFunction.h

Anders Carlsson andersca at mac.com
Sat Apr 24 14:06:20 PDT 2010


Author: andersca
Date: Sat Apr 24 16:06:20 2010
New Revision: 102270

URL: http://llvm.org/viewvc/llvm-project?rev=102270&view=rev
Log:
Add a new GetAddressOfBaseClass overload that takes a base path and. Use it for derived-to-base casts.

Modified:
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=102270&r1=102269&r2=102270&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Sat Apr 24 16:06:20 2010
@@ -20,6 +20,35 @@
 using namespace CodeGen;
 
 static uint64_t 
+ComputeNonVirtualBaseClassOffset(ASTContext &Context, 
+                                 const CXXRecordDecl *DerivedClass,
+                                 CXXBaseSpecifierArray::iterator Start,
+                                 CXXBaseSpecifierArray::iterator End) {
+  uint64_t Offset = 0;
+  
+  const CXXRecordDecl *RD = DerivedClass;
+  
+  for (CXXBaseSpecifierArray::iterator I = Start; I != End; ++I) {
+    const CXXBaseSpecifier *Base = *I;
+    assert(!Base->isVirtual() && "Should not see virtual bases here!");
+
+    // Get the layout.
+    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
+    
+    const CXXRecordDecl *BaseDecl = 
+      cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+    
+    // Add the offset.
+    Offset += Layout.getBaseClassOffset(BaseDecl);
+    
+    RD = BaseDecl;
+  }
+  
+  // FIXME: We should not use / 8 here.
+  return Offset / 8;
+}
+                                 
+static uint64_t 
 ComputeNonVirtualBaseClassOffset(ASTContext &Context,
                                  const CXXBasePath &Path,
                                  unsigned Start) {
@@ -133,6 +162,81 @@
 }
 
 llvm::Value *
+CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value, 
+                                       const CXXRecordDecl *ClassDecl,
+                                       const CXXBaseSpecifierArray &BasePath, 
+                                       bool NullCheckValue) {
+  assert(!BasePath.empty() && "Base path should not be empty!");
+
+  CXXBaseSpecifierArray::iterator Start = BasePath.begin();
+  const CXXRecordDecl *VBase = 0;
+  
+  // Get the virtual base.
+  if ((*Start)->isVirtual()) {
+    VBase = 
+      cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl());
+    ++Start;
+  }
+  
+  uint64_t NonVirtualOffset = 
+    ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : ClassDecl,
+                                     Start, BasePath.end());
+
+  // Get the base pointer type.
+  const llvm::Type *BasePtrTy = 
+    llvm::PointerType::getUnqual(ConvertType((BasePath.end()[-1])->getType()));
+  
+  if (!NonVirtualOffset && !VBase) {
+    // Just cast back.
+    return Builder.CreateBitCast(Value, BasePtrTy);
+  }    
+  
+  llvm::BasicBlock *CastNull = 0;
+  llvm::BasicBlock *CastNotNull = 0;
+  llvm::BasicBlock *CastEnd = 0;
+  
+  if (NullCheckValue) {
+    CastNull = createBasicBlock("cast.null");
+    CastNotNull = createBasicBlock("cast.notnull");
+    CastEnd = createBasicBlock("cast.end");
+    
+    llvm::Value *IsNull = 
+      Builder.CreateICmpEQ(Value,
+                           llvm::Constant::getNullValue(Value->getType()));
+    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
+    EmitBlock(CastNotNull);
+  }
+
+  llvm::Value *VirtualOffset = 0;
+
+  if (VBase)
+    VirtualOffset = GetVirtualBaseClassOffset(Value, ClassDecl, VBase);
+
+  // Apply the offsets.
+  Value = ApplyNonVirtualAndVirtualOffset(*this, Value, NonVirtualOffset, 
+                                          VirtualOffset);
+  
+  // Cast back.
+  Value = Builder.CreateBitCast(Value, BasePtrTy);
+ 
+  if (NullCheckValue) {
+    Builder.CreateBr(CastEnd);
+    EmitBlock(CastNull);
+    Builder.CreateBr(CastEnd);
+    EmitBlock(CastEnd);
+    
+    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType());
+    PHI->reserveOperandSpace(2);
+    PHI->addIncoming(Value, CastNotNull);
+    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 
+                     CastNull);
+    Value = PHI;
+  }
+  
+  return Value;
+}
+
+llvm::Value *
 CodeGenFunction::GetAddressOfBaseClass(llvm::Value *Value,
                                        const CXXRecordDecl *Class,
                                        const CXXRecordDecl *BaseClass,

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=102270&r1=102269&r2=102270&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sat Apr 24 16:06:20 2010
@@ -840,15 +840,9 @@
     CXXRecordDecl *DerivedClassDecl = 
       cast<CXXRecordDecl>(DerivedClassTy->getDecl());
 
-    const RecordType *BaseClassTy = 
-      DestTy->getAs<PointerType>()->getPointeeType()->getAs<RecordType>();
-    CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseClassTy->getDecl());
-    
-    Value *Src = Visit(const_cast<Expr*>(E));
-
-    bool NullCheckValue = ShouldNullCheckClassCastValue(CE);
-    return CGF.GetAddressOfBaseClass(Src, DerivedClassDecl, BaseClassDecl,
-                                     NullCheckValue);
+    return CGF.GetAddressOfBaseClass(Visit(E), DerivedClassDecl, 
+                                     CE->getBasePath(),
+                                     ShouldNullCheckClassCastValue(CE));
   }
   case CastExpr::CK_Dynamic: {
     Value *V = Visit(const_cast<Expr*>(E));

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=102270&r1=102269&r2=102270&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Sat Apr 24 16:06:20 2010
@@ -787,7 +787,11 @@
                                      const CXXRecordDecl *ClassDecl,
                                      const CXXRecordDecl *BaseClassDecl,
                                      bool NullCheckValue);
-  
+  llvm::Value *GetAddressOfBaseClass(llvm::Value *Value, 
+                                     const CXXRecordDecl *ClassDecl,
+                                     const CXXBaseSpecifierArray &BasePath, 
+                                     bool NullCheckValue);
+
   llvm::Value *GetAddressOfDerivedClass(llvm::Value *Value,
                                         const CXXRecordDecl *ClassDecl,
                                         const CXXRecordDecl *DerivedClassDecl,





More information about the cfe-commits mailing list