diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.cpp b/src/plugins/genericprojectmanager/genericprojectnodes.cpp
index d9e4d3155c9e3b4a3b8424e16ee85192594adb63..c40b8e42fc818c9079d9304b6b31e362ff123aea 100644
--- a/src/plugins/genericprojectmanager/genericprojectnodes.cpp
+++ b/src/plugins/genericprojectmanager/genericprojectnodes.cpp
@@ -95,7 +95,7 @@ void GenericProjectNode::refresh()
         QFileInfo fileInfo(absoluteFileName);
         const QString absoluteFilePath = fileInfo.path();
 
-        QString baseDir(QFileInfo(path()).absolutePath());
+        QString baseDir = QFileInfo(path()).absolutePath();
         if (! absoluteFilePath.startsWith(baseDir))
             continue; // `file' is not part of the project.
 
diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp
index 9f3780d9a95f0bbda8073a9c0ed833af3b7c229c..3a8b84d4c5bbc740757e5d30b67b335cc8f76bb4 100644
--- a/src/plugins/projectexplorer/taskwindow.cpp
+++ b/src/plugins/projectexplorer/taskwindow.cpp
@@ -46,6 +46,7 @@
 #include <QtGui/QListView>
 #include <QtGui/QPainter>
 #include <QtCore/QAbstractItemModel>
+#include <QtGui/QSortFilterProxyModel>
 #include <QtGui/QApplication>
 #include <QtGui/QClipboard>
 #include <QtGui/QFont>
@@ -93,6 +94,32 @@ private:
     QIcon m_unspecifiedIcon;
 };
 
+class ProjectExplorer::Internal::TaskFilterModel : public QSortFilterProxyModel
+{
+public:
+    TaskFilterModel(TaskModel *sourceModel, QObject *parent = 0);
+
+    TaskModel *taskModel() const;
+
+    bool filterIncludesUnknowns() const { return m_includeUnknowns; }
+    void setFilterIncludesUnknowns(bool b) { m_includeUnknowns = b; invalidateFilter(); }
+
+    bool filterIncludesWarnings() const { return m_includeWarnings; }
+    void setFilterIncludesWarnings(bool b) { m_includeWarnings = b; invalidateFilter(); }
+
+    bool filterIncludesErrors() const { return m_includeErrors; }
+    void setFilterIncludesErrors(bool b) { m_includeErrors = b; invalidateFilter(); }
+
+protected:
+    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+
+private:
+    // These correspond to ProjectExplorer::BuildParserInterface::PatternType.
+    bool m_includeUnknowns;
+    bool m_includeWarnings;
+    bool m_includeErrors;
+};
+
 ////
 //  TaskView
 ////
@@ -241,18 +268,71 @@ void TaskModel::setFileNotFound(const QModelIndex &idx, bool b)
     }
 }
 
+/////
+// TaskFilterModel
+/////
+
+TaskFilterModel::TaskFilterModel(TaskModel *sourceModel, QObject *parent)
+    : QSortFilterProxyModel(parent)
+{
+    setSourceModel(sourceModel);
+    setDynamicSortFilter(true);
+    m_includeUnknowns = m_includeWarnings = m_includeErrors = true;
+}
+
+TaskModel *TaskFilterModel::taskModel() const
+{
+    return static_cast<TaskModel*>(sourceModel());
+}
+
+bool TaskFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+    QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
+    ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt());
+    switch (type) {
+    case ProjectExplorer::BuildParserInterface::Unknown:
+        return m_includeUnknowns;
+
+    case ProjectExplorer::BuildParserInterface::Warning:
+        return m_includeWarnings;
+
+    case ProjectExplorer::BuildParserInterface::Error:
+        return m_includeErrors;
+    }
+
+    // Not one of the three supported types -- shouldn't happen, but we'll let it slide.
+    return true;
+}
+
 /////
 // TaskWindow
 /////
 
+static QToolButton *createFilterButton(ProjectExplorer::BuildParserInterface::PatternType type,
+                                       const QString &toolTip, TaskModel *model,
+                                       QObject *receiver, const char *slot)
+{
+    QToolButton *button = new QToolButton;
+    button->setIcon(model->iconFor(type));
+    button->setProperty("type", "dockbutton");
+    button->setToolTip(toolTip);
+    button->setCheckable(true);
+    button->setChecked(true);
+    button->setAutoRaise(true);
+    button->setEnabled(true);
+    QObject::connect(button, SIGNAL(toggled(bool)), receiver, slot);
+    return button;
+}
+
 TaskWindow::TaskWindow()
 {
     Core::ICore *core = Core::ICore::instance();
 
     m_model = new TaskModel;
+    m_filter = new TaskFilterModel(m_model);
     m_listview = new TaskView;
 
-    m_listview->setModel(m_model);
+    m_listview->setModel(m_filter);
     m_listview->setFrameStyle(QFrame::NoFrame);
     m_listview->setWindowTitle(tr("Build Issues"));
     m_listview->setSelectionMode(QAbstractItemView::SingleSelection);
@@ -280,6 +360,10 @@ TaskWindow::TaskWindow()
 
     connect(m_copyAction, SIGNAL(triggered()), SLOT(copy()));
 
+    m_filterWarningsButton = createFilterButton(ProjectExplorer::BuildParserInterface::Warning,
+                                                tr("Show Warnings"), m_model,
+                                                this, SLOT(setShowWarnings(bool)));
+
     m_errorCount = 0;
     m_currentTask = -1;
 }
@@ -287,13 +371,15 @@ TaskWindow::TaskWindow()
 TaskWindow::~TaskWindow()
 {
     Core::ICore::instance()->removeContextObject(m_taskWindowContext);
+    delete m_filterWarningsButton;
     delete m_listview;
+    delete m_filter;
     delete m_model;
 }
 
 QList<QWidget*> TaskWindow::toolBarWidgets() const
 {
-    return QList<QWidget*>();
+    return QList<QWidget*>() << m_filterWarningsButton;
 }
 
 QWidget *TaskWindow::outputWidget(QWidget *)
@@ -366,6 +452,12 @@ void TaskWindow::copy()
     QApplication::clipboard()->setText(file + ':' + line + ": " + type + description);
 }
 
+void TaskWindow::setShowWarnings(bool show)
+{
+    m_filter->setFilterIncludesWarnings(show);
+    m_filter->setFilterIncludesUnknowns(show); // "Unknowns" are often associated with warnings
+}
+
 int TaskWindow::numberOfTasks() const
 {
     return m_model->rowCount(QModelIndex());
@@ -388,41 +480,41 @@ bool TaskWindow::hasFocus()
 
 bool TaskWindow::canFocus()
 {
-    return m_model->rowCount();
+    return m_filter->rowCount();
 }
 
 void TaskWindow::setFocus()
 {
-    if (m_model->rowCount()) {
+    if (m_filter->rowCount()) {
         m_listview->setFocus();
         if (m_listview->currentIndex() == QModelIndex()) {
-            m_listview->setCurrentIndex(m_model->index(0,0, QModelIndex()));
+            m_listview->setCurrentIndex(m_filter->index(0,0, QModelIndex()));
         }
     }
 }
 
 bool TaskWindow::canNext()
 {
-    return m_model->rowCount();
+    return m_filter->rowCount();
 }
 
 bool TaskWindow::canPrevious()
 {
-    return m_model->rowCount();
+    return m_filter->rowCount();
 }
 
 void TaskWindow::goToNext()
 {
-    if (!m_model->rowCount())
+    if (!m_filter->rowCount())
         return;
     QModelIndex currentIndex = m_listview->currentIndex();
     if (currentIndex.isValid()) {
         int row = currentIndex.row() + 1;
-        if (row == m_model->rowCount())
+        if (row == m_filter->rowCount())
             row = 0;
-        currentIndex = m_model->index(row, 0);
+        currentIndex = m_filter->index(row, 0);
     } else {
-        currentIndex = m_model->index(0, 0);
+        currentIndex = m_filter->index(0, 0);
     }
     m_listview->setCurrentIndex(currentIndex);
     showTaskInFile(currentIndex);
@@ -430,16 +522,16 @@ void TaskWindow::goToNext()
 
 void TaskWindow::goToPrev()
 {
-    if (!m_model->rowCount())
+    if (!m_filter->rowCount())
         return;
     QModelIndex currentIndex = m_listview->currentIndex();
     if (currentIndex.isValid()) {
         int row = currentIndex.row() -1;
         if (row < 0)
-            row = m_model->rowCount() - 1;
-        currentIndex = m_model->index(row, 0);
+            row = m_filter->rowCount() - 1;
+        currentIndex = m_filter->index(row, 0);
     } else {
-        currentIndex = m_model->index(m_model->rowCount()-1, 0);
+        currentIndex = m_filter->index(m_filter->rowCount()-1, 0);
     }
     m_listview->setCurrentIndex(currentIndex);
     showTaskInFile(currentIndex);
@@ -475,7 +567,7 @@ QSize TaskDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelInd
     QSize s;
     s.setWidth(option.rect.width());
     const QAbstractItemView * view = qobject_cast<const QAbstractItemView *>(opt.widget);
-    TaskModel *model = static_cast<TaskModel *>(view->model());
+    TaskModel *model = static_cast<TaskFilterModel *>(view->model())->taskModel();
     int width = opt.rect.width() - model->sizeOfFile() - model->sizeOfLineNumber() - 12 - 22;
     if (view->selectionModel()->currentIndex() == index) {
         QString description = index.data(TaskModel::Description).toString();
@@ -544,7 +636,7 @@ void TaskDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
 
     painter->setPen(textColor);
 
-    TaskModel *model = static_cast<TaskModel *>(view->model());
+    TaskModel *model = static_cast<TaskFilterModel *>(view->model())->taskModel();
     ProjectExplorer::BuildParserInterface::PatternType type = ProjectExplorer::BuildParserInterface::PatternType(index.data(TaskModel::Type).toInt());
     QIcon icon = model->iconFor(type);
     painter->drawPixmap(2, opt.rect.top() + 2, icon.pixmap(16, 16));
diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h
index 7d4500677663c8ac674302f9682fa0a80be25b91..809b7efe82e8d060c6ac6814acc2c598dcd54f36 100644
--- a/src/plugins/projectexplorer/taskwindow.h
+++ b/src/plugins/projectexplorer/taskwindow.h
@@ -44,6 +44,7 @@ namespace ProjectExplorer {
 namespace Internal {
 
 class TaskModel;
+class TaskFilterModel;
 class TaskView;
 class TaskWindowContext;
 
@@ -85,6 +86,7 @@ signals:
 private slots:
     void showTaskInFile(const QModelIndex &index);
     void copy();
+    void setShowWarnings(bool);
 
 private:
     int sizeHintForColumn(int column) const;
@@ -93,9 +95,11 @@ private:
     int m_currentTask;
 
     TaskModel *m_model;
+    TaskFilterModel *m_filter;
     TaskView *m_listview;
     TaskWindowContext *m_taskWindowContext;
     QAction *m_copyAction;
+    QToolButton *m_filterWarningsButton;
 };
 
 class TaskView : public QListView
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 6a72e3b90a7c29df9ec79aaf07e882b92496517a..946ecf5cb532da95de2f39468717827c5a9c39f6 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -2104,4 +2104,55 @@ unsigned ObjCMessageArgumentAST::lastToken() const
     return parameter_key_identifier + 1;
 }
 
+unsigned ObjCProtocolExpressionAST::firstToken() const
+{
+    return protocol_token;
+}
+
+unsigned ObjCProtocolExpressionAST::lastToken() const
+{
+    if (rparen_token)
+        return rparen_token + 1;
+
+    if (identifier_token)
+        return identifier_token + 1;
+
+    if (lparen_token)
+        return lparen_token + 1;
+
+    return protocol_token + 1;
+}
+
+unsigned ObjCTypeNameAST::firstToken() const
+{
+    return lparen_token;
+}
+
+unsigned ObjCTypeNameAST::lastToken() const
+{
+    if (rparen_token)
+        return rparen_token + 1;
+
+    if (type_id)
+        return type_id->lastToken();
+
+    if (type_qualifier)
+        return type_qualifier + 1;
+
+    return lparen_token + 1;
+}
+
+unsigned ObjCEncodeExpressionAST::firstToken() const
+{
+    return encode_token;
+}
+
+unsigned ObjCEncodeExpressionAST::lastToken() const
+{
+    if (type_name)
+        return type_name->lastToken();
+
+    return encode_token + 1;
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index 393126c9d47bfb4044b00d4ebea856430b3ee583..290a84324ba041a75f4fbfdbaef4403f7d33bf99 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -2653,6 +2653,67 @@ protected:
     virtual void accept0(ASTVisitor *visitor);
 };
 
+class CPLUSPLUS_EXPORT ObjCProtocolExpressionAST: public ExpressionAST
+{
+public:
+    unsigned protocol_token;
+    unsigned lparen_token;
+    unsigned identifier_token;
+    unsigned rparen_token;
+
+public:
+    virtual ObjCProtocolExpressionAST *asObjCProtocolExpression()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCProtocolExpressionAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCTypeNameAST: public AST
+{
+public:
+    unsigned lparen_token;
+    unsigned type_qualifier;
+    ExpressionAST *type_id;
+    unsigned rparen_token;
+
+public:
+    virtual ObjCTypeNameAST *asObjCTypeName()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCTypeNameAST *clone(MemoryPool *pool) const;
+
+protected:
+    virtual void accept0(ASTVisitor *visitor);
+};
+
+class CPLUSPLUS_EXPORT ObjCEncodeExpressionAST: public ExpressionAST
+{
+public:
+    unsigned encode_token;
+    ObjCTypeNameAST *type_name;
+
+public:
+    virtual ObjCEncodeExpressionAST *asObjCEncodeExpression()
+    { return this; }
+
+    virtual unsigned firstToken() const;
+    virtual unsigned lastToken() const;
+
+    virtual ObjCEncodeExpressionAST *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 5065cfdd230d7f80546a220bdffaf859d1c12a60..abc89510a5d15c820515908d19c72d58e3ee27b3 100644
--- a/src/shared/cplusplus/ASTClone.cpp
+++ b/src/shared/cplusplus/ASTClone.cpp
@@ -1311,4 +1311,32 @@ ObjCMessageArgumentAST *ObjCMessageArgumentAST::clone(MemoryPool *pool) const
     return ast;
 }
 
+ObjCProtocolExpressionAST *ObjCProtocolExpressionAST::clone(MemoryPool *pool) const
+{
+    ObjCProtocolExpressionAST *ast = new (pool) ObjCProtocolExpressionAST;
+    ast->protocol_token = protocol_token;
+    ast->lparen_token = lparen_token;
+    ast->identifier_token = identifier_token;
+    ast->rparen_token = rparen_token;
+    return ast;
+}
+
+ObjCTypeNameAST *ObjCTypeNameAST::clone(MemoryPool *pool) const
+{
+    ObjCTypeNameAST *ast = new (pool) ObjCTypeNameAST;
+    ast->lparen_token = lparen_token;
+    ast->type_qualifier = type_qualifier;
+    if (type_id) ast->type_id = type_id->clone(pool);
+    ast->rparen_token = rparen_token;
+    return ast;
+}
+
+ObjCEncodeExpressionAST *ObjCEncodeExpressionAST::clone(MemoryPool *pool) const
+{
+    ObjCEncodeExpressionAST *ast = new (pool) ObjCEncodeExpressionAST;
+    ast->encode_token = encode_token;
+    if (type_name) ast->type_name = type_name->clone(pool);
+    return ast;
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 0f2052127d8068c4a03984ba19f5f5034e0c5cc3..02f1218afee847a7f39aa30d02e29a92d09ec39b 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -1234,4 +1234,35 @@ void ObjCMessageArgumentAST::accept0(ASTVisitor *visitor)
     visitor->endVisit(this);
 }
 
+void ObjCProtocolExpressionAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCProtocolExpressionAST
+        // visit ExpressionAST
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCTypeNameAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCTypeNameAST
+        if (type_id)
+            accept(type_id, visitor);
+        // visit AST
+    }
+    visitor->endVisit(this);
+}
+
+void ObjCEncodeExpressionAST::accept0(ASTVisitor *visitor)
+{
+    if (visitor->visit(this)) {
+        // visit ObjCEncodeExpressionAST
+        if (type_name)
+            accept(type_name, visitor);
+        // visit ExpressionAST
+    }
+    visitor->endVisit(this);
+}
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/src/shared/cplusplus/ASTVisitor.h b/src/shared/cplusplus/ASTVisitor.h
index 4b0672cbc1d9ba519a65f56e8610cdcd0df44910..130c6662622698a8976a36b50abef95ddb1fc324 100644
--- a/src/shared/cplusplus/ASTVisitor.h
+++ b/src/shared/cplusplus/ASTVisitor.h
@@ -206,6 +206,9 @@ public:
     virtual bool visit(ObjCMessageExpressionAST *) { return true; }
     virtual bool visit(ObjCMessageArgumentListAST *) { return true; }
     virtual bool visit(ObjCMessageArgumentAST *) { return true; }
+    virtual bool visit(ObjCProtocolExpressionAST *) { return true; }
+    virtual bool visit(ObjCTypeNameAST *) { return true; }
+    virtual bool visit(ObjCEncodeExpressionAST *) { return true; }
 
     virtual bool visit(DeclarationListAST *) { return true; }
     virtual void endVisit(DeclarationListAST *) { }
@@ -323,6 +326,9 @@ public:
     virtual void endVisit(ObjCMessageExpressionAST *) { }
     virtual void endVisit(ObjCMessageArgumentListAST *) { }
     virtual void endVisit(ObjCMessageArgumentAST *) { }
+    virtual void endVisit(ObjCProtocolExpressionAST *) { }
+    virtual void endVisit(ObjCTypeNameAST *) { }
+    virtual void endVisit(ObjCEncodeExpressionAST *) { }
 
 private:
     Control *_control;
diff --git a/src/shared/cplusplus/ASTfwd.h b/src/shared/cplusplus/ASTfwd.h
index e12393df6a88b580e6c7387082796b135e0a1e1f..f25e293282e9b528655a997c5912099cc57d7ca8 100644
--- a/src/shared/cplusplus/ASTfwd.h
+++ b/src/shared/cplusplus/ASTfwd.h
@@ -179,6 +179,9 @@ class ObjCProtocolRefsAST;
 class ObjCMessageExpressionAST;
 class ObjCMessageArgumentListAST;
 class ObjCMessageArgumentAST;
+class ObjCProtocolExpressionAST;
+class ObjCTypeNameAST;
+class ObjCEncodeExpressionAST;
 
 CPLUSPLUS_END_NAMESPACE
 CPLUSPLUS_END_HEADER
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index ba705f9551bc2765f7ca873bb5e7d5ab68b60123..571ceaa074a8dc3b9b73cf36bdaee784eed2c4a9 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -2839,26 +2839,29 @@ bool Parser::parseObjCStringLiteral(ExpressionAST *&node)
     return true;
 }
 
-bool Parser::parseObjCEncodeExpression(ExpressionAST *&)
+bool Parser::parseObjCEncodeExpression(ExpressionAST *&node)
 {
     if (LA() != T_AT_ENCODE)
         return false;
 
-    /*unsigned encode_token = */ consumeToken();
-    parseObjCTypeName();
+    ObjCEncodeExpressionAST *ast = new (_pool) ObjCEncodeExpressionAST;
+    ast->encode_token = consumeToken();
+    parseObjCTypeName(ast->type_name);
+    node = ast;
     return true;
 }
 
-bool Parser::parseObjCProtocolExpression(ExpressionAST *&)
+bool Parser::parseObjCProtocolExpression(ExpressionAST *&node)
 {
     if (LA() != T_AT_PROTOCOL)
         return false;
 
-    /*unsigned protocol_token = */ consumeToken();
-    unsigned lparen_token = 0, identifier_token = 0, rparen_token = 0;
-    match(T_LPAREN, &lparen_token);
-    match(T_IDENTIFIER, &identifier_token);
-    match(T_RPAREN, &rparen_token);
+    ObjCProtocolExpressionAST *ast = new (_pool) ObjCProtocolExpressionAST;
+    ast->protocol_token = consumeToken();
+    match(T_LPAREN, &(ast->lparen_token));
+    match(T_IDENTIFIER, &(ast->identifier_token));
+    match(T_RPAREN, &(ast->rparen_token));
+    node = ast;
     return true;
 }
 
@@ -4348,7 +4351,8 @@ bool Parser::parseObjCMethodPrototype()
 
     /*unsigned method_type_token = */ consumeToken();
 
-    parseObjCTypeName();
+    ObjCTypeNameAST *type_name = 0;
+    parseObjCTypeName(type_name);
 
     unsigned selector_token = 0;
 
@@ -4407,17 +4411,17 @@ bool Parser::parseObjCPropertyAttribute()
 
 // objc-type-name ::= T_LPAREN objc-type-qualifiers-opt type-id T_RPAREN
 //
-bool Parser::parseObjCTypeName()
+bool Parser::parseObjCTypeName(ObjCTypeNameAST *&node)
 {
     if (LA() != T_LPAREN)
         return false;
 
-    unsigned lparen_token = 0, rparen_token = 0;
-    match(T_LPAREN, &lparen_token);
-    parseObjCTypeQualifiers();
-    ExpressionAST *type_id = 0;
-    parseTypeId(type_id);
-    match(T_RPAREN, &rparen_token);
+    ObjCTypeNameAST *ast = new (_pool) ObjCTypeNameAST;
+    match(T_LPAREN, &(ast->lparen_token));
+    parseObjCTypeQualifiers(ast->type_qualifier);
+    parseTypeId(ast->type_id);
+    match(T_RPAREN, &(ast->rparen_token));
+    node = ast;
     return true;
 }
 
@@ -4445,7 +4449,8 @@ bool Parser::parseObjCKeywordDeclaration()
     unsigned colon_token = 0;
     match(T_COLON, &colon_token);
 
-    parseObjCTypeName();
+    ObjCTypeNameAST *type_name = 0;
+    parseObjCTypeName(type_name);
 
     SpecifierAST *attributes = 0, **attr = &attributes;
     while (parseAttributeSpecifier(*attr))
@@ -4457,7 +4462,7 @@ bool Parser::parseObjCKeywordDeclaration()
     return true;
 }
 
-bool Parser::parseObjCTypeQualifiers()
+bool Parser::parseObjCTypeQualifiers(unsigned &type_qualifier)
 {
     if (LA() != T_IDENTIFIER)
         return false;
@@ -4466,7 +4471,7 @@ bool Parser::parseObjCTypeQualifiers()
     const int k = classifyObjectiveCTypeQualifiers(id->chars(), id->size());
     if (k == Token_identifier)
         return false;
-    consumeToken();
+    type_qualifier = consumeToken();
     return true;
 }
 
diff --git a/src/shared/cplusplus/Parser.h b/src/shared/cplusplus/Parser.h
index c81312d94f9dbeae842198f787b1a9fd3273ccd1..2de07f1bea8088ed44f83755502b483f5593ef4d 100644
--- a/src/shared/cplusplus/Parser.h
+++ b/src/shared/cplusplus/Parser.h
@@ -240,10 +240,10 @@ public:
     bool parseObjCImplementation(DeclarationAST *&node);
     bool parseObjCMethodPrototype();
     bool parseObjCPropertyAttribute();
-    bool parseObjCTypeName();
+    bool parseObjCTypeName(ObjCTypeNameAST *&node);
     bool parseObjCSelector(unsigned &selector_token);
     bool parseObjCKeywordDeclaration();
-    bool parseObjCTypeQualifiers();
+    bool parseObjCTypeQualifiers(unsigned &type_qualifier);
     bool parseObjCEnd(DeclarationAST *&node);
 
     bool lookAtObjCSelector() const;