From e2051267743b521c44602480441b5e4c0de04396 Mon Sep 17 00:00:00 2001
From: Erik Verbruggen <erik.verbruggen@nokia.com>
Date: Fri, 31 Jul 2009 16:53:05 +0200
Subject: [PATCH] Added @synchronized parsing for Objective-C.

---
 src/shared/cplusplus/AST.cpp      | 14 ++++++++++++++
 src/shared/cplusplus/AST.h        | 22 ++++++++++++++++++++++
 src/shared/cplusplus/ASTClone.cpp | 12 ++++++++++++
 src/shared/cplusplus/ASTVisit.cpp | 13 +++++++++++++
 src/shared/cplusplus/ASTVisitor.h |  3 ++-
 src/shared/cplusplus/ASTfwd.h     |  1 +
 src/shared/cplusplus/Parser.cpp   | 25 +++++++++++++++++++++++++
 src/shared/cplusplus/Parser.h     |  1 +
 8 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index cba0a7a39dc..0d859f385ab 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -2565,4 +2565,18 @@ unsigned ObjCFastEnumerationAST::lastToken() const
         return for_token + 1;
 }
 
+unsigned ObjCSynchronizedStatementAST::firstToken() const
+{
+    return synchronized_token;
+}
+
+unsigned ObjCSynchronizedStatementAST::lastToken() const
+{
+    if (statement) return statement->lastToken();
+    if (rparen_token) return rparen_token + 1;
+    if (synchronized_object) return synchronized_object->lastToken();
+    if (lparen_token) return lparen_token + 1;
+    return synchronized_token + 1;
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index fb84d4d0a91..dcdf5abee25 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -3232,6 +3232,28 @@ protected:
     virtual void accept0(ASTVisitor *visitor);
 };
 
+class CPLUSPLUS_EXPORT ObjCSynchronizedStatementAST: public StatementAST
+{
+public:
+    unsigned synchronized_token;
+    unsigned lparen_token;
+    ExpressionAST *synchronized_object;
+    unsigned rparen_token;
+    StatementAST *statement;
+
+public:
+    virtual ObjCSynchronizedStatementAST *asObjCSynchronizedStatement()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCSynchronizedStatementAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
 CPLUSPLUS_END_NAMESPACE
 CPLUSPLUS_END_HEADER
 
diff --git a/src/shared/cplusplus/ASTClone.cpp b/src/shared/cplusplus/ASTClone.cpp
index 87e74d9ee48..a5167a59d41 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -1550,4 +1550,16 @@ ObjCFastEnumerationAST *ObjCFastEnumerationAST::clone(MemoryPool *pool) const
     return ast;
 }
 
+ObjCSynchronizedStatementAST *ObjCSynchronizedStatementAST::clone(MemoryPool *pool) const
+{
+    ObjCSynchronizedStatementAST *ast = new (pool) ObjCSynchronizedStatementAST;
+    ast->synchronized_token = synchronized_token;
+    ast->lparen_token = lparen_token;
+    if (synchronized_object) ast->synchronized_object = synchronized_object->clone(pool);
+    ast->rparen_token = rparen_token;
+    if (statement) ast->statement = statement->clone(pool);
+    return ast;
+}
+
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index a76d80df6bb..bc5f1a08739 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -1527,4 +1527,17 @@ void ObjCFastEnumerationAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
+void ObjCSynchronizedStatementAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCSynchronizedStatementAST
+        if (synchronized_object)
+            accept(synchronized_object, visitor);
+        if (statement)
+            accept(statement, visitor);
+        // visit StatementAST
+    }
+    visitor->endVisit(this);
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index ebe28a83da0..6a7c7206862 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -231,11 +231,11 @@ public:
     virtual bool visit(ObjCSynthesizedPropertiesDeclarationAST *) { return true; }
     virtual bool visit(ObjCDynamicPropertiesDeclarationAST *) { return true; }
     virtual bool visit(ObjCFastEnumerationAST *) { return true; }
+    virtual bool visit(ObjCSynchronizedStatementAST *) { return true; }
 
     virtual bool visit(DeclarationListAST *) { return true; }
     virtual void endVisit(DeclarationListAST *) { }
 
-
     virtual void endVisit(AccessDeclarationAST *) { }
     virtual void endVisit(ArrayAccessAST *) { }
     virtual void endVisit(ArrayDeclaratorAST *) { }
@@ -373,6 +373,7 @@ public:
     virtual void endVisit(ObjCSynthesizedPropertiesDeclarationAST *) { }
     virtual void endVisit(ObjCDynamicPropertiesDeclarationAST *) { }
     virtual void endVisit(ObjCFastEnumerationAST *) { }
+    virtual void endVisit(ObjCSynchronizedStatementAST *) { }
 
 private:
     Control *_control;
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index be29bc7eea8..a269713e9b6 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -205,6 +205,7 @@ class ObjCSynthesizedPropertyListAST;
 class ObjCSynthesizedPropertiesDeclarationAST;
 class ObjCDynamicPropertiesDeclarationAST;
 class ObjCFastEnumerationAST;
+class ObjCSynchronizedStatementAST;
 
 CPLUSPLUS_END_NAMESPACE
 CPLUSPLUS_END_HEADER
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index ee8e714f64e..70bc64ae3d5 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -198,6 +198,10 @@ bool Parser::skipUntilStatement()
             case T_USING:
                 return true;
 
+            case T_AT_SYNCHRONIZED:
+                if (objCEnabled())
+                    return true;
+
             default:
                 consumeToken();
         }
@@ -1932,6 +1936,10 @@ bool Parser::parseStatement(StatementAST *&node)
         return true;
     }
 
+    case T_AT_SYNCHRONIZED:
+        if (objCEnabled())
+            return parseObjCSynchronizedStatement(node);
+
     default:
         if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
             return parseLabeledStatement(node);
@@ -2894,6 +2902,23 @@ bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
     return true;
 }
 
+bool Parser::parseObjCSynchronizedStatement(StatementAST *&node)
+{
+    if (LA() != T_AT_SYNCHRONIZED)
+        return false;
+
+    ObjCSynchronizedStatementAST *ast = new (_pool) ObjCSynchronizedStatementAST;
+
+    ast->synchronized_token = consumeToken();
+    match(T_LPAREN, &ast->lparen_token);
+    parseExpression(ast->synchronized_object);
+    match(T_RPAREN, &ast->rparen_token);
+    parseStatement(ast->statement);
+
+    node = ast;
+    return true;
+}
+
 bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
 {
     if (LA() != T_AT_ENCODE)
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index 181e4b6b712..15e11994ccb 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -219,6 +219,7 @@ public:
     bool parseObjCProtocol(DeclarationAST *&node,
                            SpecifierAST *attributes = 0);
 
+    bool parseObjCSynchronizedStatement(StatementAST *&node);
     bool parseObjCEncodeExpression(ExpressionAST *&node);
     bool parseObjCProtocolExpression(ExpressionAST *&node);
     bool parseObjCSelectorExpression(ExpressionAST *&node);
-- 
GitLab