From e2b768877b77fa4e00171ee6e6443722e0f3d111 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 16 Nov 2010 05:46:29 +0000 Subject: [PATCH] Kill CK_Unknown and flesh out the documentation for the existing CastKinds. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119331 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Expr.h | 1 - include/clang/AST/OperationKinds.h | 171 ++++++++++++++++++++--------- lib/AST/Expr.cpp | 2 - lib/AST/ExprConstant.cpp | 29 ----- lib/Checker/GRExprEngine.cpp | 1 - lib/CodeGen/CGExpr.cpp | 1 - lib/CodeGen/CGExprAgg.cpp | 2 - lib/CodeGen/CGExprScalar.cpp | 5 - lib/Sema/SemaCXXCast.cpp | 4 +- lib/Sema/SemaChecking.cpp | 2 - 10 files changed, 123 insertions(+), 95 deletions(-) diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 7e67dde57b..eae3e69476 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -2004,7 +2004,6 @@ private: // fallthrough to check for null base path case CK_Dependent: - case CK_Unknown: case CK_NoOp: case CK_PointerToBoolean: case CK_IntegralToBoolean: diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index d8aa934385..cce351a770 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -17,116 +17,169 @@ namespace clang { -/// CastKind - the kind of cast this represents. +/// CastKind - The kind of operation required for a conversion. enum CastKind { - /// CK_Unknown - Unknown cast kind. - /// FIXME: The goal is to get rid of this and make all casts have a - /// kind so that the AST client doesn't have to try to figure out what's - /// going on. - CK_Unknown, - - /// CK_Dependent - This explicit cast cannot yet be analyzed because - /// the type or expression is dependent. + /// CK_Dependent - A conversion which cannot yet be analyzed because + /// either the expression or target type is dependent. These are + /// created only for explicit casts; dependent ASTs aren't required + /// to even approximately type-check. + /// (T*) malloc(sizeof(T)) + /// reinterpret_cast(A::alloc()); CK_Dependent, - /// CK_BitCast - Used for reinterpret_cast. + /// CK_BitCast - A conversion which causes a bit pattern of one type + /// to be reinterpreted as a bit pattern of another type. Generally + /// the operands must have equivalent size and unrelated types. + /// + /// The pointer conversion char* -> int* is a bitcast. Many other + /// pointer conversions which are "physically" bitcasts are given + /// special cast kinds. + /// + /// Vector coercions are bitcasts. CK_BitCast, - /// CK_LValueBitCast - Used for reinterpret_cast of expressions to - /// a reference type. + /// CK_LValueBitCast - A conversion which reinterprets the address of + /// an l-value as an l-value of a different kind. Used for + /// reinterpret_casts of l-value expressions to reference types. + /// bool b; reinterpret_cast(b) = 'a'; CK_LValueBitCast, - /// CK_NoOp - Used for const_cast. + /// CK_NoOp - A conversion which does not affect the type other than + /// (possibly) adding qualifiers. + /// int -> int + /// char** -> const char * const * CK_NoOp, - /// CK_BaseToDerived - Base to derived class casts. + /// CK_BaseToDerived - A conversion from a C++ class pointer/reference + /// to a derived class pointer/reference. + /// B *b = static_cast(a); CK_BaseToDerived, - /// CK_DerivedToBase - Derived to base class casts. + /// CK_DerivedToBase - A conversion from a C++ class pointer + /// to a base class pointer. + /// A *a = new B(); CK_DerivedToBase, - /// CK_UncheckedDerivedToBase - Derived to base class casts that - /// assume that the derived pointer is not null. + /// CK_UncheckedDerivedToBase - A conversion from a C++ class + /// pointer/reference to a base class that can assume that the + /// derived pointer is not null. + /// const A &a = B(); + /// b->method_from_a(); CK_UncheckedDerivedToBase, - /// CK_Dynamic - Dynamic cast. + /// CK_Dynamic - A C++ dynamic_cast. CK_Dynamic, - /// CK_ToUnion - Cast to union (GCC extension). + /// CK_ToUnion - The GCC cast-to-union extension. + /// int -> union { int x; float y; } + /// float -> union { int x; float y; } CK_ToUnion, /// CK_ArrayToPointerDecay - Array to pointer decay. + /// int[10] -> int* + /// char[5][6] -> char(*)[6] CK_ArrayToPointerDecay, /// CK_FunctionToPointerDecay - Function to pointer decay. + /// void(int) -> void(*)(int) CK_FunctionToPointerDecay, - /// CK_NullToPointer - Null pointer to pointer. + /// CK_NullToPointer - Null pointer constant to pointer, ObjC + /// pointer, or block pointer. + /// (void*) 0 + /// void (^block)() = 0; CK_NullToPointer, - /// CK_NullToMemberPointer - Null pointer to member pointer. + /// CK_NullToMemberPointer - Null pointer constant to member pointer. + /// int A::*mptr = 0; + /// int (A::*fptr)(int) = nullptr; CK_NullToMemberPointer, /// CK_BaseToDerivedMemberPointer - Member pointer in base class to /// member pointer in derived class. + /// int B::*mptr = &A::member; CK_BaseToDerivedMemberPointer, /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to /// member pointer in base class. + /// int A::*mptr = static_cast(&B::member); CK_DerivedToBaseMemberPointer, + /// CK_MemberPointerToBoolean - Member pointer to boolean. A check + /// against the null member pointer. + CK_MemberPointerToBoolean, + /// CK_UserDefinedConversion - Conversion using a user defined type /// conversion function. + /// struct A { operator int(); }; int i = int(A()); CK_UserDefinedConversion, - /// CK_ConstructorConversion - Conversion by constructor + /// CK_ConstructorConversion - Conversion by constructor. + /// struct A { A(int); }; A a = A(10); CK_ConstructorConversion, - /// CK_IntegralToPointer - Integral to pointer + /// CK_IntegralToPointer - Integral to pointer. A special kind of + /// reinterpreting conversion. Applies to normal, ObjC, and block + /// pointers. + /// (char*) 0x1001aab0 + /// reinterpret_cast(0) CK_IntegralToPointer, - /// CK_PointerToIntegral - Pointer to integral + /// CK_PointerToIntegral - Pointer to integral. A special kind of + /// reinterpreting conversion. Applies to normal, ObjC, and block + /// pointers. + /// (intptr_t) "help!" CK_PointerToIntegral, - /// CK_PointerToBoolean - Pointer to boolean (i.e. is not null) + /// CK_PointerToBoolean - Pointer to boolean conversion. A check + /// against null. Applies to normal, ObjC, and block pointers. CK_PointerToBoolean, - /// CK_ToVoid - Cast to void. + /// CK_ToVoid - Cast to void, discarding the computed value. + /// (void) malloc(2048) CK_ToVoid, - /// CK_VectorSplat - Casting from an integer/floating type to an extended - /// vector type with the same element type as the src type. Splats the - /// src expression into the destination expression. + /// CK_VectorSplat - A conversion from an arithmetic type to a + /// vector of that element type. Fills all elements ("splats") with + /// the source value. + /// __attribute__((ext_vector_type(4))) int v = 5; CK_VectorSplat, - /// CK_IntegralCast - A truncating or extending cast between integral - /// types of different size. + /// CK_IntegralCast - A cast between integral types (other than to + /// boolean). Variously a bitcast, a truncation, a sign-extension, + /// or a zero-extension. + /// long l = 5; + /// (unsigned) i CK_IntegralCast, - /// CK_IntegralToBoolean - Integral to boolean. + /// CK_IntegralToBoolean - Integral to boolean. A check against zero. + /// (bool) i CK_IntegralToBoolean, /// CK_IntegralToFloating - Integral to floating point. + /// float f = i; CK_IntegralToFloating, - /// CK_FloatingToIntegral - Floating point to integral. + /// CK_FloatingToIntegral - Floating point to integral. Rounds + /// towards zero, discarding any fractional component. + /// (int) f CK_FloatingToIntegral, /// CK_FloatingToBoolean - Floating point to boolean. + /// (bool) f CK_FloatingToBoolean, /// CK_FloatingCast - Casting between floating types of different size. + /// (double) f + /// (float) ld CK_FloatingCast, - /// CK_MemberPointerToBoolean - Member pointer to boolean - CK_MemberPointerToBoolean, - - /// CK_AnyPointerToObjCPointerCast - Casting any pointer to objective-c - /// pointer + /// CK_AnyPointerToObjCPointerCast - Casting any other pointer kind + /// to an Objective-C pointer. CK_AnyPointerToObjCPointerCast, - /// CK_AnyPointerToBlockPointerCast - Casting any pointer to block - /// pointer + /// CK_AnyPointerToBlockPointerCast - Casting any other pointer kind + /// to a block pointer. CK_AnyPointerToBlockPointerCast, /// \brief Converting between two Objective-C object types, which @@ -134,34 +187,52 @@ enum CastKind { /// object. CK_ObjCObjectLValueCast, - /// \brief Floating point real to floating point complex + /// \brief A conversion of a floating point real to a floating point + /// complex of the original type. Injects the value as the real + /// component with a zero imaginary component. + /// float -> _Complex float CK_FloatingRealToComplex, - /// \brief Floating pointer complex to floating point real + /// \brief Converts a floating point complex to floating point real + /// of the source's element type. Just discards the imaginary + /// component. + /// _Complex long double -> long double CK_FloatingComplexToReal, - /// \brief Converting a floating complex to bool + /// \brief Converts a floating point complex to bool by comparing + /// against 0+0i. CK_FloatingComplexToBoolean, - /// \brief Casting between floating point complex types of different size + /// \brief Converts between different floating point complex types. + /// _Complex float -> _Complex double CK_FloatingComplexCast, - /// \brief Casting from a floating complex to an integral complex + /// \brief Converts from a floating complex to an integral complex. + /// _Complex float -> _Complex int CK_FloatingComplexToIntegralComplex, - /// \brief Integral real to integral complex + /// \brief Converts from an integral real to an integral complex + /// whose element type matches the source. Injects the value as + /// the real component with a zero imaginary component. + /// long -> _Complex long CK_IntegralRealToComplex, - /// \brief Integral complex to integral real + /// \brief Converts an integral complex to an integral real of the + /// source's element type by discarding the imaginary component. + /// _Complex short -> short CK_IntegralComplexToReal, - /// \brief Converting an integral complex to bool + /// \brief Converts an integral complex to bool by comparing against + /// 0+0i. CK_IntegralComplexToBoolean, - /// \brief Casting between integral complex types of different size + /// \brief Converts between different integral complex types. + /// _Complex char -> _Complex long long + /// _Complex unsigned int -> _Complex signed int CK_IntegralComplexCast, - /// \brief Casting from an integral complex to a floating complex + /// \brief Converts from an integral complex to a floating complex. + /// _Complex unsigned -> _Complex float CK_IntegralComplexToFloatingComplex }; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 6ae334ed25..e36c02f3a9 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -740,8 +740,6 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, const char *CastExpr::getCastKindName() const { switch (getCastKind()) { - case CK_Unknown: - return "Unknown"; case CK_Dependent: return "Dependent"; case CK_BitCast: diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index d0b4c31937..f4685933dc 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -532,35 +532,6 @@ bool PointerExprEvaluator::VisitCastExpr(CastExpr* E) { default: break; - case CK_Unknown: { - // FIXME: The handling for CK_Unknown is ugly/shouldn't be necessary! - - // Check for pointer->pointer cast - if (SubExpr->getType()->isPointerType() || - SubExpr->getType()->isObjCObjectPointerType() || - SubExpr->getType()->isNullPtrType() || - SubExpr->getType()->isBlockPointerType()) - return Visit(SubExpr); - - if (SubExpr->getType()->isIntegralOrEnumerationType()) { - APValue Value; - if (!EvaluateIntegerOrLValue(SubExpr, Value, Info)) - break; - - if (Value.isInt()) { - Value.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType())); - Result.Base = 0; - Result.Offset = CharUnits::fromQuantity(Value.getInt().getZExtValue()); - return true; - } else { - Result.Base = Value.getLValueBase(); - Result.Offset = Value.getLValueOffset(); - return true; - } - } - break; - } - case CK_NoOp: case CK_BitCast: case CK_LValueBitCast: diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index d5c9ffa0af..017a6959cc 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -2541,7 +2541,6 @@ void GRExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex, } return; - case CK_Unknown: case CK_Dependent: case CK_ArrayToPointerDecay: case CK_BitCast: diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index ac40f3d580..2ef22b2401 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1804,7 +1804,6 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { } // Fall through to synthesize a temporary. - case CK_Unknown: case CK_BitCast: case CK_ArrayToPointerDecay: case CK_FunctionToPointerDecay: diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 31ba3373f0..00cfb21447 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -285,8 +285,6 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { break; } - // FIXME: Remove the CK_Unknown check here. - case CK_Unknown: case CK_NoOp: case CK_UserDefinedConversion: case CK_ConstructorConversion: diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 183afbe72b..98676d9ff7 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -999,11 +999,6 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { switch (Kind) { case CK_Dependent: llvm_unreachable("dependent cast kind in IR gen!"); - case CK_Unknown: - // FIXME: All casts should have a known kind! - //assert(0 && "Unknown cast kind!"); - break; - case CK_LValueBitCast: case CK_ObjCObjectLValueCast: { Value *V = EmitLValue(E).getAddress(); diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index e8e9deddc2..e57e89e4a4 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -526,7 +526,7 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, Self.Diag(OpRange.getBegin(), msg) << CT_Static << SrcExpr->getType() << DestType << OpRange; } - else if (Kind == CK_Unknown || Kind == CK_BitCast) + else if (Kind == CK_BitCast) Self.CheckCastAlign(SrcExpr, DestType, OpRange); } @@ -1413,7 +1413,7 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, << CastExpr->getType() << CastTy << R; } } - else if (Kind == CK_Unknown || Kind == CK_BitCast) + else if (Kind == CK_BitCast) CheckCastAlign(CastExpr, CastTy, R); return tcr != TC_Success; diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index e11d68ca19..83d7c0760e 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2280,8 +2280,6 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { IntRange OutputTypeRange = IntRange::forValueOfType(C, CE->getType()); bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast); - if (!isIntegerCast && CE->getCastKind() == CK_Unknown) - isIntegerCast = CE->getSubExpr()->getType()->isIntegerType(); // Assume that non-integer casts can span the full range of the type. if (!isIntegerCast) -- 2.40.0