diff options
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index e1939d329e9..48d31056a79 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -39,6 +39,9 @@ GetConversionCategory(ImplicitConversionKind Kind) { ICC_Qualification_Adjustment, ICC_Promotion, ICC_Promotion, + ICC_Promotion, + ICC_Conversion, + ICC_Conversion, ICC_Conversion, ICC_Conversion, ICC_Conversion, @@ -63,6 +66,9 @@ ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind) { ICR_Exact_Match, ICR_Promotion, ICR_Promotion, + ICR_Promotion, + ICR_Conversion, + ICR_Conversion, ICR_Conversion, ICR_Conversion, ICR_Conversion, @@ -86,9 +92,12 @@ const char* GetImplicitConversionName(ImplicitConversionKind Kind) { "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 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, 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 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, 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 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, 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 @@ bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType) /// 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, |