Added Objective-C @try block parsing.

This commit is contained in:
Erik Verbruggen
2010-02-14 16:05:25 +01:00
parent 2a59d2ae0c
commit f4163b8ba0
18 changed files with 515 additions and 8 deletions

View File

@@ -1691,7 +1691,6 @@ unsigned ThisExpressionAST::lastToken() const
return this_token + 1;
}
unsigned ThrowExpressionAST::firstToken() const
{
return throw_token;
@@ -1704,6 +1703,20 @@ unsigned ThrowExpressionAST::lastToken() const
return throw_token + 1;
}
unsigned ObjCThrowExpressionAST::firstToken() const
{
return at_token;
}
unsigned ObjCThrowExpressionAST::lastToken() const
{
if (expression)
return expression->lastToken();
if (throw_token)
return throw_token + 1;
return at_token + 1;
}
unsigned TranslationUnitAST::firstToken() const
{
if(declaration_list)
@@ -2392,3 +2405,49 @@ unsigned ObjCSynchronizedStatementAST::lastToken() const
if (synchronized_token) return synchronized_token + 1;
return at_token + 1;
}
unsigned ObjCTryBlockStatementAST::firstToken() const
{ return at_token; }
unsigned ObjCTryBlockStatementAST::lastToken() const
{
if (finally_clause)
return finally_clause->lastToken();
if (catch_clause_list)
return catch_clause_list->lastToken();
if (statement)
return statement->lastToken();
if (try_token)
return try_token + 1;
return at_token + 1;
}
unsigned ObjCCatchClauseAST::firstToken() const
{ return at_token; }
unsigned ObjCCatchClauseAST::lastToken() const
{
if (statement)
return statement->lastToken();
if (rparen_token)
return rparen_token + 1;
if (exception_declaration)
return exception_declaration->lastToken();
if (lparen_token)
return lparen_token + 1;
if (catch_token)
return catch_token + 1;
return at_token + 1;
}
unsigned ObjCFinallyClauseAST::firstToken() const
{ return at_token; }
unsigned ObjCFinallyClauseAST::lastToken() const
{
if (statement)
return statement->lastToken();
if (finally_token)
return finally_token + 1;
return at_token + 1;
}

View File

@@ -218,11 +218,13 @@ public:
virtual NewPlacementAST *asNewPlacement() { return 0; }
virtual NewTypeIdAST *asNewTypeId() { return 0; }
virtual NumericLiteralAST *asNumericLiteral() { return 0; }
virtual ObjCCatchClauseAST *asObjCCatchClause() { return 0; }
virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; }
virtual ObjCClassForwardDeclarationAST *asObjCClassForwardDeclaration() { return 0; }
virtual ObjCDynamicPropertiesDeclarationAST *asObjCDynamicPropertiesDeclaration() { return 0; }
virtual ObjCEncodeExpressionAST *asObjCEncodeExpression() { return 0; }
virtual ObjCFastEnumerationAST *asObjCFastEnumeration() { return 0; }
virtual ObjCFinallyClauseAST *asObjCFinallyClause() { return 0; }
virtual ObjCInstanceVariablesDeclarationAST *asObjCInstanceVariablesDeclaration() { return 0; }
virtual ObjCMessageArgumentAST *asObjCMessageArgument() { return 0; }
virtual ObjCMessageArgumentDeclarationAST *asObjCMessageArgumentDeclaration() { return 0; }
@@ -243,6 +245,8 @@ public:
virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement() { return 0; }
virtual ObjCSynthesizedPropertiesDeclarationAST *asObjCSynthesizedPropertiesDeclaration() { return 0; }
virtual ObjCSynthesizedPropertyAST *asObjCSynthesizedProperty() { return 0; }
virtual ObjCThrowExpressionAST *asObjCThrowExpression() { return 0; }
virtual ObjCTryBlockStatementAST *asObjCTryBlockStatement() { return 0; }
virtual ObjCTypeNameAST *asObjCTypeName() { return 0; }
virtual ObjCVisibilityDeclarationAST *asObjCVisibilityDeclaration() { return 0; }
virtual OperatorAST *asOperator() { return 0; }
@@ -2359,6 +2363,26 @@ protected:
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT ObjCThrowExpressionAST: public ExpressionAST
{
public:
unsigned at_token;
unsigned throw_token;
ExpressionAST *expression;
public:
virtual ObjCThrowExpressionAST *asObjCThrowExpression() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual ObjCThrowExpressionAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT TranslationUnitAST: public AST
{
public:
@@ -3169,6 +3193,74 @@ protected:
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT ObjCTryBlockStatementAST: public StatementAST
{
public:
unsigned at_token;
unsigned try_token;
StatementAST *statement;
ObjCCatchClauseListAST *catch_clause_list;
ObjCFinallyClauseAST *finally_clause;
public:
virtual ObjCTryBlockStatementAST *asObjCTryBlockStatement() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual ObjCTryBlockStatementAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT ObjCCatchClauseAST: public StatementAST
{
public:
unsigned at_token;
unsigned catch_token;
unsigned lparen_token;
ExceptionDeclarationAST *exception_declaration;
unsigned rparen_token;
StatementAST *statement;
public: // annotations
Block *symbol;
public:
virtual ObjCCatchClauseAST *asObjCCatchClause() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual ObjCCatchClauseAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT ObjCFinallyClauseAST: public StatementAST
{
public:
unsigned at_token;
unsigned finally_token;
StatementAST *statement;
public:
virtual ObjCFinallyClauseAST *asObjCFinallyClause() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual ObjCFinallyClauseAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
} // end of namespace CPlusPlus

View File

@@ -1108,6 +1108,16 @@ ThrowExpressionAST *ThrowExpressionAST::clone(MemoryPool *pool) const
return ast;
}
ObjCThrowExpressionAST *ObjCThrowExpressionAST::clone(MemoryPool *pool) const
{
ObjCThrowExpressionAST *ast = new (pool) ObjCThrowExpressionAST;
ast->at_token = at_token;
ast->throw_token = throw_token;
if (expression)
ast->expression = expression->clone(pool);
return ast;
}
TranslationUnitAST *TranslationUnitAST::clone(MemoryPool *pool) const
{
TranslationUnitAST *ast = new (pool) TranslationUnitAST;
@@ -1564,3 +1574,42 @@ ObjCSynchronizedStatementAST *ObjCSynchronizedStatementAST::clone(MemoryPool *po
return ast;
}
ObjCTryBlockStatementAST *ObjCTryBlockStatementAST::clone(MemoryPool *pool) const
{
ObjCTryBlockStatementAST *ast = new (pool) ObjCTryBlockStatementAST;
ast->at_token = at_token;
ast->try_token = try_token;
if (statement)
ast->statement = statement->clone(pool);
for (ObjCCatchClauseListAST *iter = catch_clause_list, **ast_iter = &ast->catch_clause_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) ObjCCatchClauseListAST((iter->value) ? iter->value->clone(pool) : 0);
if (finally_clause)
ast->finally_clause = finally_clause->clone(pool);
return ast;
}
ObjCCatchClauseAST *ObjCCatchClauseAST::clone(MemoryPool *pool) const
{
ObjCCatchClauseAST *ast = new (pool) ObjCCatchClauseAST;
ast->at_token = at_token;
ast->catch_token = catch_token;
ast->lparen_token = lparen_token;
if (exception_declaration)
ast->exception_declaration = exception_declaration->clone(pool);
ast->rparen_token = rparen_token;
if (statement)
ast->statement = statement->clone(pool);
return ast;
}
ObjCFinallyClauseAST *ObjCFinallyClauseAST::clone(MemoryPool *pool) const
{
ObjCFinallyClauseAST *ast = new (pool) ObjCFinallyClauseAST;
ast->at_token = at_token;
ast->finally_token = finally_token;
if (statement)
ast->statement = statement->clone(pool);
return ast;
}

View File

@@ -793,6 +793,14 @@ bool ThrowExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
bool ObjCThrowExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (ObjCThrowExpressionAST *_other = pattern->asObjCThrowExpression())
return matcher->match(this, _other);
return false;
}
bool TranslationUnitAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (TranslationUnitAST *_other = pattern->asTranslationUnit())
@@ -1081,3 +1089,27 @@ bool ObjCSynchronizedStatementAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
bool ObjCTryBlockStatementAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (ObjCTryBlockStatementAST *_other = pattern->asObjCTryBlockStatement())
return matcher->match(this, _other);
return false;
}
bool ObjCCatchClauseAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (ObjCCatchClauseAST *_other = pattern->asObjCCatchClause())
return matcher->match(this, _other);
return false;
}
bool ObjCFinallyClauseAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (ObjCFinallyClauseAST *_other = pattern->asObjCFinallyClause())
return matcher->match(this, _other);
return false;
}

View File

@@ -1848,6 +1848,23 @@ bool ASTMatcher::match(ThrowExpressionAST *node, ThrowExpressionAST *pattern)
return true;
}
bool ASTMatcher::match(ObjCThrowExpressionAST *node, ObjCThrowExpressionAST *pattern)
{
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->throw_token = node->throw_token;
if (! pattern->expression)
pattern->expression = node->expression;
else if (! AST::match(node->expression, pattern->expression, this))
return false;
return true;
}
bool ASTMatcher::match(TranslationUnitAST *node, TranslationUnitAST *pattern)
{
(void) node;
@@ -2632,3 +2649,73 @@ bool ASTMatcher::match(ObjCSynchronizedStatementAST *node, ObjCSynchronizedState
return true;
}
bool ASTMatcher::match(ObjCTryBlockStatementAST *node, ObjCTryBlockStatementAST *pattern)
{
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->try_token = node->try_token;
if (! pattern->statement)
pattern->statement = node->statement;
else if (! AST::match(node->statement, pattern->statement, this))
return false;
if (! pattern->catch_clause_list)
pattern->catch_clause_list = node->catch_clause_list;
else if (! AST::match(node->catch_clause_list, pattern->catch_clause_list, this))
return false;
if (! pattern->finally_clause)
pattern->finally_clause = node->finally_clause;
else if (! AST::match(node->finally_clause, pattern->finally_clause, this))
return false;
return true;
}
bool ASTMatcher::match(ObjCCatchClauseAST *node, ObjCCatchClauseAST *pattern)
{
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->catch_token = node->catch_token;
pattern->lparen_token = node->lparen_token;
if (! pattern->exception_declaration)
pattern->exception_declaration = node->exception_declaration;
else if (! AST::match(node->exception_declaration, pattern->exception_declaration, this))
return false;
pattern->rparen_token = node->rparen_token;
if (! pattern->statement)
pattern->statement = node->statement;
else if (! AST::match(node->statement, pattern->statement, this))
return false;
return true;
}
bool ASTMatcher::match(ObjCFinallyClauseAST *node, ObjCFinallyClauseAST *pattern)
{
(void) node;
(void) pattern;
pattern->at_token = node->at_token;
pattern->finally_token = node->finally_token;
if (! pattern->statement)
pattern->statement = node->statement;
else if (! AST::match(node->statement, pattern->statement, this))
return false;
return true;
}

View File

@@ -126,6 +126,7 @@ public:
virtual bool match(TemplateTypeParameterAST *node, TemplateTypeParameterAST *pattern);
virtual bool match(ThisExpressionAST *node, ThisExpressionAST *pattern);
virtual bool match(ThrowExpressionAST *node, ThrowExpressionAST *pattern);
virtual bool match(ObjCThrowExpressionAST *node, ObjCThrowExpressionAST *pattern);
virtual bool match(TranslationUnitAST *node, TranslationUnitAST *pattern);
virtual bool match(TryBlockStatementAST *node, TryBlockStatementAST *pattern);
virtual bool match(TypeConstructorCallAST *node, TypeConstructorCallAST *pattern);
@@ -169,6 +170,9 @@ public:
virtual bool match(ObjCDynamicPropertiesDeclarationAST *node, ObjCDynamicPropertiesDeclarationAST *pattern);
virtual bool match(ObjCFastEnumerationAST *node, ObjCFastEnumerationAST *pattern);
virtual bool match(ObjCSynchronizedStatementAST *node, ObjCSynchronizedStatementAST *pattern);
virtual bool match(ObjCTryBlockStatementAST *node, ObjCTryBlockStatementAST *pattern);
virtual bool match(ObjCCatchClauseAST *node, ObjCCatchClauseAST *pattern);
virtual bool match(ObjCFinallyClauseAST *node, ObjCFinallyClauseAST *pattern);
};
} // end of namespace CPlusPlus

View File

@@ -831,6 +831,14 @@ void ThrowExpressionAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
void ObjCThrowExpressionAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(expression, visitor);
}
visitor->endVisit(this);
}
void TranslationUnitAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
@@ -1147,3 +1155,30 @@ void ObjCSynchronizedStatementAST::accept0(ASTVisitor *visitor)
visitor->endVisit(this);
}
void ObjCTryBlockStatementAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
accept(catch_clause_list, visitor);
accept(finally_clause, visitor);
}
visitor->endVisit(this);
}
void ObjCCatchClauseAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(exception_declaration, visitor);
accept(statement, visitor);
}
visitor->endVisit(this);
}
void ObjCFinallyClauseAST::accept0(ASTVisitor *visitor)
{
if (visitor->visit(this)) {
accept(statement, visitor);
}
visitor->endVisit(this);
}

View File

@@ -235,6 +235,10 @@ public:
virtual bool visit(ObjCDynamicPropertiesDeclarationAST *) { return true; }
virtual bool visit(ObjCFastEnumerationAST *) { return true; }
virtual bool visit(ObjCSynchronizedStatementAST *) { return true; }
virtual bool visit(ObjCTryBlockStatementAST *) { return true; }
virtual bool visit(ObjCCatchClauseAST *) { return true; }
virtual bool visit(ObjCFinallyClauseAST *) { return true; }
virtual bool visit(ObjCThrowExpressionAST *) { return true; }
virtual void endVisit(AccessDeclarationAST *) { }
virtual void endVisit(QtPropertyDeclarationAST *) { }
@@ -369,6 +373,10 @@ public:
virtual void endVisit(ObjCDynamicPropertiesDeclarationAST *) { }
virtual void endVisit(ObjCFastEnumerationAST *) { }
virtual void endVisit(ObjCSynchronizedStatementAST *) { }
virtual void endVisit(ObjCTryBlockStatementAST *) { }
virtual void endVisit(ObjCCatchClauseAST *) { }
virtual void endVisit(ObjCFinallyClauseAST *) { }
virtual void endVisit(ObjCThrowExpressionAST *) { }
private:
TranslationUnit *_translationUnit;

View File

@@ -125,11 +125,13 @@ class NewInitializerAST;
class NewPlacementAST;
class NewTypeIdAST;
class NumericLiteralAST;
class ObjCCatchClauseAST;
class ObjCClassDeclarationAST;
class ObjCClassForwardDeclarationAST;
class ObjCDynamicPropertiesDeclarationAST;
class ObjCEncodeExpressionAST;
class ObjCFastEnumerationAST;
class ObjCFinallyClauseAST;
class ObjCInstanceVariablesDeclarationAST;
class ObjCMessageArgumentAST;
class ObjCMessageArgumentDeclarationAST;
@@ -150,6 +152,8 @@ class ObjCSelectorWithoutArgumentsAST;
class ObjCSynchronizedStatementAST;
class ObjCSynthesizedPropertiesDeclarationAST;
class ObjCSynthesizedPropertyAST;
class ObjCThrowExpressionAST;
class ObjCTryBlockStatementAST;
class ObjCTypeNameAST;
class ObjCVisibilityDeclarationAST;
class OperatorAST;
@@ -224,6 +228,7 @@ typedef List<ObjCSelectorArgumentAST *> ObjCSelectorArgumentListAST;
typedef List<ObjCPropertyAttributeAST *> ObjCPropertyAttributeListAST;
typedef List<ObjCMessageArgumentDeclarationAST *> ObjCMessageArgumentDeclarationListAST;
typedef List<ObjCSynthesizedPropertyAST *> ObjCSynthesizedPropertyListAST;
typedef List<ObjCCatchClauseAST *> ObjCCatchClauseListAST;
typedef ExpressionListAST TemplateArgumentListAST;

View File

@@ -305,6 +305,12 @@ bool CheckExpression::visit(ThrowExpressionAST *ast)
return false;
}
bool CheckExpression::visit(ObjCThrowExpressionAST *ast)
{
FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
return false;
}
bool CheckExpression::visit(TypeIdAST *ast)
{
FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope);

View File

@@ -90,6 +90,7 @@ protected:
virtual bool visit(NestedExpressionAST *ast);
virtual bool visit(StringLiteralAST *ast);
virtual bool visit(ThrowExpressionAST *ast);
virtual bool visit(ObjCThrowExpressionAST *ast);
virtual bool visit(TypeIdAST *ast);
virtual bool visit(UnaryExpressionAST *ast);
virtual bool visit(QtMethodAST *ast);

View File

@@ -379,3 +379,35 @@ bool CheckStatement::visit(QtMemberDeclarationAST *ast)
_exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(ObjCTryBlockStatementAST *ast)
{
semantic()->check(ast->statement, _scope);
for (ObjCCatchClauseListAST *it = ast->catch_clause_list; it; it = it->next) {
semantic()->check(it->value, _scope);
}
_exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(ObjCCatchClauseAST *ast)
{
Block *block = control()->newBlock(ast->at_token);
block->setStartOffset(tokenAt(ast->firstToken()).offset);
block->setEndOffset(tokenAt(ast->lastToken()).offset);
ast->symbol = block;
_scope->enterSymbol(block);
Scope *previousScope = switchScope(block->members());
semantic()->check(ast->exception_declaration, _scope);
semantic()->check(ast->statement, _scope);
(void) switchScope(previousScope);
_exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(ObjCFinallyClauseAST *ast)
{
semantic()->check(ast->statement, _scope);
_exprType = FullySpecifiedType();
return false;
}

View File

@@ -90,6 +90,9 @@ protected:
virtual bool visit(CatchClauseAST *ast);
virtual bool visit(WhileStatementAST *ast);
virtual bool visit(QtMemberDeclarationAST *ast);
virtual bool visit(ObjCTryBlockStatementAST *ast);
virtual bool visit(ObjCCatchClauseAST *ast);
virtual bool visit(ObjCFinallyClauseAST *ast);
bool forEachFastEnum(unsigned firstToken,
unsigned lastToken,

View File

@@ -362,8 +362,17 @@ bool Parser::skipUntilStatement()
return true;
case T_AT:
if (objCEnabled() && LA(2) == T_SYNCHRONIZED)
return true;
if (objCEnabled()) {
switch (LA(2)) {
case T_SYNCHRONIZED:
case T_TRY:
case T_THROW:
return true;
default: {
// INTENTIONAL FALL-THROUGH!
}
}
}
default:
consumeToken();
@@ -2442,8 +2451,12 @@ bool Parser::parseStatement(StatementAST *&node)
} return true;
case T_AT:
return objCEnabled() && LA(2) == T_SYNCHRONIZED
&& parseObjCSynchronizedStatement(node);
if (objCEnabled()) {
if (LA(2) == T_SYNCHRONIZED)
return parseObjCSynchronizedStatement(node);
if (LA(2) == T_TRY)
return parseObjCTryBlockStatement(node);
}
default:
if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
@@ -3552,7 +3565,7 @@ bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
if (LA() != T_AT || LA(2) != T_STRING_LITERAL)
return false;
StringLiteralAST **ast = 0;
StringLiteralAST **ast = reinterpret_cast<StringLiteralAST **> (&node);
while (LA()) {
if (LA() == T_AT && LA(2) == T_STRING_LITERAL) {
*ast = new (_pool) StringLiteralAST;
@@ -4503,6 +4516,14 @@ bool Parser::parseThrowExpression(ExpressionAST *&node)
node = ast;
return true;
}
if (LA() == T_AT && LA(2) == T_THROW) {
ObjCThrowExpressionAST *ast = new (_pool) ObjCThrowExpressionAST;
ast->at_token = consumeToken();
ast->throw_token = consumeToken();
parseAssignmentExpression(ast->expression);
node = ast;
return true;
}
return false;
}
@@ -5373,3 +5394,51 @@ int Parser::peekAtQtContextKeyword() const
const Identifier *id = tok().identifier;
return classifyQtContextKeyword(id->chars(), id->size());
}
bool Parser::parseObjCTryBlockStatement(StatementAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_AT && LA(2) == T_TRY) {
ObjCTryBlockStatementAST *ast = new (_pool) ObjCTryBlockStatementAST;
ast->at_token = consumeToken();
ast->try_token = consumeToken();
parseCompoundStatement(ast->statement);
ObjCCatchClauseListAST **catch_clause_ptr = &ast->catch_clause_list;
while (parseObjCCatchClause(*catch_clause_ptr))
catch_clause_ptr = &(*catch_clause_ptr)->next;
parseObjCFinallyClause(ast->finally_clause);
node = ast;
return true;
}
return false;
}
bool Parser::parseObjCCatchClause(ObjCCatchClauseListAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_AT && LA(2) == T_CATCH) {
ObjCCatchClauseAST *ast = new (_pool) ObjCCatchClauseAST;
ast->at_token = consumeToken();
ast->catch_token = consumeToken();
match(T_LPAREN, &ast->lparen_token);
parseExceptionDeclaration(ast->exception_declaration);
match(T_RPAREN, &ast->rparen_token);
parseCompoundStatement(ast->statement);
node = new (_pool) ObjCCatchClauseListAST(ast);
return true;
}
return false;
}
bool Parser::parseObjCFinallyClause(ObjCFinallyClauseAST *&node)
{
DEBUG_THIS_RULE();
if (LA() == T_AT && LA(2) == T_FINALLY) {
node = new (_pool) ObjCFinallyClauseAST;
node->at_token = consumeToken();
node->finally_token = consumeToken();
parseCompoundStatement(node->statement);
return true;
}
return false;
}

View File

@@ -251,6 +251,9 @@ public:
bool parseObjCTypeQualifiers(unsigned &type_qualifier);
bool peekAtObjCContextKeyword(int kind);
bool parseObjCContextKeyword(int kind, unsigned &in_token);
bool parseObjCTryBlockStatement(StatementAST *&node);
bool parseObjCCatchClause(ObjCCatchClauseListAST *&node);
bool parseObjCFinallyClause(ObjCFinallyClauseAST *&node);
bool lookAtObjCSelector() const;