[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