[cfe-commits] r111770 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CGCXXABI.h CGExprAgg.cpp ItaniumCXXABI.cpp

John McCall rjmccall at apple.com
Sat Aug 21 20:04:22 PDT 2010


Author: rjmccall
Date: Sat Aug 21 22:04:22 2010
New Revision: 111770

URL: http://llvm.org/viewvc/llvm-project?rev=111770&view=rev
Log:
Abstract out member-pointer conversions.

Pretty much everything having to do with member pointers is ABI-specific.


Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGCXXABI.h
    cfe/trunk/lib/CodeGen/CGExprAgg.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=111770&r1=111769&r2=111770&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sat Aug 21 22:04:22 2010
@@ -358,16 +358,21 @@
 
 CGCXXABI::~CGCXXABI() {}
 
+static void ErrorUnsupportedABI(CodeGenFunction &CGF,
+                                llvm::StringRef S) {
+  Diagnostic &Diags = CGF.CGM.getDiags();
+  unsigned DiagID = Diags.getCustomDiagID(Diagnostic::Error,
+                                          "cannot yet compile %s in this ABI");
+  Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
+               DiagID)
+    << S;
+}
+
 llvm::Value *CGCXXABI::EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF,
                                                        llvm::Value *&This,
                                                        llvm::Value *MemPtr,
                                                  const MemberPointerType *MPT) {
-  Diagnostic &Diags = CGF.CGM.getDiags();
-  unsigned DiagID =
-    Diags.getCustomDiagID(Diagnostic::Error,
-                          "cannot yet compile member pointer calls in this ABI");
-  Diags.Report(CGF.getContext().getFullLoc(CGF.CurCodeDecl->getLocation()),
-               DiagID);
+  ErrorUnsupportedABI(CGF, "calls through member pointers");
 
   const FunctionProtoType *FPT = 
     MPT->getPointeeType()->getAs<FunctionProtoType>();
@@ -379,3 +384,11 @@
                                  FPT->isVariadic());
   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");
+}

Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=111770&r1=111769&r2=111770&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Sat Aug 21 22:04:22 2010
@@ -20,6 +20,7 @@
 }
 
 namespace clang {
+  class CastExpr;
   class MemberPointerType;
 
 namespace CodeGen {
@@ -40,6 +41,12 @@
                                   llvm::Value *&This,
                                   llvm::Value *MemPtr,
                                   const MemberPointerType *MPT);
+
+  virtual void EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                           const CastExpr *E,
+                                           llvm::Value *Src,
+                                           llvm::Value *Dest,
+                                           bool VolatileDest);
 };
 
 /// 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=111770&r1=111769&r2=111770&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Sat Aug 21 22:04:22 2010
@@ -322,39 +322,15 @@
     
     llvm::Value *Src = CGF.CreateMemTemp(SrcType, "tmp");
     CGF.EmitAggExpr(E->getSubExpr(), Src, SrcType.isVolatileQualified());
-    
-    llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr");
-    SrcPtr = Builder.CreateLoad(SrcPtr);
-    
-    llvm::Value *SrcAdj = Builder.CreateStructGEP(Src, 1, "src.adj");
-    SrcAdj = Builder.CreateLoad(SrcAdj);
-    
-    llvm::Value *DstPtr = Builder.CreateStructGEP(DestPtr, 0, "dst.ptr");
-    Builder.CreateStore(SrcPtr, DstPtr, VolatileDest);
-    
-    llvm::Value *DstAdj = Builder.CreateStructGEP(DestPtr, 1, "dst.adj");
-    
-    // Now See if we need to update the adjustment.
-    const CXXRecordDecl *BaseDecl = 
-      cast<CXXRecordDecl>(SrcType->getAs<MemberPointerType>()->
-                          getClass()->getAs<RecordType>()->getDecl());
-    const CXXRecordDecl *DerivedDecl = 
-      cast<CXXRecordDecl>(E->getType()->getAs<MemberPointerType>()->
-                          getClass()->getAs<RecordType>()->getDecl());
-    if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
-      std::swap(DerivedDecl, BaseDecl);
-
-    if (llvm::Constant *Adj = 
-          CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
-                                               E->path_begin(),
-                                               E->path_end())) {
-      if (E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer)
-        SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj");
-      else
-        SrcAdj = Builder.CreateAdd(SrcAdj, Adj, "adj");
-    }
-    
-    Builder.CreateStore(SrcAdj, DstAdj, VolatileDest);
+
+    // Note that the AST doesn't distinguish between checked and
+    // unchecked member pointer conversions, so we always have to
+    // implement checked conversions here.  This is inefficient for
+    // 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);
     break;
   }
   }

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=111770&r1=111769&r2=111770&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Sat Aug 21 22:04:22 2010
@@ -46,6 +46,12 @@
                                                llvm::Value *&This,
                                                llvm::Value *MemFnPtr,
                                                const MemberPointerType *MPT);
+
+  void EmitMemberPointerConversion(CodeGenFunction &CGF,
+                                   const CastExpr *E,
+                                   llvm::Value *Src,
+                                   llvm::Value *Dest,
+                                   bool VolatileDest);
 };
 
 class ARMCXXABI : public ItaniumCXXABI {
@@ -168,3 +174,54 @@
   Callee->addIncoming(NonVirtualFn, FnNonVirtual);
   return Callee;
 }
+
+/// 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) {
+  assert(E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer ||
+         E->getCastKind() == CastExpr::CK_BaseToDerivedMemberPointer);
+
+  CGBuilderTy &Builder = CGF.Builder;
+
+  const MemberPointerType *SrcTy =
+    E->getSubExpr()->getType()->getAs<MemberPointerType>();
+  const MemberPointerType *DestTy = E->getType()->getAs<MemberPointerType>();
+
+  const CXXRecordDecl *SrcDecl = SrcTy->getClass()->getAsCXXRecordDecl();
+  const CXXRecordDecl *DestDecl = DestTy->getClass()->getAsCXXRecordDecl();
+
+  llvm::Value *SrcPtr = Builder.CreateStructGEP(Src, 0, "src.ptr");
+  SrcPtr = Builder.CreateLoad(SrcPtr);
+    
+  llvm::Value *SrcAdj = Builder.CreateStructGEP(Src, 1, "src.adj");
+  SrcAdj = Builder.CreateLoad(SrcAdj);
+    
+  llvm::Value *DstPtr = Builder.CreateStructGEP(Dest, 0, "dst.ptr");
+  Builder.CreateStore(SrcPtr, DstPtr, VolatileDest);
+    
+  llvm::Value *DstAdj = Builder.CreateStructGEP(Dest, 1, "dst.adj");
+
+  bool DerivedToBase =
+    E->getCastKind() == CastExpr::CK_DerivedToBaseMemberPointer;
+
+  const CXXRecordDecl *BaseDecl, *DerivedDecl;
+  if (DerivedToBase)
+    DerivedDecl = SrcDecl, BaseDecl = DestDecl;
+  else
+    BaseDecl = SrcDecl, DerivedDecl = DestDecl;
+
+  if (llvm::Constant *Adj = 
+        CGF.CGM.GetNonVirtualBaseClassOffset(DerivedDecl,
+                                             E->path_begin(),
+                                             E->path_end())) {
+    if (DerivedToBase)
+      SrcAdj = Builder.CreateSub(SrcAdj, Adj, "adj");
+    else
+      SrcAdj = Builder.CreateAdd(SrcAdj, Adj, "adj");
+  }
+    
+  Builder.CreateStore(SrcAdj, DstAdj, VolatileDest);
+}





More information about the cfe-commits mailing list