mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 08:30:34 +08:00
Parser support for rvalue references.
llvm-svn: 67033
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user