Parser support for rvalue references.

llvm-svn: 67033
This commit is contained in:
Sebastian Redl
2009-03-15 22:02:01 +00:00
parent 5bd30395b9
commit ed0f3b021e
3 changed files with 18 additions and 5 deletions

View 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;
}

View 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());
}
}

View 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);