forked from qt-creator/qt-creator
Parse C++ 0x argument packs.
This commit is contained in:
@@ -2555,3 +2555,22 @@ unsigned TrailingReturnTypeAST::lastToken() const
|
||||
|
||||
return arrow_token + 1;
|
||||
}
|
||||
|
||||
unsigned BracedInitializerAST::firstToken() const
|
||||
{
|
||||
return lbrace_token;
|
||||
}
|
||||
|
||||
unsigned BracedInitializerAST::lastToken() const
|
||||
{
|
||||
if (rbrace_token)
|
||||
return rbrace_token + 1;
|
||||
|
||||
else if (comma_token)
|
||||
return comma_token + 1;
|
||||
|
||||
else if (expression_list)
|
||||
return expression_list->lastToken();
|
||||
|
||||
return lbrace_token + 1;
|
||||
}
|
||||
|
||||
@@ -162,6 +162,7 @@ public:
|
||||
virtual BaseSpecifierAST *asBaseSpecifier() { return 0; }
|
||||
virtual BinaryExpressionAST *asBinaryExpression() { return 0; }
|
||||
virtual BoolLiteralAST *asBoolLiteral() { return 0; }
|
||||
virtual BracedInitializerAST *asBracedInitializer() { return 0; }
|
||||
virtual BreakStatementAST *asBreakStatement() { return 0; }
|
||||
virtual CallAST *asCall() { return 0; }
|
||||
virtual CaptureAST *asCapture() { return 0; }
|
||||
@@ -2895,6 +2896,7 @@ public:
|
||||
public:
|
||||
SizeofExpressionAST()
|
||||
: sizeof_token(0)
|
||||
, dot_dot_dot_token(0)
|
||||
, lparen_token(0)
|
||||
, expression(0)
|
||||
, rparen_token(0)
|
||||
@@ -4265,6 +4267,33 @@ protected:
|
||||
virtual bool match0(AST *, ASTMatcher *);
|
||||
};
|
||||
|
||||
class BracedInitializerAST: public ExpressionAST
|
||||
{
|
||||
public:
|
||||
unsigned lbrace_token;
|
||||
ExpressionListAST *expression_list;
|
||||
unsigned comma_token;
|
||||
unsigned rbrace_token;
|
||||
|
||||
public:
|
||||
BracedInitializerAST()
|
||||
: lbrace_token(0)
|
||||
, expression_list(0)
|
||||
, comma_token(0)
|
||||
, rbrace_token(0)
|
||||
{}
|
||||
|
||||
virtual BracedInitializerAST *asBracedInitializer() { return this; }
|
||||
virtual unsigned firstToken() const;
|
||||
virtual unsigned lastToken() const;
|
||||
|
||||
virtual BracedInitializerAST *clone(MemoryPool *pool) const;
|
||||
|
||||
protected:
|
||||
virtual void accept0(ASTVisitor *visitor);
|
||||
virtual bool match0(AST *, ASTMatcher *);
|
||||
};
|
||||
|
||||
} // end of namespace CPlusPlus
|
||||
|
||||
#endif // CPLUSPLUS_AST_H
|
||||
|
||||
@@ -1083,6 +1083,7 @@ SizeofExpressionAST *SizeofExpressionAST::clone(MemoryPool *pool) const
|
||||
{
|
||||
SizeofExpressionAST *ast = new (pool) SizeofExpressionAST;
|
||||
ast->sizeof_token = sizeof_token;
|
||||
ast->dot_dot_dot_token = dot_dot_dot_token;
|
||||
ast->lparen_token = lparen_token;
|
||||
if (expression)
|
||||
ast->expression = expression->clone(pool);
|
||||
@@ -1659,3 +1660,15 @@ TrailingReturnTypeAST *TrailingReturnTypeAST::clone(MemoryPool *pool) const
|
||||
return ast;
|
||||
}
|
||||
|
||||
BracedInitializerAST *BracedInitializerAST::clone(MemoryPool *pool) const
|
||||
{
|
||||
BracedInitializerAST *ast = new (pool) BracedInitializerAST;
|
||||
ast->lbrace_token = lbrace_token;
|
||||
for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list;
|
||||
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
|
||||
*ast_iter = new (pool) ExpressionListAST((iter->value) ? iter->value->clone(pool) : 0);
|
||||
ast->comma_token = comma_token;
|
||||
ast->rbrace_token = rbrace_token;
|
||||
return ast;
|
||||
}
|
||||
|
||||
|
||||
@@ -1137,3 +1137,11 @@ bool TrailingReturnTypeAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BracedInitializerAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
{
|
||||
if (BracedInitializerAST *_other = pattern->asBracedInitializer())
|
||||
return matcher->match(this, _other);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1808,6 +1808,8 @@ bool ASTMatcher::match(SizeofExpressionAST *node, SizeofExpressionAST *pattern)
|
||||
|
||||
pattern->sizeof_token = node->sizeof_token;
|
||||
|
||||
pattern->dot_dot_dot_token = node->dot_dot_dot_token;
|
||||
|
||||
pattern->lparen_token = node->lparen_token;
|
||||
|
||||
if (! pattern->expression)
|
||||
@@ -2796,3 +2798,22 @@ bool ASTMatcher::match(TrailingReturnTypeAST *node, TrailingReturnTypeAST *patte
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTMatcher::match(BracedInitializerAST *node, BracedInitializerAST *pattern)
|
||||
{
|
||||
(void) node;
|
||||
(void) pattern;
|
||||
|
||||
pattern->lbrace_token = node->lbrace_token;
|
||||
|
||||
if (! pattern->expression_list)
|
||||
pattern->expression_list = node->expression_list;
|
||||
else if (! AST::match(node->expression_list, pattern->expression_list, this))
|
||||
return false;
|
||||
|
||||
pattern->comma_token = node->comma_token;
|
||||
|
||||
pattern->rbrace_token = node->rbrace_token;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -176,6 +176,7 @@ public:
|
||||
virtual bool match(LambdaDeclaratorAST *node, LambdaDeclaratorAST *pattern);
|
||||
virtual bool match(CaptureAST *node, CaptureAST *pattern);
|
||||
virtual bool match(TrailingReturnTypeAST *node, TrailingReturnTypeAST *pattern);
|
||||
virtual bool match(BracedInitializerAST *node, BracedInitializerAST *pattern);
|
||||
};
|
||||
|
||||
} // end of namespace CPlusPlus
|
||||
|
||||
@@ -1214,3 +1214,11 @@ void TrailingReturnTypeAST::accept0(ASTVisitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void BracedInitializerAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(expression_list, visitor);
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -216,6 +216,7 @@ public:
|
||||
virtual bool visit(LambdaDeclaratorAST *) { return true; }
|
||||
virtual bool visit(CaptureAST *) { return true; }
|
||||
virtual bool visit(TrailingReturnTypeAST *) { return true; }
|
||||
virtual bool visit(BracedInitializerAST *) { return true; }
|
||||
|
||||
// ObjC++
|
||||
virtual bool visit(ObjCClassDeclarationAST *) { return true; }
|
||||
@@ -351,12 +352,14 @@ public:
|
||||
virtual void endVisit(QtInterfacesDeclarationAST *) { }
|
||||
virtual void endVisit(QtInterfaceNameAST *) { }
|
||||
|
||||
// C++0x
|
||||
virtual void endVisit(LambdaExpressionAST *) { }
|
||||
virtual void endVisit(LambdaIntroducerAST *) { }
|
||||
virtual void endVisit(LambdaCaptureAST *) { }
|
||||
virtual void endVisit(LambdaDeclaratorAST *) { }
|
||||
virtual void endVisit(CaptureAST *) { }
|
||||
virtual void endVisit(TrailingReturnTypeAST *) { }
|
||||
virtual void endVisit(BracedInitializerAST *) { }
|
||||
|
||||
// ObjC++
|
||||
virtual void endVisit(ObjCClassDeclarationAST *) { }
|
||||
|
||||
@@ -69,6 +69,7 @@ class AttributeSpecifierAST;
|
||||
class BaseSpecifierAST;
|
||||
class BinaryExpressionAST;
|
||||
class BoolLiteralAST;
|
||||
class BracedInitializerAST;
|
||||
class BreakStatementAST;
|
||||
class CallAST;
|
||||
class CaptureAST;
|
||||
|
||||
@@ -404,3 +404,10 @@ bool CheckExpression::visit(LambdaExpressionAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckExpression::visit(BracedInitializerAST *ast)
|
||||
{
|
||||
for (ExpressionListAST *it = ast->expression_list; it; it = it->next)
|
||||
(void) semantic()->check(it->value, _scope);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ protected:
|
||||
virtual bool visit(CompoundLiteralAST *ast);
|
||||
virtual bool visit(CompoundExpressionAST *ast);
|
||||
virtual bool visit(LambdaExpressionAST *ast);
|
||||
virtual bool visit(BracedInitializerAST *ast);
|
||||
|
||||
//names
|
||||
virtual bool visit(QualifiedNameAST *ast);
|
||||
|
||||
@@ -1278,7 +1278,10 @@ bool Parser::parseDeclarator(DeclaratorAST *&node, bool stopAtCppInitializer)
|
||||
|
||||
bool blocked = blockErrors(true);
|
||||
if (parseInitializer(initializer, &node->equals_token)) {
|
||||
if (NestedExpressionAST *expr = initializer->asNestedExpression()) {
|
||||
NestedExpressionAST *expr = 0;
|
||||
if (initializer)
|
||||
expr = initializer->asNestedExpression();
|
||||
if (expr) {
|
||||
if (expr->expression && expr->rparen_token && (LA() == T_COMMA || LA() == T_SEMICOLON)) {
|
||||
rewind(lparen_token);
|
||||
|
||||
@@ -2269,15 +2272,101 @@ bool Parser::parseBaseClause(BaseSpecifierListAST *&node)
|
||||
bool Parser::parseInitializer(ExpressionAST *&node, unsigned *equals_token)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
if (LA() == T_LPAREN) {
|
||||
return parsePrimaryExpression(node);
|
||||
} else if (LA() == T_EQUAL) {
|
||||
(*equals_token) = consumeToken();
|
||||
return parseInitializerClause(node);
|
||||
|
||||
return parseInitializer0x(node, equals_token);
|
||||
}
|
||||
|
||||
bool Parser::parseInitializer0x(ExpressionAST *&node, unsigned *equals_token)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
|
||||
if ((_cxx0xEnabled && LA() == T_LBRACE) || LA() == T_EQUAL) {
|
||||
if (LA() == T_EQUAL)
|
||||
*equals_token = cursor();
|
||||
|
||||
return parseBraceOrEqualInitializer0x(node);
|
||||
}
|
||||
|
||||
else if (LA() == T_LPAREN) {
|
||||
return parsePrimaryExpression(node);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Parser::parseBraceOrEqualInitializer0x(ExpressionAST *&node)
|
||||
{
|
||||
if (LA() == T_EQUAL) {
|
||||
consumeToken();
|
||||
parseInitializerClause0x(node);
|
||||
return true;
|
||||
|
||||
} else if (LA() == T_LBRACE) {
|
||||
return parseBracedInitList0x(node);
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Parser::parseInitializerClause0x(ExpressionAST *&node)
|
||||
{
|
||||
if (LA() == T_LBRACE)
|
||||
return parseBracedInitList0x(node);
|
||||
|
||||
parseAssignmentExpression(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::parseInitializerList0x(ExpressionListAST *&node)
|
||||
{
|
||||
ExpressionListAST **expression_list_ptr = &node;
|
||||
ExpressionAST *expression = 0;
|
||||
|
||||
if (parseInitializerClause0x(expression)) {
|
||||
*expression_list_ptr = new (_pool) ExpressionListAST;
|
||||
(*expression_list_ptr)->value = expression;
|
||||
expression_list_ptr = &(*expression_list_ptr)->next;
|
||||
|
||||
if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COMMA || LA(2) == T_RBRACE || LA(2) == T_RPAREN))
|
||||
consumeToken(); // ### create an argument pack
|
||||
|
||||
while (LA() == T_COMMA && LA(2) != T_RBRACE) {
|
||||
consumeToken(); // consume T_COMMA
|
||||
|
||||
if (parseInitializerClause0x(expression)) {
|
||||
*expression_list_ptr = new (_pool) ExpressionListAST;
|
||||
(*expression_list_ptr)->value = expression;
|
||||
|
||||
if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT && (LA(2) == T_COMMA || LA(2) == T_RBRACE || LA(2) == T_RPAREN))
|
||||
consumeToken(); // ### create an argument pack
|
||||
|
||||
expression_list_ptr = &(*expression_list_ptr)->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::parseBracedInitList0x(ExpressionAST *&node)
|
||||
{
|
||||
if (LA() != T_LBRACE)
|
||||
return false;
|
||||
|
||||
BracedInitializerAST *ast = new (_pool) BracedInitializerAST;
|
||||
ast->lbrace_token = consumeToken();
|
||||
|
||||
parseInitializerList0x(ast->expression_list);
|
||||
|
||||
if (LA() == T_COMMA && LA(2) == T_RBRACE)
|
||||
ast->comma_token = consumeToken();
|
||||
|
||||
match(T_RBRACE, &ast->rbrace_token);
|
||||
node = ast;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::parseMemInitializerList(MemInitializerListAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
@@ -2374,6 +2463,13 @@ bool Parser::parseTypeIdList(ExpressionListAST *&node)
|
||||
bool Parser::parseExpressionList(ExpressionListAST *&node)
|
||||
{
|
||||
DEBUG_THIS_RULE();
|
||||
|
||||
if (_cxx0xEnabled)
|
||||
return parseInitializerList0x(node);
|
||||
|
||||
|
||||
|
||||
// ### remove me
|
||||
ExpressionListAST **expression_list_ptr = &node;
|
||||
ExpressionAST *expression = 0;
|
||||
if (parseAssignmentExpression(expression)) {
|
||||
@@ -2391,6 +2487,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -222,6 +222,12 @@ public:
|
||||
bool parseQtMethod(ExpressionAST *&node);
|
||||
|
||||
// C++0x
|
||||
bool parseInitializer0x(ExpressionAST *&node, unsigned *equals_token);
|
||||
bool parseBraceOrEqualInitializer0x(ExpressionAST *&node);
|
||||
bool parseInitializerClause0x(ExpressionAST *&node);
|
||||
bool parseInitializerList0x(ExpressionListAST *&node);
|
||||
bool parseBracedInitList0x(ExpressionAST *&node);
|
||||
|
||||
bool parseLambdaExpression(ExpressionAST *&node);
|
||||
bool parseLambdaIntroducer(LambdaIntroducerAST *&node);
|
||||
bool parseLambdaCapture(LambdaCaptureAST *&node);
|
||||
|
||||
Reference in New Issue
Block a user