Commit 8c1a4556 authored by Christian Kamm's avatar Christian Kamm Committed by hjk
Browse files

C++11: Accept ref-qualifiers in function declarators.



Means
void foo() const &; void bar() &&;
and the corresponding pointer-to-member declarators
now parse.

Change-Id: Idbf295bd4f51cd5d9e38efcac1940b8cc2e32fce
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 6a6083cb
......@@ -1369,6 +1369,8 @@ unsigned FunctionDeclaratorAST::firstToken() const
if (cv_qualifier_list)
if (unsigned candidate = cv_qualifier_list->firstToken())
return candidate;
if (ref_qualifier_token)
return ref_qualifier_token;
if (exception_specification)
if (unsigned candidate = exception_specification->firstToken())
return candidate;
......@@ -1393,6 +1395,8 @@ unsigned FunctionDeclaratorAST::lastToken() const
if (exception_specification)
if (unsigned candidate = exception_specification->lastToken())
return candidate;
if (ref_qualifier_token)
return ref_qualifier_token + 1;
if (cv_qualifier_list)
if (unsigned candidate = cv_qualifier_list->lastToken())
return candidate;
......@@ -3067,12 +3071,16 @@ unsigned PointerToMemberAST::firstToken() const
if (cv_qualifier_list)
if (unsigned candidate = cv_qualifier_list->firstToken())
return candidate;
if (ref_qualifier_token)
return ref_qualifier_token;
return 0;
}
/** \generated */
unsigned PointerToMemberAST::lastToken() const
{
if (ref_qualifier_token)
return ref_qualifier_token + 1;
if (cv_qualifier_list)
if (unsigned candidate = cv_qualifier_list->lastToken())
return candidate;
......
......@@ -1457,6 +1457,7 @@ public:
ParameterDeclarationClauseAST *parameter_declaration_clause;
unsigned rparen_token;
SpecifierListAST *cv_qualifier_list;
unsigned ref_qualifier_token;
ExceptionSpecificationAST *exception_specification;
TrailingReturnTypeAST *trailing_return_type;
ExpressionAST *as_cpp_initializer;
......@@ -1470,6 +1471,7 @@ public:
, parameter_declaration_clause(0)
, rparen_token(0)
, cv_qualifier_list(0)
, ref_qualifier_token(0)
, exception_specification(0)
, trailing_return_type(0)
, as_cpp_initializer(0)
......@@ -2825,6 +2827,7 @@ public:
NestedNameSpecifierListAST *nested_name_specifier_list;
unsigned star_token;
SpecifierListAST *cv_qualifier_list;
unsigned ref_qualifier_token;
public:
PointerToMemberAST()
......@@ -2832,6 +2835,7 @@ public:
, nested_name_specifier_list(0)
, star_token(0)
, cv_qualifier_list(0)
, ref_qualifier_token(0)
{}
virtual PointerToMemberAST *asPointerToMember() { return this; }
......
......@@ -487,6 +487,7 @@ FunctionDeclaratorAST *FunctionDeclaratorAST::clone(MemoryPool *pool) const
for (SpecifierListAST *iter = cv_qualifier_list, **ast_iter = &ast->cv_qualifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->ref_qualifier_token = ref_qualifier_token;
if (exception_specification)
ast->exception_specification = exception_specification->clone(pool);
if (trailing_return_type)
......@@ -1068,6 +1069,7 @@ PointerToMemberAST *PointerToMemberAST::clone(MemoryPool *pool) const
for (SpecifierListAST *iter = cv_qualifier_list, **ast_iter = &ast->cv_qualifier_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) SpecifierListAST((iter->value) ? iter->value->clone(pool) : 0);
ast->ref_qualifier_token = ref_qualifier_token;
return ast;
}
......
......@@ -809,6 +809,8 @@ bool ASTMatcher::match(FunctionDeclaratorAST *node, FunctionDeclaratorAST *patte
else if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this))
return false;
pattern->ref_qualifier_token = node->ref_qualifier_token;
if (! pattern->exception_specification)
pattern->exception_specification = node->exception_specification;
else if (! AST::match(node->exception_specification, pattern->exception_specification, this))
......@@ -1817,6 +1819,8 @@ bool ASTMatcher::match(PointerToMemberAST *node, PointerToMemberAST *pattern)
else if (! AST::match(node->cv_qualifier_list, pattern->cv_qualifier_list, this))
return false;
pattern->ref_qualifier_token = node->ref_qualifier_token;
return true;
}
......
......@@ -1176,6 +1176,21 @@ bool Parser::parseCvQualifiers(SpecifierListAST *&node)
return start != cursor();
}
bool Parser::parseRefQualifier(unsigned &ref_qualifier)
{
DEBUG_THIS_RULE();
if (!_cxx0xEnabled)
return false;
if (LA() == T_AMPER || LA() == T_AMPER_AMPER) {
ref_qualifier = consumeToken();
return true;
}
return false;
}
/**
* \brief Handles override and final from C++ 2011, they are pseudo keywords and has special meaning only in function declaration
*/
......@@ -1474,8 +1489,7 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif
ast->rparen_token = consumeToken();
// ### parse attributes
parseCvQualifiers(ast->cv_qualifier_list);
parseOverrideFinalQualifiers(ast->cv_qualifier_list);
// ### parse ref-qualifiers
parseRefQualifier(ast->ref_qualifier_token);
parseExceptionSpecification(ast->exception_specification);
if (_cxx0xEnabled && ! node->ptr_operator_list && LA() == T_ARROW) {
......@@ -1494,6 +1508,8 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specif
parseTrailingReturnType(ast->trailing_return_type);
}
parseOverrideFinalQualifiers(ast->cv_qualifier_list);
*postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
postfix_ptr = &(*postfix_ptr)->next;
} else if (LA() == T_LBRACKET) {
......@@ -1579,6 +1595,7 @@ bool Parser::parseAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *dec
ast->rparen_token = consumeToken();
}
parseCvQualifiers(ast->cv_qualifier_list);
parseRefQualifier(ast->ref_qualifier_token);
parseExceptionSpecification(ast->exception_specification);
*postfix_ptr = new (_pool) PostfixDeclaratorListAST(ast);
postfix_ptr = &(*postfix_ptr)->next;
......
......@@ -82,6 +82,7 @@ public:
bool parseConstantExpression(ExpressionAST *&node);
bool parseCtorInitializer(CtorInitializerAST *&node);
bool parseCvQualifiers(SpecifierListAST *&node);
bool parseRefQualifier(unsigned &ref_qualifier);
bool parseOverrideFinalQualifiers(SpecifierListAST *&node);
bool parseDeclaratorOrAbstractDeclarator(DeclaratorAST *&node, SpecifierListAST *decl_specifier_list);
bool parseDeclaration(DeclarationAST *&node);
......
void foo() noexcept;
class C {
void foo() const noexcept final override;
void foo() const & noexcept final override;
void foo() const && noexcept final override;
auto foo() const noexcept -> void final override;
auto foo() const & noexcept -> void final override;
auto foo() const && noexcept -> void final override;
void foo();
void foo() &;
void foo() &&;
};
int main() {
void (C::*p)() const;
void (C::*p)() const &;
void (C::*p)() const &&;
void (C::*p)();
void (C::*p)() &;
void (C::*p)() &&;
}
......@@ -139,6 +139,7 @@ void tst_cxx11::parse_data()
QTest::newRow("braceInitializers.1") << "braceInitializers.1.cpp" << "braceInitializers.1.errors.txt";
QTest::newRow("braceInitializers.2") << "braceInitializers.2.cpp" << "";
QTest::newRow("defaultdeleteInitializer.1") << "defaultdeleteInitializer.1.cpp" << "";
QTest::newRow("refQualifier.1") << "refQualifier.1.cpp" << "";
}
void tst_cxx11::parse()
......
......@@ -479,6 +479,8 @@ virtual bool visit(FunctionDeclaratorAST *ast)
terminal(ast->rparen_token, ast);
for (SpecifierListAST *iter = ast->cv_qualifier_list; iter; iter = iter->next)
nonterminal(iter->value);
if (ast->ref_qualifier_token)
terminal(ast->ref_qualifier_token, ast);
nonterminal(ast->exception_specification);
nonterminal(ast->trailing_return_type);
nonterminal(ast->as_cpp_initializer);
......@@ -1028,6 +1030,8 @@ virtual bool visit(PointerToMemberAST *ast)
terminal(ast->star_token, ast);
for (SpecifierListAST *iter = ast->cv_qualifier_list; iter; iter = iter->next)
nonterminal(iter->value);
if (ast->ref_qualifier_token)
terminal(ast->ref_qualifier_token, ast);
return false;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment