aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/cplusplus/Parser.cpp
diff options
context:
space:
mode:
authorWang Hoi <wanghoi@126.com>2014-05-05 22:56:15 +0800
committerNikolai Kosjar <nikolai.kosjar@digia.com>2014-06-17 16:23:23 +0200
commitc56b999ffff249d4cb7dc7e8026a3297b63ff56d (patch)
tree007d1f5208cd7e03fdc2eceb4cefe3dd4a12ded8 /src/libs/3rdparty/cplusplus/Parser.cpp
parentd70485180a676c3d97108bb87ec1c32223ee0f2b (diff)
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 <nikolai.kosjar@digia.com>
Diffstat (limited to 'src/libs/3rdparty/cplusplus/Parser.cpp')
-rw-r--r--src/libs/3rdparty/cplusplus/Parser.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp
index dfd6d1e49a..0163046176 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)