Almost complete implementation of rvalue references. One bug, and a few unclear areas. Maybe Doug can shed some light on some of the fixmes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67059 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Parser/cxx-reference.cpp b/test/Parser/cxx-reference.cpp
index 1fd2fd6..8d65def 100644
--- a/test/Parser/cxx-reference.cpp
+++ b/test/Parser/cxx-reference.cpp
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only -verify -std=c++0x %s
+// RUN: clang -fsyntax-only -verify %s
 
 extern char *bork;
 char *& bar = bork;
@@ -17,8 +17,3 @@
 int & volatile Y = val; // expected-error {{'volatile' qualifier may not be applied to a reference}}
 int & const volatile Z = val; /* expected-error {{'const' qualifier may not be applied}} \
                            expected-error {{'volatile' qualifier may not be applied}} */
-
-int && r1(int &&a);
-
-typedef int && R;
-void r2(const R a);
diff --git a/test/Parser/cxx0x-rvalue-reference.cpp b/test/Parser/cxx0x-rvalue-reference.cpp
new file mode 100644
index 0000000..3643233
--- /dev/null
+++ b/test/Parser/cxx0x-rvalue-reference.cpp
@@ -0,0 +1,6 @@
+// RUN: clang -fsyntax-only -verify -std=c++0x %s
+
+int && r1(int &&a);
+
+typedef int && R;
+void r2(const R a);
diff --git a/test/SemaCXX/convert-to-bool.cpp b/test/SemaCXX/convert-to-bool.cpp
index 100267c..74d925a 100644
--- a/test/SemaCXX/convert-to-bool.cpp
+++ b/test/SemaCXX/convert-to-bool.cpp
@@ -49,7 +49,7 @@
 }
 
 void test_explicit_conv_to_ref(ExplicitConvToRef ecr) {
-  int& i1 = ecr; // expected-error{{non-const reference to type 'int' cannot be initialized with a value of type 'struct ExplicitConvToRef'}}
+  int& i1 = ecr; // expected-error{{non-const lvalue reference to type 'int' cannot be initialized with a value of type 'struct ExplicitConvToRef'}}
   int& i2(ecr); // okay
 }
 
@@ -61,7 +61,7 @@
 };
 
 void test_copy_init_conversions(C c) {
-  A &a = c; // expected-error{{non-const reference to type 'struct A' cannot be initialized with a value of type 'struct C'}}
+  A &a = c; // expected-error{{non-const lvalue reference to type 'struct A' cannot be initialized with a value of type 'struct C'}}
   B &b = b; // okay
 }
 
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index 7a5e06e..d51354e 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -67,7 +67,7 @@
   float &f1 = (e1 == e2);
   float &f2 = (enum1 == e2); 
   float &f3 = (e1 == enum2); 
-  float &f4 = (enum1 == enum2);  // expected-error{{non-const reference to type 'float' cannot be initialized with a temporary of type '_Bool'}}
+  float &f4 = (enum1 == enum2);  // expected-error{{non-const lvalue reference to type 'float' cannot be initialized with a temporary of type '_Bool'}}
 }
 
 
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index 61e30b5..8ee7745 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -44,9 +44,9 @@
 
 // C++ [dcl.init.ref]p5b2
 void test4() {
-  double& rd2 = 2.0; // expected-error{{non-const reference to type 'double' cannot be initialized with a temporary of type 'double'}}
+  double& rd2 = 2.0; // expected-error{{non-const lvalue reference to type 'double' cannot be initialized with a temporary of type 'double'}}
   int i = 2;
-  double& rd3 = i; // expected-error{{non-const reference to type 'double' cannot be initialized with a value of type 'int'}}
+  double& rd3 = i; // expected-error{{non-const lvalue reference to type 'double' cannot be initialized with a value of type 'int'}}
 
   const A& rca = fB();
 }
diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp
new file mode 100644
index 0000000..ae26449
--- /dev/null
+++ b/test/SemaCXX/rval-references.cpp
@@ -0,0 +1,33 @@
+// RUN: clang -fsyntax-only -verify -std=c++0x %s
+
+typedef int&& irr;
+typedef irr& ilr_c1; // Collapses to int&
+typedef int& ilr;
+typedef ilr&& ilr_c2; // Collapses to int&
+
+irr ret_irr() {
+  return 0;
+}
+
+struct not_int {};
+
+int over(int&);
+not_int over(int&&);
+
+void f() {
+  int &&virr1; // expected-error {{declaration of reference variable 'virr1' requires an initializer}}
+  int &&virr2 = 0;
+  // FIXME: named rvalue references are lvalues!
+  //int &&virr3 = virr1; // xpected-error {{rvalue reference cannot bind to lvalue}}
+  int i1 = 0;
+  int &&virr4 = i1; // expected-error {{rvalue reference cannot bind to lvalue}}
+  int &&virr5 = ret_irr();
+
+  int i2 = over(i1);
+  not_int ni1 = over(0);
+  int i3 = over(virr2);
+  not_int ni2 = over(ret_irr());
+
+  ilr_c1 vilr1 = i1;
+  ilr_c2 vilr2 = i1;
+}
diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp
index 9bbcdf6..bf7561d 100644
--- a/test/SemaCXX/static-cast.cpp
+++ b/test/SemaCXX/static-cast.cpp
@@ -54,7 +54,7 @@
   //(void)static_cast<A*>((H*)0); // {{static_cast from 'struct H *' to 'struct A *' is not allowed}}
   (void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
   (void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'struct B **' to 'struct A **' is not allowed}}
-  (void)static_cast<char&>(i); // expected-error {{non-const reference to type 'char' cannot be initialized with a value of type 'int'}}
+  (void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot be initialized with a value of type 'int'}}
 }
 
 // Anything to void
@@ -86,7 +86,7 @@
   (void)static_cast<H*>((A*)0); // expected-error {{ambiguous static_cast from base 'struct A' to derived 'struct H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
   (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous static_cast from base 'struct A' to derived 'struct H':\n    struct A -> struct B -> struct G1 -> struct H\n    struct A -> struct B -> struct G2 -> struct H}}
   (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'struct B *' to 'struct E *' is not allowed}}
-  (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const reference to type 'struct E' cannot be initialized with a value of type 'struct B'}}
+  (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'struct E' cannot be initialized with a value of type 'struct B'}}
 
   // TODO: Test inaccessible base in context where it's accessible, i.e.
   // member function and friend.