diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index dc6a50567751613fbad3f63d3dc0c2dec1bd757f..3da0dbf4646c07feb8d7067160bbcddfe7170bc0 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -1946,6 +1946,122 @@ unsigned ObjCClassDeclarationAST::lastToken() const
     return class_token + 1;
 }
 
+unsigned ObjCProtocolDeclarationAST::firstToken() const
+{
+    if (attributes)
+        return attributes->firstToken();
+    return protocol_token;
+}
+
+unsigned ObjCProtocolDeclarationAST::lastToken() const
+{
+    if (semicolon_token)
+        return semicolon_token + 1;
+
+    for (IdentifierListAST *it = identifier_list; it; it = it->next) {
+        if (! it->next && it->identifier_token)
+            return it->identifier_token + 1;
+    }
+
+    for (SpecifierAST *it = attributes; it; it = it->next) {
+        if (! it->next)
+            return it->lastToken();
+    }
+
+    return protocol_token + 1;
+}
 
+unsigned ObjCClassInterfaceDeclarationAST::firstToken() const
+{
+    if (attributes)
+        return attributes->firstToken();
+    return interface_token;
+}
+
+unsigned ObjCClassInterfaceDeclarationAST::lastToken() const
+{
+    if (end_token)                   return end_token + 1;
+    if (superclass_identifier_token) return superclass_identifier_token + 1;
+    if (colon_token)                 return colon_token + 1;
+    if (class_identifier_token)      return class_identifier_token + 1;
+
+    for (SpecifierAST *it = attributes; it; it = it->next) {
+        if (! it->next)
+            return it->lastToken();
+    }
+
+    return interface_token + 1;
+}
+
+unsigned ObjCCategoryInterfaceDeclarationAST::firstToken() const
+{
+    return interface_token;
+}
+
+unsigned ObjCCategoryInterfaceDeclarationAST::lastToken() const
+{
+    if (end_token)
+        return end_token + 1;
+
+    if (rparen_token)              return rparen_token + 1;
+    if (category_identifier_token) return category_identifier_token + 1;
+    if (lparen_token)              return lparen_token + 1;
+    if (class_identifier_token)    return class_identifier_token + 1;
+    return interface_token + 1;
+}
+
+unsigned ObjCProtocolDefinitionAST::firstToken() const
+{
+    if (attributes)
+        return attributes->firstToken();
+    return protocol_token;
+}
+
+unsigned ObjCProtocolDefinitionAST::lastToken() const
+{
+    if (end_token)
+        return end_token + 1;
+
+    if (identifier_token)
+        return identifier_token + 1;
+
+    for (SpecifierAST *it = attributes; it; it = it->next) {
+        if (! it->next)
+            return it->lastToken();
+    }
+
+    return protocol_token + 1;
+}
+
+unsigned ObjCProtocolRefsAST::firstToken() const
+{
+    return less_token;
+}
+
+unsigned ObjCProtocolRefsAST::lastToken() const
+{
+    if (greater_token) return greater_token + 1;
+
+    for (IdentifierListAST *it = identifier_list; it; it = it->next) {
+        if (! it->next && it->identifier_token)
+            return it->identifier_token + 1;
+    }
+
+    return less_token + 1;
+}
+
+unsigned ObjCMessageExpressionAST::firstToken() const
+{
+    return lbracket_token;
+}
+
+unsigned ObjCMessageExpressionAST::lastToken() const
+{
+    if (rbracket_token) return rbracket_token + 1;
+
+    // FIXME: TODO
+
+    return lbracket_token + 1;
+}
 
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index d22735eeb145b23c01098a7d1e7ac67b450d8d39..2e56fc52645b83d1abcaa508553f1ff00296c8a6 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -197,6 +197,8 @@ public:
     virtual WhileStatementAST *asWhileStatement() { return 0; }
     virtual IdentifierListAST *asIdentifierList() { return 0; }
     virtual ObjCClassDeclarationAST *asObjCClassDeclaration() { return 0; }
+    virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration() { return 0; }
+    virtual ObjCProtocolDefinitionAST *asObjCProtocolDefinition() { return 0; }
 
     virtual AST *clone(MemoryPool *pool) const = 0;
 
@@ -2443,6 +2445,7 @@ class CPLUSPLUS_EXPORT IdentifierListAST: public AST
 {
 public:
     unsigned identifier_token;
+    unsigned comma_token;
     IdentifierListAST *next;
 
 public:
@@ -2479,6 +2482,137 @@ protected:
     virtual void accept0(ASTVisitor *visitor);
 };
 
+class CPLUSPLUS_EXPORT ObjCClassInterfaceDeclarationAST: public DeclarationAST
+{
+public:
+    SpecifierAST *attributes;
+    unsigned interface_token;
+    unsigned class_identifier_token;
+    unsigned colon_token;
+    unsigned superclass_identifier_token;
+    ObjCProtocolRefsAST *protocol_refs;
+    unsigned end_token;
+
+public:
+    virtual ObjCClassInterfaceDeclarationAST *asObjCClassInterfaceDeclaration()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCClassInterfaceDeclarationAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCCategoryInterfaceDeclarationAST: public DeclarationAST
+{
+public:
+    unsigned interface_token;
+    unsigned class_identifier_token;
+    unsigned lparen_token;
+    unsigned category_identifier_token;
+    unsigned rparen_token;
+    ObjCProtocolRefsAST *protocol_refs;
+    unsigned end_token;
+
+public:
+    virtual ObjCCategoryInterfaceDeclarationAST *asObjCCategoryInterfaceDeclaration()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCCategoryInterfaceDeclarationAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCProtocolDeclarationAST: public DeclarationAST
+{
+public:
+    SpecifierAST *attributes;
+    unsigned protocol_token;
+    IdentifierListAST *identifier_list;
+    unsigned semicolon_token;
+
+public:
+    virtual ObjCProtocolDeclarationAST *asObjCProtocolDeclaration()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCProtocolDeclarationAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCProtocolDefinitionAST: public DeclarationAST
+{
+public:
+    SpecifierAST *attributes;
+    unsigned protocol_token;
+    unsigned identifier_token;
+    ObjCProtocolRefsAST *protocol_refs;
+    unsigned end_token;
+
+public:
+    virtual ObjCProtocolDefinitionAST *asObjCProtocolDefinition()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCProtocolDefinitionAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCProtocolRefsAST: public AST
+{
+public:
+    unsigned less_token;
+    IdentifierListAST *identifier_list;
+    unsigned greater_token;
+
+public:
+    virtual ObjCProtocolRefsAST *asObjCProtocolRefs()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCProtocolRefsAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCMessageExpressionAST: public ExpressionAST
+{
+public:
+    unsigned lbracket_token;
+    // ..
+    unsigned rbracket_token;
+
+public:
+    virtual ObjCMessageExpressionAST *asObjCMessageExpression()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCMessageExpressionAST *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 2e446c89ef1274f4542c053d17aeb7e89b569e68..b8ceec183cab538f9a5debc587878c49cd1c9b09 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -1224,4 +1224,73 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
     return ast;
 }
 
+ObjCClassInterfaceDeclarationAST *ObjCClassInterfaceDeclarationAST::clone(MemoryPool *pool) const
+{
+    ObjCClassInterfaceDeclarationAST *ast = new (pool) ObjCClassInterfaceDeclarationAST;
+    // copy DeclarationAST
+    // copy ObjCClassInterfaceDeclarationAST
+    if (attributes) ast->attributes = attributes->clone(pool);
+    ast->interface_token = interface_token;
+    ast->class_identifier_token = class_identifier_token;
+    ast->colon_token = colon_token;
+    ast->superclass_identifier_token = superclass_identifier_token;
+    if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool);
+    ast->end_token = end_token;
+    return ast;
+}
+
+ObjCCategoryInterfaceDeclarationAST *ObjCCategoryInterfaceDeclarationAST::clone(MemoryPool *pool) const
+{
+    ObjCCategoryInterfaceDeclarationAST *ast = new (pool) ObjCCategoryInterfaceDeclarationAST;
+    // copy DeclarationAST
+    // copy ObjCCategoryInterfaceDeclarationAST
+    ast->interface_token = interface_token;
+    ast->class_identifier_token = class_identifier_token;
+    if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool);
+    ast->lparen_token = lparen_token;
+    ast->category_identifier_token = category_identifier_token;
+    ast->rparen_token = rparen_token;
+    ast->end_token = end_token;
+    return ast;
+}
+
+ObjCProtocolDeclarationAST *ObjCProtocolDeclarationAST::clone(MemoryPool *pool) const
+{
+    ObjCProtocolDeclarationAST *ast = new (pool) ObjCProtocolDeclarationAST;
+    if (attributes) ast->attributes = attributes->clone(pool);
+    ast->protocol_token = protocol_token;
+    if (identifier_list) ast->identifier_list = identifier_list;
+    ast->semicolon_token = semicolon_token;
+    return ast;
+}
+
+ObjCProtocolDefinitionAST *ObjCProtocolDefinitionAST::clone(MemoryPool *pool) const
+{
+    ObjCProtocolDefinitionAST *ast = new (pool) ObjCProtocolDefinitionAST;
+    if (attributes) ast->attributes = attributes->clone(pool);
+    ast->protocol_token = protocol_token;
+    ast->identifier_token = identifier_token;
+    if (protocol_refs) ast->protocol_refs = protocol_refs->clone(pool);
+    ast->end_token = end_token;
+    return ast;
+}
+
+ObjCProtocolRefsAST *ObjCProtocolRefsAST::clone(MemoryPool *pool) const
+{
+    ObjCProtocolRefsAST *ast = new (pool) ObjCProtocolRefsAST;
+    ast->less_token = less_token;
+    if (ast->identifier_list) ast->identifier_list = identifier_list->clone(pool);
+    ast->greater_token = greater_token;
+    return ast;
+}
+
+ObjCMessageExpressionAST *ObjCMessageExpressionAST::clone(MemoryPool *pool) const
+{
+    ObjCMessageExpressionAST *ast = new (pool) ObjCMessageExpressionAST;
+    ast->lbracket_token = lbracket_token;
+    // FIXME: TODO
+    ast->rbracket_token = rbracket_token;
+    return ast;
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 1673577474f4a8793b613287f4e2d9e74de6fdc6..c556b21015ea6c9899776b61b8e03db7569f30cf 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -1139,4 +1139,70 @@ void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
+void ObjCClassInterfaceDeclarationAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCClassInterfaceDeclarationAST
+        for (SpecifierAST *it = attributes; it; it = it->next)
+            accept(it, visitor);
+        accept(protocol_refs, visitor);
+        // visit DeclarationAST
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCCategoryInterfaceDeclarationAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCCategoryInterfaceDeclarationAST
+        accept(protocol_refs, visitor);
+        // visit DeclarationAST
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCProtocolDeclarationAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCProtocolDeclarationAST
+        for (SpecifierAST *it = attributes; it; it = it->next)
+            accept(it, visitor);
+        for (IdentifierListAST *it = identifier_list; it; it = it->next)
+            accept(it, visitor);
+        // visit DeclarationAST
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCProtocolDefinitionAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCProtocolDefinitionAST
+        for (SpecifierAST *it = attributes; it; it = it->next)
+            accept(it, visitor);
+        accept(protocol_refs, visitor);
+        // visit DeclarationAST
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCProtocolRefsAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCProtocolRefsAST
+        for (IdentifierListAST *it = identifier_list; it; it = it->next)
+            accept(it, visitor);
+        // visit AST
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCMessageExpressionAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // FIXME: TODO
+    }
+    visitor->endVisit(this);
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index caa93e5e1b82572c87f90c818fb8a7a144bf1bdc..fd8c21971f3427c6e9fb467c33363ac1ebd083ed 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -198,6 +198,12 @@ public:
     // ObjC++
     virtual bool visit(IdentifierListAST *) { return true; }
     virtual bool visit(ObjCClassDeclarationAST *) { return true; }
+    virtual bool visit(ObjCClassInterfaceDeclarationAST *) { return true; }
+    virtual bool visit(ObjCCategoryInterfaceDeclarationAST *) { return true; }
+    virtual bool visit(ObjCProtocolDeclarationAST *) { return true; }
+    virtual bool visit(ObjCProtocolDefinitionAST *) { return true; }
+    virtual bool visit(ObjCProtocolRefsAST *) { return true; }
+    virtual bool visit(ObjCMessageExpressionAST *) { return true; }
 
     virtual bool visit(DeclarationListAST *) { return true; }
     virtual void endVisit(DeclarationListAST *) { }
@@ -307,6 +313,12 @@ public:
     // ObjC++
     virtual void endVisit(IdentifierListAST *) { }
     virtual void endVisit(ObjCClassDeclarationAST *) { }
+    virtual void endVisit(ObjCClassInterfaceDeclarationAST *) { }
+    virtual void endVisit(ObjCCategoryInterfaceDeclarationAST *) { }
+    virtual void endVisit(ObjCProtocolDeclarationAST *) { }
+    virtual void endVisit(ObjCProtocolDefinitionAST *) { }
+    virtual void endVisit(ObjCProtocolRefsAST *) { }
+    virtual void endVisit(ObjCMessageExpressionAST *) { }
 
 private:
     Control *_control;
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index ee5f8e876ffaf2b961439f959b7bb4667350c65c..a4662226fa5121395cdbd8b9a636119fc19568e3 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -171,6 +171,12 @@ class QtMethodAST;
 // ObjC++
 class IdentifierListAST;
 class ObjCClassDeclarationAST;
+class ObjCProtocolDeclarationAST;
+class ObjCProtocolDefinitionAST;
+class ObjCClassInterfaceDeclarationAST;
+class ObjCCategoryInterfaceDeclarationAST;
+class ObjCProtocolRefsAST;
+class ObjCMessageExpressionAST;
 
 CPLUSPLUS_END_NAMESPACE
 CPLUSPLUS_END_HEADER
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index a005f7250bbc7aa67c421cfd8bfa46145dfcb1fb..c3faca243fdd3b468abc570905f1525dfd7a3d89 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -2890,18 +2890,19 @@ bool Parser::parseObjCSelectorExpression(ExpressionAST *&)
     return true;
 }
 
-bool Parser::parseObjCMessageExpression(ExpressionAST *&)
+bool Parser::parseObjCMessageExpression(ExpressionAST *&node)
 {
     if (LA() != T_LBRACKET)
         return false;
 
-    /*unsigned lbracket_token = */ consumeToken();
+    ObjCMessageExpressionAST *ast = new (_pool) ObjCMessageExpressionAST;
+    ast->lbracket_token = consumeToken();
 
     parseObjCMessageReceiver();
     parseObjCMessageArguments();
 
-    unsigned rbracket_token = 0;
-    match(T_RBRACKET, &rbracket_token);
+    match(T_RBRACKET, &(ast->rbracket_token));
+    node = ast;
     return true;
 }
 
@@ -3838,21 +3839,33 @@ bool Parser::lookAtObjCSelector() const
 
 // objc-class-declaraton ::= T_AT_CLASS (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
 //
-bool Parser::parseObjCClassDeclaration(DeclarationAST *&)
+bool Parser::parseObjCClassDeclaration(DeclarationAST *&node)
 {
     if (LA() != T_AT_CLASS)
         return false;
 
-    /*unsigned objc_class_token = */ consumeToken();
+    ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
+
+    ast->class_token = consumeToken();
     unsigned identifier_token = 0;
     match(T_IDENTIFIER, &identifier_token);
+
+    ast->identifier_list = new (_pool) IdentifierListAST;
+    ast->identifier_list->identifier_token = identifier_token;
+    IdentifierListAST **nextId = &(ast->identifier_list->next);
+
     while (LA() == T_COMMA) {
-        consumeToken(); // skip T_COMMA
+        unsigned comma_token = consumeToken();
         match(T_IDENTIFIER, &identifier_token);
+
+        *nextId = new (_pool) IdentifierListAST;
+        (*nextId)->comma_token = comma_token;
+        (*nextId)->identifier_token = identifier_token;
+        nextId = &((*nextId)->next);
     }
 
-    unsigned semicolon_token = 0;
-    match(T_SEMICOLON, &semicolon_token);
+    match(T_SEMICOLON, &(ast->semicolon_token));
+    node = ast;
     return true;
 }
 
@@ -3871,7 +3884,7 @@ bool Parser::parseObjCClassDeclaration(DeclarationAST *&)
 //                             objc-interface-declaration-list
 //                             T_AT_END
 //
-bool Parser::parseObjCInterface(DeclarationAST *&,
+bool Parser::parseObjCInterface(DeclarationAST *&node,
                                 SpecifierAST *attributes)
 {
     if (! attributes && LA() == T___ATTRIBUTE__) {
@@ -3883,7 +3896,7 @@ bool Parser::parseObjCInterface(DeclarationAST *&,
     if (LA() != T_AT_INTERFACE)
         return false;
 
-    /*unsigned objc_interface_token = */ consumeToken();
+    unsigned objc_interface_token = consumeToken();
     unsigned identifier_token = 0;
     match(T_IDENTIFIER, &identifier_token);
 
@@ -3894,40 +3907,49 @@ bool Parser::parseObjCInterface(DeclarationAST *&,
             _translationUnit->error(attributes->firstToken(),
                                     "invalid attributes for category interface declaration");
 
-        unsigned lparen_token = 0, rparen_token = 0;
-        match(T_LPAREN, &lparen_token);
+        ObjCCategoryInterfaceDeclarationAST *ast = new (_pool) ObjCCategoryInterfaceDeclarationAST;
+        // XXX: Should the attributes get stored anyway? (for fixing/refactoring purposes maybe...)
+        ast->interface_token = objc_interface_token;
+        ast->class_identifier_token = identifier_token;
+
+        match(T_LPAREN, &(ast->lparen_token));
         if (LA() == T_IDENTIFIER)
-            consumeToken();
+            ast->category_identifier_token = consumeToken();
 
-        match(T_RPAREN, &rparen_token);
+        match(T_RPAREN, &(ast->rparen_token));
 
-        parseObjCProtocolRefs();
+        parseObjCProtocolRefs(ast->protocol_refs);
         while (parseObjCInterfaceMemberDeclaration()) {
         }
-        unsigned objc_end_token = 0;
-        match(T_AT_END, &objc_end_token);
+        match(T_AT_END, &(ast->end_token));
+
+        node = ast;
         return true;
-    }
+    } else {
+        // a class interface declaration
+        ObjCClassInterfaceDeclarationAST *ast = new (_pool) ObjCClassInterfaceDeclarationAST;
+        ast->attributes = attributes;
+        ast->interface_token = objc_interface_token;
+        ast->class_identifier_token = identifier_token;
 
-    // a class interface declaration
-    if (LA() == T_COLON) {
-        consumeToken();
-        unsigned identifier_token = 0;
-        match(T_IDENTIFIER, &identifier_token);
-    }
+        if (LA() == T_COLON) {
+            ast->colon_token = consumeToken();
+            match(T_IDENTIFIER, &(ast->superclass_identifier_token));
+        }
 
-    parseObjCProtocolRefs();
-    parseObjClassInstanceVariables();
-    while (parseObjCInterfaceMemberDeclaration()) {
+        parseObjCProtocolRefs(ast->protocol_refs);
+        parseObjClassInstanceVariables();
+        while (parseObjCInterfaceMemberDeclaration()) {
+        }
+        match(T_AT_END, &(ast->end_token));
+        node = ast;
+        return true;
     }
-    unsigned objc_end_token = 0;
-    match(T_AT_END, &objc_end_token);
-    return true;
 }
 
 // objc-protocol ::= T_AT_PROTOCOL (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
 //
-bool Parser::parseObjCProtocol(DeclarationAST *&,
+bool Parser::parseObjCProtocol(DeclarationAST *&node,
                                SpecifierAST *attributes)
 {
     if (! attributes && LA() == T___ATTRIBUTE__) {
@@ -3939,32 +3961,50 @@ bool Parser::parseObjCProtocol(DeclarationAST *&,
     if (LA() != T_AT_PROTOCOL)
         return false;
 
-    /*unsigned objc_protocol_token = */ consumeToken();
+    unsigned protocol_token = consumeToken();
     unsigned identifier_token = 0;
     match(T_IDENTIFIER, &identifier_token);
 
     if (LA() == T_COMMA || LA() == T_SEMICOLON) {
         // a protocol forward declaration
 
+        ObjCProtocolDeclarationAST *ast = new (_pool) ObjCProtocolDeclarationAST;
+        ast->attributes = attributes;
+        ast->protocol_token = protocol_token;
+        ast->identifier_list = new (_pool) IdentifierListAST;
+        ast->identifier_list->identifier_token = identifier_token;
+        IdentifierListAST **nextId = &(ast->identifier_list->next);
+
         while (LA() == T_COMMA) {
-            consumeToken();
+            unsigned comma_token = consumeToken();
             match(T_IDENTIFIER, &identifier_token);
+
+            *nextId = new (_pool) IdentifierListAST;
+            (*nextId)->comma_token = comma_token;
+            (*nextId)->identifier_token = identifier_token;
+            nextId = &((*nextId)->next);
         }
-        unsigned semicolon_token = 0;
-        match(T_SEMICOLON, &semicolon_token);
+
+        match(T_SEMICOLON, &ast->semicolon_token);
+        node = ast;
         return true;
-    }
+    } else {
+        // a protocol definition
+        ObjCProtocolDefinitionAST *ast = new (_pool) ObjCProtocolDefinitionAST;
+        ast->attributes = attributes;
+        ast->protocol_token = protocol_token;
+        ast->identifier_token = identifier_token;
 
-    // a protocol definition
-    parseObjCProtocolRefs();
+        parseObjCProtocolRefs(ast->protocol_refs);
 
-    while (parseObjCInterfaceMemberDeclaration()) {
-    }
+        while (parseObjCInterfaceMemberDeclaration()) {
+        }
 
-    unsigned objc_end_token = 0;
-    match(T_AT_END, &objc_end_token);
+        match(T_AT_END, &(ast->end_token));
 
-    return true;
+        node = ast;
+        return true;
+    }
 }
 
 // objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER (T_COLON T_IDENTIFIER)?
@@ -4057,19 +4097,33 @@ bool Parser::parseObjCMethodDefinition()
 
 // objc-protocol-refs ::= T_LESS (T_IDENTIFIER @ T_COMMA) T_GREATER
 //
-bool Parser::parseObjCProtocolRefs()
+bool Parser::parseObjCProtocolRefs(ObjCProtocolRefsAST *&node)
 {
     if (LA() != T_LESS)
         return false;
-    unsigned less_token = 0, greater_token = 0;
+
+    ObjCProtocolRefsAST *ast = new (_pool) ObjCProtocolRefsAST;
+
+    match(T_LESS, &(ast->less_token));
+
     unsigned identifier_token = 0;
-    match(T_LESS, &less_token);
     match(T_IDENTIFIER, &identifier_token);
+    ast->identifier_list = new (_pool) IdentifierListAST;
+    ast->identifier_list->identifier_token = identifier_token;
+    IdentifierListAST **nextId = &(ast->identifier_list->next);
+
     while (LA() == T_COMMA) {
-        consumeToken();
+        unsigned comma_token = consumeToken();
         match(T_IDENTIFIER, &identifier_token);
+
+        *nextId = new (_pool) IdentifierListAST;
+        (*nextId)->comma_token = comma_token;
+        (*nextId)->identifier_token = identifier_token;
+        nextId = &((*nextId)->next);
     }
-    match(T_GREATER, &greater_token);
+
+    match(T_GREATER, &(ast->greater_token));
+    node = ast;
     return true;
 }
 
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index c5515b05ec0107db849b94b9f154cbcccfe14c72..8d02e429555a35bb935db4fbb8f41dc42b3e4c53 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -231,7 +231,7 @@ public:
     bool parseObjCMethodDefinitionList();
     bool parseObjCMethodDefinition();
 
-    bool parseObjCProtocolRefs();
+    bool parseObjCProtocolRefs(ObjCProtocolRefsAST *&node);
     bool parseObjClassInstanceVariables();
     bool parseObjCInterfaceMemberDeclaration();
     bool parseObjCInstanceVariableDeclaration(DeclarationAST *&node);