diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp index 9c6804219bc6a94a71ac9651ebb0b5ca31637cd7..9a9c9ced78245bb269ac091dd51e56d089b2256f 100644 --- a/src/libs/3rdparty/cplusplus/Parser.cpp +++ b/src/libs/3rdparty/cplusplus/Parser.cpp @@ -333,6 +333,7 @@ bool Parser::skipUntilStatement() case T_USING: return true; + case T_AT_TRY: case T_AT_SYNCHRONIZED: if (objCEnabled()) return true; @@ -3106,6 +3107,9 @@ bool Parser::parseStatement(StatementAST *&node) return true; } + case T_AT_TRY: + return objCEnabled() && parseObjCTryStatement(node); + case T_AT_SYNCHRONIZED: return objCEnabled() && parseObjCSynchronizedStatement(node); @@ -4404,6 +4408,50 @@ bool Parser::parseObjCStringLiteral(ExpressionAST *&node) return true; } +/// objc-try-catch-statement: +/// @try compound-statement objc-catch-list[opt] +/// @try compound-statement objc-catch-list[opt] @finally compound-statement +/// +/// objc-catch-list: +/// @catch ( parameter-declaration ) compound-statement +/// objc-catch-list @catch ( catch-parameter-declaration ) compound-statement +/// catch-parameter-declaration: +/// parameter-declaration +/// '...' [OBJC2] +/// +bool Parser::parseObjCTryStatement(StatementAST *& /*node*/) +{ + DEBUG_THIS_RULE(); + if (LA() != T_AT_TRY) + return false; + + /*try_token =*/ consumeToken(); + StatementAST *body_statment; + parseCompoundStatement(body_statment); + while (LA() == T_AT_CATCH) { + /*catch_token =*/ consumeToken(); + unsigned lparen_token; + match(T_LPAREN, &lparen_token); + if (LA() == T_DOT_DOT_DOT) { + /*unsigned ellipsis_token =*/ consumeToken(); + } else { + ParameterDeclarationAST *exception_decl; + parseParameterDeclaration(exception_decl); + } + unsigned rparen_token; + match(T_RPAREN, &rparen_token); + StatementAST *catch_statement; + parseCompoundStatement(catch_statement); + } + + if (LA() == T_AT_FINALLY) { + StatementAST *finally_statement; + parseCompoundStatement(finally_statement); + } + + return true; +} + bool Parser::parseObjCSynchronizedStatement(StatementAST *&node) { DEBUG_THIS_RULE(); diff --git a/src/libs/3rdparty/cplusplus/Parser.h b/src/libs/3rdparty/cplusplus/Parser.h index 978b1f99a19aa4ab146403b049a32ed2f9dfa093..71c3afa11b0afc596891141886e7259414865421 100644 --- a/src/libs/3rdparty/cplusplus/Parser.h +++ b/src/libs/3rdparty/cplusplus/Parser.h @@ -222,6 +222,7 @@ public: bool parseObjCProtocol(DeclarationAST *&node, SpecifierListAST *attributes = 0); + bool parseObjCTryStatement(StatementAST *&node); bool parseObjCSynchronizedStatement(StatementAST *&node); bool parseObjCEncodeExpression(ExpressionAST *&node); bool parseObjCProtocolExpression(ExpressionAST *&node); diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp index 6bfda0f503575789965a18d3f3af7145b1034750..f17de6b613d1087654f2a9aa8eac2ce6a72444c5 100644 --- a/tests/auto/cplusplus/ast/tst_ast.cpp +++ b/tests/auto/cplusplus/ast/tst_ast.cpp @@ -159,6 +159,9 @@ private slots: void objc_method_attributes_1(); void objc_selector_error_recovery_1(); void objc_selector_error_recovery_2(); + void objc_try_statement_1(); + void objc_try_statement_2(); + void objc_try_statement_3(); // expressions with (square) brackets void normal_array_access(); @@ -1380,6 +1383,60 @@ void tst_AST::objc_selector_error_recovery_2() QVERIFY(ast); } +void tst_AST::objc_try_statement_1() +{ + QSharedPointer<TranslationUnit> unit( + parseDeclaration( + "\n" + "void tst() {\n" + " @try {\n" + " something();\n" + " }\n" + "}\n" + )); + AST *ast = unit->ast(); + QVERIFY(ast); + QCOMPARE(diag.errorCount, 0); +} + +void tst_AST::objc_try_statement_2() +{ + QSharedPointer<TranslationUnit> unit( + parseDeclaration( + "void tst() {\n" + " @try {\n" + " something();\n" + " } @catch (NSException *e) {\n" + " another_thing();\n" + " } @catch (UIException *e) { \n" + " one_more_thing();\n" + " } @finally {\n" + " nothing();\n" + " }\n" + "}\n" + )); + AST *ast = unit->ast(); + QVERIFY(ast); + QCOMPARE(diag.errorCount, 0); +} + +void tst_AST::objc_try_statement_3() +{ + QSharedPointer<TranslationUnit> unit( + parseDeclaration( + "void tst() {\n" + " @try {\n" + " get_banana();\n" + " } @catch (...) {\n" + " printf(\"Oek?\");\n" + " }\n" + "}\n" + )); + AST *ast = unit->ast(); + QVERIFY(ast); + QCOMPARE(diag.errorCount, 0); +} + void tst_AST::normal_array_access() { QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"