Fully implement delegating constructors!

As far as I know, this implementation is complete but might be missing a
few optimizations. Exceptions and virtual bases are handled correctly.

Because I'm an optimist, the web page has appropriately been updated. If
I'm wrong, feel free to downgrade its support categories.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130642 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
new file mode 100644
index 0000000..5b432c7
--- /dev/null
+++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -emit-llvm -fexceptions -fcxx-exceptions -std=c++0x -o - %s | FileCheck %s
+
+struct non_trivial {
+  non_trivial();
+  ~non_trivial();
+};
+non_trivial::non_trivial() {}
+non_trivial::~non_trivial() {}
+
+// We use a virtual base to ensure that the constructor
+// delegation optimization (complete->base) can't be
+// performed.
+struct delegator {
+  non_trivial n; 
+  delegator();
+  delegator(int);
+  delegator(char);
+  delegator(bool);
+};
+
+delegator::delegator() {
+  throw 0;
+}
+
+// CHECK: define void @_ZN9delegatorC1Ei
+// CHECK: call void @_ZN9delegatorC1Ev
+// CHECK-NOT: lpad
+// CHECK: ret
+// CHECK-NOT: lpad
+// CHECK: define void @_ZN9delegatorC2Ei
+// CHECK: call void @_ZN9delegatorC2Ev
+// CHECK-NOT: lpad
+// CHECK: ret
+// CHECK-NOT: lpad
+delegator::delegator(int)
+  : delegator()
+{}
+
+delegator::delegator(bool)
+{}
+
+// CHECK: define void @_ZN9delegatorC2Ec
+// CHECK: call void @_ZN9delegatorC2Eb
+// CHECK: call void @__cxa_throw
+delegator::delegator(char)
+  : delegator(true) {
+  throw 0;
+}
diff --git a/test/SemaCXX/cxx0x-delegating-ctors.cpp b/test/SemaCXX/cxx0x-delegating-ctors.cpp
new file mode 100644
index 0000000..b211cb1
--- /dev/null
+++ b/test/SemaCXX/cxx0x-delegating-ctors.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+struct foo {
+  int i;
+  foo();
+  foo(int);
+  foo(int, int);
+  foo(bool);
+  foo(char);
+  foo(float*);
+  foo(float&);
+};
+
+// Good
+foo::foo (int i) : i(i) {
+}
+// Good
+foo::foo () : foo(-1) {
+}
+// Good
+foo::foo (int, int) : foo() {
+}
+
+foo::foo (bool) : foo(true) { // expected-error{{delegates to itself}}
+}
+
+// Good
+foo::foo (float* f) : foo(*f) {
+}
+
+// FIXME: This should error
+foo::foo (float &f) : foo(&f) {
+}
+
+foo::foo (char) : i(3), foo(3) { // expected-error{{must appear alone}}
+}