[cfe-commits] r39415 - in /cfe/cfe/trunk: AST/SemaExpr.cpp AST/Type.cpp Sema/SemaExpr.cpp

Steve Naroff snaroff at apple.com
Wed Jul 11 09:44:07 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:44:07 2007
New Revision: 39415

URL: http://llvm.org/viewvc/llvm-project?rev=39415&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Implement FIXME's for signed/unsigned operands in UsualArithmeticConversions()...
- Added GetIntegerRank() and used it in the appropriate places.
- Added ConvertSignedWithGreaterRankThanUnsigned(), with a FIXME.
Misc...converted a bunch of static_cast usage to dyn_cast (in Type.cpp)

A and handled signed/unsigned combos.

Modified:
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/AST/Type.cpp
    cfe/cfe/trunk/Sema/SemaExpr.cpp

Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39415&r1=39414&r2=39415&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:07 2007
@@ -409,6 +409,40 @@
   return t;
 }
 
+/// GetIntegerRank - Helper function for UsualArithmeticConversions().
+static inline int GetIntegerRank(QualType t) {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(t.getCanonicalType())) {
+    switch (BT->getKind()) {
+    case BuiltinType::SChar:
+    case BuiltinType::UChar:
+      return 1;
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+      return 2;
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+      return 3;
+    case BuiltinType::Long:
+    case BuiltinType::ULong:
+      return 4;
+    case BuiltinType::LongLong:
+    case BuiltinType::ULongLong:
+      return 5;
+    default:
+      assert(0 && "getFloatingPointRank(): not a floating type");
+    }
+  }
+  return 0;
+}
+
+static inline QualType ConvertSignedWithGreaterRankThanUnsigned(
+  QualType signedType, QualType unsignedType) {
+  // FIXME: Need to check if the signed type can represent all values of the 
+  // unsigned type. If it can, then the result is the signed type. If it can't, 
+  // then the result is the unsigned version of the signed type.
+  return signedType; 
+}
+
 /// GetFloatingRank - Helper function for UsualArithmeticConversions().
 static inline int GetFloatingRank(QualType t) {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(t.getCanonicalType())) {
@@ -501,16 +535,21 @@
     // we have two real floating types, float/complex combos were handled above.
     return GetFloatingRank(lhs) >= GetFloatingRank(rhs) ? lhs : rhs;
   }
-  // Lastly, handle two integers.
+  // Lastly, handle two integers (C99 6.3.1.8p1)
   bool t1Unsigned = lhs->isUnsignedIntegerType();
   bool t2Unsigned = rhs->isUnsignedIntegerType();
   
-  if (t1Unsigned && t2Unsigned)
-    return lhs; // FIXME: return the unsigned type with the greatest rank
-  else if (!t1Unsigned && !t2Unsigned)
-    return lhs; // FIXME: return the signed type with the greatest rank
+  if ((t1Unsigned && t2Unsigned) || (!t1Unsigned && !t2Unsigned))
+    return GetIntegerRank(lhs) >= GetIntegerRank(rhs) ? lhs : rhs; 
+  
+  // We have two integer types with differing signs
+  QualType unsignedType = t1Unsigned ? lhs : rhs;
+  QualType signedType = t1Unsigned ? rhs : lhs;
+  
+  if (GetIntegerRank(unsignedType) >= GetIntegerRank(signedType))
+    return unsignedType;
   else 
-    return lhs; // FIXME: we have a mixture...
+    return ConvertSignedWithGreaterRankThanUnsigned(signedType, unsignedType); 
 }
 
 Action::ExprResult Sema::CheckMultiplicativeOperands(

Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39415&r1=39414&r2=39415&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:44:07 2007
@@ -72,18 +72,13 @@
 }
 
 bool Type::isIntegerType() const {
-  switch (CanonicalType->getTypeClass()) {
-  default: return false;
-  case Builtin:
-    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType.getTypePtr());
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&
            BT->getKind() <= BuiltinType::ULongLong;
-  case Tagged:
-    const TagType *TT = static_cast<TagType*>(CanonicalType.getTypePtr());
+  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
     if (TT->getDecl()->getKind() == Decl::Enum)
       return true;
-    return false;
-  }
+  return false;
 }
 
 bool Type::isSignedIntegerType() const {
@@ -115,19 +110,13 @@
 }
 
 bool Type::isRealType() const {
-  // this is equivalent to (isIntegerType() || isRealFloatingType()).
-  switch (CanonicalType->getTypeClass()) { // inlined for performance
-  default: return false;
-  case Builtin:
-    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType.getTypePtr());
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&
            BT->getKind() <= BuiltinType::LongDouble;
-  case Tagged:
-    const TagType *TT = static_cast<TagType*>(CanonicalType.getTypePtr());
+  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
     if (TT->getDecl()->getKind() == Decl::Enum)
       return true;
-    return false;
-  }
+  return false;
 }
 
 bool Type::isComplexType() const {
@@ -145,28 +134,17 @@
 }
 
 bool Type::isScalarType() const {
-  switch (CanonicalType->getTypeClass()) {
-  default: return false;
-  case Builtin:
-    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType.getTypePtr());
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() >= BuiltinType::Bool &&
            BT->getKind() <= BuiltinType::LongDoubleComplex;
-  case Pointer:
-    return true;
-  }
+  return CanonicalType->getTypeClass() == Pointer;
 }
 
 bool Type::isAggregateType() const {
-  switch (CanonicalType->getTypeClass()) {
-  default: return false;
-  case Array:
-    return true;
-  case Tagged:
-    const TagType *TT = static_cast<TagType*>(CanonicalType.getTypePtr());
+  if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
     if (TT->getDecl()->getKind() == Decl::Struct)
       return true;
-    return true;
-  }
+  return CanonicalType->getTypeClass() == Array;
 }
 
 
@@ -202,8 +180,7 @@
 }
 
 bool Type::isPromotableIntegerType() const {
-  if (CanonicalType->getTypeClass() == Builtin) {
-    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType.getTypePtr());
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
     switch (BT->getKind()) {
       case BuiltinType::Bool:
       case BuiltinType::Char:

Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39415&r1=39414&r2=39415&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:07 2007
@@ -409,6 +409,40 @@
   return t;
 }
 
+/// GetIntegerRank - Helper function for UsualArithmeticConversions().
+static inline int GetIntegerRank(QualType t) {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(t.getCanonicalType())) {
+    switch (BT->getKind()) {
+    case BuiltinType::SChar:
+    case BuiltinType::UChar:
+      return 1;
+    case BuiltinType::Short:
+    case BuiltinType::UShort:
+      return 2;
+    case BuiltinType::Int:
+    case BuiltinType::UInt:
+      return 3;
+    case BuiltinType::Long:
+    case BuiltinType::ULong:
+      return 4;
+    case BuiltinType::LongLong:
+    case BuiltinType::ULongLong:
+      return 5;
+    default:
+      assert(0 && "getFloatingPointRank(): not a floating type");
+    }
+  }
+  return 0;
+}
+
+static inline QualType ConvertSignedWithGreaterRankThanUnsigned(
+  QualType signedType, QualType unsignedType) {
+  // FIXME: Need to check if the signed type can represent all values of the 
+  // unsigned type. If it can, then the result is the signed type. If it can't, 
+  // then the result is the unsigned version of the signed type.
+  return signedType; 
+}
+
 /// GetFloatingRank - Helper function for UsualArithmeticConversions().
 static inline int GetFloatingRank(QualType t) {
   if (const BuiltinType *BT = dyn_cast<BuiltinType>(t.getCanonicalType())) {
@@ -501,16 +535,21 @@
     // we have two real floating types, float/complex combos were handled above.
     return GetFloatingRank(lhs) >= GetFloatingRank(rhs) ? lhs : rhs;
   }
-  // Lastly, handle two integers.
+  // Lastly, handle two integers (C99 6.3.1.8p1)
   bool t1Unsigned = lhs->isUnsignedIntegerType();
   bool t2Unsigned = rhs->isUnsignedIntegerType();
   
-  if (t1Unsigned && t2Unsigned)
-    return lhs; // FIXME: return the unsigned type with the greatest rank
-  else if (!t1Unsigned && !t2Unsigned)
-    return lhs; // FIXME: return the signed type with the greatest rank
+  if ((t1Unsigned && t2Unsigned) || (!t1Unsigned && !t2Unsigned))
+    return GetIntegerRank(lhs) >= GetIntegerRank(rhs) ? lhs : rhs; 
+  
+  // We have two integer types with differing signs
+  QualType unsignedType = t1Unsigned ? lhs : rhs;
+  QualType signedType = t1Unsigned ? rhs : lhs;
+  
+  if (GetIntegerRank(unsignedType) >= GetIntegerRank(signedType))
+    return unsignedType;
   else 
-    return lhs; // FIXME: we have a mixture...
+    return ConvertSignedWithGreaterRankThanUnsigned(signedType, unsignedType); 
 }
 
 Action::ExprResult Sema::CheckMultiplicativeOperands(





More information about the cfe-commits mailing list