[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