[cfe-commits] r39412 - in /cfe/cfe/trunk: AST/SemaExpr.cpp AST/Type.cpp Sema/SemaExpr.cpp include/clang/AST/Type.h
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:44:05 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:44:05 2007
New Revision: 39412
URL: http://llvm.org/viewvc/llvm-project?rev=39412&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
-Lot's of detail work in UsualArithmeticConversion(). Needed to expand
the code for dealing with floating types. This code still has a couple
of FIXME's and could be refactored a bit.
-Added a bunch of Type predicates to simplify the float conversions.
Used the opportunity to convert a bunch of predicates to dyn_cast (it's cleaner
when just dealing with Builtin types).
Modified:
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/AST/Type.cpp
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/AST/Type.h
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39412&r1=39411&r2=39412&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:05 2007
@@ -428,13 +428,81 @@
return t1;
// at this point, we have two different arithmetic types. Handle the
- // real floating types first (C99 6.3.1.8p1). If either operand is float,
- // double, or long double, the result is float, double, or long double.
- if (t1->isRealFloatingType())
- return t1;
- else if (t2->isRealFloatingType())
- return t2;
-
+ // six floating types first (C99 6.3.1.8p1).
+ if (t1->isFloatingType() || t2->isFloatingType()) {
+ if (t1->isRealFloatingType() && t2->isRealFloatingType()) {
+ // types are homogeneous, return the type with the greatest precision
+ if (t1->isLongDoubleType())
+ return t1;
+ else if (t2->isLongDoubleType())
+ return t2;
+ if (t1->isDoubleType())
+ return t1;
+ else if (t2->isDoubleType())
+ return t2;
+ assert(0 && "UsualArithmeticConversions(): floating point conversion");
+ } else if (t1->isComplexType() && t2->isComplexType()) {
+ // types are homogeneous, return the type with the greatest precision
+ if (t1->isLongDoubleComplexType())
+ return t1;
+ else if (t2->isLongDoubleComplexType())
+ return t2;
+ if (t1->isDoubleComplexType())
+ return t1;
+ else if (t2->isDoubleComplexType())
+ return t2;
+ assert(0 && "UsualArithmeticConversions(): floating point conversion");
+ }
+ // type are heterogeneous, handle various permutations.
+ if (t1->isRealFloatingType()) {
+ if (t2->isIntegerType())
+ return t1;
+
+ // return the complex type with the greatest precision (across domains).
+ if (t2->isComplexType()) {
+ if (t1->isLongDoubleType()) {
+ if (t2->isLongDoubleComplexType())
+ return t2;
+ else
+ return t1; // FIXME: need to return "long double _Complex"?
+ } else if (t1->isDoubleType()) {
+ if (t2->isLongDoubleComplexType() || t2->isDoubleComplexType())
+ return t2;
+ else
+ return t1; // FIXME: need to return "double _Complex"?
+ } else {
+ // t1 is a float, there is no need to promote t2 (the complex type).
+ return t2;
+ }
+ }
+ assert(0 && "UsualArithmeticConversions(): floating point conversion");
+ }
+ if (t1->isComplexType()) {
+ if (t2->isIntegerType())
+ return t1;
+
+ if (t2->isRealFloatingType()) {
+ // return the complex type with the greatest precision (across domains).
+ if (t2->isLongDoubleType()) {
+ if (t1->isLongDoubleComplexType())
+ return t1;
+ else
+ return t2; // FIXME: need to return "long double _Complex"?
+ } else if (t2->isDoubleType()) {
+ if (t1->isLongDoubleComplexType() || t1->isDoubleComplexType())
+ return t1;
+ else
+ return t2; // FIXME: need to return "double _Complex"?
+ } else {
+ // t2 is a float, there is no need to promote t1 (the complex type).
+ return t1;
+ }
+ }
+ assert(0 && "UsualArithmeticConversions(): floating point conversion");
+ }
+ if (t1->isIntegerType())
+ return t2;
+ }
bool t1Unsigned = t1->isUnsignedIntegerType();
bool t2Unsigned = t2->isUnsignedIntegerType();
Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39412&r1=39411&r2=39412&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:44:05 2007
@@ -87,43 +87,67 @@
}
bool Type::isSignedIntegerType() 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::SChar &&
BT->getKind() <= BuiltinType::LongLong;
- }
+ return false;
}
bool Type::isUnsignedIntegerType() 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::UChar &&
BT->getKind() <= BuiltinType::ULongLong;
- }
+ return false;
}
bool Type::isFloatingType() 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::Float &&
BT->getKind() <= BuiltinType::LongDoubleComplex;
- }
+ return false;
+}
+
+bool Type::isFloatType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::Float;
+ return false;
+}
+
+bool Type::isDoubleType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::Double;
+ return false;
+}
+
+bool Type::isLongDoubleType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::LongDouble;
+ return false;
+}
+
+bool Type::isFloatComplexType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::FloatComplex;
+ return false;
+}
+
+bool Type::isDoubleComplexType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::DoubleComplex;
+ return false;
+}
+
+bool Type::isLongDoubleComplexType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::LongDoubleComplex;
+ return false;
}
bool Type::isRealFloatingType() 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::Float &&
BT->getKind() <= BuiltinType::LongDouble;
- }
+ return false;
}
bool Type::isRealType() const {
@@ -143,23 +167,17 @@
}
bool Type::isComplexType() 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::FloatComplex &&
BT->getKind() <= BuiltinType::LongDoubleComplex;
- }
+ return false;
}
bool Type::isArithmeticType() 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;
- }
+ return false;
}
bool Type::isScalarType() const {
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39412&r1=39411&r2=39412&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:05 2007
@@ -428,13 +428,81 @@
return t1;
// at this point, we have two different arithmetic types. Handle the
- // real floating types first (C99 6.3.1.8p1). If either operand is float,
- // double, or long double, the result is float, double, or long double.
- if (t1->isRealFloatingType())
- return t1;
- else if (t2->isRealFloatingType())
- return t2;
-
+ // six floating types first (C99 6.3.1.8p1).
+ if (t1->isFloatingType() || t2->isFloatingType()) {
+ if (t1->isRealFloatingType() && t2->isRealFloatingType()) {
+ // types are homogeneous, return the type with the greatest precision
+ if (t1->isLongDoubleType())
+ return t1;
+ else if (t2->isLongDoubleType())
+ return t2;
+ if (t1->isDoubleType())
+ return t1;
+ else if (t2->isDoubleType())
+ return t2;
+ assert(0 && "UsualArithmeticConversions(): floating point conversion");
+ } else if (t1->isComplexType() && t2->isComplexType()) {
+ // types are homogeneous, return the type with the greatest precision
+ if (t1->isLongDoubleComplexType())
+ return t1;
+ else if (t2->isLongDoubleComplexType())
+ return t2;
+ if (t1->isDoubleComplexType())
+ return t1;
+ else if (t2->isDoubleComplexType())
+ return t2;
+ assert(0 && "UsualArithmeticConversions(): floating point conversion");
+ }
+ // type are heterogeneous, handle various permutations.
+ if (t1->isRealFloatingType()) {
+ if (t2->isIntegerType())
+ return t1;
+
+ // return the complex type with the greatest precision (across domains).
+ if (t2->isComplexType()) {
+ if (t1->isLongDoubleType()) {
+ if (t2->isLongDoubleComplexType())
+ return t2;
+ else
+ return t1; // FIXME: need to return "long double _Complex"?
+ } else if (t1->isDoubleType()) {
+ if (t2->isLongDoubleComplexType() || t2->isDoubleComplexType())
+ return t2;
+ else
+ return t1; // FIXME: need to return "double _Complex"?
+ } else {
+ // t1 is a float, there is no need to promote t2 (the complex type).
+ return t2;
+ }
+ }
+ assert(0 && "UsualArithmeticConversions(): floating point conversion");
+ }
+ if (t1->isComplexType()) {
+ if (t2->isIntegerType())
+ return t1;
+
+ if (t2->isRealFloatingType()) {
+ // return the complex type with the greatest precision (across domains).
+ if (t2->isLongDoubleType()) {
+ if (t1->isLongDoubleComplexType())
+ return t1;
+ else
+ return t2; // FIXME: need to return "long double _Complex"?
+ } else if (t2->isDoubleType()) {
+ if (t1->isLongDoubleComplexType() || t1->isDoubleComplexType())
+ return t1;
+ else
+ return t2; // FIXME: need to return "double _Complex"?
+ } else {
+ // t2 is a float, there is no need to promote t1 (the complex type).
+ return t1;
+ }
+ }
+ assert(0 && "UsualArithmeticConversions(): floating point conversion");
+ }
+ if (t1->isIntegerType())
+ return t2;
+ }
bool t1Unsigned = t1->isUnsignedIntegerType();
bool t2Unsigned = t2->isUnsignedIntegerType();
Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39412&r1=39411&r2=39412&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:44:05 2007
@@ -208,9 +208,20 @@
/// Helper methods to distinguish type categories. All type predicates
/// operate on the canonical type, ignoring typedefs.
bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
+
+ /// Floating point categories.
bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
bool isComplexType() const; // C99 6.2.5p11 (complex)
bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
+
+ /// Floating point types.
+ bool isFloatType() const;
+ bool isDoubleType() const;
+ bool isLongDoubleType() const;
+ bool isFloatComplexType() const;
+ bool isDoubleComplexType() const;
+ bool isLongDoubleComplexType() const;
+
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
bool isArithmeticType() const; // C99 6.2.5p18 (integral + floating)
bool isVoidType() const; // C99 6.2.5p19
More information about the cfe-commits
mailing list