Handle converting member pointers to bool.

llvm-svn: 89692
This commit is contained in:
Anders Carlsson 2009-11-23 20:04:44 +00:00
parent 3f21c159dc
commit 7fa434c2b8
5 changed files with 47 additions and 3 deletions

View File

@ -1574,7 +1574,11 @@ public:
CK_FloatingToIntegral,
/// CK_FloatingCast - Casting between floating types of different size.
CK_FloatingCast
CK_FloatingCast,
/// CK_MemberPointerToBoolean - Member pointer to boolean
CK_MemberPointerToBoolean
};
private:

View File

@ -556,6 +556,8 @@ const char *CastExpr::getCastKindName() const {
return "FloatingToIntegral";
case CastExpr::CK_FloatingCast:
return "FloatingCast";
case CastExpr::CK_MemberPointerToBoolean:
return "MemberPointerToBoolean";
}
assert(0 && "Unhandled cast kind!");

View File

@ -901,6 +901,35 @@ Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) {
return Yay;
}
case CastExpr::CK_MemberPointerToBoolean: {
const MemberPointerType* T = E->getType()->getAs<MemberPointerType>();
if (T->getPointeeType()->isFunctionType()) {
// We have a member function pointer.
llvm::Value *Ptr = CGF.CreateTempAlloca(ConvertType(E->getType()));
CGF.EmitAggExpr(E, Ptr, /*VolatileDest=*/false);
// Get the pointer.
llvm::Value *FuncPtr = Builder.CreateStructGEP(Ptr, 0, "src.ptr");
FuncPtr = Builder.CreateLoad(FuncPtr);
llvm::Value *IsNotNull =
Builder.CreateICmpNE(FuncPtr,
llvm::Constant::getNullValue(FuncPtr->getType()),
"tobool");
return IsNotNull;
}
// We have a regular member pointer.
Value *Ptr = Visit(const_cast<Expr*>(E));
llvm::Value *IsNotNull =
Builder.CreateICmpNE(Ptr, CGF.CGM.EmitNullConstant(E->getType()),
"tobool");
return IsNotNull;
}
}
// Handle cases where the source is an non-complex type.

View File

@ -1359,9 +1359,14 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
ImpCastExprToType(From, ToType, Kind);
break;
}
case ICK_Boolean_Conversion:
ImpCastExprToType(From, Context.BoolTy, CastExpr::CK_Unknown);
case ICK_Boolean_Conversion: {
CastExpr::CastKind Kind = CastExpr::CK_Unknown;
if (FromType->isMemberPointerType())
Kind = CastExpr::CK_MemberPointerToBoolean;
ImpCastExprToType(From, Context.BoolTy, Kind);
break;
}
case ICK_Derived_To_Base:
if (CheckDerivedToBaseConversion(From->getType(),

View File

@ -55,6 +55,10 @@ void f3(A *a, A &ar) {
(ar.*pa)();
}
bool f4() {
return pa;
}
// PR5177
namespace PR5177 {
struct A {