Handle converting member pointers to bool.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89692 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anders Carlsson 2009-11-23 20:04:44 +00:00
Родитель a79f8b3989
Коммит bc0e0781da
5 изменённых файлов: 47 добавлений и 3 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -901,6 +901,35 @@ Value *ScalarExprEmitter::EmitCastExpr(const CastExpr *CE) {
return Yay; 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. // Handle cases where the source is an non-complex type.

Просмотреть файл

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

Просмотреть файл

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