Introduce _Complex conversions into the function overloading
system. Since C99 doesn't have overloading and C++ doesn't have
_Complex, there is no specification for this. Here's what I think
makes sense.
Complex conversions come in several flavors:
- Complex promotions: a complex -> complex conversion where the
underlying real-type conversion is a floating-point promotion. GCC
seems to call this a promotion, EDG does something else. This is
given "promotion" rank for determining the best viable function.
- Complex conversions: a complex -> complex conversion that is
not a complex promotion. This is given "conversion" rank for
determining the best viable function.
- Complex-real conversions: a real -> complex or complex -> real
conversion. This is given "conversion" rank for determining the
best viable function.
These rules are the same for C99 (when using the "overloadable"
attribute) and C++. However, there is one difference in the handling
of floating-point promotions: in C99, float -> long double and double
-> long double are considered promotions (so we give them "promotion"
rank), while C++ considers these conversions ("conversion" rank).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64343 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index aafddc5..a0fa0c7 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -424,6 +424,7 @@
StandardConversionSequence& SCS);
bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
+ bool IsComplexPromotion(QualType FromType, QualType ToType);
bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
QualType& ConvertedType, bool &IncompatibleObjC);
bool isObjCPointerConversion(QualType FromType, QualType ToType,
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 6ce8331..9f494d9 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -806,9 +806,12 @@
case ICK_Integral_Promotion:
case ICK_Floating_Promotion:
+ case ICK_Complex_Promotion:
case ICK_Integral_Conversion:
case ICK_Floating_Conversion:
+ case ICK_Complex_Conversion:
case ICK_Floating_Integral:
+ case ICK_Complex_Real:
case ICK_Compatible_Conversion:
// FIXME: Go deeper to get the unqualified type!
FromType = ToType.getUnqualifiedType();
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index e1939d3..48d3105 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -39,6 +39,9 @@
ICC_Qualification_Adjustment,
ICC_Promotion,
ICC_Promotion,
+ ICC_Promotion,
+ ICC_Conversion,
+ ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
@@ -63,6 +66,9 @@
ICR_Exact_Match,
ICR_Promotion,
ICR_Promotion,
+ ICR_Promotion,
+ ICR_Conversion,
+ ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
@@ -86,9 +92,12 @@
"Qualification",
"Integral promotion",
"Floating point promotion",
+ "Complex promotion",
"Integral conversion",
"Floating conversion",
+ "Complex conversion",
"Floating-integral conversion",
+ "Complex-real conversion",
"Pointer conversion",
"Pointer-to-member conversion",
"Boolean conversion",
@@ -552,6 +561,11 @@
SCS.Second = ICK_Floating_Promotion;
FromType = ToType.getUnqualifiedType();
}
+ // Complex promotion (Clang extension)
+ else if (IsComplexPromotion(FromType, ToType)) {
+ SCS.Second = ICK_Complex_Promotion;
+ FromType = ToType.getUnqualifiedType();
+ }
// Integral conversions (C++ 4.7).
// FIXME: isIntegralType shouldn't be true for enums in C++.
else if ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
@@ -564,6 +578,11 @@
SCS.Second = ICK_Floating_Conversion;
FromType = ToType.getUnqualifiedType();
}
+ // Complex conversions (C99 6.3.1.6)
+ else if (FromType->isComplexType() && ToType->isComplexType()) {
+ SCS.Second = ICK_Complex_Conversion;
+ FromType = ToType.getUnqualifiedType();
+ }
// Floating-integral conversions (C++ 4.9).
// FIXME: isIntegralType shouldn't be true for enums in C++.
else if ((FromType->isFloatingType() &&
@@ -574,6 +593,12 @@
SCS.Second = ICK_Floating_Integral;
FromType = ToType.getUnqualifiedType();
}
+ // Complex-real conversions (C99 6.3.1.7)
+ else if ((FromType->isComplexType() && ToType->isArithmeticType()) ||
+ (ToType->isComplexType() && FromType->isArithmeticType())) {
+ SCS.Second = ICK_Complex_Real;
+ FromType = ToType.getUnqualifiedType();
+ }
// Pointer conversions (C++ 4.10).
else if (IsPointerConversion(From, FromType, ToType, FromType,
IncompatibleObjC)) {
@@ -756,14 +781,42 @@
/// An rvalue of type float can be converted to an rvalue of type
/// double. (C++ 4.6p1).
if (const BuiltinType *FromBuiltin = FromType->getAsBuiltinType())
- if (const BuiltinType *ToBuiltin = ToType->getAsBuiltinType())
+ if (const BuiltinType *ToBuiltin = ToType->getAsBuiltinType()) {
if (FromBuiltin->getKind() == BuiltinType::Float &&
ToBuiltin->getKind() == BuiltinType::Double)
return true;
+ // C99 6.3.1.5p1:
+ // When a float is promoted to double or long double, or a
+ // double is promoted to long double [...].
+ if (!getLangOptions().CPlusPlus &&
+ (FromBuiltin->getKind() == BuiltinType::Float ||
+ FromBuiltin->getKind() == BuiltinType::Double) &&
+ (ToBuiltin->getKind() == BuiltinType::LongDouble))
+ return true;
+ }
+
return false;
}
+/// \brief Determine if a conversion is a complex promotion.
+///
+/// A complex promotion is defined as a complex -> complex conversion
+/// where the conversion between the underlying real types is a
+/// floating-point conversion.
+bool Sema::IsComplexPromotion(QualType FromType, QualType ToType) {
+ const ComplexType *FromComplex = FromType->getAsComplexType();
+ if (!FromComplex)
+ return false;
+
+ const ComplexType *ToComplex = ToType->getAsComplexType();
+ if (!ToComplex)
+ return false;
+
+ return IsFloatingPointPromotion(FromComplex->getElementType(),
+ ToComplex->getElementType());
+}
+
/// BuildSimilarlyQualifiedPointerType - In a pointer conversion from
/// the pointer type FromPtr to a pointer to type ToPointee, with the
/// same type qualifiers as FromPtr has on its pointee type. ToType,
diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h
index 2511c2d..3da8eca 100644
--- a/lib/Sema/SemaOverload.h
+++ b/lib/Sema/SemaOverload.h
@@ -33,9 +33,12 @@
ICK_Qualification, ///< Qualification conversions (C++ 4.4)
ICK_Integral_Promotion, ///< Integral promotions (C++ 4.5)
ICK_Floating_Promotion, ///< Floating point promotions (C++ 4.6)
+ ICK_Complex_Promotion, ///< Complex promotions (Clang extension)
ICK_Integral_Conversion, ///< Integral conversions (C++ 4.7)
ICK_Floating_Conversion, ///< Floating point conversions (C++ 4.8)
+ ICK_Complex_Conversion, ///< Complex conversions (C99 6.3.1.6)
ICK_Floating_Integral, ///< Floating-integral conversions (C++ 4.9)
+ ICK_Complex_Real, ///< Complex-real conversions (C99 6.3.1.7)
ICK_Pointer_Conversion, ///< Pointer conversions (C++ 4.10)
ICK_Pointer_Member, ///< Pointer-to-member conversions (C++ 4.11)
ICK_Boolean_Conversion, ///< Boolean conversions (C++ 4.12)