forked from qt-creator/qt-creator
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: hjk <qthjk@ovi.com>
This commit is contained in:
Vendored
+8
@@ -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;
|
||||
|
||||
Vendored
+4
@@ -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; }
|
||||
|
||||
+2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+19
-2
@@ -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;
|
||||
|
||||
Vendored
+1
@@ -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);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user