Rework base and member initialization in constructors, with several
(necessarily simultaneous) changes:

  - CXXBaseOrMemberInitializer now contains only a single initializer
    rather than a set of initialiation arguments + a constructor. The
    single initializer covers all aspects of initialization, including
    constructor calls as necessary but also cleanup of temporaries
    created by the initializer (which we never handled
    before!).

  - Rework + simplify code generation for CXXBaseOrMemberInitializers,
    since we can now just emit the initializer as an initializer.

  - Switched base and member initialization over to the new
    initialization code (InitializationSequence), so that it

  - Improved diagnostics for the new initialization code when
    initializing bases and members, to match the diagnostics produced
    by the previous (special-purpose) code.

  - Simplify the representation of type-checked constructor initializers in
    templates; instead of keeping the fully-type-checked AST, which is
    rather hard to undo at template instantiation time, throw away the
    type-checked AST and store the raw expressions in the AST. This
    simplifies instantiation, but loses a little but of information in
    the AST.

  - When type-checking implicit base or member initializers within a
    dependent context, don't add the generated initializers into the
    AST, because they'll look like they were explicit.

  - Record in CXXConstructExpr when the constructor call is to
  initialize a base class, so that CodeGen does not have to infer it
  from context. This ensures that we call the right kind of
  constructor.

There are also a few "opportunity" fixes here that were needed to not
regress, for example:

  - Diagnose default-initialization of a const-qualified class that
    does not have a user-declared default constructor. We had this
    diagnostic specifically for bases and members, but missed it for
    variables. That's fixed now.

  - When defining the implicit constructors, destructor, and
    copy-assignment operator, set the CurContext to that constructor
    when we're defining the body.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94952 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CXX/dcl.decl/dcl.init/p6.cpp b/test/CXX/dcl.decl/dcl.init/p6.cpp
new file mode 100644
index 0000000..370bafc
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/p6.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: Very incomplete!
+
+// If a program calls for the default initialization of an object of a
+// const-qualified type T, T shall be a class type with a
+// user-provided default constructor.
+struct NoUserDefault { };
+struct HasUserDefault { HasUserDefault(); };
+
+void test_const_default_init() {
+  const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'struct NoUserDefault const' requires a user-provided default constructor}}
+  const HasUserDefault x2;
+  const int x3; // FIXME: xpected-error{{default initialization of an object of const type 'struct NoUserDefault const' requires a user-provided default constructor}}
+}
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index 53f057e..2efb7b9 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -104,8 +104,8 @@
 };
 
 struct N : M  {
-  N() : M(1),        // expected-error {{no matching constructor for initialization of 'M'}}
-        m1(100) {  } // expected-error {{no matching constructor for initialization of 'm1'}}
+  N() : M(1),        // expected-error {{no matching constructor for initialization of 'struct M'}}
+        m1(100) {  } // expected-error {{no matching constructor for initialization of 'struct M'}}
   M m1;
 };
 
@@ -116,8 +116,8 @@
 };
 
 struct Q {
-  Q() : f1(1,2),       // expected-error {{Too many arguments for member initializer 'f1'}}
-        pf(0.0)  { }   // expected-error {{incompatible type passing 'double', expected 'float *'}}
+  Q() : f1(1,2),       // expected-error {{excess elements in scalar initializer}}
+        pf(0.0)  { }   // expected-error {{cannot initialize a member subobject of type 'float *' with an rvalue of type 'double'}}
   float f1;
 
   float *pf;
diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp
index 315e29a..d7eb5cf 100644
--- a/test/SemaCXX/copy-assignment.cpp
+++ b/test/SemaCXX/copy-assignment.cpp
@@ -47,22 +47,22 @@
 
 void test() {
   A a, na;
-  const A constA;
+  const A constA = A();
   ConvertibleToA convertibleToA;
   ConvertibleToConstA convertibleToConstA;
 
   B b, nb;
-  const B constB;
+  const B constB = B();
   ConvertibleToB convertibleToB;
   ConvertibleToBref convertibleToBref;
   ConvertibleToConstB convertibleToConstB;
   ConvertibleToConstBref convertibleToConstBref;
 
   C c, nc;
-  const C constC;
+  const C constC = C();
 
   D d, nd;
-  const D constD;
+  const D constD = D();
 
   ConvertibleToInt convertibleToInt;
 
diff --git a/test/SemaCXX/illegal-member-initialization.cpp b/test/SemaCXX/illegal-member-initialization.cpp
index 1890dbc..be5f91d 100644
--- a/test/SemaCXX/illegal-member-initialization.cpp
+++ b/test/SemaCXX/illegal-member-initialization.cpp
@@ -1,9 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s 
 
 struct A {
-   A() : value(), cvalue() { } // expected-error {{cannot initialize the member to null in default constructor because reference member 'value' cannot be null-initialized}} \
-                               // expected-error {{constructor for 'struct A' must explicitly initialize the reference member 'value'}}
-   int &value; // expected-note{{declared at}} {{expected-note{{declared at}}
+   A() : value(), cvalue() { } // expected-error {{reference to type 'int' requires an initializer}}
+   int &value;
    const int cvalue;
 };
 
@@ -18,7 +17,7 @@
    int &value; // expected-note{{declared at}}
    const int cvalue; // expected-note{{declared at}}
    B& b; // expected-note{{declared at}}
-   const B cb; // expected-note{{declared at}}
+   const B cb; // expected-note{{declared here}}
 };
 
 
diff --git a/test/SemaCXX/overload-member-call.cpp b/test/SemaCXX/overload-member-call.cpp
index 22416f3..77d9965 100644
--- a/test/SemaCXX/overload-member-call.cpp
+++ b/test/SemaCXX/overload-member-call.cpp
@@ -89,7 +89,7 @@
     A a;
     a.foo(4, "hello"); //expected-error {{no matching member function for call to 'foo'}}
 
-    const A b;
+    const A b = A();
     b.bar(0); //expected-error {{no matching member function for call to 'bar'}}
 
     a.baz(b); //expected-error {{no matching member function for call to 'baz'}}
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 861d679..e07afe2 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -344,7 +344,7 @@
     int operator[](unsigned); // expected-note {{candidate}}
   };
   int test1() {
-    const NonConstArray x;
+    const NonConstArray x = NonConstArray();
     return x[0]; // expected-error {{no viable overloaded operator[] for type}}
   }
 
diff --git a/test/SemaTemplate/instantiate-member-initializers.cpp b/test/SemaTemplate/instantiate-member-initializers.cpp
index f7b7e47..eecb445 100644
--- a/test/SemaTemplate/instantiate-member-initializers.cpp
+++ b/test/SemaTemplate/instantiate-member-initializers.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -Wall -verify %s
 
 template<typename T> struct A {
-  A() : a(1) { } // expected-error{{incompatible type passing 'int', expected 'void *'}}
+  A() : a(1) { } // expected-error{{cannot initialize a member subobject of type 'void *' with an rvalue of type 'int'}}
 
   T a;
 };