]> granicus.if.org Git - clang/commitdiff
Parser support for rvalue references.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sun, 15 Mar 2009 22:02:01 +0000 (22:02 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sun, 15 Mar 2009 22:02:01 +0000 (22:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67033 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/DeclSpec.h
lib/Parse/ParseDecl.cpp
test/Parser/cxx-reference.cpp

index 09b6e5c52214e3ad420fcf28bfe1cafac01ee961..3c6995e50bf02d105ddd8a27ad1777508edb5bc1 100644 (file)
@@ -454,7 +454,9 @@ struct DeclaratorChunk {
 
   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 @@ struct DeclaratorChunk {
   /// 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;
   }
index aa96db540ae5cf4749456cff41681742e1cc5751..25565e657687dd092d550f6e0fdab58ee09700a1 100644 (file)
@@ -1616,7 +1616,9 @@ void Parser::ParseDeclarator(Declarator &D) {
 ///       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 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
   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 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
 
     // 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());
   }
 }
index 8d65defe7df69751575cdc7989b858c0d2760ca3..1fd2fd652c911e01574a6abca1ee61231c875a74 100644 (file)
@@ -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 & const X = val; // expected-error {{'const' qualifier may not be applied to
 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);