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/test/SemaCXX/complex-overload.cpp b/test/SemaCXX/complex-overload.cpp
new file mode 100644
index 0000000..4d27a20
--- /dev/null
+++ b/test/SemaCXX/complex-overload.cpp
@@ -0,0 +1,43 @@
+// RUN: clang -fsyntax-only -verify %s
+char *foo(float); // expected-note 3 {{candidate function}}
+
+void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv);
+  // Note: GCC and EDG reject these two, but they are valid C99 conversions
+  char *cp3 = foo(fc);
+  char *cp4 = foo(dc);
+}
+
+int *foo(float _Complex); // expected-note 3 {{candidate function}}
+
+void test_foo_2(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+  int *ip = foo(fc);
+  int *lp = foo(dc); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+}
+
+long *foo(double _Complex); // expected-note {{candidate function}}
+
+void test_foo_3(float fv, double dv, float _Complex fc, double _Complex dc) {
+  char *cp1 = foo(fv);
+  char *cp2 = foo(dv); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+  int *ip = foo(fc);
+  long *lp = foo(dc);
+}
+
+char *promote_or_convert(double _Complex);  // expected-note{{candidate function}}
+int *promote_or_convert(long double _Complex); // expected-note{{candidate function}} 
+
+void test_promote_or_convert(float f, float _Complex fc) {
+  char *cp = promote_or_convert(fc);
+  int *ip2 = promote_or_convert(f); // expected-error{{call to 'promote_or_convert' is ambiguous; candidates are:}}
+}
+
+char *promote_or_convert2(float);
+int *promote_or_convert2(double _Complex);
+
+void test_promote_or_convert(float _Complex fc) {
+  int *cp = promote_or_convert2(fc);
+}