[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