[cfe-commits] r111771 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CGCXXABI.h CGExprAgg.cpp CGExprCXX.cpp CGExprConstant.cpp CodeGenFunction.cpp ItaniumCXXABI.cpp

John McCall rjmccall at apple.com
Sat Aug 21 21:16:25 PDT 2010


Author: rjmccall
Date: Sat Aug 21 23:16:24 2010
New Revision: 111771

URL: http://llvm.org/viewvc/llvm-project?rev=111771&view=rev
Log:
Abstract more member-pointerness out.


Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGCXXABI.h
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=111771&r1=111770&r2=111771&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sat Aug 21 23:16:24 2010
@@ -385,10 +385,36 @@
   return llvm::Constant::getNullValue(FTy->getPointerTo());
 }
 
-void CGCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
-                                           const CastExpr *E,
-                                           llvm::Value *Src,
-                                           llvm::Value *Dest,
-                                           bool VolatileDest) {
-  ErrorUnsupportedABI(CGF, "member pointer conversions");
+void CGCXXABI::EmitMemberFunctionPointerConversion(CodeGenFunction &CGF,
+                                                   const CastExpr *E,
+                                                   llvm::Value *Src,
+                                                   llvm::Value *Dest,
+                                                   bool VolatileDest) {
+  ErrorUnsupportedABI(CGF, "member function pointer conversions");
+}
+
+void CGCXXABI::EmitNullMemberFunctionPointer(CodeGenFunction &CGF,
+                                             const MemberPointerType *MPT,
+                                             llvm::Value *Dest,
+                                             bool VolatileDest) {
+  ErrorUnsupportedABI(CGF, "null member function pointers");
+}
+
+llvm::Constant *
+CGCXXABI::EmitMemberFunctionPointerConversion(llvm::Constant *C,
+                                              const CastExpr *E) {
+  return 0;
+}
+
+llvm::Constant *
+CGCXXABI::EmitNullMemberFunctionPointer(const MemberPointerType *MPT) {
+  return 0;
+}
+
+bool CGCXXABI::RequiresNonZeroInitializer(QualType T) {
+  return false;
+}
+
+bool CGCXXABI::RequiresNonZeroInitializer(const CXXRecordDecl *D) {
+  return RequiresNonZeroInitializer(QualType(D->getTypeForDecl(), 0));
 }

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=111771&r1=111770&r2=111771&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Sat Aug 21 23:16:24 2010
@@ -16,12 +16,15 @@
 #define CLANG_CODEGEN_CXXABI_H
 
 namespace llvm {
+  class Constant;
   class Value;
 }
 
 namespace clang {
   class CastExpr;
+  class CXXRecordDecl;
   class MemberPointerType;
+  class QualType;
 
 namespace CodeGen {
   class CodeGenFunction;
@@ -42,11 +45,31 @@
                                   llvm::Value *MemPtr,
                                   const MemberPointerType *MPT);
 
-  virtual void EmitMemberPointerConversion(CodeGenFunction &CGF,
-                                           const CastExpr *E,
-                                           llvm::Value *Src,
-                                           llvm::Value *Dest,
-                                           bool VolatileDest);
+  virtual void
+  EmitMemberFunctionPointerConversion(CodeGenFunction &CGF,
+                                      const CastExpr *E,
+                                      llvm::Value *Src,
+                                      llvm::Value *Dest,
+                                      bool VolatileDest);
+
+  virtual void EmitNullMemberFunctionPointer(CodeGenFunction &CGF,
+                                             const MemberPointerType *MPT,
+                                             llvm::Value *Dest,
+                                             bool VolatileDest);
+  
+  // Manipulations on constant expressions.
+
+  /// \brief Returns true if zero-initializing the given type requires
+  /// a constant other than the LLVM null value.
+  virtual bool RequiresNonZeroInitializer(QualType T);
+  virtual bool RequiresNonZeroInitializer(const CXXRecordDecl *D);
+
+  virtual llvm::Constant *
+  EmitMemberFunctionPointerConversion(llvm::Constant *C,
+                                      const CastExpr *E);
+
+  virtual llvm::Constant *
+  EmitNullMemberFunctionPointer(const MemberPointerType *MPT);
 };
 
 /// Creates an instance of a C++ ABI class.

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=111771&r1=111770&r2=111771&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sat Aug 21 23:16:24 2010
@@ -293,15 +293,9 @@
     if (E->getSubExpr()->getType()->isNullPtrType())
       Visit(E->getSubExpr());
 
-    const llvm::Type *PtrDiffTy = 
-      CGF.ConvertType(CGF.getContext().getPointerDiffType());
-
-    llvm::Value *NullValue = llvm::Constant::getNullValue(PtrDiffTy);
-    llvm::Value *Ptr = Builder.CreateStructGEP(DestPtr, 0, "ptr");
-    Builder.CreateStore(NullValue, Ptr, VolatileDest);
-    
-    llvm::Value *Adj = Builder.CreateStructGEP(DestPtr, 1, "adj");
-    Builder.CreateStore(NullValue, Adj, VolatileDest);
+    CGF.CGM.getCXXABI().EmitNullMemberFunctionPointer(CGF,
+                                    E->getType()->getAs<MemberPointerType>(),
+                                                      DestPtr, VolatileDest);
 
     break;
   }
@@ -329,8 +323,8 @@
     // ABIs where an actual null check is thus required; fortunately,
     // the Itanium and ARM ABIs ignore the adjustment value when
     // considering null-ness.
-    CGF.CGM.getCXXABI().EmitMemberPointerConversion(CGF, E, Src,
-                                                    DestPtr, VolatileDest);
+    CGF.CGM.getCXXABI().EmitMemberFunctionPointerConversion(CGF, E, Src,
+                                                   DestPtr, VolatileDest);
     break;
   }
   }

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=111771&r1=111770&r2=111771&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Sat Aug 21 23:16:24 2010
@@ -552,7 +552,7 @@
         if (!E->hasInitializer() || Ctor->getParent()->isEmpty())
           return;
       
-        if (!CGF.CGM.getTypes().ContainsPointerToDataMember(
+        if (!CGF.CGM.getCXXABI().RequiresNonZeroInitializer(
                                                        E->getAllocatedType())) {
           // Optimization: since zero initialization will just set the memory
           // to all zeroes, generate a single memset to do it in one shot.

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=111771&r1=111770&r2=111771&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Sat Aug 21 23:16:24 2010
@@ -549,42 +549,17 @@
       return llvm::ConstantStruct::get(STy, Elts);
     }
     case CastExpr::CK_NullToMemberPointer:
-      return CGM.EmitNullConstant(E->getType());
+      return CGM.getCXXABI().EmitNullMemberFunctionPointer(
+                                   E->getType()->getAs<MemberPointerType>());
       
     case CastExpr::CK_BaseToDerivedMemberPointer: {
       Expr *SubExpr = E->getSubExpr();
 
-      const MemberPointerType *SrcTy = 
-        SubExpr->getType()->getAs<MemberPointerType>();
-      const MemberPointerType *DestTy = 
-        E->getType()->getAs<MemberPointerType>();
-      
-      const CXXRecordDecl *DerivedClass =
-        cast<CXXRecordDecl>(cast<RecordType>(DestTy->getClass())->getDecl());
-
-      if (SrcTy->getPointeeType()->isFunctionProtoType()) {
-        llvm::Constant *C = 
-          CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
-        if (!C)
-          return 0;
-        
-        llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C);
-        
-        // Check if we need to update the adjustment.
-        if (llvm::Constant *Offset = 
-            CGM.GetNonVirtualBaseClassOffset(DerivedClass,
-                                             E->path_begin(),
-                                             E->path_end())) {
-          llvm::Constant *Values[2];
-        
-          Values[0] = CS->getOperand(0);
-          Values[1] = llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset);
-          return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2, 
-                                           /*Packed=*/false);
-        }
-        
-        return CS;
-      }          
+      llvm::Constant *C = 
+        CGM.EmitConstantExpr(SubExpr, SubExpr->getType(), CGF);
+      if (!C) return 0;
+
+      return CGM.getCXXABI().EmitMemberFunctionPointerConversion(C, E);
     }
 
     case CastExpr::CK_BitCast: 
@@ -990,7 +965,8 @@
                              uint64_t StartOffset) {
   assert(StartOffset % 8 == 0 && "StartOffset not byte aligned!");
 
-  if (!CGM.getTypes().ContainsPointerToDataMember(T))
+  if (!CGM.getLangOptions().CPlusPlus ||
+      !CGM.getCXXABI().RequiresNonZeroInitializer(T))
     return;
 
   if (const ConstantArrayType *CAT = 
@@ -1023,7 +999,7 @@
         continue;
       
       // Ignore bases that don't have any pointer to data members.
-      if (!CGM.getTypes().ContainsPointerToDataMember(BaseDecl))
+      if (!CGM.getCXXABI().RequiresNonZeroInitializer(BaseDecl))
         continue;
 
       uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl);
@@ -1037,7 +1013,7 @@
          E = RD->field_end(); I != E; ++I, ++FieldNo) {
       QualType FieldType = I->getType();
       
-      if (!CGM.getTypes().ContainsPointerToDataMember(FieldType))
+      if (!CGM.getCXXABI().RequiresNonZeroInitializer(FieldType))
         continue;
 
       uint64_t FieldOffset = StartOffset + Layout.getFieldOffset(FieldNo);
@@ -1062,7 +1038,8 @@
 }
 
 llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
-  if (!getTypes().ContainsPointerToDataMember(T))
+  if (!getLangOptions().CPlusPlus ||
+      !getCXXABI().RequiresNonZeroInitializer(T))
     return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));
     
   if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(T)) {
@@ -1106,7 +1083,7 @@
         continue;
 
       // Ignore bases that don't have any pointer to data members.
-      if (!getTypes().ContainsPointerToDataMember(BaseDecl))
+      if (!getCXXABI().RequiresNonZeroInitializer(BaseDecl))
         continue;
 
       // Currently, all bases are arrays of i8. Figure out how many elements

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=111771&r1=111770&r2=111771&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Sat Aug 21 23:16:24 2010
@@ -579,7 +579,8 @@
 
   // If the type contains a pointer to data member we can't memset it to zero.
   // Instead, create a null constant and copy it to the destination.
-  if (CGM.getTypes().ContainsPointerToDataMember(Ty)) {
+  if (CGM.getLangOptions().CPlusPlus &&
+      CGM.getCXXABI().RequiresNonZeroInitializer(Ty)) {
     llvm::Constant *NullConstant = CGM.EmitNullConstant(Ty);
 
     llvm::GlobalVariable *NullVariable = 

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=111771&r1=111770&r2=111771&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Sat Aug 21 23:16:24 2010
@@ -42,16 +42,30 @@
     return MangleCtx;
   }
 
+  bool RequiresNonZeroInitializer(QualType T);
+  bool RequiresNonZeroInitializer(const CXXRecordDecl *D);
+
   llvm::Value *EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
                                                llvm::Value *&This,
                                                llvm::Value *MemFnPtr,
                                                const MemberPointerType *MPT);
 
-  void EmitMemberPointerConversion(CodeGenFunction &CGF,
-                                   const CastExpr *E,
-                                   llvm::Value *Src,
-                                   llvm::Value *Dest,
-                                   bool VolatileDest);
+  void EmitMemberFunctionPointerConversion(CodeGenFunction &CGF,
+                                           const CastExpr *E,
+                                           llvm::Value *Src,
+                                           llvm::Value *Dest,
+                                           bool VolatileDest);
+
+  llvm::Constant *EmitMemberFunctionPointerConversion(llvm::Constant *C,
+                                                      const CastExpr *E);
+
+  void EmitNullMemberFunctionPointer(CodeGenFunction &CGF,
+                                     const MemberPointerType *MPT,
+                                     llvm::Value *Dest,
+                                     bool VolatileDest);
+
+  llvm::Constant *EmitNullMemberFunctionPointer(const MemberPointerType *MPT);
+
 };
 
 class ARMCXXABI : public ItaniumCXXABI {
@@ -176,11 +190,11 @@
 }
 
 /// Perform a derived-to-base or base-to-derived member pointer conversion.
-void ItaniumCXXABI::EmitMemberPointerConversion(CodeGenFunction &CGF,
-                                                const CastExpr *E,
-                                                llvm::Value *Src,
-                                                llvm::Value *Dest,
-                                                bool VolatileDest) {
+void ItaniumCXXABI::EmitMemberFunctionPointerConversion(CodeGenFunction &CGF,
+                                                        const CastExpr *E,
+                                                        llvm::Value *Src,
+                                                        llvm::Value *Dest,
+                                                        bool VolatileDest) {
   assert(E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer ||
          E->getCastKind() == CastExpr::CK_BaseToDerivedMemberPointer);
 
@@ -225,3 +239,71 @@
     
   Builder.CreateStore(SrcAdj, DstAdj, VolatileDest);
 }
+
+llvm::Constant *
+ItaniumCXXABI::EmitMemberFunctionPointerConversion(llvm::Constant *C,
+                                                   const CastExpr *E) {
+  const MemberPointerType *SrcTy = 
+    E->getSubExpr()->getType()->getAs<MemberPointerType>();
+  const MemberPointerType *DestTy = 
+    E->getType()->getAs<MemberPointerType>();
+
+  bool DerivedToBase =
+    E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer;
+
+  const CXXRecordDecl *DerivedDecl;
+  if (DerivedToBase)
+    DerivedDecl = SrcTy->getClass()->getAsCXXRecordDecl();
+  else
+    DerivedDecl = DestTy->getClass()->getAsCXXRecordDecl();
+
+  // Calculate the offset to the base class.
+  llvm::Constant *Offset = 
+    CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
+                                     E->path_begin(),
+                                     E->path_end());
+  // If there's no offset, we're done.
+  if (!Offset) return C;
+
+  llvm::ConstantStruct *CS = cast<llvm::ConstantStruct>(C);
+
+  llvm::Constant *Values[2] = {
+    CS->getOperand(0),
+    llvm::ConstantExpr::getAdd(CS->getOperand(1), Offset)
+  };
+  return llvm::ConstantStruct::get(CGM.getLLVMContext(), Values, 2,
+                                   /*Packed=*/false);
+}        
+
+
+void ItaniumCXXABI::EmitNullMemberFunctionPointer(CodeGenFunction &CGF,
+                                                  const MemberPointerType *MPT,
+                                                  llvm::Value *Dest,
+                                                  bool VolatileDest) {
+  // Should this be "unabstracted" and implemented in terms of the
+  // Constant version?
+
+  CGBuilderTy &Builder = CGF.Builder;
+
+  const llvm::IntegerType *PtrDiffTy = CGF.IntPtrTy;
+  llvm::Value *Zero = llvm::ConstantInt::get(PtrDiffTy, 0);
+
+  llvm::Value *Ptr = Builder.CreateStructGEP(Dest, 0, "ptr");
+  Builder.CreateStore(Zero, Ptr, VolatileDest);
+    
+  llvm::Value *Adj = Builder.CreateStructGEP(Dest, 1, "adj");
+  Builder.CreateStore(Zero, Adj, VolatileDest);
+}
+
+llvm::Constant *
+ItaniumCXXABI::EmitNullMemberFunctionPointer(const MemberPointerType *MPT) {
+  return CGM.EmitNullConstant(QualType(MPT, 0));
+}
+
+bool ItaniumCXXABI::RequiresNonZeroInitializer(QualType T) {
+  return CGM.getTypes().ContainsPointerToDataMember(T);
+}
+
+bool ItaniumCXXABI::RequiresNonZeroInitializer(const CXXRecordDecl *D) {
+  return CGM.getTypes().ContainsPointerToDataMember(D);
+}





More information about the cfe-commits mailing list