Add support for ObjC message expressions, in the Analyzer:

-Accept an ObjC method and find all message expressions that this method may respond to.
-Accept an ObjC message expression and find all methods that may respond to it.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@77551 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Index/objc-decls.m b/test/Index/objc-decls.m
new file mode 100644
index 0000000..1a8ab4b
--- /dev/null
+++ b/test/Index/objc-decls.m
@@ -0,0 +1,16 @@
+// RUN: clang-cc -emit-pch %S/t1.m -o %t1.m.ast &&
+// RUN: clang-cc -emit-pch %S/t2.m -o %t2.m.ast &&
+
+// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/t1.m:12:12 -print-decls > %t &&
+// RUN: cat %t | count 2 &&
+// RUN: grep 'objc.h:2:9,' %t | count 2 && 
+
+// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:5:13 -print-decls > %t &&
+// RUN: cat %t | count 3 &&
+// RUN: grep 'objc.h:5:1,' %t | count 2 &&
+// RUN: grep 't1.m:15:1,' %t | count 1 &&
+
+// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:10:13 -print-decls > %t &&
+// RUN: cat %t | count 3 &&
+// RUN: grep 'objc.h:10:1,' %t | count 2 &&
+// RUN: grep 't2.m:11:1,' %t | count 1
diff --git a/test/Index/objc-message.m b/test/Index/objc-message.m
new file mode 100644
index 0000000..45ce838
--- /dev/null
+++ b/test/Index/objc-message.m
@@ -0,0 +1,38 @@
+// RUN: clang-cc -emit-pch %S/t1.m -o %t1.m.ast &&
+// RUN: clang-cc -emit-pch %S/t2.m -o %t2.m.ast &&
+
+// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:5:13 -print-refs > %t &&
+// RUN: cat %t | count 1 &&
+// RUN: grep 't1.m:6:3,' %t &&
+
+// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:6:13 -print-refs > %t &&
+// RUN: cat %t | count 2 &&
+// RUN: grep 't1.m:7:3,' %t &&
+// RUN: grep 't2.m:7:3,' %t &&
+
+// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/objc.h:10:13 -print-refs > %t &&
+// RUN: cat %t | count 2 &&
+// RUN: grep 't1.m:6:3,' %t &&
+// RUN: grep 't2.m:6:3,' %t &&
+
+// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/t1.m:6:15 -print-decls > %t &&
+// RUN: cat %t | count 6 &&
+// RUN: grep 'objc.h:5:1,' %t | count 2 &&
+// RUN: grep 'objc.h:10:1,' %t | count 2 &&
+// RUN: grep 't1.m:15:1,' %t &&
+// RUN: grep 't2.m:11:1,' %t &&
+
+// RUN: index-test %t1.m.ast %t2.m.ast -point-at %S/t1.m:7:15 -print-decls > %t &&
+// RUN: cat %t | count 3 &&
+// RUN: grep 'objc.h:6:1,' %t | count 2 &&
+// RUN: grep 't1.m:18:1,' %t &&
+
+// RUN: index-test %t2.m.ast %t1.m.ast -point-at %S/t2.m:6:15 -print-decls > %t &&
+// RUN: cat %t | count 3 &&
+// RUN: grep 'objc.h:10:1,' %t | count 2 &&
+// RUN: grep 't2.m:11:1,' %t &&
+
+// RUN: index-test %t2.m.ast %t1.m.ast -point-at %S/t2.m:7:15 -print-decls > %t &&
+// RUN: cat %t | count 3 &&
+// RUN: grep 'objc.h:6:1,' %t | count 2 &&
+// RUN: grep 't1.m:18:1,' %t
diff --git a/test/Index/objc.h b/test/Index/objc.h
new file mode 100644
index 0000000..c671add
--- /dev/null
+++ b/test/Index/objc.h
@@ -0,0 +1,11 @@
+@interface Base {
+    int my_var;
+}
+-(int) my_var;
+-(void) my_method: (int)param;
++(void) my_method: (int)param;
+@end
+
+@interface Sub : Base
+-(void) my_method: (int)param;
+@end
diff --git a/test/Index/t1.m b/test/Index/t1.m
new file mode 100644
index 0000000..b2a7a37
--- /dev/null
+++ b/test/Index/t1.m
@@ -0,0 +1,23 @@
+#include "objc.h"
+
+static void foo() {
+  Base *base;
+  int x = [base my_var];
+  [base my_method:x];
+  [Base my_method:x];
+}
+
+@implementation Base
+-(int) my_var {
+  return my_var;
+}
+
+-(void) my_method: (int)param {
+}
+
++(void) my_method: (int)param {
+}
+@end
+
+// Suppress 'no run line' failure.
+// RUN: true
diff --git a/test/Index/t2.m b/test/Index/t2.m
new file mode 100644
index 0000000..00d2f1d
--- /dev/null
+++ b/test/Index/t2.m
@@ -0,0 +1,16 @@
+#include "objc.h"
+
+static void foo() {
+  Sub *sub;
+  int x = [sub my_var];
+  [sub my_method:x];
+  [Sub my_method:x];
+}
+
+@implementation Sub
+-(void) my_method: (int)param {
+}
+@end
+
+// Suppress 'no run line' failure.
+// RUN: true