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.

llvm-svn: 39415
This commit is contained in:
Steve Naroff 2007-04-25 21:10:52 +00:00
parent f633d0914a
commit 82ceca595e
3 changed files with 101 additions and 46 deletions

View File

@ -409,6 +409,40 @@ QualType Sema::UsualUnaryConversion(QualType t) {
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 @@ QualType Sema::UsualArithmeticConversions(QualType t1, QualType t2) {
// 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(

View File

@ -72,18 +72,13 @@ bool Type::isUnionType() const {
}
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::isRealFloatingType() const {
}
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::isArithmeticType() const {
}
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::isLvalue() const {
}
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:

View File

@ -409,6 +409,40 @@ QualType Sema::UsualUnaryConversion(QualType t) {
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 @@ QualType Sema::UsualArithmeticConversions(QualType t1, QualType t2) {
// 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(