[cfe-commits] r119036 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/OperationKinds.h lib/AST/Expr.cpp lib/AST/ExprConstant.cpp lib/Checker/GRExprEngine.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprComplex.cpp lib/CodeGen/CGExprScalar.cpp lib/Sema/SemaExpr.cpp
John McCall
rjmccall at apple.com
Sun Nov 14 00:17:51 PST 2010
Author: rjmccall
Date: Sun Nov 14 02:17:51 2010
New Revision: 119036
URL: http://llvm.org/viewvc/llvm-project?rev=119036&view=rev
Log:
Add a few more complex-related cast kinds that arise due to arbitrary
implicit conversions; the last batch was specific to promotions.
I think this is the full set we need. I do think dividing the cast
kinds into floating and integral is probably a good idea.
Annotate a *lot* more C casts with useful cast kinds.
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/OperationKinds.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Checker/GRExprEngine.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprComplex.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sun Nov 14 02:17:51 2010
@@ -1998,10 +1998,15 @@
case CK_AnyPointerToBlockPointerCast:
case CK_ObjCObjectLValueCast:
case CK_FloatingRealToComplex:
+ case CK_FloatingComplexToReal:
+ case CK_FloatingComplexToBoolean:
case CK_FloatingComplexCast:
+ case CK_FloatingComplexToIntegralComplex:
case CK_IntegralRealToComplex:
+ case CK_IntegralComplexToReal:
+ case CK_IntegralComplexToBoolean:
case CK_IntegralComplexCast:
- case CK_IntegralToFloatingComplex:
+ case CK_IntegralComplexToFloatingComplex:
assert(path_empty() && "Cast kind should not have a base path!");
break;
}
Modified: cfe/trunk/include/clang/AST/OperationKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OperationKinds.h?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OperationKinds.h (original)
+++ cfe/trunk/include/clang/AST/OperationKinds.h Sun Nov 14 02:17:51 2010
@@ -123,17 +123,32 @@
/// \brief Floating point real to floating point complex
CK_FloatingRealToComplex,
+ /// \brief Floating pointer complex to floating point real
+ CK_FloatingComplexToReal,
+
+ /// \brief Converting a floating complex to bool
+ CK_FloatingComplexToBoolean,
+
/// \brief Casting between floating point complex types of different size
CK_FloatingComplexCast,
+ /// \brief Casting from a floating complex to an integral complex
+ CK_FloatingComplexToIntegralComplex,
+
/// \brief Integral real to integral complex
CK_IntegralRealToComplex,
+ /// \brief Integral complex to integral real
+ CK_IntegralComplexToReal,
+
+ /// \brief Converting an integral complex to bool
+ CK_IntegralComplexToBoolean,
+
/// \brief Casting between integral complex types of different size
CK_IntegralComplexCast,
- /// \brief Casting from an integral complex to a floating complex.
- CK_IntegralToFloatingComplex
+ /// \brief Casting from an integral complex to a floating complex
+ CK_IntegralComplexToFloatingComplex
};
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Sun Nov 14 02:17:51 2010
@@ -800,14 +800,24 @@
return "ObjCObjectLValueCast";
case CK_FloatingRealToComplex:
return "FloatingRealToComplex";
+ case CK_FloatingComplexToReal:
+ return "FloatingComplexToReal";
+ case CK_FloatingComplexToBoolean:
+ return "FloatingComplexToBoolean";
case CK_FloatingComplexCast:
return "FloatingComplexCast";
+ case CK_FloatingComplexToIntegralComplex:
+ return "FloatingComplexToIntegralComplex";
case CK_IntegralRealToComplex:
return "IntegralRealToComplex";
+ case CK_IntegralComplexToReal:
+ return "IntegralComplexToReal";
+ case CK_IntegralComplexToBoolean:
+ return "IntegralComplexToBoolean";
case CK_IntegralComplexCast:
return "IntegralComplexCast";
- case CK_IntegralToFloatingComplex:
- return "IntegralToFloatingComplex";
+ case CK_IntegralComplexToFloatingComplex:
+ return "IntegralComplexToFloatingComplex";
}
llvm_unreachable("Unhandled cast kind!");
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Nov 14 02:17:51 2010
@@ -2073,7 +2073,14 @@
Result, Info.Ctx);
return true;
}
- // FIXME: Handle complex types
+
+ if (E->getCastKind() == CK_FloatingComplexToReal) {
+ ComplexValue V;
+ if (!EvaluateComplex(SubExpr, V, Info))
+ return false;
+ Result = V.getComplexFloatReal();
+ return true;
+ }
return false;
}
Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Sun Nov 14 02:17:51 2010
@@ -2525,10 +2525,15 @@
case CK_FloatingToIntegral:
case CK_FloatingCast:
case CK_FloatingRealToComplex:
+ case CK_FloatingComplexToReal:
+ case CK_FloatingComplexToBoolean:
case CK_FloatingComplexCast:
+ case CK_FloatingComplexToIntegralComplex:
case CK_IntegralRealToComplex:
+ case CK_IntegralComplexToReal:
+ case CK_IntegralComplexToBoolean:
case CK_IntegralComplexCast:
- case CK_IntegralToFloatingComplex:
+ case CK_IntegralComplexToFloatingComplex:
case CK_AnyPointerToObjCPointerCast:
case CK_AnyPointerToBlockPointerCast:
case CK_DerivedToBase:
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Sun Nov 14 02:17:51 2010
@@ -1815,10 +1815,15 @@
case CK_FloatingToIntegral:
case CK_FloatingCast:
case CK_FloatingRealToComplex:
+ case CK_FloatingComplexToReal:
+ case CK_FloatingComplexToBoolean:
case CK_FloatingComplexCast:
+ case CK_FloatingComplexToIntegralComplex:
case CK_IntegralRealToComplex:
+ case CK_IntegralComplexToReal:
+ case CK_IntegralComplexToBoolean:
case CK_IntegralComplexCast:
- case CK_IntegralToFloatingComplex:
+ case CK_IntegralComplexToFloatingComplex:
case CK_DerivedToBaseMemberPointer:
case CK_BaseToDerivedMemberPointer:
case CK_MemberPointerToBoolean:
Modified: cfe/trunk/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprComplex.cpp?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprComplex.cpp Sun Nov 14 02:17:51 2010
@@ -274,6 +274,8 @@
bool isVolatile) {
llvm::Value *Real=0, *Imag=0;
+ // FIXME: we should really not be suppressing volatile loads.
+
if (!IgnoreReal) {
llvm::Value *RealP = Builder.CreateStructGEP(SrcPtr, 0,
SrcPtr->getName() + ".realp");
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Sun Nov 14 02:17:51 2010
@@ -1083,7 +1083,8 @@
case CK_FloatingComplexCast:
case CK_IntegralRealToComplex:
case CK_IntegralComplexCast:
- case CK_IntegralToFloatingComplex:
+ case CK_IntegralComplexToFloatingComplex:
+ case CK_FloatingComplexToIntegralComplex:
case CK_ConstructorConversion:
assert(0 && "Should be unreachable!");
break;
@@ -1151,6 +1152,20 @@
const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>();
return CGF.CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
}
+
+ case CK_FloatingComplexToReal:
+ case CK_IntegralComplexToReal:
+ return CGF.EmitComplexExpr(E, false, true, false, true).first;
+
+ case CK_FloatingComplexToBoolean:
+ case CK_IntegralComplexToBoolean: {
+ CodeGenFunction::ComplexPairTy V
+ = CGF.EmitComplexExpr(E, false, false, false, false);
+
+ // TODO: kill this function off, inline appropriate case here
+ return EmitComplexToScalarConversion(V, E->getType(), DestTy);
+ }
+
}
// Handle cases where the source is an non-complex type.
@@ -1162,8 +1177,10 @@
return EmitScalarConversion(Src, E->getType(), DestTy);
}
+ // Handle cases where the source is a complex type.
+ // TODO: when we're certain about cast kinds, we should just be able
+ // to assert that no complexes make it here.
if (E->getType()->isAnyComplexType()) {
- // Handle cases where the source is a complex type.
bool IgnoreImag = true;
bool IgnoreImagAssign = true;
bool IgnoreReal = IgnoreResultAssign;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=119036&r1=119035&r2=119036&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Nov 14 02:17:51 2010
@@ -406,7 +406,7 @@
ImpCastExprToType(rhsExpr, lhs, CK_FloatingRealToComplex);
} else {
assert(rhs->isComplexIntegerType());
- ImpCastExprToType(rhsExpr, lhs, CK_IntegralToFloatingComplex);
+ ImpCastExprToType(rhsExpr, lhs, CK_IntegralComplexToFloatingComplex);
}
return lhs;
}
@@ -420,7 +420,7 @@
ImpCastExprToType(lhsExpr, rhs, CK_FloatingRealToComplex);
} else {
assert(lhs->isComplexIntegerType());
- ImpCastExprToType(lhsExpr, rhs, CK_IntegralToFloatingComplex);
+ ImpCastExprToType(lhsExpr, rhs, CK_IntegralComplexToFloatingComplex);
}
}
return rhs;
@@ -537,7 +537,7 @@
QualType result = Context.getComplexType(lhs);
// _Complex int -> _Complex float
- ImpCastExprToType(rhsExpr, result, CK_IntegralToFloatingComplex);
+ ImpCastExprToType(rhsExpr, result, CK_IntegralComplexToFloatingComplex);
// float -> _Complex float
if (!isCompAssign)
@@ -560,7 +560,7 @@
// _Complex int -> _Complex float
if (!isCompAssign)
- ImpCastExprToType(lhsExpr, result, CK_IntegralToFloatingComplex);
+ ImpCastExprToType(lhsExpr, result, CK_IntegralComplexToFloatingComplex);
// float -> _Complex float
ImpCastExprToType(rhsExpr, result, CK_FloatingRealToComplex);
@@ -4252,43 +4252,131 @@
return Owned(E);
}
-static CastKind getScalarCastKind(ASTContext &Context,
- Expr *Src, QualType DestTy) {
+enum ScalarKind {
+ SK_Pointer,
+ SK_Bool,
+ SK_Integral,
+ SK_Floating,
+ SK_IntegralComplex,
+ SK_FloatingComplex
+};
+static ScalarKind ClassifyScalarType(QualType QT) {
+ assert(QT->isScalarType());
+
+ const Type *T = QT->getCanonicalTypeUnqualified().getTypePtr();
+ if (T->hasPointerRepresentation())
+ return SK_Pointer;
+ if (T->isBooleanType())
+ return SK_Bool;
+ if (T->isRealFloatingType())
+ return SK_Floating;
+ if (const ComplexType *CT = dyn_cast<ComplexType>(T)) {
+ if (CT->getElementType()->isRealFloatingType())
+ return SK_FloatingComplex;
+ return SK_IntegralComplex;
+ }
+ assert(T->isIntegerType());
+ return SK_Integral;
+}
+
+/// Prepares for a scalar cast, performing all the necessary stages
+/// except the final cast and returning the kind required.
+static CastKind PrepareScalarCast(Sema &S, Expr *&Src, QualType DestTy) {
+ // Both Src and Dest are scalar types, i.e. arithmetic or pointer.
+ // Also, callers should have filtered out the invalid cases with
+ // pointers. Everything else should be possible.
+
QualType SrcTy = Src->getType();
- if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
+ if (S.Context.hasSameUnqualifiedType(SrcTy, DestTy))
return CK_NoOp;
- if (SrcTy->hasPointerRepresentation()) {
- if (DestTy->hasPointerRepresentation())
- return DestTy->isObjCObjectPointerType() ?
- CK_AnyPointerToObjCPointerCast :
- CK_BitCast;
+ switch (ClassifyScalarType(SrcTy)) {
+ case SK_Pointer:
if (DestTy->isIntegerType())
return CK_PointerToIntegral;
- }
+ assert(DestTy->hasPointerRepresentation());
+ return DestTy->isObjCObjectPointerType() ?
+ CK_AnyPointerToObjCPointerCast :
+ CK_BitCast;
- if (SrcTy->isIntegerType()) {
- if (DestTy->isIntegerType())
- return CK_IntegralCast;
- if (DestTy->hasPointerRepresentation()) {
- if (Src->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
+ case SK_Bool: // casting from bool is like casting from an integer
+ case SK_Integral:
+ switch (ClassifyScalarType(DestTy)) {
+ case SK_Pointer:
+ if (Src->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull))
return CK_NullToPointer;
return CK_IntegralToPointer;
- }
- if (DestTy->isRealFloatingType())
+
+ case SK_Bool: // TODO: there should be an int->bool cast kind
+ case SK_Integral:
+ return CK_IntegralCast;
+ case SK_Floating:
return CK_IntegralToFloating;
- }
+ case SK_IntegralComplex:
+ return CK_IntegralRealToComplex;
+ case SK_FloatingComplex:
+ S.ImpCastExprToType(Src, cast<ComplexType>(DestTy)->getElementType(),
+ CK_IntegralToFloating);
+ return CK_FloatingRealToComplex;
+ }
+ break;
- if (SrcTy->isRealFloatingType()) {
- if (DestTy->isRealFloatingType())
+ case SK_Floating:
+ switch (ClassifyScalarType(DestTy)) {
+ case SK_Floating:
return CK_FloatingCast;
- if (DestTy->isIntegerType())
+ case SK_Bool: // TODO: there should be a float->bool cast kind
+ case SK_Integral:
return CK_FloatingToIntegral;
+ case SK_FloatingComplex:
+ return CK_FloatingRealToComplex;
+ case SK_IntegralComplex:
+ S.ImpCastExprToType(Src, cast<ComplexType>(DestTy)->getElementType(),
+ CK_FloatingToIntegral);
+ return CK_IntegralRealToComplex;
+ case SK_Pointer: llvm_unreachable("valid float->pointer cast?");
+ }
+ break;
+
+ case SK_FloatingComplex:
+ switch (ClassifyScalarType(DestTy)) {
+ case SK_FloatingComplex:
+ return CK_FloatingComplexCast;
+ case SK_IntegralComplex:
+ return CK_FloatingComplexToIntegralComplex;
+ case SK_Floating:
+ return CK_FloatingComplexToReal;
+ case SK_Bool:
+ return CK_FloatingComplexToBoolean;
+ case SK_Integral:
+ S.ImpCastExprToType(Src, cast<ComplexType>(SrcTy)->getElementType(),
+ CK_FloatingComplexToReal);
+ return CK_FloatingToIntegral;
+ case SK_Pointer: llvm_unreachable("valid complex float->pointer cast?");
+ }
+ break;
+
+ case SK_IntegralComplex:
+ switch (ClassifyScalarType(DestTy)) {
+ case SK_FloatingComplex:
+ return CK_IntegralComplexToFloatingComplex;
+ case SK_IntegralComplex:
+ return CK_IntegralComplexCast;
+ case SK_Integral:
+ return CK_IntegralComplexToReal;
+ case SK_Bool:
+ return CK_IntegralComplexToBoolean;
+ case SK_Floating:
+ S.ImpCastExprToType(Src, cast<ComplexType>(SrcTy)->getElementType(),
+ CK_IntegralComplexToReal);
+ return CK_IntegralToFloating;
+ case SK_Pointer: llvm_unreachable("valid complex int->pointer cast?");
+ }
+ break;
}
- // FIXME: Assert here.
- // assert(false && "Unhandled cast combination!");
- return CK_Unknown;
+ llvm_unreachable("Unhandled scalar cast");
+ return CK_BitCast;
}
/// CheckCastTypes - Check type constraints for casting between types.
@@ -4353,6 +4441,9 @@
<< castType << castExpr->getSourceRange();
}
+ // The type we're casting to is known to be a scalar or vector.
+
+ // Require the operand to be a scalar or vector.
if (!castExpr->getType()->isScalarType() &&
!castExpr->getType()->isVectorType()) {
return Diag(castExpr->getLocStart(),
@@ -4368,9 +4459,16 @@
if (castExpr->getType()->isVectorType())
return CheckVectorCast(TyR, castExpr->getType(), castType, Kind);
+ // The source and target types are both scalars, i.e.
+ // - arithmetic types (fundamental, enum, and complex)
+ // - all kinds of pointers
+ // Note that member pointers were filtered out with C++, above.
+
if (isa<ObjCSelectorExpr>(castExpr))
return Diag(castExpr->getLocStart(), diag::err_cast_selector_expr);
+ // If either type is a pointer, the other type has to be either an
+ // integer or a pointer.
if (!castType->isArithmeticType()) {
QualType castExprType = castExpr->getType();
if (!castExprType->isIntegralType(Context) &&
@@ -4385,9 +4483,9 @@
<< castType << castExpr->getSourceRange();
}
- Kind = getScalarCastKind(Context, castExpr, castType);
+ Kind = PrepareScalarCast(*this, castExpr, castType);
- if (Kind == CK_Unknown || Kind == CK_BitCast)
+ if (Kind == CK_BitCast)
CheckCastAlign(castExpr, castType, TyR);
return false;
@@ -4439,7 +4537,7 @@
QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
ImpCastExprToType(CastExpr, DestElemTy,
- getScalarCastKind(Context, CastExpr, DestElemTy));
+ PrepareScalarCast(*this, CastExpr, DestElemTy));
Kind = CK_VectorSplat;
return false;
More information about the cfe-commits
mailing list