diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index cba0a7a39dc4a6ccd222125100c324e662b3554c..0d859f385abb175463cd5aeafca68258c6acaf18 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 fb84d4d0a917634fcb5aa2403441a5ce768adf98..dcdf5abee256be64199122e4d509738ab63f11b2 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 87e74d9ee485201666ac7f210e3e668a37d47615..a5167a59d41946372f77076b61971c181d96b229 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 a76d80df6bbd5e154adb2f2f5ddeab23997eedd1..bc5f1a0873975acb04cec0fb61a31df9c82c3e88 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 ebe28a83da07c9270e6ded0e849b3fef62ba9a67..6a7c72068629a8bfb60a7e24bd6b00ac7af00fa6 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 be29bc7eea8937091c4489aa1b70ed05a05e5a5b..a269713e9b679f25e6235bab725def87f9db2ac8 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 ee8e714f64e1d39036ef02b491c306a810405b09..70bc64ae3d5a0739007c121bfb11a31f86059cc9 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 181e4b6b712fb735dfd293b8e1b3323a3eb857d0..15e11994ccbc2bf46eb95aa045ad63ba4ad53727 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);