diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp
index 67980ce4e127fbd02232e706283e5832f5925f6c..3bfec589c8caf0d2624614492d6995fcd2684cfb 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.cpp
+++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp
@@ -106,8 +106,45 @@ int ExpressionUnderCursor::startOfExpression_helper(BackwardsScanner &tk, int in
             return startOfExpression(tk, index - 2);
         } else if (tk[index - 2].is(T_DOT_STAR) || tk[index - 2].is(T_ARROW_STAR)) {
             return startOfExpression(tk, index - 2);
-//        } else if (tk[index - 2].is(T_IDENTIFIER) && tk[index - 3].is(T_LBRACKET)) {
-//            return index - 3;
+        } else if (tk[index - 2].is(T_LBRACKET)) {
+            // array subscription:
+            //     array[i
+            return index - 1;
+        } else if (tk[index - 2].is(T_COLON)) {
+            // either of:
+            //     cond ? expr1 : id
+            // or:
+            //     [receiver messageParam:id
+            // and in both cases, the id (and only the id) is what we want, so:
+            return index - 1;
+        } else if (tk[index - 2].is(T_IDENTIFIER) && tk[index - 3].is(T_LBRACKET)) {
+            // Very common Objective-C case:
+            //     [receiver message
+            // which we handle immediately:
+            return index - 3;
+        } else {
+            // See if we are handling an Objective-C messaging expression in the form of:
+            //     [receiver messageParam1:expression messageParam2
+            // or:
+            //     [receiver messageParam1:expression messageParam2:expression messageParam3
+            // ... etc
+            int i = index - 1;
+            while (tk[i].isNot(T_EOF_SYMBOL)) {
+                if (tk[i].is(T_LBRACKET))
+                    break;
+                if (tk[i].is(T_LBRACE) || tk[i].is(T_RBRACE))
+                    break;
+                else if (tk[i].is(T_RBRACKET))
+                    i = tk.startOfMatchingBrace(i + 1) - 1;
+                else
+                    --i;
+            }
+
+            int j = i;
+            while (tk[j].is(T_LBRACKET))
+                ++j;
+            if (tk[j].is(T_IDENTIFIER) && tk[j + 1].is(T_IDENTIFIER))
+                return i;
         }
         return index - 1;
     } else if (tk[index - 1].is(T_RPAREN)) {
diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp
index 31b5f208b401a3b3a00e587f2d30b2c73434eedb..33ddf1c3e55ebacd237015dec8b63d692d291c5c 100644
--- a/tests/auto/cplusplus/semantic/tst_semantic.cpp
+++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp
@@ -78,7 +78,7 @@ public:
             : errorCount(0)
         { }
 
-        virtual void report(int level,
+        virtual void report(int /*level*/,
                             StringLiteral *fileName,
                             unsigned line, unsigned column,
                             const char *format, va_list ap)
@@ -118,6 +118,15 @@ private slots:
 
     void expression_under_cursor_1();
 
+    void bracketed_expression_under_cursor_1();
+    void bracketed_expression_under_cursor_2();
+    void bracketed_expression_under_cursor_3();
+    void bracketed_expression_under_cursor_4();
+    void bracketed_expression_under_cursor_5();
+    void bracketed_expression_under_cursor_6();
+    void bracketed_expression_under_cursor_7();
+    void bracketed_expression_under_cursor_8();
+
     void objcClass_1();
 };
 
@@ -447,6 +456,134 @@ void tst_Semantic::expression_under_cursor_1()
     QCOMPARE(expression, QString("bar"));
 }
 
+void tst_Semantic::bracketed_expression_under_cursor_1()
+{
+    const QString plainText = "int i = 0, j[1], k = j[i";
+
+    QTextDocument textDocument;
+    textDocument.setPlainText(plainText);
+
+    QTextCursor tc(&textDocument);
+    tc.movePosition(QTextCursor::End);
+
+    ExpressionUnderCursor expressionUnderCursor;
+    const QString expression = expressionUnderCursor(tc);
+
+    QCOMPARE(expression, QString("i"));
+}
+
+void tst_Semantic::bracketed_expression_under_cursor_2()
+{
+    const QString plainText = "[receiver msg";
+
+    QTextDocument textDocument;
+    textDocument.setPlainText(plainText);
+
+    QTextCursor tc(&textDocument);
+    tc.movePosition(QTextCursor::End);
+
+    ExpressionUnderCursor expressionUnderCursor;
+    const QString expression = expressionUnderCursor(tc);
+
+    QCOMPARE(expression, plainText);
+}
+
+void tst_Semantic::bracketed_expression_under_cursor_3()
+{
+    const QString plainText = "[receiver msgParam1:0 msgParam2";
+
+    QTextDocument textDocument;
+    textDocument.setPlainText(plainText);
+
+    QTextCursor tc(&textDocument);
+    tc.movePosition(QTextCursor::End);
+
+    ExpressionUnderCursor expressionUnderCursor;
+    const QString expression = expressionUnderCursor(tc);
+
+    QCOMPARE(expression, plainText);
+}
+
+void tst_Semantic::bracketed_expression_under_cursor_4()
+{
+    const QString plainText = "[receiver msgParam1:0 msgParam2:@\"zoo\" msgParam3";
+
+    QTextDocument textDocument;
+    textDocument.setPlainText(plainText);
+
+    QTextCursor tc(&textDocument);
+    tc.movePosition(QTextCursor::End);
+
+    ExpressionUnderCursor expressionUnderCursor;
+    const QString expression = expressionUnderCursor(tc);
+
+    QCOMPARE(expression, plainText);
+}
+
+void tst_Semantic::bracketed_expression_under_cursor_5()
+{
+    const QString plainText = "if ([receiver message";
+
+    QTextDocument textDocument;
+    textDocument.setPlainText(plainText);
+
+    QTextCursor tc(&textDocument);
+    tc.movePosition(QTextCursor::End);
+
+    ExpressionUnderCursor expressionUnderCursor;
+    const QString expression = expressionUnderCursor(tc);
+
+    QCOMPARE(expression, QString("[receiver message"));
+}
+
+void tst_Semantic::bracketed_expression_under_cursor_6()
+{
+    const QString plainText = "if ([receiver msgParam1:1 + i[1] msgParam2";
+
+    QTextDocument textDocument;
+    textDocument.setPlainText(plainText);
+
+    QTextCursor tc(&textDocument);
+    tc.movePosition(QTextCursor::End);
+
+    ExpressionUnderCursor expressionUnderCursor;
+    const QString expression = expressionUnderCursor(tc);
+
+    QCOMPARE(expression, QString("[receiver msgParam1:1 + i[1] msgParam2"));
+}
+
+void tst_Semantic::bracketed_expression_under_cursor_7()
+{
+    const QString plainText = "int i = 0, j[1], k = j[(i == 0) ? 0 : i";
+
+    QTextDocument textDocument;
+    textDocument.setPlainText(plainText);
+
+    QTextCursor tc(&textDocument);
+    tc.movePosition(QTextCursor::End);
+
+    ExpressionUnderCursor expressionUnderCursor;
+    const QString expression = expressionUnderCursor(tc);
+
+    QCOMPARE(expression, QString("i"));
+}
+
+void tst_Semantic::bracketed_expression_under_cursor_8()
+{
+    const QString plainText = "[[receiver msg] param1:[receiver msg] param2";
+
+    QTextDocument textDocument;
+    textDocument.setPlainText(plainText);
+
+    QTextCursor tc(&textDocument);
+    tc.movePosition(QTextCursor::End);
+
+    ExpressionUnderCursor expressionUnderCursor;
+    const QString expression = expressionUnderCursor(tc);
+
+    QCOMPARE(expression, plainText);
+}
+
 void tst_Semantic::objcClass_1()
 {
     QSharedPointer<Document> doc = document("\n"