[cfe-commits] r124615 - /cfe/trunk/lib/Sema/SemaExpr.cpp

John McCall rjmccall at apple.com
Mon Jan 31 14:28:28 PST 2011


Author: rjmccall
Date: Mon Jan 31 16:28:28 2011
New Revision: 124615

URL: http://llvm.org/viewvc/llvm-project?rev=124615&view=rev
Log:
Slightly reorganize CheckAssignmentConstraints and remove some redundant
logic.


Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=124615&r1=124614&r2=124615&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jan 31 16:28:28 2011
@@ -5557,16 +5557,9 @@
   lhsType = Context.getCanonicalType(lhsType).getUnqualifiedType();
   rhsType = Context.getCanonicalType(rhsType).getUnqualifiedType();
 
+  // Common case: no conversion required.
   if (lhsType == rhsType) {
     Kind = CK_NoOp;
-    return Compatible; // Common case: fast path an exact match.
-  }
-
-  if ((lhsType->isObjCClassType() &&
-       (Context.hasSameType(rhsType, Context.ObjCClassRedefinitionType))) ||
-     (rhsType->isObjCClassType() &&
-       (Context.hasSameType(lhsType, Context.ObjCClassRedefinitionType)))) {
-    Kind = CK_BitCast;
     return Compatible;
   }
 
@@ -5584,6 +5577,7 @@
     }
     return Incompatible;
   }
+
   // Allow scalar to ExtVector assignments, and assignments of an ExtVector type
   // to the same ExtVector type.
   if (lhsType->isExtVectorType()) {
@@ -5602,6 +5596,7 @@
     }
   }
 
+  // Conversions to or from vector type.
   if (lhsType->isVectorType() || rhsType->isVectorType()) {
     if (lhsType->isVectorType() && rhsType->isVectorType()) {
       // Allow assignments of an AltiVec vector type to an equivalent GCC
@@ -5623,146 +5618,173 @@
     return Incompatible;
   }
 
+  // Arithmetic conversions.
   if (lhsType->isArithmeticType() && rhsType->isArithmeticType() &&
       !(getLangOptions().CPlusPlus && lhsType->isEnumeralType())) {
     Kind = PrepareScalarCast(*this, rhs, lhsType);
     return Compatible;
   }
 
-  if (isa<PointerType>(lhsType)) {
-    if (rhsType->isIntegerType()) {
-      Kind = CK_IntegralToPointer; // FIXME: null?
-      return IntToPointer;
-    }
-
+  // Conversions to normal pointers.
+  if (const PointerType *lhsPointer = dyn_cast<PointerType>(lhsType)) {
+    // U* -> T*
     if (isa<PointerType>(rhsType)) {
       Kind = CK_BitCast;
       return CheckPointerTypesForAssignment(lhsType, rhsType);
     }
 
-    // In general, C pointers are not compatible with ObjC object pointers.
+    // int -> T*
+    if (rhsType->isIntegerType()) {
+      Kind = CK_IntegralToPointer; // FIXME: null?
+      return IntToPointer;
+    }
+
+    // C pointers are not compatible with ObjC object pointers,
+    // with two exceptions:
     if (isa<ObjCObjectPointerType>(rhsType)) {
-      Kind = CK_AnyPointerToObjCPointerCast;
-      if (lhsType->isVoidPointerType()) // an exception to the rule.
+      //  - conversions to void*
+      if (lhsPointer->getPointeeType()->isVoidType()) {
+        Kind = CK_AnyPointerToObjCPointerCast;
         return Compatible;
-      return IncompatiblePointer;
-    }
-    if (rhsType->getAs<BlockPointerType>()) {
-      if (lhsType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
+      }
+
+      //  - conversions from 'Class' to the redefinition type
+      if (rhsType->isObjCClassType() &&
+          Context.hasSameType(lhsType, Context.ObjCClassRedefinitionType)) {
         Kind = CK_BitCast;
         return Compatible;
       }
 
-      // Treat block pointers as objects.
-      if (getLangOptions().ObjC1 && lhsType->isObjCIdType()) {
-        Kind = CK_AnyPointerToObjCPointerCast;
+      Kind = CK_BitCast;
+      return IncompatiblePointer;
+    }
+
+    // U^ -> void*
+    if (rhsType->getAs<BlockPointerType>()) {
+      if (lhsPointer->getPointeeType()->isVoidType()) {
+        Kind = CK_BitCast;
         return Compatible;
       }
     }
+
     return Incompatible;
   }
 
+  // Conversions to block pointers.
   if (isa<BlockPointerType>(lhsType)) {
+    // U^ -> T^
+    if (rhsType->isBlockPointerType()) {
+      Kind = CK_AnyPointerToBlockPointerCast;
+      return CheckBlockPointerTypesForAssignment(lhsType, rhsType);
+    }
+
+    // int or null -> T^
     if (rhsType->isIntegerType()) {
       Kind = CK_IntegralToPointer; // FIXME: null
       return IntToBlockPointer;
     }
 
-    Kind = CK_AnyPointerToObjCPointerCast;
-
-    // Treat block pointers as objects.
-    if (getLangOptions().ObjC1 && rhsType->isObjCIdType())
+    // id -> T^
+    if (getLangOptions().ObjC1 && rhsType->isObjCIdType()) {
+      Kind = CK_AnyPointerToBlockPointerCast;
       return Compatible;
+    }
 
-    if (rhsType->isBlockPointerType())
-      return CheckBlockPointerTypesForAssignment(lhsType, rhsType);
-
+    // void* -> T^
     if (const PointerType *RHSPT = rhsType->getAs<PointerType>())
-      if (RHSPT->getPointeeType()->isVoidType())
+      if (RHSPT->getPointeeType()->isVoidType()) {
+        Kind = CK_AnyPointerToBlockPointerCast;
         return Compatible;
+      }
 
     return Incompatible;
   }
 
+  // Conversions to Objective-C pointers.
   if (isa<ObjCObjectPointerType>(lhsType)) {
+    // A* -> B*
+    if (rhsType->isObjCObjectPointerType()) {
+      Kind = CK_BitCast;
+      return CheckObjCPointerTypesForAssignment(lhsType, rhsType);
+    }
+
+    // int or null -> A*
     if (rhsType->isIntegerType()) {
       Kind = CK_IntegralToPointer; // FIXME: null
       return IntToPointer;
     }
 
-    Kind = CK_BitCast;
-
-    // In general, C pointers are not compatible with ObjC object pointers.
+    // In general, C pointers are not compatible with ObjC object pointers,
+    // with two exceptions:
     if (isa<PointerType>(rhsType)) {
-      if (rhsType->isVoidPointerType()) // an exception to the rule.
+      //  - conversions from 'void*'
+      if (rhsType->isVoidPointerType()) {
+        Kind = CK_AnyPointerToObjCPointerCast;
         return Compatible;
-      return IncompatiblePointer;
-    }
-    if (rhsType->isObjCObjectPointerType()) {
-      return CheckObjCPointerTypesForAssignment(lhsType, rhsType);
-    }
-    if (const PointerType *RHSPT = rhsType->getAs<PointerType>()) {
-      if (RHSPT->getPointeeType()->isVoidType())
+      }
+
+      //  - conversions to 'Class' from its redefinition type
+      if (lhsType->isObjCClassType() &&
+          Context.hasSameType(rhsType, Context.ObjCClassRedefinitionType)) {
+        Kind = CK_BitCast;
         return Compatible;
+      }
+
+      Kind = CK_AnyPointerToObjCPointerCast;
+      return IncompatiblePointer;
     }
-    // Treat block pointers as objects.
-    if (rhsType->isBlockPointerType())
+
+    // T^ -> A*
+    if (rhsType->isBlockPointerType()) {
+      Kind = CK_AnyPointerToObjCPointerCast;
       return Compatible;
+    }
+
     return Incompatible;
   }
+
+  // Conversions from pointers that are not covered by the above.
   if (isa<PointerType>(rhsType)) {
-    // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
+    // T* -> _Bool
     if (lhsType == Context.BoolTy) {
       Kind = CK_PointerToBoolean;
       return Compatible;
     }
 
+    // T* -> int
     if (lhsType->isIntegerType()) {
       Kind = CK_PointerToIntegral;
       return PointerToInt;
     }
 
-    if (isa<BlockPointerType>(lhsType) &&
-        rhsType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
-      Kind = CK_AnyPointerToBlockPointerCast;
-      return Compatible;
-    }
     return Incompatible;
   }
+
+  // Conversions from Objective-C pointers that are not covered by the above.
   if (isa<ObjCObjectPointerType>(rhsType)) {
-    // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
+    // T* -> _Bool
     if (lhsType == Context.BoolTy) {
       Kind = CK_PointerToBoolean;
       return Compatible;
     }
 
+    // T* -> int
     if (lhsType->isIntegerType()) {
       Kind = CK_PointerToIntegral;
       return PointerToInt;
     }
 
-    Kind = CK_BitCast;
-
-    // In general, C pointers are not compatible with ObjC object pointers.
-    if (isa<PointerType>(lhsType)) {
-      if (lhsType->isVoidPointerType()) // an exception to the rule.
-        return Compatible;
-      return IncompatiblePointer;
-    }
-    if (isa<BlockPointerType>(lhsType) &&
-        rhsType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
-      Kind = CK_AnyPointerToBlockPointerCast;
-      return Compatible;
-    }
     return Incompatible;
   }
 
+  // struct A -> struct B
   if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
     if (Context.typesAreCompatible(lhsType, rhsType)) {
       Kind = CK_NoOp;
       return Compatible;
     }
   }
+
   return Incompatible;
 }
 





More information about the cfe-commits mailing list