diff --git a/shared/cplusplus/AST.cpp b/shared/cplusplus/AST.cpp
index d112f9ab537ebd4d7c0264ab8dfc79147a207d8d..11be99ea48a1257371a3a584e5894b9669c55ca1 100644
--- a/shared/cplusplus/AST.cpp
+++ b/shared/cplusplus/AST.cpp
@@ -3898,6 +3898,8 @@ void IdentifierListAST::accept0(ASTVisitor *visitor)
 
 unsigned ObjCClassDeclarationAST::firstToken() const
 {
+    if (attributes)
+        return attributes->firstToken();
     return class_token;
 }
 
@@ -3911,12 +3913,19 @@ unsigned ObjCClassDeclarationAST::lastToken() const
             return it->identifier_token + 1;
     }
 
+    for (SpecifierAST *it = attributes; it; it = it->next) {
+        if (! it->next)
+            return it->lastToken();
+    }
+
     return class_token + 1;
 }
 
 ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
 {
     ObjCClassDeclarationAST *ast = new (pool) ObjCClassDeclarationAST;
+    if (attributes)
+        ast->attributes = attributes->clone(pool);
     ast->class_token = class_token;
     if (identifier_list)
         ast->identifier_list = identifier_list->clone(pool);
@@ -3927,6 +3936,9 @@ ObjCClassDeclarationAST *ObjCClassDeclarationAST::clone(MemoryPool *pool) const
 void ObjCClassDeclarationAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
+        for (SpecifierAST *it = attributes; it; it = it->next) {
+            accept(it, visitor);
+        }
     }
 }
 
diff --git a/shared/cplusplus/AST.h b/shared/cplusplus/AST.h
index d03cd3ff82c6fc44aac09abbc9979ced259ff7bd..6607e76805b8072094d40bc4f43551d34ff57920 100644
--- a/shared/cplusplus/AST.h
+++ b/shared/cplusplus/AST.h
@@ -1949,6 +1949,7 @@ protected:
 class CPLUSPLUS_EXPORT ObjCClassDeclarationAST: public DeclarationAST
 {
 public:
+    SpecifierAST *attributes;
     unsigned class_token;
     IdentifierListAST *identifier_list;
     unsigned semicolon_token;
diff --git a/shared/cplusplus/Parser.cpp b/shared/cplusplus/Parser.cpp
index 8e15a220be538f5406fe351b8a7ae3977eb24904..407cbc36fd8530b797cee2f181ae1708dcc988d3 100644
--- a/shared/cplusplus/Parser.cpp
+++ b/shared/cplusplus/Parser.cpp
@@ -403,39 +403,48 @@ bool Parser::parseDeclaration(DeclarationAST *&node)
     case T_EXPORT:
         return parseTemplateDeclaration(node);
 
-    // objc++
-    case T_AT_IMPLEMENTATION:
-        return parseObjCClassImplementation(node);
-
+    // ObjcC++
     case T_AT_CLASS:
         return parseObjCClassDeclaration(node);
 
     case T_AT_INTERFACE:
-        return parseObjCInterfaceDeclaration(node);
+        return parseObjCInterface(node);
 
     case T_AT_PROTOCOL:
-        return parseObjCProtocolDeclaration(node);
-
-    case T_AT_END:
-        return parseObjCEndDeclaration(node);
+        return parseObjCProtocol(node);
 
-    case T_AT_COMPATIBILITY_ALIAS:
-        return parseObjCAliasDeclaration(node);
+    case T_AT_IMPLEMENTATION:
+        return parseObjCImplementation(node);
 
-    case T_AT_SYNTHESIZE:
-        return parseObjCPropertySynthesize(node);
+    case T_AT_END:
+        return parseObjCEnd(node);
 
-    case T_AT_DYNAMIC:
-        return parseObjCPropertyDynamic(node);
+    default: {
+        if (_objCEnabled && LA() == T___ATTRIBUTE__) {
+            const unsigned start = cursor();
+            SpecifierAST *attributes = 0, **attr = &attributes;
+            while (parseAttributeSpecifier(*attr))
+                attr = &(*attr)->next;
+            if (LA() == T_AT_INTERFACE)
+                return parseObjCInterface(node, attributes);
+            else if (LA() == T_AT_PROTOCOL)
+                return parseObjCProtocol(node, attributes);
+            else if (LA() == T_AT_PROPERTY)
+                return parseObjCPropertyDeclaration(node, attributes);
+            rewind(start);
+        }
 
-    default:
         if (LA() == T_EXTERN && LA(2) == T_TEMPLATE)
             return parseTemplateDeclaration(node);
         else if (LA() == T_EXTERN && LA(2) == T_STRING_LITERAL)
             return parseLinkageSpecification(node);
         else
             return parseSimpleDeclaration(node);
+    }   break; // default
+
     } // end switch
+
+    return false;
 }
 
 bool Parser::parseLinkageSpecification(DeclarationAST *&node)
@@ -2543,16 +2552,7 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
     case T_SLOT:
         return parseQtMethod(node);
 
-    case T_AT_ENCODE:
-    case T_AT_PROTOCOL:
-    case T_AT_SELECTOR:
-    case T_AT_STRING_LITERAL:
-        return parseObjCExpression(node);
-
     default: {
-        if (_objCEnabled && LA() == T_LBRACKET)
-            return parseObjCExpression(node);
-
         unsigned startOfName = cursor();
         NameAST *name = 0;
         if (parseName(name)) {
@@ -3303,513 +3303,451 @@ bool Parser::parseThrowExpression(ExpressionAST *&node)
     return false;
 }
 
-bool Parser::parseObjCClassImplementation(DeclarationAST *&)
+bool Parser::lookAtObjCSelector() const
 {
-    if (LA() != T_AT_IMPLEMENTATION)
-        return false;
-
-    /*unsigned implementation_token = */ consumeToken();
-    unsigned identifier_token = 0;
-    match(T_IDENTIFIER, &identifier_token);
+    switch (LA()) {
+    case T_IDENTIFIER:
+    case T_OR:
+    case T_AND:
+    case T_NOT:
+    case T_XOR:
+    case T_BITOR:
+    case T_COMPL:
+    case T_OR_EQ:
+    case T_AND_EQ:
+    case T_BITAND:
+    case T_NOT_EQ:
+    case T_XOR_EQ:
+        return true;
 
-    if (LA() == T_COLON) {
-        /*unsigned colon_token = */ consumeToken();
-        unsigned superclass_name_token = 0;
-        match(T_IDENTIFIER, &superclass_name_token);
-    } else if (LA() == T_LPAREN) {
-        /*unsigned lparen_token = */ consumeToken();
-        unsigned category_name_token = 0;
-        if (LA() == T_IDENTIFIER)
-            category_name_token = consumeToken();
-        unsigned rparen_token = 0;
-        match(T_RPAREN, &rparen_token);
-    }
+    default:
+        if (tok().isKeyword())
+            return true;
+    } // switch
 
-    _inObjCImplementationContext = true;
-    parseObjCMethodDefinitionList();
-    return true;
+    return false;
 }
 
-bool Parser::parseObjCClassDeclaration(DeclarationAST *&node)
+// objc-class-declaraton ::= T_AT_CLASS (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
+//
+bool Parser::parseObjCClassDeclaration(DeclarationAST *&)
 {
     if (LA() != T_AT_CLASS)
         return false;
 
-    ObjCClassDeclarationAST *ast = new (_pool) ObjCClassDeclarationAST;
-    ast->class_token = consumeToken();
-    parseObjCIdentifierList(ast->identifier_list);
-    match(T_SEMICOLON, &ast->semicolon_token);
-    node = ast;
+    /*unsigned objc_class_token = */ consumeToken();
+    unsigned identifier_token = 0;
+    match(T_IDENTIFIER, &identifier_token);
+    while (LA() == T_COMMA) {
+        consumeToken(); // skip T_COMMA
+        match(T_IDENTIFIER, &identifier_token);
+    }
+
+    unsigned semicolon_token = 0;
+    match(T_SEMICOLON, &semicolon_token);
     return true;
 }
 
-bool Parser::parseObjCInterfaceDeclaration(DeclarationAST *&)
+// objc-interface ::= attribute-specifier-list-opt objc-class-interface
+// objc-interface ::= objc-category-interface
+//
+// objc-class-interface ::= T_AT_INTERFACE T_IDENTIFIER (T_COLON T_IDENTIFIER)?
+//                          objc-protocol-refs-opt
+//                          objc-class-instance-variables-opt
+//                          objc-interface-declaration-list
+//                          T_AT_END
+//
+// objc-category-interface ::= T_AT_INTERFACE T_IDENTIFIER
+//                             T_LPAREN T_IDENTIFIER? T_RPAREN
+//                             objc-protocol-refs-opt
+//                             objc-interface-declaration-list
+//                             T_AT_END
+//
+bool Parser::parseObjCInterface(DeclarationAST *&,
+                                SpecifierAST *attributes)
 {
+    if (! attributes && LA() == T___ATTRIBUTE__) {
+        SpecifierAST **attr = &attributes;
+        while (parseAttributeSpecifier(*attr))
+            attr = &(*attr)->next;
+    }
+
     if (LA() != T_AT_INTERFACE)
         return false;
 
-    /*unsigned interface_token = */ consumeToken();
-    unsigned interface_name_token = 0;
-    match(T_IDENTIFIER, &interface_name_token);
+    /*unsigned objc_interface_token = */ consumeToken();
+    unsigned identifier_token = 0;
+    match(T_IDENTIFIER, &identifier_token);
+
     if (LA() == T_LPAREN) {
-        // category interface
-        /*unsigned lparen_token = */ consumeToken();
-        unsigned catagory_name_token = 0;
+        // a category interface
+
+        if (attributes)
+            _translationUnit->error(attributes->firstToken(),
+                                    "invalid attributes for category interface declaration");
+
+        unsigned lparen_token = 0, rparen_token = 0;
+        match(T_LPAREN, &lparen_token);
         if (LA() == T_IDENTIFIER)
-            catagory_name_token = consumeToken();
-        unsigned rparen_token = 0;
+            consumeToken();
+
         match(T_RPAREN, &rparen_token);
+
         parseObjCProtocolRefs();
-        parseObjCClassInstanceVariables();
-        parseObjCInterfaceDeclList();
-        unsigned end_token = 0;
-        match(T_AT_END, &end_token);
-        return true;
-    } else {
-        // class interface
-        unsigned colon_token = 0;
-        unsigned super_class_token = 0;
-        if (LA() == T_COLON) {
-            colon_token = consumeToken();
-            match(T_IDENTIFIER, &super_class_token);
+        while (parseObjCInterfaceMemberDeclaration()) {
         }
-        parseObjCProtocolRefs();
-        parseObjCInterfaceDeclList();
-        unsigned end_token = 0;
-        match(T_AT_END, &end_token);
+        unsigned objc_end_token = 0;
+        match(T_AT_END, &objc_end_token);
         return true;
     }
-    return false;
-}
-
-bool Parser::parseObjCProtocolDeclaration(DeclarationAST *&)
-{
-    return false;
-}
 
-bool Parser::parseObjCEndDeclaration(DeclarationAST *&)
-{
-    if (LA() != T_AT_END)
-        return false;
-
-    unsigned end_token = consumeToken();
-
-    if (! _inObjCImplementationContext) {
-        _translationUnit->warning(end_token,
-            "@end must appear in an @implementation context");
+    // a class interface declaration
+    if (LA() == T_COLON) {
+        consumeToken();
+        unsigned identifier_token = 0;
+        match(T_IDENTIFIER, &identifier_token);
     }
 
-    _inObjCImplementationContext = false;
+    parseObjCProtocolRefs();
+    parseObjClassInstanceVariables();
+    while (parseObjCInterfaceMemberDeclaration()) {
+    }
+    unsigned objc_end_token = 0;
+    match(T_AT_END, &objc_end_token);
     return true;
 }
 
-bool Parser::parseObjCAliasDeclaration(DeclarationAST *&)
+// objc-protocol ::= T_AT_PROTOCOL (T_IDENTIFIER @ T_COMMA) T_SEMICOLON
+//
+bool Parser::parseObjCProtocol(DeclarationAST *&,
+                               SpecifierAST *attributes)
 {
-    return false;
-}
+    if (! attributes && LA() == T___ATTRIBUTE__) {
+        SpecifierAST **attr = &attributes;
+        while (parseAttributeSpecifier(*attr))
+            attr = &(*attr)->next;
+    }
 
-bool Parser::parseObjCPropertySynthesize(DeclarationAST *&)
-{
-    return false;
-}
+    if (LA() != T_AT_PROTOCOL)
+        return false;
 
-bool Parser::parseObjCPropertyDynamic(DeclarationAST *&)
-{
-    return false;
-}
+    /*unsigned objc_protocol_token = */ consumeToken();
+    unsigned identifier_token = 0;
+    match(T_IDENTIFIER, &identifier_token);
+
+    if (LA() == T_COMMA || LA() == T_SEMICOLON) {
+        // a protocol forward declaration
 
-bool Parser::parseObjCIdentifierList(IdentifierListAST *&node)
-{
-    if (LA() == T_IDENTIFIER) {
-        IdentifierListAST **it = &node;
-        IdentifierListAST *id = new (_pool) IdentifierListAST;
-        id->identifier_token = consumeToken();
-        *it = id;
         while (LA() == T_COMMA) {
             consumeToken();
-            if (LA() == T_IDENTIFIER) {
-                it = &(*it)->next;
-                IdentifierListAST *id = new (_pool) IdentifierListAST;
-                id->identifier_token = consumeToken();
-                *it = id;
-            }
+            match(T_IDENTIFIER, &identifier_token);
         }
+        unsigned semicolon_token = 0;
+        match(T_SEMICOLON, &semicolon_token);
         return true;
     }
-    return false;
-}
 
-bool Parser::parseObjCProtocolRefs()
-{
-    return false;
-}
+    // a protocol definition
+    parseObjCProtocolRefs();
 
-bool Parser::parseObjCClassInstanceVariables()
-{
-    return false;
-}
-
-bool Parser::parseObjCInterfaceDeclList()
-{
-    unsigned saved = cursor();
-    while (LA() != T_AT_END && parseObjCInterfaceMemberDeclaration()) {
-        if (saved == cursor())
-            consumeToken(); // skip a token
+    while (parseObjCInterfaceMemberDeclaration()) {
     }
+
+    unsigned objc_end_token = 0;
+    match(T_AT_END, &objc_end_token);
+
     return true;
 }
 
-bool Parser::parseObjCInterfaceMemberDeclaration()
+// objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER (T_COLON T_IDENTIFIER)?
+//                         objc-class-instance-variables-opt
+// objc-implementation ::= T_AT_IMPLEMENTAION T_IDENTIFIER T_LPAREN T_IDENTIFIER T_RPAREN
+//
+bool Parser::parseObjCImplementation(DeclarationAST *&)
 {
-    switch (LA()) {
-    case T_SEMICOLON:
-        consumeToken();
-        return true;
+    if (LA() != T_AT_IMPLEMENTATION)
+        return false;
 
-    case T_AT_REQUIRED:
-    case T_AT_OPTIONAL:
-        consumeToken();
-        return true;
+    consumeToken();
 
-    case T_PLUS:
-    case T_MINUS:
-        return parseObjCMethodPrototype();
+    unsigned identifier_token = 0;
+    match(T_IDENTIFIER, &identifier_token);
 
-    default: {
-        DeclarationAST *declaration = 0;
-        if (parseDeclaration(declaration))
-            return true;
-    } // default
+    if (LA() == T_LPAREN) {
+        // a category implementation
+        unsigned lparen_token = 0, rparen_token = 0;
+        unsigned category_name_token = 0;
+        match(T_LPAREN, &lparen_token);
+        match(T_IDENTIFIER, &category_name_token);
+        match(T_RPAREN, &rparen_token);
+        return true;
+    }
 
-    } // switch
+    // a class implementation
+    if (LA() == T_COLON) {
+        consumeToken();
+        unsigned super_class_name_token = 0;
+        match(T_IDENTIFIER, &super_class_name_token);
+    }
 
-    return false;
+    parseObjClassInstanceVariables();
+    return true;
 }
 
-bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&)
+// objc-protocol-refs ::= T_LESS (T_IDENTIFIER @ T_COMMA) T_GREATER
+//
+bool Parser::parseObjCProtocolRefs()
 {
-    return false;
+    if (LA() != T_LESS)
+        return false;
+    unsigned less_token = 0, greater_token = 0;
+    unsigned identifier_token = 0;
+    match(T_LESS, &less_token);
+    match(T_IDENTIFIER, &identifier_token);
+    while (LA() == T_COMMA) {
+        consumeToken();
+        match(T_IDENTIFIER, &identifier_token);
+    }
+    match(T_GREATER, &greater_token);
+    return true;
 }
 
-bool Parser::parseObjCMethodPrototype()
+// objc-class-instance-variables ::= T_LBRACE
+//                                   objc-instance-variable-decl-list-opt
+//                                   T_RBRACE
+//
+bool Parser::parseObjClassInstanceVariables()
 {
-    if (LA() != T_PLUS && LA() != T_MINUS)
+    if (LA() != T_LBRACE)
         return false;
 
-    // instance or class method?
-    /*unsigned method_type_token = */ consumeToken();
-
-    SpecifierAST *attributes = 0, **attr = &attributes;
-    while (parseAttributeSpecifier(*attr))
-        attr = &(*attr)->next;
+    unsigned lbrace_token =  0, rbrace_token = 0;
 
-    return false;
-}
-
-bool Parser::parseObjCExpression(ExpressionAST *&node)
-{
-    switch (LA()) {
-    case T_LBRACKET:
-        return parseObjCMessageExpression(node);
-
-    case T_AT_STRING_LITERAL:
-        return parseObjCStringLiteral(node);
+    match(T_LBRACE, &lbrace_token);
+    while (LA()) {
+        if (LA() == T_RBRACE)
+            break;
 
-    case T_AT_ENCODE:
-        return parseObjCEncodeExpression(node);
+        const unsigned start = cursor();
 
-    case T_AT_PROTOCOL:
-        return parseObjCProtocolExpression(node);
+        DeclarationAST *declaration = 0;
+        parseObjCInstanceVariableDeclaration(declaration);
 
-    case T_AT_SELECTOR:
-        return parseObjCSelectorExpression(node);
+        if (start == cursor()) {
+            // skip stray token.
+            _translationUnit->error(cursor(), "skip stray token `%s'", tok().spell());
+            consumeToken();
+        }
     }
-    return false;
-}
-
-bool Parser::parseObjCMessageExpression(ExpressionAST *&)
-{
-    if (LA() != T_LBRACKET)
-        return false;
 
-    /*unsigned lbracket_token = */ consumeToken();
-    ExpressionAST *receiver = 0;
-    parseObjCMessageReceiver(receiver);
-    parseObjCMessageArguments();
-    unsigned rbracket_token = 0;
-    match(T_RBRACKET, &rbracket_token);
+    match(T_RBRACE, &rbrace_token);
     return true;
 }
 
-bool Parser::parseObjCStringLiteral(ExpressionAST *&)
+// objc-interface-declaration ::= T_AT_REQUIRED
+// objc-interface-declaration ::= T_AT_OPTIONAL
+// objc-interface-declaration ::= T_SEMICOLON
+// objc-interface-declaration ::= objc-property-declaration
+// objc-interface-declaration ::= objc-method-prototype
+bool Parser::parseObjCInterfaceMemberDeclaration()
 {
-    if (LA() != T_AT_STRING_LITERAL)
-        return false;
-
-    do {
+    switch (LA()) {
+    case T_AT_REQUIRED:
+    case T_AT_OPTIONAL:
         consumeToken();
-    } while (LA() == T_AT_STRING_LITERAL);
+        return true;
 
-    return true;
-}
+    case T_SEMICOLON:
+        consumeToken();
+        return true;
 
-bool Parser::parseObjCEncodeExpression(ExpressionAST *&)
-{
-    if (LA() != T_AT_ENCODE)
-        return false;
+    case T_AT_PROPERTY: {
+        DeclarationAST *declaration = 0;
+        return parseObjCPropertyDeclaration(declaration);
+    }
 
-    /*unsigned encode_token = */ consumeToken();
-    unsigned lparen_token = 0, rparen_token = 0;
-    match(T_LPAREN, &lparen_token);
-    SpecifierAST *type_specifier = 0;
-    parseSimpleTypeSpecifier(type_specifier);
-    match(T_RPAREN, &rparen_token);
-    return true;
-}
+    case T_PLUS:
+    case T_MINUS:
+        return parseObjCMethodPrototype();
 
-bool Parser::parseObjCProtocolExpression(ExpressionAST *&)
-{
-    if (LA() != T_AT_PROTOCOL)
+    default:
         return false;
-
-    /*unsigned protocol_token = */ consumeToken();
-    unsigned protocol_name_token = 0, lparen_token = 0, rparen_token = 0;
-    match(T_LPAREN, &lparen_token);
-    match(T_IDENTIFIER, &protocol_name_token);
-    match(T_RPAREN, &rparen_token);
-    return true;
+    }
 }
 
-bool Parser::parseObjCSelectorExpression(ExpressionAST *&)
+// objc-instance-variable-declaration ::= objc-visibility-specifier
+// objc-instance-variable-declaration ::= block-declaration
+//
+bool Parser::parseObjCInstanceVariableDeclaration(DeclarationAST *&node)
 {
-    if (LA() != T_AT_SELECTOR)
-        return false;
+    switch (LA()) {
+    case T_AT_PRIVATE:
+    case T_AT_PROTECTED:
+    case T_AT_PUBLIC:
+    case T_AT_PACKAGE:
+        consumeToken();
+        return true;
 
-    /*unsigned selector_token = */ consumeToken();
-    unsigned lparen_token = 0, rparen_token = 0;
-    match(T_LPAREN, &lparen_token);
-    while (LA(1) == T_IDENTIFIER && LA(2) == T_COLON) {
-        /*unsigned identifier_token = */ consumeToken();
-        /*unsigned colon_token = */ consumeToken();
+    default:
+        return parseBlockDeclaration(node);
     }
-    match(T_RPAREN, &rparen_token);
-    return true;
-}
-
-bool Parser::parseObjCMessageReceiver(ExpressionAST *&node)
-{
-    // ### expression or simple-type-specifier.
-    return parseExpression(node);
 }
 
-bool Parser::parseObjCMessageArguments()
+// objc-property-declaration ::=
+//    T_AT_PROPERTY T_LPAREN (property-attribute @ T_COMMA) T_RPAREN simple-declaration
+//
+bool Parser::parseObjCPropertyDeclaration(DeclarationAST *&, SpecifierAST *)
 {
-    if (LA() != T_IDENTIFIER && LA() != T_COLON)
+    if (LA() != T_AT_PROPERTY)
         return false;
 
-    unsigned selector_name_token = 0;
-
-    if (LA() == T_IDENTIFIER)
-        selector_name_token = consumeToken();
-
-    if (LA() == T_COLON) {
-        /*unsigned colon_token = */ consumeToken();
-
-        ExpressionAST *expr = 0;
-        parseAssignmentExpression(expr);
-
-        while ((LA() == T_IDENTIFIER && LA(2) == T_COLON) || LA() == T_COLON) {
-            if (LA() == T_IDENTIFIER)
-                consumeToken();
-
-            if (LA() == T_COLON)
-                consumeToken();
+    /*unsigned objc_property_token = */ consumeToken();
 
-            parseAssignmentExpression(expr);
-        }
-
-        while (LA() == T_COMMA) {
-            consumeToken();
-            parseAssignmentExpression(expr);
+    if (LA() == T_LPAREN) {
+        unsigned lparen_token = 0, rparen_token = 0;
+        match(T_LPAREN, &lparen_token);
+        while (parseObjCPropertyAttribute()) {
         }
+        match(T_RPAREN, &rparen_token);
     }
 
+    DeclarationAST *simple_declaration = 0;
+    parseSimpleDeclaration(simple_declaration, /*accept-struct-declarators = */ false);
     return true;
 }
 
-bool Parser::parseObjCMethodDefinitionList()
+// objc-method-prototype ::= (T_PLUS | T_MINUS) objc-method-decl objc-method-attrs-opt
+//
+// objc-method-decl ::= objc-type-name? objc-selector
+// objc-method-decl ::= objc-type-name? objc-keyword-decl-list objc-parmlist-opt
+//
+bool Parser::parseObjCMethodPrototype()
 {
-    bool done = false;
-    while (! done) {
-        switch (LA()) {
-        case T_EOF_SYMBOL:
-        case T_AT_END:
-            done = true;
-            break;
-
-        case T_PLUS:
-        case T_MINUS:
-            parseObjCMethodSignature();
-            if (LA() == T_SEMICOLON)
-                consumeToken();
-            break;
+    if (LA() != T_PLUS && LA() != T_MINUS)
+        return false;
 
-        case T_AT_PROPERTY:
-            parseObjCAtProperty();
-            break;
+    /*unsigned method_type_token = */ consumeToken();
 
-        case T_SEMICOLON:
-            consumeToken();
-            break;
+    parseObjCTypeName();
 
-        case T_AT_OPTIONAL:
-            consumeToken();
-            break;
+    if ((lookAtObjCSelector() && LA(2) == T_COLON) || LA() == T_COLON) {
+        while (parseObjCKeywordDeclaration()) {
+        }
 
-        case T_AT_REQUIRED:
+        while (LA() == T_COMMA) {
             consumeToken();
-            break;
 
-        case T_TEMPLATE:
-        case T_NAMESPACE: {
-            DeclarationAST *declaration = 0;
-            parseDeclaration(declaration);
-        }   break;
-
-        default: {
-            unsigned start = cursor();
-            DeclarationAST *declaration = 0;
-            if (LA(1) == T_EXTERN && LA(2) == T_STRING_LITERAL) {
-                parseLinkageSpecification(declaration);
-            } else if (parseBlockDeclaration(declaration)) {
-                // ### accept the declaration.
-            } else {
-                if (cursor() == start) {
-                    _translationUnit->error(cursor(),
-                            "stray `%s' between Objective-C++ methods",
-                            tok().spell());
-                    consumeToken();
-                }
+            if (LA() == T_DOT_DOT_DOT) {
+                consumeToken();
+                break;
             }
-        }   break; // default
 
-        } // switch
+            DeclarationAST *parameter_declaration = 0;
+            parseParameterDeclaration(parameter_declaration);
+        }
+    } else if (lookAtObjCSelector()) {
+        parseObjCSelector();
+    } else {
+        _translationUnit->error(cursor(), "expected a selector");
     }
 
+    SpecifierAST *attributes = 0, **attr = &attributes;
+    while (parseAttributeSpecifier(*attr))
+        attr = &(*attr)->next;
+
     return true;
 }
 
-bool Parser::parseObjCMethodSignature()
+// objc-property-attribute ::= getter '=' identifier
+// objc-property-attribute ::= setter '=' identifier ':'
+// objc-property-attribute ::= readonly
+// objc-property-attribute ::= readwrite
+// objc-property-attribute ::= assign
+// objc-property-attribute ::= retain
+// objc-property-attribute ::= copy
+// objc-property-attribute ::= nonatomic
+bool Parser::parseObjCPropertyAttribute()
 {
-    if (LA() != T_PLUS && LA() != T_MINUS)
+    if (LA() != T_IDENTIFIER)
         return false;
 
-    /*unsigned method_type_token = */ consumeToken();
-    parseObjCTypeName();
-
-    bool first = true;
-
-    while (lookAtObjCSelector() || LA() == T_COLON) {
-        if (LA() != T_COLON)
-            /*selector_name_token = */ consumeToken();
-
-        SpecifierAST *attributes = 0, **attr = &attributes;
-        while (parseAttributeSpecifier(*attr))
-            attr = &(*attr)->next;
-
-        if (first) {
-            first = false;
-
-            if (LA() != T_COLON)
-                break;
-        }
-
-        unsigned colon_token = 0;
-        match(T_COLON, &colon_token);
-
-        parseObjCTypeName();
-
-        unsigned identifier_token = 0;
-        match(T_IDENTIFIER, &identifier_token);
-
-        while (parseAttributeSpecifier(*attr))
-            attr = &(*attr)->next;
-    }
-
-    // parse the method tail parameters.
-    while (LA() == T_COMMA) {
+    unsigned identifier_token = 0;
+    match(T_IDENTIFIER, &identifier_token);
+    if (LA() == T_EQUAL) {
         consumeToken();
-
-        if (LA() == T_DOT_DOT_DOT) {
+        match(T_IDENTIFIER, &identifier_token);
+        if (LA() == T_COLON)
             consumeToken();
-            break;
-        }
-
-        DeclarationAST *parameter_declaration = 0;
-        parseParameterDeclaration(parameter_declaration);
     }
 
     return true;
 }
 
+// objc-type-name ::= T_LPAREN objc-type-qualifiers-opt type-id T_RPAREN
+//
 bool Parser::parseObjCTypeName()
 {
     if (LA() != T_LPAREN)
         return false;
 
-    /*unsigned lparen_token = */ consumeToken();
-
-    parseObjCProtocolQualifiers();
-
+    unsigned lparen_token = 0, rparen_token = 0;
+    match(T_LPAREN, &lparen_token);
+    parseObjCTypeQualifiers();
     ExpressionAST *type_id = 0;
-    if (LA() != T_RPAREN)
-        parseTypeId(type_id);
+    parseTypeId(type_id);
+    match(T_RPAREN, &rparen_token);
+    return true;
+}
 
-    SpecifierAST *attributes = 0, **attr = &attributes;
-    while (parseAttributeSpecifier(*attr))
-        attr = &(*attr)->next;
+// objc-selector ::= T_IDENTIFIER | keyword
+//
+bool Parser::parseObjCSelector()
+{
+    if (! lookAtObjCSelector())
+        return false;
 
-    unsigned rparen_token = 0;
-    match(T_RPAREN, &rparen_token);
+    consumeToken();
     return true;
 }
 
-bool Parser::parseObjCAtProperty()
+// objc-keyword-decl ::= objc-selector? T_COLON objc-type-name? objc-keyword-attributes-opt T_IDENTIFIER
+//
+bool Parser::parseObjCKeywordDeclaration()
 {
-    if (LA() != T_AT_PROPERTY)
+    if (! (LA() == T_COLON || (lookAtObjCSelector() && LA(2) == T_COLON)))
         return false;
 
-    /*unsigned property_token = */ consumeToken();
+    parseObjCSelector();
+
+    unsigned colon_token = 0;
+    match(T_COLON, &colon_token);
+
+    parseObjCTypeName();
+
+    SpecifierAST *attributes = 0, **attr = &attributes;
+    while (parseAttributeSpecifier(*attr))
+        attr = &(*attr)->next;
+
+    unsigned identifier_token = 0;
+    match(T_IDENTIFIER, &identifier_token);
+
     return true;
 }
 
-bool Parser::parseObjCProtocolQualifiers()
+bool Parser::parseObjCTypeQualifiers()
 {
     return false;
 }
 
-bool Parser::lookAtObjCSelector() const
+// objc-end: T_AT_END
+bool Parser::parseObjCEnd(DeclarationAST *&)
 {
-    switch (LA()) {
-    case T_IDENTIFIER:
-    case T_OR:
-    case T_AND:
-    case T_NOT:
-    case T_XOR:
-    case T_BITOR:
-    case T_COMPL:
-    case T_OR_EQ:
-    case T_AND_EQ:
-    case T_BITAND:
-    case T_NOT_EQ:
-    case T_XOR_EQ:
-        return true;
-
-    default:
-        if (tok().isKeyword())
-            return true;
-    } // switch
+    if (LA() != T_AT_END)
+        return false;
 
-    return false;
+    consumeToken();
+    return true;
 }
+
+
 CPLUSPLUS_END_NAMESPACE
diff --git a/shared/cplusplus/Parser.h b/shared/cplusplus/Parser.h
index c943664afe1b6428e511bce4e13f52ee146bb7c0..84bf03e74e670683d5d68316737e201c85fcb726 100644
--- a/shared/cplusplus/Parser.h
+++ b/shared/cplusplus/Parser.h
@@ -206,46 +206,33 @@ public:
     bool parseUsingDirective(DeclarationAST *&node);
     bool parseWhileStatement(StatementAST *&node);
 
+    // Qt MOC run
+    bool parseQtMethod(ExpressionAST *&node);
+
     // ObjC++
-    bool parseObjCClassImplementation(DeclarationAST *&node);
     bool parseObjCClassDeclaration(DeclarationAST *&node);
-    bool parseObjCInterfaceDeclaration(DeclarationAST *&node);
-    bool parseObjCProtocolDeclaration(DeclarationAST *&node);
-    bool parseObjCEndDeclaration(DeclarationAST *&node);
-    bool parseObjCAliasDeclaration(DeclarationAST *&node);
-    bool parseObjCPropertySynthesize(DeclarationAST *&node);
-    bool parseObjCPropertyDynamic(DeclarationAST *&node);
+    bool parseObjCInterface(DeclarationAST *&node,
+                            SpecifierAST *attributes = 0);
+    bool parseObjCProtocol(DeclarationAST *&node,
+                           SpecifierAST *attributes = 0);
 
-    bool parseObjCIdentifierList(IdentifierListAST *&node);
-
-    bool parseObjCPropertyDeclaration(DeclarationAST *&node);
     bool parseObjCProtocolRefs();
-    bool parseObjCClassInstanceVariables();
+    bool parseObjClassInstanceVariables();
     bool parseObjCInterfaceMemberDeclaration();
-    bool parseObjCInterfaceDeclList();
+    bool parseObjCInstanceVariableDeclaration(DeclarationAST *&node);
+    bool parseObjCPropertyDeclaration(DeclarationAST *&node,
+                                      SpecifierAST *attributes = 0);
+    bool parseObjCImplementation(DeclarationAST *&node);
     bool parseObjCMethodPrototype();
-
-    bool parseObjCExpression(ExpressionAST *&node);
-    bool parseObjCMessageExpression(ExpressionAST *&node);
-    bool parseObjCStringLiteral(ExpressionAST *&node);
-    bool parseObjCEncodeExpression(ExpressionAST *&node);
-    bool parseObjCProtocolExpression(ExpressionAST *&node);
-    bool parseObjCSelectorExpression(ExpressionAST *&node);
-
-    bool parseObjCMessageReceiver(ExpressionAST *&node);
-    bool parseObjCMessageArguments();
-
-    bool parseObjCMethodSignature();
-    bool parseObjCMethodDefinitionList();
-    bool parseObjCAtProperty();
+    bool parseObjCPropertyAttribute();
     bool parseObjCTypeName();
-    bool parseObjCProtocolQualifiers();
+    bool parseObjCSelector();
+    bool parseObjCKeywordDeclaration();
+    bool parseObjCTypeQualifiers();
+    bool parseObjCEnd(DeclarationAST *&node);
 
     bool lookAtObjCSelector() const;
 
-    // Qt MOC run
-    bool parseQtMethod(ExpressionAST *&node);
-
     bool skipUntil(int token);
     bool skipUntilDeclaration();
     bool skipUntilStatement();
diff --git a/shared/cplusplus/Token.h b/shared/cplusplus/Token.h
index d5b6f1a1c0eab08279942cd3bae67c78708ae394..fdc3298202f697f35604cebcb74ecc75ea36dbf5 100644
--- a/shared/cplusplus/Token.h
+++ b/shared/cplusplus/Token.h
@@ -201,9 +201,9 @@ enum Kind {
     T___TYPEOF__,
 
     // obj c++ @ keywords
-    T_FIRST_OBJC_KEYWORD,
+    T_FIRST_OBJC_AT_KEYWORD,
 
-    T_AT_CATCH = T_FIRST_OBJC_KEYWORD,
+    T_AT_CATCH = T_FIRST_OBJC_AT_KEYWORD,
     T_AT_CLASS,
     T_AT_COMPATIBILITY_ALIAS,
     T_AT_DEFS,
@@ -228,7 +228,9 @@ enum Kind {
     T_AT_THROW,
     T_AT_TRY,
 
-    T_FIRST_QT_KEYWORD,
+    T_LAST_OBJC_AT_KEYWORD,
+
+    T_FIRST_QT_KEYWORD = T_LAST_OBJC_AT_KEYWORD,
 
     // Qt keywords
     T_SIGNAL = T_FIRST_QT_KEYWORD,
@@ -295,6 +297,9 @@ public:
     inline bool isKeyword() const
     { return kind >= T_FIRST_KEYWORD && kind < T_FIRST_QT_KEYWORD; }
 
+    inline bool isObjCAtKeyword() const
+    { return kind >= T_FIRST_OBJC_AT_KEYWORD && kind < T_LAST_OBJC_AT_KEYWORD; }
+
     static const char *name(int kind);
 
 public:
diff --git a/src/libs/utils/filewizarddialog.cpp b/src/libs/utils/filewizarddialog.cpp
index a564c63bb4fb1eb0d166972c2c4077a1250b5940..0e8655bf7cafb1207fdef126b1f798fbf3d42360 100644
--- a/src/libs/utils/filewizarddialog.cpp
+++ b/src/libs/utils/filewizarddialog.cpp
@@ -46,7 +46,7 @@ FileWizardDialog::FileWizardDialog(QWidget *parent) :
     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
     setOption(QWizard::NoCancelButton, false);
     setOption(QWizard::NoDefaultButton, false);
-    setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/qworkbench/images/qtwatermark.png")));
+    setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/core/images/qtwatermark.png")));
     addPage(m_filePage);
     connect(m_filePage, SIGNAL(activated()), button(QWizard::FinishButton), SLOT(animateClick()));
 }
diff --git a/src/plugins/coreplugin/basefilewizard.cpp b/src/plugins/coreplugin/basefilewizard.cpp
index 51ad57bc27d6ceb7cfd74af153d7e2b9d112d4e0..468c76a0dc64fed1af46fa5f1424bb553302c305 100644
--- a/src/plugins/coreplugin/basefilewizard.cpp
+++ b/src/plugins/coreplugin/basefilewizard.cpp
@@ -503,7 +503,7 @@ QStringList BaseFileWizard::runWizard(const QString &path, QWidget *parent)
 
 QPixmap BaseFileWizard::watermark()
 {
-    return QPixmap(QLatin1String(":/qworkbench/images/qtwatermark.png"));
+    return QPixmap(QLatin1String(":/core/images/qtwatermark.png"));
 }
 
 void BaseFileWizard::setupWizard(QWizard *w)
diff --git a/src/plugins/coreplugin/core.qrc b/src/plugins/coreplugin/core.qrc
index 00cd47c92b0ef82e3548503aee4e69955a2f5bb6..c2a38452dcfe7a6ca41184fd04f87f06d8e48112 100644
--- a/src/plugins/coreplugin/core.qrc
+++ b/src/plugins/coreplugin/core.qrc
@@ -1,5 +1,5 @@
 <RCC>
-    <qresource prefix="/qworkbench" >
+    <qresource prefix="/core" >
         <file>html/images/bg_site_header_dark_grey.png</file>
         <file>html/images/body_bg_circles_bottom_right.png</file>
         <file>html/images/body_bg_gradient.png</file>
diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h
index 301cfb6d39af0c7761faea1afe8bf2f455eaaf64..dd8155db8209803999264344c91628e035752eba 100644
--- a/src/plugins/coreplugin/coreconstants.h
+++ b/src/plugins/coreplugin/coreconstants.h
@@ -194,27 +194,27 @@ const char * const G_WINDOW_LIST         = "QtCreator.Group.Window.List";
 const char * const G_HELP_HELP           = "QtCreator.Group.Help.Help";
 const char * const G_HELP_ABOUT          = "QtCreator.Group.Help.About";
 
-const char * const ICON_MINUS            = ":/qworkbench/images/minus.png";
-const char * const ICON_PLUS             = ":/qworkbench/images/plus.png";
-const char * const ICON_NEWFILE          = ":/qworkbench/images/filenew.png";
-const char * const ICON_OPENFILE         = ":/qworkbench/images/fileopen.png";
-const char * const ICON_SAVEFILE         = ":/qworkbench/images/filesave.png";
-const char * const ICON_UNDO             = ":/qworkbench/images/undo.png";
-const char * const ICON_REDO             = ":/qworkbench/images/redo.png";
-const char * const ICON_COPY             = ":/qworkbench/images/editcopy.png";
-const char * const ICON_PASTE            = ":/qworkbench/images/editpaste.png";
-const char * const ICON_CUT              = ":/qworkbench/images/editcut.png";
-const char * const ICON_NEXT             = ":/qworkbench/images/next.png";
-const char * const ICON_PREV             = ":/qworkbench/images/prev.png";
-const char * const ICON_DIR              = ":/qworkbench/images/dir.png";
-const char * const ICON_CLEAN_PANE       = ":/qworkbench/images/clean_pane_small.png";
-const char * const ICON_CLEAR            = ":/qworkbench/images/clear.png";
-const char * const ICON_FIND             = ":/qworkbench/images/find.png";
-const char * const ICON_FINDNEXT         = ":/qworkbench/images/findnext.png";
-const char * const ICON_REPLACE          = ":/qworkbench/images/replace.png";
-const char * const ICON_RESET            = ":/qworkbench/images/reset.png";
-const char * const ICON_MAGNIFIER        = ":/qworkbench/images/magnifier.png";
-const char * const ICON_TOGGLE_SIDEBAR   = ":/qworkbench/images/sidebaricon.png";
+const char * const ICON_MINUS            = ":/core/images/minus.png";
+const char * const ICON_PLUS             = ":/core/images/plus.png";
+const char * const ICON_NEWFILE          = ":/core/images/filenew.png";
+const char * const ICON_OPENFILE         = ":/core/images/fileopen.png";
+const char * const ICON_SAVEFILE         = ":/core/images/filesave.png";
+const char * const ICON_UNDO             = ":/core/images/undo.png";
+const char * const ICON_REDO             = ":/core/images/redo.png";
+const char * const ICON_COPY             = ":/core/images/editcopy.png";
+const char * const ICON_PASTE            = ":/core/images/editpaste.png";
+const char * const ICON_CUT              = ":/core/images/editcut.png";
+const char * const ICON_NEXT             = ":/core/images/next.png";
+const char * const ICON_PREV             = ":/core/images/prev.png";
+const char * const ICON_DIR              = ":/core/images/dir.png";
+const char * const ICON_CLEAN_PANE       = ":/core/images/clean_pane_small.png";
+const char * const ICON_CLEAR            = ":/core/images/clear.png";
+const char * const ICON_FIND             = ":/core/images/find.png";
+const char * const ICON_FINDNEXT         = ":/core/images/findnext.png";
+const char * const ICON_REPLACE          = ":/core/images/replace.png";
+const char * const ICON_RESET            = ":/core/images/reset.png";
+const char * const ICON_MAGNIFIER        = ":/core/images/magnifier.png";
+const char * const ICON_TOGGLE_SIDEBAR   = ":/core/images/sidebaricon.png";
 
 // wizard kind
 const char * const WIZARD_TYPE_FILE      = "QtCreator::WizardType::File";
diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h
index f14d3b1a74cd50e2b61054b7be7a6e556c40a236..a8341c97e907aebd78f5f965e70e89eb0c2744db 100644
--- a/src/plugins/coreplugin/coreplugin.h
+++ b/src/plugins/coreplugin/coreplugin.h
@@ -31,8 +31,8 @@
 **
 ***************************************************************************/
 
-#ifndef QWORKBENCHPLUGIN_H
-#define QWORKBENCHPLUGIN_H
+#ifndef COREPLUGIN_H
+#define COREPLUGIN_H
 
 #include <extensionsystem/iplugin.h>
 
@@ -68,4 +68,4 @@ private:
 } // namespace Internal
 } // namespace Core
 
-#endif // QWORKBENCHPLUGIN_H
+#endif // COREPLUGIN_H
diff --git a/src/plugins/coreplugin/dialogs/shortcutsettings.ui b/src/plugins/coreplugin/dialogs/shortcutsettings.ui
index 4faaec4b32ef3298644604549700d255517de2dd..f1cc3f795a5e17d3e6a2fa89f8c75bf46a957166 100644
--- a/src/plugins/coreplugin/dialogs/shortcutsettings.ui
+++ b/src/plugins/coreplugin/dialogs/shortcutsettings.ui
@@ -131,7 +131,7 @@
           </property>
           <property name="icon">
            <iconset resource="../core.qrc">
-            <normaloff>:/qworkbench/images/reset.png</normaloff>:/qworkbench/images/reset.png</iconset>
+            <normaloff>:/core/images/reset.png</normaloff>:/core/images/reset.png</iconset>
           </property>
          </widget>
         </item>
@@ -145,7 +145,7 @@
           </property>
           <property name="icon">
            <iconset resource="../core.qrc">
-            <normaloff>:/qworkbench/images/clear.png</normaloff>:/qworkbench/images/clear.png</iconset>
+            <normaloff>:/core/images/clear.png</normaloff>:/core/images/clear.png</iconset>
           </property>
          </widget>
         </item>
diff --git a/src/plugins/coreplugin/editormanager/editorgroup.cpp b/src/plugins/coreplugin/editormanager/editorgroup.cpp
index 82c30db30fbb07140093ca18d6511ce727b22355..91adef17805cc1e60ebdf157aa5d3aea4fb26e67 100644
--- a/src/plugins/coreplugin/editormanager/editorgroup.cpp
+++ b/src/plugins/coreplugin/editormanager/editorgroup.cpp
@@ -118,7 +118,7 @@ QVariant EditorModel::data(const QModelIndex &index, int role) const
                 : editor->displayName();
     case Qt::DecorationRole:
         return editor->file()->isReadOnly()
-                ? QIcon(QLatin1String(":/qworkbench/images/locked.png"))
+                ? QIcon(QLatin1String(":/core/images/locked.png"))
                 : QIcon();
     case Qt::ToolTipRole:
         return editor->file()->fileName().isEmpty()
diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.cpp b/src/plugins/coreplugin/editormanager/openeditorsview.cpp
index a25e92ef0ce551b1365864f888a08c56595f849a..755826c94a4c2dbcd057def2ebe681b760549c06 100644
--- a/src/plugins/coreplugin/editormanager/openeditorsview.cpp
+++ b/src/plugins/coreplugin/editormanager/openeditorsview.cpp
@@ -172,8 +172,8 @@ void OpenEditorsWidget::updateCurrentItem(QTreeWidgetItem *currentItem)
 //todo: this is almost duplicated in openeditorswindow
 void OpenEditorsWidget::updateItem(QTreeWidgetItem *item, IEditor *editor)
 {
-    static const QIcon lockedIcon(QLatin1String(":/qworkbench/images/locked.png"));
-    static const QIcon emptyIcon(QLatin1String(":/qworkbench/images/empty14.png"));
+    static const QIcon lockedIcon(QLatin1String(":/core/images/locked.png"));
+    static const QIcon emptyIcon(QLatin1String(":/core/images/empty14.png"));
     QString title = editor->displayName();
     if (editor->file()->isModified())
         title += tr("*");
diff --git a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp
index b17b79c91190d66a6f110cd56ec5f61447a243ab..c7fe93b71556d184e07f44fa8f27f94a72dcf066 100644
--- a/src/plugins/coreplugin/editormanager/openeditorswindow.cpp
+++ b/src/plugins/coreplugin/editormanager/openeditorswindow.cpp
@@ -300,8 +300,8 @@ void OpenEditorsWindow::centerOnItem(int selectedIndex)
 
 void OpenEditorsWindow::updateItem(QTreeWidgetItem *item, IEditor *editor)
 {
-    static const QIcon lockedIcon(QLatin1String(":/qworkbench/images/locked.png"));
-    static const QIcon emptyIcon(QLatin1String(":/qworkbench/images/empty14.png"));
+    static const QIcon lockedIcon(QLatin1String(":/core/images/locked.png"));
+    static const QIcon emptyIcon(QLatin1String(":/core/images/empty14.png"));
 
     QString title = editor->displayName();
     if (editor->file()->isModified())
diff --git a/src/plugins/coreplugin/editormanager/stackededitorgroup.cpp b/src/plugins/coreplugin/editormanager/stackededitorgroup.cpp
index 6b46fa3b164e2dbedc06046f8b0017da9b01ae2d..0111be02b76f5670b7c7db6e950f423d1a6e938b 100644
--- a/src/plugins/coreplugin/editormanager/stackededitorgroup.cpp
+++ b/src/plugins/coreplugin/editormanager/stackededitorgroup.cpp
@@ -103,7 +103,7 @@ StackedEditorGroup::StackedEditorGroup(QWidget *parent) :
         m_lockButton->setProperty("type", QLatin1String("dockbutton"));
 
         m_closeButton->setAutoRaise(true);
-        m_closeButton->setIcon(QIcon(":/qworkbench/images/closebutton.png"));
+        m_closeButton->setIcon(QIcon(":/core/images/closebutton.png"));
         m_closeButton->setProperty("type", QLatin1String("dockbutton"));
 
         QToolBar *rightToolBar = new QToolBar;
@@ -150,7 +150,7 @@ StackedEditorGroup::StackedEditorGroup(QWidget *parent) :
 
         QToolButton *closeButton = new QToolButton;
         closeButton->setAutoRaise(true);
-        closeButton->setIcon(QIcon(":/qworkbench/images/clear.png"));
+        closeButton->setIcon(QIcon(":/core/images/clear.png"));
         closeButton->setToolTip(tr("Close"));
         connect(closeButton, SIGNAL(clicked()), m_infoWidget, SLOT(hide()));
 
@@ -303,8 +303,8 @@ void StackedEditorGroup::checkEditorStatus()
 
 void StackedEditorGroup::updateEditorStatus(IEditor *editor)
 {
-    static const QIcon lockedIcon(QLatin1String(":/qworkbench/images/locked.png"));
-    static const QIcon unlockedIcon(QLatin1String(":/qworkbench/images/unlocked.png"));
+    static const QIcon lockedIcon(QLatin1String(":/core/images/locked.png"));
+    static const QIcon unlockedIcon(QLatin1String(":/core/images/unlocked.png"));
 
     if (editor->file()->isReadOnly()) {
         m_lockButton->setIcon(lockedIcon);
diff --git a/src/plugins/coreplugin/fileiconprovider.cpp b/src/plugins/coreplugin/fileiconprovider.cpp
index 772c826d3fe597d43930252f8dc0ca14cbeef3f4..0c4b4a39de13bf09286524d7b7db73e14fcb3705 100644
--- a/src/plugins/coreplugin/fileiconprovider.cpp
+++ b/src/plugins/coreplugin/fileiconprovider.cpp
@@ -48,7 +48,7 @@ using namespace Core;
 FileIconProvider *FileIconProvider::m_instance = 0;
 
 FileIconProvider::FileIconProvider()
-    : m_unknownFileIcon(QLatin1String(":/qworkbench/images/unknownfile.png"))
+    : m_unknownFileIcon(QLatin1String(":/core/images/unknownfile.png"))
 {
 }
 
diff --git a/src/plugins/coreplugin/generalsettings.ui b/src/plugins/coreplugin/generalsettings.ui
index f3b50c5e4b3603de5d247201430d8192916e20d5..c014fae607b8a6585a8b966abeadb117573bff85 100644
--- a/src/plugins/coreplugin/generalsettings.ui
+++ b/src/plugins/coreplugin/generalsettings.ui
@@ -77,7 +77,7 @@
           </property>
           <property name="icon">
            <iconset resource="core.qrc">
-            <normaloff>:/qworkbench/images/reset.png</normaloff>:/qworkbench/images/reset.png</iconset>
+            <normaloff>:/core/images/reset.png</normaloff>:/core/images/reset.png</iconset>
           </property>
          </widget>
         </item>
@@ -118,7 +118,7 @@
           </property>
           <property name="icon">
            <iconset resource="core.qrc">
-            <normaloff>:/qworkbench/images/reset.png</normaloff>:/qworkbench/images/reset.png</iconset>
+            <normaloff>:/core/images/reset.png</normaloff>:/core/images/reset.png</iconset>
           </property>
          </widget>
         </item>
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index f68c5da7d06772f8684ddcb53f8244774e098153..9a70673e0887507bf510964586df928c0492a215 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -149,7 +149,7 @@ MainWindow::MainWindow() :
     m_toggleSideBarButton(new QToolButton)
 {
     setWindowTitle(tr("Qt Creator"));
-    qApp->setWindowIcon(QIcon(":/qworkbench/images/qtcreator_logo_128.png"));
+    qApp->setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png"));
     setDockNestingEnabled(true);
 
     setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
diff --git a/src/plugins/coreplugin/manhattanstyle.cpp b/src/plugins/coreplugin/manhattanstyle.cpp
index 5b72c891cd6bd27a619346aa40fe3b3f2bc5372d..9237883221bba260a50188943182ed9ee098ce7f 100644
--- a/src/plugins/coreplugin/manhattanstyle.cpp
+++ b/src/plugins/coreplugin/manhattanstyle.cpp
@@ -102,11 +102,11 @@ public:
     {
         style = QStyleFactory::create(baseStyleName);
         QTC_ASSERT(style, /**/);
-        buttonImage_pressed = QImage(":/qworkbench/images/pushbutton_pressed.png");
-        buttonImage = QImage(":/qworkbench/images/pushbutton.png");
+        buttonImage_pressed = QImage(":/core/images/pushbutton_pressed.png");
+        buttonImage = QImage(":/core/images/pushbutton.png");
 
-        lineeditImage = QImage(":/qworkbench/images/inputfield.png");
-        lineeditImage_disabled = QImage(":/qworkbench/images/inputfield_disabled.png");
+        lineeditImage = QImage(":/core/images/inputfield.png");
+        lineeditImage_disabled = QImage(":/core/images/inputfield_disabled.png");
     }
 
     ~ManhattanStylePrivate()
@@ -345,7 +345,7 @@ void ManhattanStyle::polish(QPalette &pal)
 QIcon ManhattanStyle::standardIconImplementation(StandardPixmap standardIcon, const QStyleOption *option,
                                                  const QWidget *widget) const
 {
-    static const QIcon closeButton(":/qworkbench/images/closebutton.png");
+    static const QIcon closeButton(":/core/images/closebutton.png");
     QIcon icon;
     switch (standardIcon) {
     case QStyle::SP_TitleBarCloseButton:
@@ -360,7 +360,7 @@ QIcon ManhattanStyle::standardIconImplementation(StandardPixmap standardIcon, co
 QPixmap ManhattanStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt,
                                        const QWidget *widget) const
 {
-    static const QPixmap closeButton(":/qworkbench/images/closebutton.png");
+    static const QPixmap closeButton(":/core/images/closebutton.png");
     QPixmap pixmap;
     switch (standardPixmap) {
     case QStyle::SP_TitleBarCloseButton:
diff --git a/src/plugins/coreplugin/navigationwidget.cpp b/src/plugins/coreplugin/navigationwidget.cpp
index 412559a9b0aecd1c2c22d19554776d8de37fe439..491c394343820bea218a06fa4098b08a5f1136d3 100644
--- a/src/plugins/coreplugin/navigationwidget.cpp
+++ b/src/plugins/coreplugin/navigationwidget.cpp
@@ -358,13 +358,13 @@ NavigationSubWidget::NavigationSubWidget(NavigationWidget *parentWidget)
 
     QToolButton *split = new QToolButton;
     split->setProperty("type", QLatin1String("dockbutton"));
-    split->setIcon(QIcon(":/qworkbench/images/splitbutton_horizontal.png"));
+    split->setIcon(QIcon(":/core/images/splitbutton_horizontal.png"));
     split->setToolTip(tr("Split"));
     connect(split, SIGNAL(clicked(bool)), this, SIGNAL(split()));
 
     QToolButton *close = new QToolButton;
     close->setProperty("type", QLatin1String("dockbutton"));
-    close->setIcon(QIcon(":/qworkbench/images/closebutton.png"));
+    close->setIcon(QIcon(":/core/images/closebutton.png"));
     close->setToolTip(tr("Close"));
 
     connect(close, SIGNAL(clicked(bool)), this, SIGNAL(close()));
diff --git a/src/plugins/coreplugin/outputpane.cpp b/src/plugins/coreplugin/outputpane.cpp
index 6d97c5d3611fd3f64574fb8aab68cae0866e5c86..6b5c3b146d11580fa68bc299ab7690c1702ee440 100644
--- a/src/plugins/coreplugin/outputpane.cpp
+++ b/src/plugins/coreplugin/outputpane.cpp
@@ -167,7 +167,7 @@ OutputPane::OutputPane(const QList<int> &context, QWidget *parent) :
     m_clearButton->setToolTip(tr("Clear"));
     connect(m_clearButton, SIGNAL(clicked()), this, SLOT(clearPage()));
 
-    m_closeButton->setIcon(QIcon(":/qworkbench/images/closebutton.png"));
+    m_closeButton->setIcon(QIcon(":/core/images/closebutton.png"));
     m_closeButton->setProperty("type", QLatin1String("dockbutton"));
     connect(m_closeButton, SIGNAL(clicked()), this, SLOT(slotHide()));
 
@@ -488,13 +488,13 @@ OutputPaneToggleButton::OutputPaneToggleButton(int number, const QString &text,
     setFocusPolicy(Qt::NoFocus);
     setCheckable(true);
     setStyleSheet(
-            "QPushButton { border-image: url(:/qworkbench/images/panel_button.png) 2 2 2 19;"
+            "QPushButton { border-image: url(:/core/images/panel_button.png) 2 2 2 19;"
                          " border-width: 2px 2px 2px 19px; padding-left: -17; padding-right: 4 } "
-            "QPushButton:checked { border-image: url(:/qworkbench/images/panel_button_checked.png) 2 2 2 19 } "
+            "QPushButton:checked { border-image: url(:/core/images/panel_button_checked.png) 2 2 2 19 } "
 #ifndef Q_WS_MAC // Mac UI's dont usually do hover
-            "QPushButton:checked:hover { border-image: url(:/qworkbench/images/panel_button_checked_hover.png) 2 2 2 19 } "
-            "QPushButton:pressed:hover { border-image: url(:/qworkbench/images/panel_button_pressed.png) 2 2 2 19 } "
-            "QPushButton:hover { border-image: url(:/qworkbench/images/panel_button_hover.png) 2 2 2 19 } "
+            "QPushButton:checked:hover { border-image: url(:/core/images/panel_button_checked_hover.png) 2 2 2 19 } "
+            "QPushButton:pressed:hover { border-image: url(:/core/images/panel_button_pressed.png) 2 2 2 19 } "
+            "QPushButton:hover { border-image: url(:/core/images/panel_button_hover.png) 2 2 2 19 } "
 #endif
             );
 }
diff --git a/src/plugins/coreplugin/sidebar.cpp b/src/plugins/coreplugin/sidebar.cpp
index 36f744769fb1c076e11a825aef7904e636c6c474..17887450d9bc5fe1fba312ffecb9252d9d0b5475 100644
--- a/src/plugins/coreplugin/sidebar.cpp
+++ b/src/plugins/coreplugin/sidebar.cpp
@@ -231,13 +231,13 @@ SideBarWidget::SideBarWidget(SideBar *sideBar, const QString &title)
 
     m_splitButton = new QToolButton;
     m_splitButton->setProperty("type", QLatin1String("dockbutton"));
-    m_splitButton->setIcon(QIcon(":/qworkbench/images/splitbutton_horizontal.png"));
+    m_splitButton->setIcon(QIcon(":/core/images/splitbutton_horizontal.png"));
     m_splitButton->setToolTip(tr("Split"));
     connect(m_splitButton, SIGNAL(clicked(bool)), this, SIGNAL(split()));
 
     m_closeButton = new QToolButton;
     m_closeButton->setProperty("type", QLatin1String("dockbutton"));
-    m_closeButton->setIcon(QIcon(":/qworkbench/images/closebutton.png"));
+    m_closeButton->setIcon(QIcon(":/core/images/closebutton.png"));
     m_closeButton->setToolTip(tr("Close"));
 
     connect(m_closeButton, SIGNAL(clicked(bool)), this, SIGNAL(close()));
diff --git a/src/plugins/coreplugin/versiondialog.cpp b/src/plugins/coreplugin/versiondialog.cpp
index 4fdb3166cf31e33e408156eb3e13bde5ca209015..52810c00efcef1730a58ad27b1ef7de6f49f65c1 100644
--- a/src/plugins/coreplugin/versiondialog.cpp
+++ b/src/plugins/coreplugin/versiondialog.cpp
@@ -56,7 +56,7 @@ VersionDialog::VersionDialog(QWidget *parent)
 {
     // We need to set the window icon explicitly here since for some reason the
     // application icon isn't used when the size of the dialog is fixed (at least not on X11/GNOME)
-    setWindowIcon(QIcon(":/qworkbench/images/qtcreator_logo_128.png"));
+    setWindowIcon(QIcon(":/core/images/qtcreator_logo_128.png"));
 
     setWindowTitle(tr("About Qt Creator"));
     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
@@ -102,7 +102,7 @@ VersionDialog::VersionDialog(QWidget *parent)
     connect(buttonBox , SIGNAL(helpRequested()), this, SLOT(popupLicense()));
 
     QLabel *logoLabel = new QLabel;
-    logoLabel->setPixmap(QPixmap(QLatin1String(":/qworkbench/images/qtcreator_logo_128.png")));
+    logoLabel->setPixmap(QPixmap(QLatin1String(":/core/images/qtcreator_logo_128.png")));
     layout->addWidget(logoLabel , 0, 0, 1, 1);
     layout->addWidget(copyRightLabel, 0, 1, 4, 4);
     layout->addWidget(buttonBox, 4, 0, 1, 5);
diff --git a/src/plugins/coreplugin/welcomemode.cpp b/src/plugins/coreplugin/welcomemode.cpp
index be5dd624295befd7eacf7be4a60b0da3f8ce375b..a0f5f98b998b00affdc00e2caec1f5ab118e17a7 100644
--- a/src/plugins/coreplugin/welcomemode.cpp
+++ b/src/plugins/coreplugin/welcomemode.cpp
@@ -92,16 +92,16 @@ WelcomeModePrivate::WelcomeModePrivate() :
 #else
     m_label(new QLabel),
 #endif
-    m_htmlTemplate(readFile(QLatin1String(":/qworkbench/html/welcome.html"))),
-    m_sessionHtmlTemplate(readFile(QLatin1String(":/qworkbench/html/recent_sessions.html"))),
-    m_projectHtmlTemplate(readFile(QLatin1String(":/qworkbench/html/recent_projects.html"))),
-    m_baseUrl(QUrl(QLatin1String("qrc:/qworkbench/html/welcome.html")))
+    m_htmlTemplate(readFile(QLatin1String(":/core/html/welcome.html"))),
+    m_sessionHtmlTemplate(readFile(QLatin1String(":/core/html/recent_sessions.html"))),
+    m_projectHtmlTemplate(readFile(QLatin1String(":/core/html/recent_projects.html"))),
+    m_baseUrl(QUrl(QLatin1String("qrc:/core/html/welcome.html")))
 {
 }
 
 #if defined(QT_NO_WEBKIT)
 
-const char *LABEL = "<center><table><tr><td><img src=\":/qworkbench/html/images/product_logo.png\"/></td><td width=300>"
+const char *LABEL = "<center><table><tr><td><img src=\":/core/html/images/product_logo.png\"/></td><td width=300>"
                     "<h2><br/><br/>Welcome</h2><p> Qt Creator is an intuitive, modern cross platform IDE that enables "
                     "developers to create graphically appealing applications for desktop, "
                     "embedded, and mobile devices. "
@@ -172,7 +172,7 @@ QString WelcomeMode::name() const
 
 QIcon WelcomeMode::icon() const
 {
-    return QIcon(QLatin1String(":/qworkbench/images/qtcreator_logo_32.png"));
+    return QIcon(QLatin1String(":/core/images/qtcreator_logo_32.png"));
 }
 
 int WelcomeMode::priority() const
diff --git a/src/plugins/find/findtoolbar.cpp b/src/plugins/find/findtoolbar.cpp
index d11768499a93d4040d6169c0ed998c8a7d20b27f..edfb5015baaa1ac5a85e23471c71354264e66e0a 100644
--- a/src/plugins/find/findtoolbar.cpp
+++ b/src/plugins/find/findtoolbar.cpp
@@ -81,7 +81,7 @@ FindToolBar::FindToolBar(FindPlugin *plugin, CurrentDocumentFind *currentDocumen
     addWidget(spacerItem);
     QToolButton *close = new QToolButton;
     close->setProperty("type", QLatin1String("dockbutton"));
-    close->setIcon(QIcon(":/qworkbench/images/closebutton.png"));
+    close->setIcon(QIcon(":/core/images/closebutton.png"));
     connect(close, SIGNAL(clicked()), this, SLOT(hideAndResetFocus()));
     addWidget(close);
 
diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp
index 5ecb375240dcc4057b06f75f55ddbb7c327ea288..3ed3263478d36ec732d984170715cf3d84c688f7 100644
--- a/src/plugins/help/helpplugin.cpp
+++ b/src/plugins/help/helpplugin.cpp
@@ -355,7 +355,7 @@ void HelpPlugin::createRightPaneSideBar()
 
     QToolButton *closeButton = new QToolButton();
     closeButton->setProperty("type", QLatin1String("dockbutton"));
-    closeButton->setIcon(QIcon(":/qworkbench/images/closebutton.png"));
+    closeButton->setIcon(QIcon(":/core/images/closebutton.png"));
 
     // Dummy layout to align the close button to the right
     QHBoxLayout *hboxLayout = new QHBoxLayout();
diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
index 8a42ec127369992f3cfb73d8a12056a5139b5e38..b642a4e3867a399bb08771beabf2c112d0136673 100644
--- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp
@@ -36,6 +36,7 @@
 #include "buildstepspage.h"
 #include "project.h"
 
+#include <coreplugin/coreconstants.h>
 #include <extensionsystem/pluginmanager.h>
 
 #include <QtCore/QDebug>
@@ -102,9 +103,9 @@ BuildSettingsWidget::BuildSettingsWidget(Project *project)
     m_ui.splitter->setStretchFactor(1,10);
     m_ui.buildSettingsList->setContextMenuPolicy(Qt::CustomContextMenu);
 
-    m_ui.addButton->setIcon(QIcon(":/qworkbench/images/plus.png"));
+    m_ui.addButton->setIcon(QIcon(Core::Constants::ICON_PLUS));
     m_ui.addButton->setText("");
-    m_ui.removeButton->setIcon(QIcon(":/qworkbench/images/minus.png"));
+    m_ui.removeButton->setIcon(QIcon(Core::Constants::ICON_MINUS));
     m_ui.removeButton->setText("");
 
     QMenu *addButtonMenu = new QMenu(this);
diff --git a/src/plugins/projectexplorer/buildstepspage.cpp b/src/plugins/projectexplorer/buildstepspage.cpp
index 88536a09e09637757b5944e1773bcda604ca1317..735770877b0724465997ed14636f1e0848ec06b3 100644
--- a/src/plugins/projectexplorer/buildstepspage.cpp
+++ b/src/plugins/projectexplorer/buildstepspage.cpp
@@ -36,6 +36,7 @@
 #include "ui_buildstepspage.h"
 #include "project.h"
 
+#include <coreplugin/coreconstants.h>
 #include <extensionsystem/pluginmanager.h>
 #include <utils/qtcassert.h>
 
@@ -50,8 +51,8 @@ BuildStepsPage::BuildStepsPage(Project *project) :
     m_ui->setupUi(this);
 
     m_ui->buildStepAddButton->setMenu(new QMenu(this));
-    m_ui->buildStepAddButton->setIcon(QIcon(":/qworkbench/images/plus.png"));
-    m_ui->buildStepRemoveToolButton->setIcon(QIcon(":/qworkbench/images/minus.png"));
+    m_ui->buildStepAddButton->setIcon(QIcon(Core::Constants::ICON_PLUS));
+    m_ui->buildStepRemoveToolButton->setIcon(QIcon(Core::Constants::ICON_MINUS));
     m_ui->buildStepUpToolButton->setArrowType(Qt::UpArrow);
     m_ui->buildStepDownToolButton->setArrowType(Qt::DownArrow);
 
diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp
index 75a92945dd6b799cda560c281ba272e05b3d032c..4fcca61516356f509ea9053559e671686207f2ff 100644
--- a/src/plugins/projectexplorer/foldernavigationwidget.cpp
+++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp
@@ -209,7 +209,7 @@ Core::NavigationView FolderNavigationWidgetFactory::createWidget()
     n.widget = ptw;
     QToolButton *toggleSync = new QToolButton;
     toggleSync->setProperty("type", "dockbutton");
-    toggleSync->setIcon(QIcon(":/qworkbench/images/linkicon.png"));
+    toggleSync->setIcon(QIcon(":/core/images/linkicon.png"));
     toggleSync->setCheckable(true);
     toggleSync->setChecked(ptw->autoSynchronization());
     toggleSync->setToolTip(tr("Synchronize with Editor"));
diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp
index 49d8ff3070e6d6b7c3e80f67b92e4d95ff5a2507..39b7214d2142cb8a0f1b789c5ada5476ec36b184 100644
--- a/src/plugins/projectexplorer/projecttreewidget.cpp
+++ b/src/plugins/projectexplorer/projecttreewidget.cpp
@@ -159,7 +159,7 @@ ProjectTreeWidget::ProjectTreeWidget(Core::ICore *core, QWidget *parent)
 
     m_toggleSync = new QToolButton;
     m_toggleSync->setProperty("type", "dockbutton");
-    m_toggleSync->setIcon(QIcon(":/qworkbench/images/linkicon.png"));
+    m_toggleSync->setIcon(QIcon(":/core/images/linkicon.png"));
     m_toggleSync->setCheckable(true);
     m_toggleSync->setChecked(autoSynchronization());
     m_toggleSync->setToolTip(tr("Synchronize with Editor"));
diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
index afaa8b04cceb00bb5dfcd92ed4b1393a5a254c15..2f309814dd79bab29327154db1f68681e5bd7a8c 100644
--- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp
+++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp
@@ -36,6 +36,7 @@
 
 #include "ui_runsettingspropertiespage.h"
 
+#include <coreplugin/coreconstants.h>
 #include <extensionsystem/pluginmanager.h>
 #include <utils/qtcassert.h>
 
@@ -180,9 +181,9 @@ RunSettingsWidget::RunSettingsWidget(Project *project)
     m_ui = new Ui::RunSettingsPropertiesPage;
     m_ui->setupUi(this);
     m_addMenu = new QMenu(m_ui->addToolButton);
-    m_ui->addToolButton->setIcon(QIcon(":/qworkbench/images/plus.png"));
+    m_ui->addToolButton->setIcon(QIcon(Core::Constants::ICON_PLUS));
     m_ui->addToolButton->setMenu(m_addMenu);
-    m_ui->removeToolButton->setIcon(QIcon(":/qworkbench/images/minus.png"));
+    m_ui->removeToolButton->setIcon(QIcon(Core::Constants::ICON_MINUS));
     m_ui->runConfigurationCombo->setModel(m_runConfigurationsModel);
 
     connect(m_addMenu, SIGNAL(aboutToShow()),
diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp
index 969f1ac5ae16453edd8be26484adf4e4aaaf0768..5756d2dd2245053c564ee73eea2f9dca11b70da0 100644
--- a/tests/auto/cplusplus/ast/tst_ast.cpp
+++ b/tests/auto/cplusplus/ast/tst_ast.cpp
@@ -20,11 +20,15 @@ public:
     {
         StringLiteral *fileId = control.findOrInsertFileName("<stdin>");
         TranslationUnit *unit = new TranslationUnit(&control, fileId);
+        unit->setObjCEnabled(true);
         unit->setSource(source.constData(), source.length());
         unit->parse(mode);
         return unit;
     }
 
+    TranslationUnit *parseDeclaration(const QByteArray &source)
+    { return parse(source, TranslationUnit::ParseDeclaration); }
+
     TranslationUnit *parseExpression(const QByteArray &source)
     { return parse(source, TranslationUnit::ParseExpression); }
 
@@ -43,6 +47,11 @@ private slots:
     void while_condition_statement();
     void for_statement();
     void cpp_initializer_or_function_declaration();
+
+    // objc++
+    void objc_attributes_followed_by_at_keyword();
+    void objc_protocol_forward_declaration_1();
+    void objc_protocol_definition_1();
 };
 
 void tst_AST::simple_name()
@@ -293,6 +302,31 @@ void tst_AST::cpp_initializer_or_function_declaration()
     QCOMPARE(param->type_specifier->asNamedTypeSpecifier()->name->asSimpleName()->identifier_token, 4U);
 }
 
+void tst_AST::objc_attributes_followed_by_at_keyword()
+{
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
+"__attribute__((deprecated)) @interface foo <bar>\n"
+"{\n"
+" int a, b;\n"
+"}\n"
+"+ (id) init;\n"
+"- (id) init:(int)a foo:(int)b, c;\n"
+"@end\n"
+    ));
+    AST *ast = unit->ast();
+}
+
+void tst_AST::objc_protocol_forward_declaration_1()
+{
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n@protocol foo;"));
+    AST *ast = unit->ast();
+}
+
+void tst_AST::objc_protocol_definition_1()
+{
+    QSharedPointer<TranslationUnit> unit(parseDeclaration("\n@protocol foo <ciao, bar> @end"));
+    AST *ast = unit->ast();
+}
 
 QTEST_APPLESS_MAIN(tst_AST)
 #include "tst_ast.moc"
diff --git a/tests/manual/cplusplus/main.cpp b/tests/manual/cplusplus/main.cpp
index c33bcbbeff7fc8accdb3e923f63e4ed7fb6867cc..4292fe929f62d933063ff6e13ef8bd7cf257c54f 100644
--- a/tests/manual/cplusplus/main.cpp
+++ b/tests/manual/cplusplus/main.cpp
@@ -248,6 +248,7 @@ int main(int argc, char *argv[])
     Control control;
     StringLiteral *fileId = control.findOrInsertFileName("<stdin>");
     TranslationUnit unit(&control, fileId);
+    unit.setObjCEnabled(true);
     unit.setSource(source.constData(), source.size());
     unit.parse();
     if (! unit.ast())