summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus/Parser.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2010-03-25 12:15:38 +0100
committerRoberto Raggi <roberto.raggi@nokia.com>2010-03-25 12:16:18 +0100
commitfe261bc256abb3e470a0e33a4b7569307e973db5 (patch)
tree6f359760d060f3a347e060ae4647ac92639ef252 /src/shared/cplusplus/Parser.cpp
parent1bdae0815d20f9a93c57b14f52dd69a808b739c6 (diff)
downloadqt-creator-fe261bc256abb3e470a0e33a4b7569307e973db5.tar.gz
Parse C++ 0x argument packs.
Diffstat (limited to 'src/shared/cplusplus/Parser.cpp')
-rw-r--r--src/shared/cplusplus/Parser.cpp107
1 files changed, 102 insertions, 5 deletions
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index a1c6f74f39..d36226ce25 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -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 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);
- } else if (LA() == T_EQUAL) {
- (*equals_token) = consumeToken();
- return parseInitializerClause(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;
}