summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-11-07 17:29:11 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-11-07 17:29:11 +0000
commit74ca15e3f76c91138998c908e1ab2044acd11fd3 (patch)
treefde48ecdbbd3e13b307ea631b8e009ae22c6249a
parente2686b2cbccd63ecf0f1f346b7230bf4aa7d6a7f (diff)
[index] index field references in __builtin_offset
rdar://35109556 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@317593 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Index/IndexBody.cpp11
-rw-r--r--test/Index/Core/index-source.cpp33
2 files changed, 44 insertions, 0 deletions
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp
index 6bbd381025..a54d2cbb92 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -427,6 +427,17 @@ public:
return true;
}
+
+ bool VisitOffsetOfExpr(OffsetOfExpr *S) {
+ for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
+ const OffsetOfNode &Component = S->getComponent(I);
+ if (Component.getKind() == OffsetOfNode::Field)
+ IndexCtx.handleReference(Component.getField(), Component.getLocStart(),
+ Parent, ParentDC, SymbolRoleSet(), {});
+ // FIXME: Try to resolve dependent field references.
+ }
+ return true;
+ }
};
} // anonymous namespace
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index f9c88d5ea6..cb64bd7396 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -525,3 +525,36 @@ struct rd33122110::Outer::Nested<int>;
// CHECK-NEXT: RelCont | Nested | c:@N@rd33122110@S@Outer@S@Nested>#I
// CHECK: [[@LINE-3]]:20 | struct/C++ | Outer | c:@N@rd33122110@S@Outer | <no-cgname> | Ref,RelCont | rel: 1
// CHECK-NEXT: RelCont | Nested | c:@N@rd33122110@S@Outer@S@Nested>#I
+
+namespace index_offsetof {
+
+struct Struct {
+ int field;
+};
+
+struct Struct2 {
+ Struct array[4][2];
+};
+
+void foo() {
+ __builtin_offsetof(Struct, field);
+// CHECK: [[@LINE-1]]:30 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+ __builtin_offsetof(Struct2, array[1][0].field);
+// CHECK: [[@LINE-1]]:31 | field/C | array | c:@N@index_offsetof@S@Struct2@FI@array | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+// CHECK: [[@LINE-3]]:42 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+}
+
+#define OFFSET_OF_(X, Y) __builtin_offsetof(X, Y)
+
+class SubclassOffsetof : public Struct {
+ void foo() {
+ OFFSET_OF_(SubclassOffsetof, field);
+// CHECK: [[@LINE-1]]:34 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@S@SubclassOffsetof@F@foo#
+ }
+};
+
+}