зеркало из https://github.com/microsoft/clang-1.git
Move the code for converting a member pointer to a bool so that it is usable
for logical not. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91112 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b81c786de5
Коммит
3a1737030e
|
@ -38,6 +38,21 @@ llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty,
|
|||
/// expression and compare the result against zero, returning an Int1Ty value.
|
||||
llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
|
||||
QualType BoolTy = getContext().BoolTy;
|
||||
if (E->getType()->isMemberFunctionPointerType()) {
|
||||
llvm::Value *Ptr = CreateTempAlloca(ConvertType(E->getType()));
|
||||
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;
|
||||
}
|
||||
if (!E->getType()->isAnyComplexType())
|
||||
return EmitScalarConversion(EmitScalarExpr(E), E->getType(), BoolTy);
|
||||
|
||||
|
|
|
@ -954,34 +954,8 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
|
|||
case CastExpr::CK_FloatingCast:
|
||||
return EmitScalarConversion(Visit(E), E->getType(), DestTy);
|
||||
|
||||
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;
|
||||
}
|
||||
case CastExpr::CK_MemberPointerToBoolean:
|
||||
return CGF.EvaluateExprAsBool(E);
|
||||
}
|
||||
|
||||
// Handle cases where the source is an non-complex type.
|
||||
|
|
|
@ -113,3 +113,18 @@ namespace PR5718 {
|
|||
return f == g;
|
||||
}
|
||||
}
|
||||
|
||||
namespace BoolMemberPointer {
|
||||
struct A { };
|
||||
|
||||
bool f(void (A::*f)()) {
|
||||
return !f;
|
||||
}
|
||||
|
||||
bool g(void (A::*f)()) {
|
||||
if (!!f)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче