From e5377519d63620a6321278249f330d9a6f2baf04 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen <erik.verbruggen@nokia.com> Date: Thu, 16 Jul 2009 11:27:45 +0200 Subject: [PATCH] Added varargs parsing for ObjC send_msg arguments. --- src/shared/cplusplus/Parser.cpp | 70 +++++++++++++++++++++++---------- src/shared/cplusplus/Parser.h | 4 +- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp index cf091cfa0e0..ba705f9551b 100644 --- a/src/shared/cplusplus/Parser.cpp +++ b/src/shared/cplusplus/Parser.cpp @@ -2892,7 +2892,8 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&) } while (lookAtObjCSelector()) { - parseObjCSelector(); + unsigned selector_token = 0; + parseObjCSelector(selector_token); if (LA() == T_COLON) consumeToken(); else { @@ -2927,49 +2928,73 @@ bool Parser::parseObjCMessageReceiver(ExpressionAST *&node) return parseExpression(node); } -bool Parser::parseObjCMessageArguments(ObjCMessageArgumentListAST *& /*node*/) +bool Parser::parseObjCMessageArguments(ObjCMessageArgumentListAST *& node) { if (LA() == T_RBRACKET) return false; // nothing to do. unsigned start = cursor(); - if (parseObjCSelectorArgs()) { - while (parseObjCSelectorArgs()) { + ObjCMessageArgumentListAST *ast = new (_pool) ObjCMessageArgumentListAST; + ObjCMessageArgumentAST *argument = 0; + + if (parseObjCSelectorArg(argument)) { + ast->arg = argument; + ObjCMessageArgumentListAST *lastArgument = ast; + + while (parseObjCSelectorArg(argument)) { // accept the selector args. + lastArgument->next = new (_pool) ObjCMessageArgumentListAST; + lastArgument = lastArgument->next; + lastArgument->arg = argument; + } + + if (LA() == T_COMMA) { + ExpressionAST **lastExpression = &(lastArgument->arg->parameter_value_expression); + + while (LA() == T_COMMA) { + BinaryExpressionAST *binaryExpression = new (_pool) BinaryExpressionAST; + binaryExpression->left_expression = *lastExpression; + binaryExpression->binary_op_token = consumeToken(); // T_COMMA + parseAssignmentExpression(binaryExpression->right_expression); + lastExpression = &(binaryExpression->right_expression); + } } } else { rewind(start); - parseObjCSelector(); + ast->arg = new (_pool) ObjCMessageArgumentAST; + parseObjCSelector(ast->arg->parameter_key_identifier); } - while (LA() == T_COMMA) { - consumeToken(); // skip T_COMMA - ExpressionAST *expression = 0; - parseAssignmentExpression(expression); - } + node = ast; return true; } -bool Parser::parseObjCSelectorArgs() +bool Parser::parseObjCSelectorArg(ObjCMessageArgumentAST *&node) { - parseObjCSelector(); + unsigned selector_token = 0; + if (!parseObjCSelector(selector_token)) + return false; + if (LA() != T_COLON) return false; - /*unsigned colon_token = */consumeToken(); + ObjCMessageArgumentAST *argument = new (_pool) ObjCMessageArgumentAST; + argument->parameter_key_identifier = selector_token; + argument->colon_token = consumeToken(); - ExpressionAST *expression = 0; - parseAssignmentExpression(expression); + parseAssignmentExpression(argument->parameter_value_expression); + node = argument; return true; } bool Parser::parseObjCMethodSignature() { - if (parseObjCSelector()) { + unsigned selector_token = 0; + if (parseObjCSelector(selector_token)) { while (LA() == T_COMMA) { consumeToken(); // skip T_COMMA - parseObjCSelector(); + parseObjCSelector(selector_token); } return true; } @@ -4325,6 +4350,8 @@ bool Parser::parseObjCMethodPrototype() parseObjCTypeName(); + unsigned selector_token = 0; + if ((lookAtObjCSelector() && LA(2) == T_COLON) || LA() == T_COLON) { while (parseObjCKeywordDeclaration()) { } @@ -4341,7 +4368,7 @@ bool Parser::parseObjCMethodPrototype() parseParameterDeclaration(parameter_declaration); } } else if (lookAtObjCSelector()) { - parseObjCSelector(); + parseObjCSelector(selector_token); } else { _translationUnit->error(cursor(), "expected a selector"); } @@ -4396,12 +4423,12 @@ bool Parser::parseObjCTypeName() // objc-selector ::= T_IDENTIFIER | keyword // -bool Parser::parseObjCSelector() +bool Parser::parseObjCSelector(unsigned &selector_token) { if (! lookAtObjCSelector()) return false; - consumeToken(); + selector_token = consumeToken(); return true; } @@ -4412,7 +4439,8 @@ bool Parser::parseObjCKeywordDeclaration() if (! (LA() == T_COLON || (lookAtObjCSelector() && LA(2) == T_COLON))) return false; - parseObjCSelector(); + unsigned selector_token = 0; + parseObjCSelector(selector_token); unsigned colon_token = 0; match(T_COLON, &colon_token); diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h index 4d6af741bfd..c81312d94f9 100644 --- a/src/shared/cplusplus/Parser.h +++ b/src/shared/cplusplus/Parser.h @@ -227,7 +227,7 @@ public: bool parseObjCMessageExpression(ExpressionAST *&node); bool parseObjCMessageReceiver(ExpressionAST *&node); bool parseObjCMessageArguments(ObjCMessageArgumentListAST *&node); - bool parseObjCSelectorArgs(); + bool parseObjCSelectorArg(ObjCMessageArgumentAST *&node); bool parseObjCMethodDefinitionList(); bool parseObjCMethodDefinition(); @@ -241,7 +241,7 @@ public: bool parseObjCMethodPrototype(); bool parseObjCPropertyAttribute(); bool parseObjCTypeName(); - bool parseObjCSelector(); + bool parseObjCSelector(unsigned &selector_token); bool parseObjCKeywordDeclaration(); bool parseObjCTypeQualifiers(); bool parseObjCEnd(DeclarationAST *&node); -- GitLab