Commit f4163b8b authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

Added Objective-C @try block parsing.

parent 2a59d2ae
......@@ -322,6 +322,11 @@ bool ResolveExpression::visit(ThrowExpressionAST *)
return false;
}
bool ResolveExpression::visit(ObjCThrowExpressionAST *)
{
return false;
}
bool ResolveExpression::visit(TypeIdAST *)
{
return false;
......
......@@ -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(CompoundLiteralAST *ast);
......
......@@ -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;
}
......@@ -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
......
......@@ -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;
}
......@@ -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;
}
......@@ -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;
}
......@@ -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
......
......@@ -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);
}
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
}