зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
a79f8b3989
Коммит
bc0e0781da
|
@ -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 {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче