forked from qt-creator/qt-creator
C++: handle @try statements in the parser.
No semantic analysis yet, but this prevents the parser from generating bogus diagnostics. Task-number: QTCREATORBUG-9309 Change-Id: I2ec575a8474cd51bfa97b17678d3da71ab8dcd7a Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
48
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
48
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -333,6 +333,7 @@ bool Parser::skipUntilStatement()
|
|||||||
case T_USING:
|
case T_USING:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case T_AT_TRY:
|
||||||
case T_AT_SYNCHRONIZED:
|
case T_AT_SYNCHRONIZED:
|
||||||
if (objCEnabled())
|
if (objCEnabled())
|
||||||
return true;
|
return true;
|
||||||
@@ -3106,6 +3107,9 @@ bool Parser::parseStatement(StatementAST *&node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case T_AT_TRY:
|
||||||
|
return objCEnabled() && parseObjCTryStatement(node);
|
||||||
|
|
||||||
case T_AT_SYNCHRONIZED:
|
case T_AT_SYNCHRONIZED:
|
||||||
return objCEnabled() && parseObjCSynchronizedStatement(node);
|
return objCEnabled() && parseObjCSynchronizedStatement(node);
|
||||||
|
|
||||||
@@ -4404,6 +4408,50 @@ bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
|
|||||||
return true;
|
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)
|
bool Parser::parseObjCSynchronizedStatement(StatementAST *&node)
|
||||||
{
|
{
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/Parser.h
vendored
1
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -222,6 +222,7 @@ public:
|
|||||||
bool parseObjCProtocol(DeclarationAST *&node,
|
bool parseObjCProtocol(DeclarationAST *&node,
|
||||||
SpecifierListAST *attributes = 0);
|
SpecifierListAST *attributes = 0);
|
||||||
|
|
||||||
|
bool parseObjCTryStatement(StatementAST *&node);
|
||||||
bool parseObjCSynchronizedStatement(StatementAST *&node);
|
bool parseObjCSynchronizedStatement(StatementAST *&node);
|
||||||
bool parseObjCEncodeExpression(ExpressionAST *&node);
|
bool parseObjCEncodeExpression(ExpressionAST *&node);
|
||||||
bool parseObjCProtocolExpression(ExpressionAST *&node);
|
bool parseObjCProtocolExpression(ExpressionAST *&node);
|
||||||
|
|||||||
@@ -159,6 +159,9 @@ private slots:
|
|||||||
void objc_method_attributes_1();
|
void objc_method_attributes_1();
|
||||||
void objc_selector_error_recovery_1();
|
void objc_selector_error_recovery_1();
|
||||||
void objc_selector_error_recovery_2();
|
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
|
// expressions with (square) brackets
|
||||||
void normal_array_access();
|
void normal_array_access();
|
||||||
@@ -1380,6 +1383,60 @@ void tst_AST::objc_selector_error_recovery_2()
|
|||||||
QVERIFY(ast);
|
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()
|
void tst_AST::normal_array_access()
|
||||||
{
|
{
|
||||||
QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
|
QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user