]> granicus.if.org Git - clang/commitdiff
Recognize rvalue references in C++03, but complain about them. This leads to far...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 23 Mar 2009 00:00:23 +0000 (00:00 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 23 Mar 2009 00:00:23 +0000 (00:00 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67495 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseDecl.cpp
test/Parser/cxx-reference.cpp

index bc31c987614863429d21c85f1317f436781e6494..3a71db063142d9623b942d7b3b2b8103ed2ed62b 100644 (file)
@@ -121,6 +121,8 @@ def err_invalid_reference_qualifier_application : Error<
   "'%0' qualifier may not be applied to a reference">;
 def err_illegal_decl_reference_to_reference : Error<
   "%0 declared as a reference to a reference">;
+def err_rvalue_reference : Error<
+  "rvalue references are only allowed in C++0x">;
 def err_argument_required_after_attribute : Error<
   "argument required after attribute">;
 def err_missing_param : Error<"expected parameter declarator">;
index 0dddfdff7942ae5df566c0883b03c1a5679eefbf..6d2aad6905f1a16e4c8021255c6b9600342d20c0 100644 (file)
@@ -1660,7 +1660,8 @@ 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) &&
+      // We parse rvalue refs in C++03, because otherwise the errors are scary.
+      (Kind != tok::ampamp || !getLang().CPlusPlus) &&
       (Kind != tok::caret || !getLang().Blocks)) {
     if (DirectDeclParser)
       (this->*DirectDeclParser)(D);
@@ -1669,7 +1670,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
 
   // Otherwise, '*' -> pointer, '^' -> block, '&' -> lvalue reference,
   // '&&' -> rvalue reference
-  SourceLocation Loc = ConsumeToken();  // Eat the *, ^ or &.
+  SourceLocation Loc = ConsumeToken();  // Eat the *, ^, & or &&.
   D.SetRangeEnd(Loc);
 
   if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) {
@@ -1695,6 +1696,11 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
     // Is a reference
     DeclSpec DS;
 
+    // Complain about rvalue references in C++03, but then go on and build
+    // the declarator.
+    if (Kind == tok::ampamp && !getLang().CPlusPlus0x)
+      Diag(Loc, diag::err_rvalue_reference);
+
     // C++ 8.3.2p1: cv-qualified references are ill-formed except when the
     // cv-qualifiers are introduced through the use of a typedef or of a
     // template type argument, in which case the cv-qualifiers are ignored.
index 8d65defe7df69751575cdc7989b858c0d2760ca3..a1cbc5ea4dec5b263e8ba284a2c1de622068bcdd 100644 (file)
@@ -17,3 +17,5 @@ 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}} */
+
+typedef int && RV; // expected-error {{rvalue references are only allowed in C++0x}}