]> granicus.if.org Git - clang/commitdiff
Add libclang visitation for __builtin_offsetof's components (fields
authorDouglas Gregor <dgregor@apple.com>
Thu, 9 Sep 2010 23:10:46 +0000 (23:10 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 9 Sep 2010 23:10:46 +0000 (23:10 +0000)
and array references).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113556 91177308-0d34-0410-b5e6-96231b3b80d8

test/Index/load-exprs.c
tools/libclang/CIndex.cpp

index 248bc6ebf5804d5e914a69b40dad65f68016c9b3..1c27490d637c4de457ba6d73077529699ac5e732 100644 (file)
@@ -20,6 +20,17 @@ int test_blocks(int x) {
   return y;
 }
 
+struct Y {
+  struct X array[3];
+};
+
+enum { StartIndex = 1 };
+
+void test_members(int aval, int bval) {
+  struct Y y0 = { .array[StartIndex].b = bval, .array[StartIndex].a = aval };
+  __builtin_offsetof(struct Y, array[StartIndex].b);
+}
+
 // RUN: c-index-test -test-load-source all %s -fblocks | FileCheck %s
 
 // CHECK: load-exprs.c:1:13: TypedefDecl=T:1:13 (Definition) Extent=[1:13 - 1:14]
@@ -52,4 +63,9 @@ int test_blocks(int x) {
 // CHECK: load-exprs.c:16:10: DeclRefExpr=z:13:17 Extent=[16:10 - 16:11]
 // CHECK: load-exprs.c:17:10: DeclRefExpr= Extent=[17:10 - 17:11]
 // CHECK: load-exprs.c:20:10: DeclRefExpr=y:11:15 Extent=[20:10 - 20:11]
+// CHECK: load-exprs.c:29:6: FunctionDecl=test_members:29:6 (Definition)
+// CHECK: load-exprs.c:31:29: TypeRef=struct Y:23:8 Extent=[31:29 - 31:30]
+// CHECK: load-exprs.c:31:32: MemberRef=array:24:12 Extent=[31:32 - 31:37]
+// CHECK: load-exprs.c:31:38: DeclRefExpr=StartIndex:27:8 Extent=[31:38 - 31:48]
+// CHECK: load-exprs.c:31:50: MemberRef=b:2:19 Extent=[31:50 - 31:51]
 
index cb2f7b53dc4312c0a9e761465d2e3a95ecd334b3..35e28ad42989e608f3be049283ec1b99be397b08 100644 (file)
@@ -1555,11 +1555,34 @@ bool CursorVisitor::VisitBlockExpr(BlockExpr *B) {
 }
 
 bool CursorVisitor::VisitOffsetOfExpr(OffsetOfExpr *E) {
-  // FIXME: Visit fields as well?
+  // Visit the type into which we're computing an offset.
   if (Visit(E->getTypeSourceInfo()->getTypeLoc()))
     return true;
+
+  // Visit the components of the offsetof expression.
+  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
+    typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
+    const OffsetOfNode &Node = E->getComponent(I);
+    switch (Node.getKind()) {
+    case OffsetOfNode::Array:
+      if (Visit(MakeCXCursor(E->getIndexExpr(Node.getArrayExprIndex()), 
+                             StmtParent, TU)))
+        return true;
+      break;
+        
+    case OffsetOfNode::Field:
+      if (Visit(MakeCursorMemberRef(Node.getField(), Node.getRange().getEnd(),
+                                    TU)))
+        return true;
+      break;
+        
+    case OffsetOfNode::Identifier:
+    case OffsetOfNode::Base:
+      continue;
+    }
+  }
   
-  return VisitExpr(E);
+  return false;
 }
 
 bool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {