[cfe-commits] r141336 - in /cfe/trunk: include/clang/AST/Type.h include/clang/Sema/Sema.h lib/Sema/SemaCXXCast.cpp lib/Sema/SemaExpr.cpp

John McCall rjmccall at apple.com
Thu Oct 6 16:25:11 PDT 2011


Author: rjmccall
Date: Thu Oct  6 18:25:11 2011
New Revision: 141336

URL: http://llvm.org/viewvc/llvm-project?rev=141336&view=rev
Log:
Move type-checking for C-style casts in C into the now-misnamed     
SemaCXXCast.cpp.  Should have no functionality change.


Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=141336&r1=141335&r2=141336&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Oct  6 18:25:11 2011
@@ -1362,6 +1362,7 @@
   /// various convenient purposes within Clang.  All such types are
   /// BuiltinTypes.
   bool isPlaceholderType() const;
+  const BuiltinType *getAsPlaceholderType() const;
 
   /// isSpecificPlaceholderType - Test for a specific placeholder type.
   bool isSpecificPlaceholderType(unsigned K) const;
@@ -4753,11 +4754,18 @@
 }
 
 inline bool Type::isPlaceholderType() const {
-  if (const BuiltinType *BT = getAs<BuiltinType>())
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
     return BT->isPlaceholderType();
   return false;
 }
 
+inline const BuiltinType *Type::getAsPlaceholderType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
+    if (BT->isPlaceholderType())
+      return BT;
+  return 0;
+}
+
 inline bool Type::isSpecificPlaceholderType(unsigned K) const {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(this))
     return (BT->getKind() == (BuiltinType::Kind) K);

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=141336&r1=141335&r2=141336&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Oct  6 18:25:11 2011
@@ -2493,6 +2493,7 @@
                                  TypeSourceInfo *Ty,
                                  SourceLocation RParenLoc,
                                  Expr *Op);
+  CastKind PrepareScalarCast(ExprResult &src, QualType destType);
 
   /// \brief Build an altivec or OpenCL literal.
   ExprResult BuildVectorLiteral(SourceLocation LParenLoc,
@@ -5769,11 +5770,6 @@
                                                       bool &ObjCConversion,
                                                 bool &ObjCLifetimeConversion);
 
-  /// CheckCCastTypes - Check type constraints for casting between
-  /// types under C semantics.
-  ExprResult CheckCCastTypes(SourceLocation CastStartLoc, SourceRange TypeRange, 
-                             QualType CastType, Expr *CastExpr, CastKind &Kind);
-
   ExprResult checkUnknownAnyCast(SourceRange TypeRange, QualType CastType,
                                  Expr *CastExpr, CastKind &CastKind,
                                  ExprValueKind &VK, CXXCastPath &Path);
@@ -5793,12 +5789,6 @@
   ExprResult CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *CastExpr,
                                 CastKind &Kind);
 
-  /// CXXBuildCStyleCastExpr - Check constraints of a C-style or function-style
-  /// cast under C++ semantics.
-  ExprResult CXXBuildCStyleCastExpr(SourceLocation LParenLoc,
-                                    TypeSourceInfo *TInfo,
-                                    SourceLocation RParenLoc,
-                                    Expr *CastExpr);
   ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
                                         SourceLocation LParenLoc,
                                         Expr *CastExpr,

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=141336&r1=141335&r2=141336&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Thu Oct  6 18:25:11 2011
@@ -1,4 +1,4 @@
-//===--- SemaNamedCast.cpp - Semantic Analysis for Named Casts ------------===//
+//===--- SemaCXXCast.cpp - Semantic Analysis for Casts --------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,13 +7,14 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This file implements semantic analysis for C++ named casts.
+//  This file implements semantic analysis for casts.
 //
 //===----------------------------------------------------------------------===//
 
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/Basic/PartialDiagnostic.h"
@@ -45,7 +46,15 @@
       : Self(S), SrcExpr(src), DestType(destType),
         ResultType(destType.getNonLValueExprType(S.Context)),
         ValueKind(Expr::getValueKindForType(destType)),
-        Kind(CK_Dependent), IsARCUnbridgedCast(false) {}
+        Kind(CK_Dependent), IsARCUnbridgedCast(false) {
+
+      if (const BuiltinType *placeholder =
+            src.get()->getType()->getAsPlaceholderType()) {
+        PlaceholderKind = placeholder->getKind();
+      } else {
+        PlaceholderKind = (BuiltinType::Kind) 0;
+      }
+    }
 
     Sema &Self;
     ExprResult SrcExpr;
@@ -54,16 +63,38 @@
     ExprValueKind ValueKind;
     CastKind Kind;
     bool IsARCUnbridgedCast;
+    BuiltinType::Kind PlaceholderKind;
     CXXCastPath BasePath;
 
     SourceRange OpRange;
     SourceRange DestRange;
 
+    // Top-level semantics-checking routines.
     void CheckConstCast();
     void CheckReinterpretCast();
     void CheckStaticCast();
     void CheckDynamicCast();
-    void CheckCStyleCast(bool FunctionalCast);
+    void CheckCXXCStyleCast(bool FunctionalCast);
+    void CheckCStyleCast();
+
+    // Internal convenience methods.
+
+    /// Try to handle the given placeholder expression kind.  Return
+    /// true if the source expression has the appropriate placeholder
+    /// kind.  A placeholder can only be claimed once.
+    bool claimPlaceholder(BuiltinType::Kind K) {
+      if (PlaceholderKind != K) return false;
+
+      PlaceholderKind = (BuiltinType::Kind) 0;
+      return true;
+    }
+
+    bool isPlaceholder() const {
+      return PlaceholderKind != 0;
+    }
+    bool isPlaceholder(BuiltinType::Kind K) const {
+      return PlaceholderKind == K;
+    }
 
     void checkCastAlign() {
       Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
@@ -74,6 +105,17 @@
       Self.CheckObjCARCConversion(OpRange, DestType, src, CCK);
       SrcExpr = src;
     }
+
+    /// Check for and handle non-overload placeholder expressions.
+    void checkNonOverloadPlaceholders() {
+      if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
+        return;
+
+      SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+      if (SrcExpr.isInvalid())
+        return;
+      PlaceholderKind = (BuiltinType::Kind) 0;
+    }
   };
 }
 
@@ -647,27 +689,29 @@
 /// Refer to C++ 5.2.9 for details. Static casts are mostly used for making
 /// implicit conversions explicit and getting rid of data loss warnings.
 void CastOperation::CheckStaticCast() {
+  if (isPlaceholder()) {
+    checkNonOverloadPlaceholders();
+    if (SrcExpr.isInvalid())
+      return;
+  }
+
   // This test is outside everything else because it's the only case where
   // a non-lvalue-reference target type does not lead to decay.
   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
   if (DestType->isVoidType()) {
-    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
-    if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
-      return;
-    if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
+    Kind = CK_ToVoid;
+
+    if (claimPlaceholder(BuiltinType::Overload)) {
       ExprResult SingleFunctionExpression = 
-         Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr.get(), 
+        Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr.get(), 
                 false, // Decay Function to ptr 
                 true, // Complain
                 OpRange, DestType, diag::err_bad_static_cast_overload);
-        if (SingleFunctionExpression.isUsable())
-        {
-          SrcExpr = SingleFunctionExpression;
-          Kind = CK_ToVoid;
-        }
+      if (SingleFunctionExpression.isUsable())
+        SrcExpr = SingleFunctionExpression;
     }
-    else
-      Kind = CK_ToVoid;
+
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
     return;
   }
 
@@ -1666,26 +1710,29 @@
   return TC_Success;
 }                                     
 
-void CastOperation::CheckCStyleCast(bool FunctionalStyle) {
-  // Check for casts from __unknown_any before anything else.
-  if (SrcExpr.get()->getType() == Self.Context.UnknownAnyTy) {
-     SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
-                                        SrcExpr.get(), Kind,
-                                        ValueKind, BasePath);
-     return;
-  }
+void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle) {
+  // Handle placeholders.
+  if (isPlaceholder()) {
+    // C-style casts can resolve __unknown_any types.
+    if (claimPlaceholder(BuiltinType::UnknownAny)) {
+      SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
+                                         SrcExpr.get(), Kind,
+                                         ValueKind, BasePath);
+      return;
+    }
 
+    checkNonOverloadPlaceholders();
+    if (SrcExpr.isInvalid())
+      return;
+  }  
+
+  // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
   // This test is outside everything else because it's the only case where
   // a non-lvalue-reference target type does not lead to decay.
-  // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
   if (DestType->isVoidType()) {
     Kind = CK_ToVoid;
 
-    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
-    if (SrcExpr.isInvalid())
-      return;
-
-    if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
+    if (claimPlaceholder(BuiltinType::Overload)) {
       SrcExpr = Self.ResolveAndFixSingleFunctionTemplateSpecialization(
                   SrcExpr.take(), /* Decay Function to ptr */ false, 
                   /* Complain */ true, DestRange, DestType,
@@ -1694,12 +1741,9 @@
         return;
     }
 
-    if (SrcExpr.get()->getType() == Self.Context.BoundMemberTy) {
-      Self.CheckPlaceholderExpr(SrcExpr.take()); // will always fail
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+    if (SrcExpr.isInvalid())
       return;
-    }
-
-    assert(!SrcExpr.get()->getType()->isPlaceholderType());
 
     return;
   }
@@ -1788,15 +1832,208 @@
     SrcExpr = ExprError();
 }
 
-ExprResult Sema::CXXBuildCStyleCastExpr(SourceLocation LPLoc,
-                                        TypeSourceInfo *CastTypeInfo,
-                                        SourceLocation RPLoc,
-                                        Expr *CastExpr) {
+/// Check the semantics of a C-style cast operation, in C.
+void CastOperation::CheckCStyleCast() {
+  assert(!Self.getLangOptions().CPlusPlus);
+
+  // Handle placeholders.
+  if (isPlaceholder()) {
+    // C-style casts can resolve __unknown_any types.
+    if (claimPlaceholder(BuiltinType::UnknownAny)) {
+      SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,
+                                         SrcExpr.get(), Kind,
+                                         ValueKind, BasePath);
+      return;
+    }
+
+    checkNonOverloadPlaceholders();
+    if (SrcExpr.isInvalid())
+      return;
+  }  
+
+  assert(!isPlaceholder());
+
+  // C99 6.5.4p2: the cast type needs to be void or scalar and the expression
+  // type needs to be scalar.
+  if (DestType->isVoidType()) {
+    // We don't necessarily do lvalue-to-rvalue conversions on this.
+    SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+    if (SrcExpr.isInvalid())
+      return;
+
+    // Cast to void allows any expr type.
+    Kind = CK_ToVoid;
+    return;
+  }
+
+  SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+  if (SrcExpr.isInvalid())
+    return;
+  QualType SrcType = SrcExpr.get()->getType();
+
+  if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
+                               diag::err_typecheck_cast_to_incomplete)) {
+    SrcExpr = ExprError();
+    return;
+  }
+
+  if (!DestType->isScalarType() && !DestType->isVectorType()) {
+    const RecordType *DestRecordTy = DestType->getAs<RecordType>();
+
+    if (DestRecordTy && Self.Context.hasSameUnqualifiedType(DestType, SrcType)){
+      // GCC struct/union extension: allow cast to self.
+      Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
+        << DestType << SrcExpr.get()->getSourceRange();
+      Kind = CK_NoOp;
+      return;
+    }
+
+    // GCC's cast to union extension.
+    if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) {
+      RecordDecl *RD = DestRecordTy->getDecl();
+      RecordDecl::field_iterator Field, FieldEnd;
+      for (Field = RD->field_begin(), FieldEnd = RD->field_end();
+           Field != FieldEnd; ++Field) {
+        if (Self.Context.hasSameUnqualifiedType(Field->getType(), SrcType) &&
+            !Field->isUnnamedBitfield()) {
+          Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
+            << SrcExpr.get()->getSourceRange();
+          break;
+        }
+      }
+      if (Field == FieldEnd) {
+        Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
+          << SrcType << SrcExpr.get()->getSourceRange();
+        SrcExpr = ExprError();
+        return;
+      }
+      Kind = CK_ToUnion;
+      return;
+    }
+
+    // Reject any other conversions to non-scalar types.
+    Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
+      << DestType << SrcExpr.get()->getSourceRange();
+    SrcExpr = ExprError();
+    return;
+  }
+
+  // The type we're casting to is known to be a scalar or vector.
+
+  // Require the operand to be a scalar or vector.
+  if (!SrcType->isScalarType() && !SrcType->isVectorType()) {
+    Self.Diag(SrcExpr.get()->getExprLoc(),
+              diag::err_typecheck_expect_scalar_operand)
+      << SrcType << SrcExpr.get()->getSourceRange();
+    SrcExpr = ExprError();
+    return;
+  }
+
+  if (DestType->isExtVectorType()) {
+    SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.take(), Kind);
+    return;
+  }
+
+  if (const VectorType *DestVecTy = DestType->getAs<VectorType>()) {
+    if (DestVecTy->getVectorKind() == VectorType::AltiVecVector &&
+          (SrcType->isIntegerType() || SrcType->isFloatingType())) {
+      Kind = CK_VectorSplat;
+    } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
+      SrcExpr = ExprError();
+    }
+    return;
+  }
+
+  if (SrcType->isVectorType()) {
+    if (Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))
+      SrcExpr = ExprError();
+    return;
+  }
+
+  // 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>(SrcExpr.get())) {
+    Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);
+    SrcExpr = ExprError();
+    return;
+  }
+
+  // If either type is a pointer, the other type has to be either an
+  // integer or a pointer.
+  if (!DestType->isArithmeticType()) {
+    if (!SrcType->isIntegralType(Self.Context) && SrcType->isArithmeticType()) {
+      Self.Diag(SrcExpr.get()->getExprLoc(),
+                diag::err_cast_pointer_from_non_pointer_int)
+        << SrcType << SrcExpr.get()->getSourceRange();
+      SrcExpr = ExprError();
+      return;
+    }
+  } else if (!SrcType->isArithmeticType()) {
+    if (!DestType->isIntegralType(Self.Context) &&
+        DestType->isArithmeticType()) {
+      Self.Diag(SrcExpr.get()->getLocStart(),
+           diag::err_cast_pointer_to_non_pointer_int)
+        << SrcType << SrcExpr.get()->getSourceRange();
+      SrcExpr = ExprError();
+      return;
+    }
+  }
+
+  // ARC imposes extra restrictions on casts.
+  if (Self.getLangOptions().ObjCAutoRefCount) {
+    checkObjCARCConversion(Sema::CCK_CStyleCast);
+    if (SrcExpr.isInvalid())
+      return;
+    
+    if (const PointerType *CastPtr = DestType->getAs<PointerType>()) {
+      if (const PointerType *ExprPtr = SrcType->getAs<PointerType>()) {
+        Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers();
+        Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
+        if (CastPtr->getPointeeType()->isObjCLifetimeType() && 
+            ExprPtr->getPointeeType()->isObjCLifetimeType() &&
+            !CastQuals.compatiblyIncludesObjCLifetime(ExprQuals)) {
+          Self.Diag(SrcExpr.get()->getLocStart(), 
+                    diag::err_typecheck_incompatible_ownership)
+            << SrcType << DestType << Sema::AA_Casting
+            << SrcExpr.get()->getSourceRange();
+          return;
+        }
+      }
+    } 
+    else if (!Self.CheckObjCARCUnavailableWeakConversion(DestType, SrcType)) {
+      Self.Diag(SrcExpr.get()->getLocStart(), 
+                diag::err_arc_convesion_of_weak_unavailable)
+        << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();
+      SrcExpr = ExprError();
+      return;
+    }
+  }
+  
+  Kind = Self.PrepareScalarCast(SrcExpr, DestType);
+  if (SrcExpr.isInvalid())
+    return;
+
+  if (Kind == CK_BitCast)
+    checkCastAlign();
+}
+
+ExprResult Sema::BuildCStyleCastExpr(SourceLocation LPLoc,
+                                     TypeSourceInfo *CastTypeInfo,
+                                     SourceLocation RPLoc,
+                                     Expr *CastExpr) {
   CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);  
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
   Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd());
 
-  Op.CheckCStyleCast(/*FunctionalStyle=*/ false);
+  if (getLangOptions().CPlusPlus) {
+    Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false);
+  } else {
+    Op.CheckCStyleCast();
+  }
+
   if (Op.SrcExpr.isInvalid())
     return ExprError();
 
@@ -1813,7 +2050,7 @@
   Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
   Op.OpRange = SourceRange(Op.DestRange.getBegin(), CastExpr->getLocEnd());
 
-  Op.CheckCStyleCast(/*FunctionalStyle=*/ true);
+  Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ true);
   if (Op.SrcExpr.isInvalid())
     return ExprError();
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=141336&r1=141335&r2=141336&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Oct  6 18:25:11 2011
@@ -3896,13 +3896,13 @@
 
 /// Prepares for a scalar cast, performing all the necessary stages
 /// except the final cast and returning the kind required.
-static CastKind PrepareScalarCast(Sema &S, ExprResult &Src, QualType DestTy) {
+CastKind Sema::PrepareScalarCast(ExprResult &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.get()->getType();
-  if (S.Context.hasSameUnqualifiedType(SrcTy, DestTy))
+  if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
     return CK_NoOp;
 
   switch (Type::ScalarTypeKind SrcKind = SrcTy->getScalarTypeKind()) {
@@ -3924,7 +3924,7 @@
       else if (SrcKind == Type::STK_CPointer)
         return CK_CPointerToObjCPointerCast;
       else {
-        maybeExtendBlockObject(S, Src);
+        maybeExtendBlockObject(*this, Src);
         return CK_BlockPointerToObjCPointerCast;
       }
     case Type::STK_Bool:
@@ -3945,7 +3945,7 @@
     case Type::STK_CPointer:
     case Type::STK_ObjCObjectPointer:
     case Type::STK_BlockPointer:
-      if (Src.get()->isNullPointerConstant(S.Context,
+      if (Src.get()->isNullPointerConstant(Context,
                                            Expr::NPC_ValueDependentIsNull))
         return CK_NullToPointer;
       return CK_IntegralToPointer;
@@ -3956,14 +3956,14 @@
     case Type::STK_Floating:
       return CK_IntegralToFloating;
     case Type::STK_IntegralComplex:
-      Src = S.ImpCastExprToType(Src.take(),
-                                DestTy->getAs<ComplexType>()->getElementType(),
-                                CK_IntegralCast);
+      Src = ImpCastExprToType(Src.take(),
+                              DestTy->castAs<ComplexType>()->getElementType(),
+                              CK_IntegralCast);
       return CK_IntegralRealToComplex;
     case Type::STK_FloatingComplex:
-      Src = S.ImpCastExprToType(Src.take(),
-                                DestTy->getAs<ComplexType>()->getElementType(),
-                                CK_IntegralToFloating);
+      Src = ImpCastExprToType(Src.take(),
+                              DestTy->castAs<ComplexType>()->getElementType(),
+                              CK_IntegralToFloating);
       return CK_FloatingRealToComplex;
     case Type::STK_MemberPointer:
       llvm_unreachable("member pointer type in C");
@@ -3979,14 +3979,14 @@
     case Type::STK_Integral:
       return CK_FloatingToIntegral;
     case Type::STK_FloatingComplex:
-      Src = S.ImpCastExprToType(Src.take(),
-                                DestTy->getAs<ComplexType>()->getElementType(),
-                                CK_FloatingCast);
+      Src = ImpCastExprToType(Src.take(),
+                              DestTy->castAs<ComplexType>()->getElementType(),
+                              CK_FloatingCast);
       return CK_FloatingRealToComplex;
     case Type::STK_IntegralComplex:
-      Src = S.ImpCastExprToType(Src.take(),
-                                DestTy->getAs<ComplexType>()->getElementType(),
-                                CK_FloatingToIntegral);
+      Src = ImpCastExprToType(Src.take(),
+                              DestTy->castAs<ComplexType>()->getElementType(),
+                              CK_FloatingToIntegral);
       return CK_IntegralRealToComplex;
     case Type::STK_CPointer:
     case Type::STK_ObjCObjectPointer:
@@ -4004,18 +4004,18 @@
     case Type::STK_IntegralComplex:
       return CK_FloatingComplexToIntegralComplex;
     case Type::STK_Floating: {
-      QualType ET = SrcTy->getAs<ComplexType>()->getElementType();
-      if (S.Context.hasSameType(ET, DestTy))
+      QualType ET = SrcTy->castAs<ComplexType>()->getElementType();
+      if (Context.hasSameType(ET, DestTy))
         return CK_FloatingComplexToReal;
-      Src = S.ImpCastExprToType(Src.take(), ET, CK_FloatingComplexToReal);
+      Src = ImpCastExprToType(Src.take(), ET, CK_FloatingComplexToReal);
       return CK_FloatingCast;
     }
     case Type::STK_Bool:
       return CK_FloatingComplexToBoolean;
     case Type::STK_Integral:
-      Src = S.ImpCastExprToType(Src.take(),
-                                SrcTy->getAs<ComplexType>()->getElementType(),
-                                CK_FloatingComplexToReal);
+      Src = ImpCastExprToType(Src.take(),
+                              SrcTy->castAs<ComplexType>()->getElementType(),
+                              CK_FloatingComplexToReal);
       return CK_FloatingToIntegral;
     case Type::STK_CPointer:
     case Type::STK_ObjCObjectPointer:
@@ -4033,18 +4033,18 @@
     case Type::STK_IntegralComplex:
       return CK_IntegralComplexCast;
     case Type::STK_Integral: {
-      QualType ET = SrcTy->getAs<ComplexType>()->getElementType();
-      if (S.Context.hasSameType(ET, DestTy))
+      QualType ET = SrcTy->castAs<ComplexType>()->getElementType();
+      if (Context.hasSameType(ET, DestTy))
         return CK_IntegralComplexToReal;
-      Src = S.ImpCastExprToType(Src.take(), ET, CK_IntegralComplexToReal);
+      Src = ImpCastExprToType(Src.take(), ET, CK_IntegralComplexToReal);
       return CK_IntegralCast;
     }
     case Type::STK_Bool:
       return CK_IntegralComplexToBoolean;
     case Type::STK_Floating:
-      Src = S.ImpCastExprToType(Src.take(),
-                                SrcTy->getAs<ComplexType>()->getElementType(),
-                                CK_IntegralComplexToReal);
+      Src = ImpCastExprToType(Src.take(),
+                              SrcTy->castAs<ComplexType>()->getElementType(),
+                              CK_IntegralComplexToReal);
       return CK_IntegralToFloating;
     case Type::STK_CPointer:
     case Type::STK_ObjCObjectPointer:
@@ -4059,196 +4059,6 @@
   llvm_unreachable("Unhandled scalar cast");
 }
 
-/// CheckCastTypes - Check type constraints for casting between types in C.
-ExprResult Sema::CheckCCastTypes(SourceLocation CastStartLoc,
-                                 SourceRange TypeRange, QualType CastType,
-                                 Expr *CastExpr, CastKind &Kind) {
-  assert(!getLangOptions().CPlusPlus);
-
-  if (CastExpr->getType() == Context.UnknownAnyTy) {
-    // We can safely ignore these here because C never has base paths
-    // or casts to l-values.
-    CXXCastPath BasePath;
-    ExprValueKind VK = VK_RValue;
-    return checkUnknownAnyCast(TypeRange, CastType, CastExpr, Kind, VK,
-                               BasePath);
-  }
-
-  ExprResult Result = CheckPlaceholderExpr(CastExpr);
-  if (Result.isInvalid())
-    return ExprError();
-  CastExpr = Result.take();
-
-  assert(!CastExpr->getType()->isPlaceholderType());
-
-  // C99 6.5.4p2: the cast type needs to be void or scalar and the expression
-  // type needs to be scalar.
-  if (CastType->isVoidType()) {
-    // We don't necessarily do lvalue-to-rvalue conversions on this.
-    ExprResult castExprRes = IgnoredValueConversions(CastExpr);
-    if (castExprRes.isInvalid())
-      return ExprError();
-    CastExpr = castExprRes.take();
-
-    // Cast to void allows any expr type.
-    Kind = CK_ToVoid;
-    return Owned(CastExpr);
-  }
-
-  ExprResult castExprRes = DefaultFunctionArrayLvalueConversion(CastExpr);
-  if (castExprRes.isInvalid())
-    return ExprError();
-  CastExpr = castExprRes.take();
-
-  if (RequireCompleteType(TypeRange.getBegin(), CastType,
-                          diag::err_typecheck_cast_to_incomplete))
-    return ExprError();
-
-  if (!CastType->isScalarType() && !CastType->isVectorType()) {
-    if (Context.hasSameUnqualifiedType(CastType, CastExpr->getType()) &&
-        (CastType->isStructureType() || CastType->isUnionType())) {
-      // GCC struct/union extension: allow cast to self.
-      // FIXME: Check that the cast destination type is complete.
-      Diag(TypeRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
-        << CastType << CastExpr->getSourceRange();
-      Kind = CK_NoOp;
-      return Owned(CastExpr);
-    }
-
-    if (CastType->isUnionType()) {
-      // GCC cast to union extension
-      RecordDecl *RD = CastType->getAs<RecordType>()->getDecl();
-      RecordDecl::field_iterator Field, FieldEnd;
-      for (Field = RD->field_begin(), FieldEnd = RD->field_end();
-           Field != FieldEnd; ++Field) {
-        if (Context.hasSameUnqualifiedType(Field->getType(),
-                                           CastExpr->getType()) &&
-            !Field->isUnnamedBitfield()) {
-          Diag(TypeRange.getBegin(), diag::ext_typecheck_cast_to_union)
-            << CastExpr->getSourceRange();
-          break;
-        }
-      }
-      if (Field == FieldEnd) {
-        Diag(TypeRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
-          << CastExpr->getType() << CastExpr->getSourceRange();
-        return ExprError();
-      }
-      Kind = CK_ToUnion;
-      return Owned(CastExpr);
-    }
-
-    // Reject any other conversions to non-scalar types.
-    Diag(TypeRange.getBegin(), diag::err_typecheck_cond_expect_scalar)
-      << CastType << CastExpr->getSourceRange();
-    return ExprError();
-  }
-
-  // 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()) {
-    Diag(CastExpr->getLocStart(),
-                diag::err_typecheck_expect_scalar_operand)
-      << CastExpr->getType() << CastExpr->getSourceRange();
-    return ExprError();
-  }
-
-  if (CastType->isExtVectorType())
-    return CheckExtVectorCast(TypeRange, CastType, CastExpr, Kind);
-
-  if (CastType->isVectorType()) {
-    if (CastType->getAs<VectorType>()->getVectorKind() ==
-        VectorType::AltiVecVector &&
-          (CastExpr->getType()->isIntegerType() ||
-           CastExpr->getType()->isFloatingType())) {
-      Kind = CK_VectorSplat;
-      return Owned(CastExpr);
-    } else if (CheckVectorCast(TypeRange, CastType, CastExpr->getType(),
-                               Kind)) {
-      return ExprError();
-    } else
-      return Owned(CastExpr);
-  }
-  if (CastExpr->getType()->isVectorType()) {
-    if (CheckVectorCast(TypeRange, CastExpr->getType(), CastType, Kind))
-      return ExprError();
-    else
-      return Owned(CastExpr);
-  }
-
-  // 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)) {
-    Diag(CastExpr->getLocStart(), diag::err_cast_selector_expr);
-    return ExprError();
-  }
-
-  // If either type is a pointer, the other type has to be either an
-  // integer or a pointer.
-  QualType CastExprType = CastExpr->getType();
-  if (!CastType->isArithmeticType()) {
-    if (!CastExprType->isIntegralType(Context) && 
-        CastExprType->isArithmeticType()) {
-      Diag(CastExpr->getLocStart(),
-           diag::err_cast_pointer_from_non_pointer_int)
-        << CastExprType << CastExpr->getSourceRange();
-      return ExprError();
-    }
-  } else if (!CastExpr->getType()->isArithmeticType()) {
-    if (!CastType->isIntegralType(Context) && CastType->isArithmeticType()) {
-      Diag(CastExpr->getLocStart(), diag::err_cast_pointer_to_non_pointer_int)
-        << CastType << CastExpr->getSourceRange();
-      return ExprError();
-    }
-  }
-
-  // ARC imposes extra restrictions on casts.
-  if (getLangOptions().ObjCAutoRefCount) {
-    CheckObjCARCConversion(SourceRange(CastStartLoc, CastExpr->getLocEnd()),
-                           CastType, CastExpr, CCK_CStyleCast);
-    
-    if (const PointerType *CastPtr = CastType->getAs<PointerType>()) {
-      if (const PointerType *ExprPtr = CastExprType->getAs<PointerType>()) {
-        Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers();
-        Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
-        if (CastPtr->getPointeeType()->isObjCLifetimeType() && 
-            ExprPtr->getPointeeType()->isObjCLifetimeType() &&
-            !CastQuals.compatiblyIncludesObjCLifetime(ExprQuals)) {
-          Diag(CastExpr->getLocStart(), 
-               diag::err_typecheck_incompatible_ownership)
-            << CastExprType << CastType << AA_Casting
-            << CastExpr->getSourceRange();
-          
-          return ExprError();
-        }
-      }
-    } 
-    else if (!CheckObjCARCUnavailableWeakConversion(CastType, CastExprType)) {
-           Diag(CastExpr->getLocStart(), 
-                diag::err_arc_convesion_of_weak_unavailable) << 1
-                << CastExprType << CastType 
-                << CastExpr->getSourceRange();
-          return ExprError();
-    }
-  }
-  
-  castExprRes = Owned(CastExpr);
-  Kind = PrepareScalarCast(*this, castExprRes, CastType);
-  if (castExprRes.isInvalid())
-    return ExprError();
-  CastExpr = castExprRes.take();
-
-  if (Kind == CK_BitCast)
-    CheckCastAlign(CastExpr, CastType, TypeRange);
-
-  return Owned(CastExpr);
-}
-
 bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
                            CastKind &Kind) {
   assert(VectorTy->isVectorType() && "Not a vector type!");
@@ -4301,7 +4111,7 @@
 
   QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
   ExprResult CastExprRes = Owned(CastExpr);
-  CastKind CK = PrepareScalarCast(*this, CastExprRes, DestElemTy);
+  CastKind CK = PrepareScalarCast(CastExprRes, DestElemTy);
   if (CastExprRes.isInvalid())
     return ExprError();
   CastExpr = ImpCastExprToType(CastExprRes.take(), DestElemTy, CK).take();
@@ -4369,25 +4179,6 @@
   return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, CastExpr);
 }
 
-ExprResult
-Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty,
-                          SourceLocation RParenLoc, Expr *CastExpr) {
-  if (getLangOptions().CPlusPlus)
-    return CXXBuildCStyleCastExpr(LParenLoc, Ty, RParenLoc, CastExpr);
-
-  CastKind Kind = CK_Invalid;
-  ExprResult CastResult =
-    CheckCCastTypes(LParenLoc, SourceRange(LParenLoc, RParenLoc),
-                    Ty->getType(), CastExpr, Kind);
-  if (CastResult.isInvalid())
-    return ExprError();
-  CastExpr = CastResult.take();
-
-  return Owned(CStyleCastExpr::Create(Context, Ty->getType(), VK_RValue, Kind,
-                                      CastExpr, /*base path*/ 0, Ty,
-                                      LParenLoc, RParenLoc));
-}
-
 ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc,
                                     SourceLocation RParenLoc, Expr *E,
                                     TypeSourceInfo *TInfo) {
@@ -4425,7 +4216,7 @@
       QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
       ExprResult Literal = Owned(exprs[0]);
       Literal = ImpCastExprToType(Literal.take(), ElemTy,
-                                  PrepareScalarCast(*this, Literal, ElemTy));
+                                  PrepareScalarCast(Literal, ElemTy));
       return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
     }
     else if (numExprs < numElems) {
@@ -4446,7 +4237,7 @@
         QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
         ExprResult Literal = Owned(exprs[0]);
         Literal = ImpCastExprToType(Literal.take(), ElemTy,
-                                    PrepareScalarCast(*this, Literal, ElemTy));
+                                    PrepareScalarCast(Literal, ElemTy));
         return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
     }
     
@@ -5432,7 +5223,7 @@
       // element type.
       QualType elType = cast<ExtVectorType>(LHSType)->getElementType();
       if (elType != RHSType) {
-        Kind = PrepareScalarCast(*this, RHS, elType);
+        Kind = PrepareScalarCast(RHS, elType);
         RHS = ImpCastExprToType(RHS.take(), elType, Kind);
       }
       Kind = CK_VectorSplat;
@@ -5465,7 +5256,7 @@
   // Arithmetic conversions.
   if (LHSType->isArithmeticType() && RHSType->isArithmeticType() &&
       !(getLangOptions().CPlusPlus && LHSType->isEnumeralType())) {
-    Kind = PrepareScalarCast(*this, RHS, LHSType);
+    Kind = PrepareScalarCast(RHS, LHSType);
     return Compatible;
   }
 





More information about the cfe-commits mailing list