Parser support for rvalue references.

llvm-svn: 67033
diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h
index 09b6e5c..3c6995e 100644
--- a/clang/include/clang/Parse/DeclSpec.h
+++ b/clang/include/clang/Parse/DeclSpec.h
@@ -454,7 +454,9 @@
 
   struct ReferenceTypeInfo {
     /// The type qualifier: restrict. [GNU] C++ extension
-    bool HasRestrict;
+    bool HasRestrict : 1;
+    /// True if this is an lvalue reference, false if it's an rvalue reference.
+    bool LValueRef : 1;
     AttributeList *AttrList;
     void destroy() {
       delete AttrList;
@@ -633,11 +635,12 @@
   /// getReference - Return a DeclaratorChunk for a reference.
   ///
   static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
-                                      AttributeList *AL) {
+                                      AttributeList *AL, bool lvalue) {
     DeclaratorChunk I;
     I.Kind            = Reference;
     I.Loc             = Loc;
     I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
+    I.Ref.LValueRef   = lvalue;
     I.Ref.AttrList  = AL;
     return I;
   }
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index aa96db5..25565e6 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1616,7 +1616,9 @@
 ///       ptr-operator:
 ///         '*' cv-qualifier-seq[opt]
 ///         '&'
+/// [C++0x] '&&'
 /// [GNU]   '&' restrict[opt] attributes[opt]
+/// [GNU?]  '&&' restrict[opt] attributes[opt]
 ///         '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt]
 void Parser::ParseDeclaratorInternal(Declarator &D,
                                      DirectDeclParseFunction DirectDeclParser) {
@@ -1657,13 +1659,15 @@
   tok::TokenKind Kind = Tok.getKind();
   // Not a pointer, C++ reference, or block.
   if (Kind != tok::star && (Kind != tok::amp || !getLang().CPlusPlus) &&
+      (Kind != tok::ampamp || !getLang().CPlusPlus0x) &&
       (Kind != tok::caret || !getLang().Blocks)) {
     if (DirectDeclParser)
       (this->*DirectDeclParser)(D);
     return;
   }
 
-  // Otherwise, '*' -> pointer, '^' -> block, '&' -> reference.
+  // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
+  // '&&' -> rvalue reference
   SourceLocation Loc = ConsumeToken();  // Eat the *, ^ or &.
   D.SetRangeEnd(Loc);
 
@@ -1730,7 +1734,8 @@
 
     // Remember that we parsed a reference type. It doesn't have type-quals.
     D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
-                                                DS.TakeAttributes()),
+                                                DS.TakeAttributes(),
+                                                Kind == tok::amp),
                   SourceLocation());
   }
 }
diff --git a/clang/test/Parser/cxx-reference.cpp b/clang/test/Parser/cxx-reference.cpp
index 8d65def..1fd2fd65 100644
--- a/clang/test/Parser/cxx-reference.cpp
+++ b/clang/test/Parser/cxx-reference.cpp
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only -verify %s
+// RUN: clang -fsyntax-only -verify -std=c++0x %s
 
 extern char *bork;
 char *& bar = bork;
@@ -17,3 +17,8 @@
 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);