diff options
-rw-r--r-- | include/clang/Parse/DeclSpec.h | 7 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 9 | ||||
-rw-r--r-- | test/Parser/cxx-reference.cpp | 7 |
3 files changed, 18 insertions, 5 deletions
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 09b6e5c522..3c6995e50b 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -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; } diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index aa96db540a..25565e6576 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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()); } } diff --git a/test/Parser/cxx-reference.cpp b/test/Parser/cxx-reference.cpp index 8d65defe7d..1fd2fd652c 100644 --- a/test/Parser/cxx-reference.cpp +++ b/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 & 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); |