From c56b999ffff249d4cb7dc7e8026a3297b63ff56d Mon Sep 17 00:00:00 2001 From: Wang Hoi Date: Mon, 5 May 2014 22:56:15 +0800 Subject: C: Parser: Support parsing of c99 designated initializers In case: int a[6] = { [4] = 29, [2] = 15 }; struct point { int x, y; }; struct point p = { .y = 3, .x = 2 }; Grammar change when c99 language feature is enabled: old grammar: braced-init-list :: '{' initializer-list '}' new grammar: braced-init-list :: '{' designated-initializer-list '}' designated-initializer-list :: designated-initializer (',' designated-initializer )* designated-initializer :: designator* initializer-clause designator :: '.' identifier | '[' constant-expression ']' Task-number: QTCREATORBUG-1902 Change-Id: Ib99d6f553f8d0f50ba3eff86f3a2e86d73372426 Reviewed-by: Nikolai Kosjar --- src/libs/3rdparty/cplusplus/Parser.cpp | 48 ++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'src/libs/3rdparty/cplusplus/Parser.cpp') diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index dfd6d1e49aa..0163046176c 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -2664,7 +2664,7 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node) ExpressionListAST **expression_list_ptr = &node; ExpressionAST *expression = 0; - if (parseInitializerClause0x(expression)) { + if (parseDesignatedInitializer(expression)) { *expression_list_ptr = new (_pool) ExpressionListAST; (*expression_list_ptr)->value = expression; expression_list_ptr = &(*expression_list_ptr)->next; @@ -2675,7 +2675,7 @@ bool Parser::parseInitializerList0x(ExpressionListAST *&node) while (LA() == T_COMMA && LA(2) != T_RBRACE) { consumeToken(); // consume T_COMMA - if (parseInitializerClause0x(expression)) { + if (parseDesignatedInitializer(expression)) { *expression_list_ptr = new (_pool) ExpressionListAST; (*expression_list_ptr)->value = expression; @@ -5484,6 +5484,50 @@ bool Parser::lookAtObjCSelector() const return false; } +// designated-initializer ::= designator* T_EQUAL initializer-clause +// +bool Parser::parseDesignatedInitializer(ExpressionAST *&node) +{ + DEBUG_THIS_RULE(); + if (!_languageFeatures.c99Enabled || (LA() != T_DOT && LA() != T_LBRACKET)) + return parseInitializerClause0x(node); + + DesignatedInitializerAST *ast = new (_pool) DesignatedInitializerAST; + DesignatorListAST **designator_list_ptr = &ast->designator_list; + DesignatorAST *designator = 0; + while (parseDesignator(designator)) { + *designator_list_ptr = new (_pool) DesignatorListAST; + (*designator_list_ptr)->value = designator; + designator_list_ptr = &(*designator_list_ptr)->next; + } + match(T_EQUAL, &ast->equal_token); + parseInitializerClause0x(ast->initializer); + node = ast; + return true; +} + +// designator ::= T_DOT T_IDENTIFIER +// T_LBRACKET constant-expression T_BRACKET +// +bool Parser::parseDesignator(DesignatorAST *&node) +{ + DesignatorAST *ast = new (_pool) DesignatorAST; + if (LA() == T_DOT) { + ast->type = DesignatorAST::Dot; + ast->u.dot.dot_token = consumeToken(); + match(T_IDENTIFIER, &ast->u.dot.identifier_token); + } else if (LA() == T_LBRACKET) { + ast->type = DesignatorAST::Bracket; + ast->u.bracket.lbracket_token = consumeToken(); + parseConstantExpression(ast->u.bracket.expression); + match(T_RBRACKET, &ast->u.bracket.rbracket_token); + } else { + return false; + } + node = ast; + return true; +} + // objc-class-declaraton ::= T_AT_CLASS (T_IDENTIFIER @ T_COMMA) T_SEMICOLON // bool Parser::parseObjCClassForwardDeclaration(DeclarationAST *&node) -- cgit v1.2.3