From 743de1f671ee0ef213c7404cfdc85579dd12c56e Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Mon, 23 Mar 2009 00:00:23 +0000 Subject: [PATCH] Recognize rvalue references in C++03, but complain about them. This leads to far better error recovery. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67495 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticParseKinds.td | 2 ++ lib/Parse/ParseDecl.cpp | 10 ++++++++-- test/Parser/cxx-reference.cpp | 2 ++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index bc31c98761..3a71db0631 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -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">; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 0dddfdff79..6d2aad6905 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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. diff --git a/test/Parser/cxx-reference.cpp b/test/Parser/cxx-reference.cpp index 8d65defe7d..a1cbc5ea4d 100644 --- a/test/Parser/cxx-reference.cpp +++ b/test/Parser/cxx-reference.cpp @@ -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}} -- 2.40.0