Switch more of Sema::CheckInitializerTypes over to
InitializationSequence. Specially, switch initialization of a C++
class type (either copy- or direct-initialization). 

Also, make sure that we create an elidable copy-construction when
performing copy initialization of a C++ class variable. Fixes PR5826.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91750 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp b/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp
index d02e5f3..aa53ebc 100644
--- a/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp
+++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp
@@ -8,13 +8,13 @@
 };
 
 template<typename T> 
-  T X<T>::value = 17; // expected-error{{initialize}}
+  T X<T>::value = 17; // expected-error{{no viable conversion}}
 
 struct InitOkay {
   InitOkay(int) { }
 };
 
-struct CannotInit { };
+struct CannotInit { }; // expected-note{{candidate function}}
 
 int &returnInt() { return X<int>::value; }
 float &returnFloat() { return X<float>::value; }
diff --git a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
index 58479cd..3cefeb8 100644
--- a/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
@@ -6,13 +6,13 @@
 };
 
 template<typename T>
-T X0<T>::value = 0; // expected-error{{initialize}}
+T X0<T>::value = 0; // expected-error{{no viable conversion}}
 
 struct X1 { 
   X1(int);
 };
 
-struct X2 { };
+struct X2 { }; // expected-note{{candidate function}}
 
 int& get_int() { return X0<int>::value; }
 X1& get_X1() { return X0<X1>::value; }
diff --git a/test/CXX/temp/temp.param/p3.cpp b/test/CXX/temp/temp.param/p3.cpp
index 7576aae..67d648e 100644
--- a/test/CXX/temp/temp.param/p3.cpp
+++ b/test/CXX/temp/temp.param/p3.cpp
@@ -15,7 +15,7 @@
 // could be interpreted as either a non-type template-parameter or a
 // type-parameter (because its identifier is the name of an already
 // existing class) is taken as a type-parameter. For example, 
-class T { /* ... */ }; 
+class T { /* ... */ };  // expected-note{{candidate function}}
 int i; 
 
 template<class T, T i> struct X2 {
@@ -23,6 +23,6 @@
   { 
     T t1 = i; //template-parameters T and i 
     ::T t2 = ::i; // global namespace members T and i  \
-    // expected-error{{cannot initialize}}
+    // expected-error{{no viable conversion}}
   } 
 };
diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp
index ae6014f..a0a35fa 100644
--- a/test/CodeGenCXX/constructor-init.cpp
+++ b/test/CodeGenCXX/constructor-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s
 
 extern "C" int printf(...);
 
@@ -59,3 +59,24 @@
   n1.PR();
 }
 
+// PR5826
+template <class T> struct A {
+  A() {}
+  A(int) {}
+  A(const A&) {}
+  ~A() {}
+  operator int() {return 0;}
+};
+
+// CHECK: define void @_Z1fv()
+void f() {
+  // CHECK: call void @_ZN1AIsEC1Ei
+  A<short> a4 = 97;
+
+  // CHECK-NEXT: store i32 17
+  int i = 17;
+
+  // CHECK-NEXT: call void @_ZN1AIsED1Ev
+  // CHECK-NOT: call void @_ZN1AIsED1Ev
+  // CHECK: ret void
+}
diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp
index 7a51f7e..aede25e 100644
--- a/test/SemaCXX/condition.cpp
+++ b/test/SemaCXX/condition.cpp
@@ -16,8 +16,8 @@
   for (;s;) ; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
   switch (s) {} // expected-error {{statement requires expression of integer type ('struct S' invalid)}}
 
-  while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize 'x' with an rvalue of type 'int'}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
-  while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize 'x' with an rvalue of type 'int'}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}}
+  while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate function}}
+  while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}} expected-note{{candidate function}}
   switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{incompatible type}}
 
   if (int x=0) { // expected-note 2 {{previous definition is here}}
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index fca5a4a..db322f4 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -56,14 +56,14 @@
 
 // This used to crash Clang.
 struct Flip;
-struct Flop {
+struct Flop { // expected-note{{candidate function}}
   Flop();
-  Flop(const Flip&);
+  Flop(const Flip&); // expected-note{{candidate function}}
 };
 struct Flip {
-  operator Flop() const;
+  operator Flop() const; // expected-note{{candidate function}}
 };
-Flop flop = Flip(); // expected-error {{cannot initialize 'flop' with an rvalue of type 'struct Flip'}}
+Flop flop = Flip(); // expected-error {{conversion from 'struct Flip' to 'struct Flop' is ambiguous}}
 
 // This tests that we don't add the second conversion declaration to the list of user conversions
 struct C {
diff --git a/test/SemaCXX/converting-constructor.cpp b/test/SemaCXX/converting-constructor.cpp
index e0e614e..e78798b 100644
--- a/test/SemaCXX/converting-constructor.cpp
+++ b/test/SemaCXX/converting-constructor.cpp
@@ -27,7 +27,7 @@
   FromShort(short s);
 };
 
-class FromShortExplicitly {
+class FromShortExplicitly { // expected-note{{candidate function}}
 public:
   explicit FromShortExplicitly(short s);
 };
@@ -36,7 +36,7 @@
   FromShort fs1(s);
   FromShort fs2 = s;
   FromShortExplicitly fse1(s);
-  FromShortExplicitly fse2 = s; // expected-error{{error: cannot initialize 'fse2' with an lvalue of type 'short'}}
+  FromShortExplicitly fse2 = s; // expected-error{{no viable conversion}}
 }
 
 // PR5519
diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp
index 8df0c63..ad14923 100644
--- a/test/SemaCXX/copy-initialization.cpp
+++ b/test/SemaCXX/copy-initialization.cpp
@@ -2,17 +2,17 @@
 class X {
 public:
   explicit X(const X&);
-  X(int*); // expected-note{{candidate function}}
+  X(int*); // expected-note 2{{candidate function}}
   explicit X(float*);
 };
 
 class Y : public X { };
 
 void f(Y y, int *ip, float *fp) {
-  X x1 = y; // expected-error{{no matching constructor for initialization of 'x1'; candidate is:}}
+  X x1 = y; // expected-error{{no matching constructor for initialization of 'class X'}}
   X x2 = 0;
   X x3 = ip;
-  X x4 = fp; // expected-error{{cannot initialize 'x4' with an lvalue of type 'float *'}}
+  X x4 = fp; // expected-error{{no viable conversion}}
 }
 
 struct foo {
diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp
index f7dc8f1..98aa721 100644
--- a/test/SemaCXX/dcl_init_aggr.cpp
+++ b/test/SemaCXX/dcl_init_aggr.cpp
@@ -115,9 +115,9 @@
 B2 b2_3 = { c2, a2, a2 };
 
 // C++ [dcl.init.aggr]p15:
-union u { int a; char* b; };
+union u { int a; char* b; }; // expected-note{{candidate function}}
 u u1 = { 1 }; 
 u u2 = u1; 
-u u3 = 1; // expected-error{{cannot initialize 'u3' with an rvalue of type 'int'}}
+u u3 = 1; // expected-error{{no viable conversion}}
 u u4 = { 0, "asdf" };  // expected-error{{excess elements in union initializer}}
 u u5 = { "asdf" }; // expected-error{{incompatible type initializing 'char const [5]', expected 'int'}}
diff --git a/test/SemaCXX/default1.cpp b/test/SemaCXX/default1.cpp
index 497a6b1..eab54f4 100644
--- a/test/SemaCXX/default1.cpp
+++ b/test/SemaCXX/default1.cpp
@@ -22,10 +22,10 @@
 
 void j(X x = 17);
 
-struct Y {
+struct Y { // expected-note 2{{candidate}}
   explicit Y(int);
 };
 
-void k(Y y = 17); // expected-error{{cannot initialize 'y' with an rvalue of type 'int'}}
+void k(Y y = 17); // expected-error{{no viable conversion}}
 
-void kk(Y = 17); // expected-error{{cannot initialize a value of type 'struct Y' with an rvalue of type 'int'}}
+void kk(Y = 17); // expected-error{{no viable conversion}}
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index dc8eda5..454af5e 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -178,7 +178,7 @@
 
 
 namespace somens {
-  struct a { };
+  struct a { }; // expected-note{{candidate function}}
 }
 
 template <typename T>
@@ -189,7 +189,7 @@
 // PR4452 / PR4451
 foo<somens:a> a2;  // expected-error {{unexpected ':' in nested name specifier}}
 
-somens::a a3 = a2; // expected-error {{cannot initialize 'a3' with an lvalue of type 'foo<somens::a>'}}
+somens::a a3 = a2; // expected-error {{no viable conversion}}
 
 // typedefs and using declarations.
 namespace test1 {
diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp
index 4c2f546..df3cc96 100644
--- a/test/SemaTemplate/default-expr-arguments.cpp
+++ b/test/SemaTemplate/default-expr-arguments.cpp
@@ -6,9 +6,9 @@
 template<>
 C<char>::C(int a0);
 
-struct S { };
+struct S { }; // expected-note 3 {{candidate function}}
 
-template<typename T> void f1(T a, T b = 10) { } // expected-error{{cannot initialize 'b' with an rvalue of type 'int'}}
+template<typename T> void f1(T a, T b = 10) { } // expected-error{{no viable conversion}}
 
 template<typename T> void f2(T a, T b = T()) { }
 
@@ -26,8 +26,8 @@
 }
 
 template<typename T> struct F {
-  F(T t = 10); // expected-error{{cannot initialize 't' with an rvalue of type 'int'}}
-  void f(T t = 10); // expected-error{{cannot initialize 't' with an rvalue of type 'int'}}
+  F(T t = 10); // expected-error{{no viable conversion}}
+  void f(T t = 10); // expected-error{{no viable conversion}}
 };
 
 struct FD : F<int> { };
diff --git a/test/SemaTemplate/fun-template-def.cpp b/test/SemaTemplate/fun-template-def.cpp
index 867b1c6..cc28553 100644
--- a/test/SemaTemplate/fun-template-def.cpp
+++ b/test/SemaTemplate/fun-template-def.cpp
@@ -8,7 +8,7 @@
 // Fake typeid, lacking a typeinfo header.
 namespace std { class type_info {}; }
 
-struct dummy {};
+struct dummy {}; // expected-note{{candidate function}}
 
 template<typename T>
 int f0(T x) {
@@ -40,7 +40,7 @@
   delete t1;
 
   dummy d1 = sizeof(t1); // FIXME: delayed checking okay?
-  dummy d2 = offsetof(T, foo); // expected-error {{cannot initialize 'd2'}}
+  dummy d2 = offsetof(T, foo); // expected-error {{no viable conversion}}
   dummy d3 = __alignof(u1); // FIXME: delayed checking okay?
   i1 = typeid(t1); // expected-error {{incompatible type assigning}}