- Change Type::isComplexType() to exlude GCC's complex integer extension. In general, we will keep the lowest level Type predicates "pure" (i.e. true to the C99 spec).

- Modify Sema::UsualArithmeticConversions() to work with the new definition of Type::isComplexType().

This is a nice cleanup and also fixes a bug submitted by Eli (which I've added to the test suite).

llvm-svn: 46005
This commit is contained in:
Steve Naroff 2008-01-15 19:36:10 +00:00
parent 4f7437f8af
commit 6fcfd0581d
4 changed files with 34 additions and 18 deletions

View File

@ -74,7 +74,9 @@ bool Type::isUnionType() const {
}
bool Type::isComplexType() const {
return isa<ComplexType>(CanonicalType);
if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
return CT->getElementType()->isFloatingType();
return false;
}
bool Type::isComplexIntegerType() const {

View File

@ -951,25 +951,12 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
// Handle complex types first (C99 6.3.1.8p1).
if (lhs->isComplexType() || rhs->isComplexType()) {
// Handle GCC complex int extension first.
// FIXME: need to verify these conversion rules are consistent with GCC.
const ComplexType *lhsComplexInt = lhs->getAsComplexIntegerType();
const ComplexType *rhsComplexInt = rhs->getAsComplexIntegerType();
if (lhsComplexInt && rhsComplexInt) {
if (Context.maxIntegerType(lhsComplexInt->getElementType(),
rhsComplexInt->getElementType()) == lhs) {
if (!isCompAssign) promoteExprToType(rhsExpr, lhs); // convert the rhs
return lhs;
}
if (!isCompAssign) promoteExprToType(lhsExpr, rhs); // convert the lhs
return rhs;
} else if (lhsComplexInt && rhs->isIntegerType()) {
// convert the rhs to the lhs complex type.
// if we have an integer operand, the result is the complex type.
if (rhs->isIntegerType()) { // convert the rhs to the lhs complex type.
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);
return lhs;
} else if (rhsComplexInt && lhs->isIntegerType()) {
// convert the lhs to the rhs complex type.
}
if (lhs->isIntegerType()) { // convert the lhs to the rhs complex type.
if (!isCompAssign) promoteExprToType(lhsExpr, rhs);
return rhs;
}
@ -1035,6 +1022,30 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
}
assert(0 && "Sema::UsualArithmeticConversions(): illegal float comparison");
}
if (lhs->isComplexIntegerType() || rhs->isComplexIntegerType()) {
// Handle GCC complex int extension.
// FIXME: need to verify these conversion rules are consistent with GCC.
const ComplexType *lhsComplexInt = lhs->getAsComplexIntegerType();
const ComplexType *rhsComplexInt = rhs->getAsComplexIntegerType();
if (lhsComplexInt && rhsComplexInt) {
if (Context.maxIntegerType(lhsComplexInt->getElementType(),
rhsComplexInt->getElementType()) == lhs) {
if (!isCompAssign) promoteExprToType(rhsExpr, lhs); // convert the rhs
return lhs;
}
if (!isCompAssign) promoteExprToType(lhsExpr, rhs); // convert the lhs
return rhs;
} else if (lhsComplexInt && rhs->isIntegerType()) {
// convert the rhs to the lhs complex type.
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);
return lhs;
} else if (rhsComplexInt && lhs->isIntegerType()) {
// convert the lhs to the rhs complex type.
if (!isCompAssign) promoteExprToType(lhsExpr, rhs);
return rhs;
}
}
// Finally, we have two differing integer types.
if (Context.maxIntegerType(lhs, rhs) == lhs) { // convert the rhs
if (!isCompAssign) promoteExprToType(rhsExpr, lhs);

View File

@ -276,6 +276,8 @@ public:
/// Floating point categories.
bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
/// isComplexType() does *not* include complex integers (a GCC extension).
/// isComplexIntegerType() can be used to test for complex integers.
bool isComplexType() const; // C99 6.2.5p11 (complex)
bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
bool isRealType() const; // C99 6.2.5p17 (real floating + integer)

View File

@ -7,6 +7,7 @@ __complex__ unsigned xx;
__complex__ signed yy;
__complex__ int result;
int ii;
int aa = 1 + 1.0iF;
result = arr*ii;
result = ii*brr;