]> granicus.if.org Git - clang/commitdiff
[libclang] During member ref expression visitation, ignore base anonymous struct...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 13 Mar 2015 04:40:07 +0000 (04:40 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 13 Mar 2015 04:40:07 +0000 (04:40 +0000)
Otherwise they will shadow the real field that that we are interested in.

rdar://19783938

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

test/Index/annotate-tokens.c
test/Index/get-cursor.c
tools/libclang/CIndex.cpp

index ffe3f632f930ffe3144b240f7a9f027286680e79..2f95ca6f458c918ab23e314db4e8c367158ddeea 100644 (file)
@@ -57,6 +57,17 @@ TYPE_INST(Foo,
 
 void func2(void);
 
+typedef union {
+  struct {
+    int field : 16;
+  };
+} r_t;
+
+void test() {
+  r_t reg;
+  reg.field = 1;
+}
+
 // RUN: c-index-test -test-annotate-tokens=%s:4:1:37:1 %s | FileCheck %s
 // CHECK: Identifier: "T" [4:3 - 4:4] TypeRef=T:1:13
 // CHECK: Punctuation: "*" [4:4 - 4:5] VarDecl=t_ptr:4:6 (Definition)
@@ -205,7 +216,7 @@ void func2(void);
 // CHECK-RANGE1: Literal: "1" [54:10 - 54:11] IntegerLiteral=
 // CHECK-RANGE1: Punctuation: "," [54:11 - 54:12] InitListExpr=
 
-// RUN: c-index-test -test-annotate-tokens=%s:54:1:59:1 %s | FileCheck %s -check-prefix=CHECK-RANGE2
+// RUN: c-index-test -test-annotate-tokens=%s:54:1:70:1 %s | FileCheck %s -check-prefix=CHECK-RANGE2
 // CHECK-RANGE2: Punctuation: "." [54:5 - 54:6] UnexposedExpr=
 // CHECK-RANGE2: Identifier: "y" [54:6 - 54:7] MemberRef=y:52:1
 // CHECK-RANGE2: Punctuation: "=" [54:8 - 54:9] UnexposedExpr=
@@ -224,3 +235,7 @@ void func2(void);
 // CHECK-RANGE2: Keyword: "void" [58:12 - 58:16] FunctionDecl=func2:58:6
 // CHECK-RANGE2: Punctuation: ")" [58:16 - 58:17] FunctionDecl=func2:58:6
 // CHECK-RANGE2: Punctuation: ";" [58:17 - 58:18]
+
+// CHECK-RANGE2: Identifier: "reg" [68:3 - 68:6] DeclRefExpr=reg:67:7
+// CHECK-RANGE2: Punctuation: "." [68:6 - 68:7] MemberRefExpr=field:62:9
+// CHECK-RANGE2: Identifier: "field" [68:7 - 68:12] MemberRefExpr=field:62:9
index c0614af5dd34efe899e2d804278dd2308a67c8f8..8671810394789a7c61ce59347915337192cb65e2 100644 (file)
@@ -6,11 +6,23 @@ struct _MyS ww;
 
 int x, y;
 
+typedef union {
+  struct {
+    int field : 16;
+  };
+} r_t;
+
+void test() {
+  r_t reg;
+  reg.field = 1;
+}
+
 // RUN: c-index-test -cursor-at=%s:1:9 \
 // RUN:              -cursor-at=%s:2:9 \
 // RUN:              -cursor-at=%s:5:9 \
 // RUN:              -cursor-at=%s:7:5 \
 // RUN:              -cursor-at=%s:7:8 \
+// RUN:              -cursor-at=%s:17:8 \
 // RUN:       %s | FileCheck %s
 
 // CHECK: StructDecl=_MyS:1:8 (Definition)
@@ -18,3 +30,4 @@ int x, y;
 // CHECK: TypeRef=struct _MyS:1:8
 // CHECK: VarDecl=x:7:5
 // CHECK: VarDecl=y:7:8
+// CHECK: 17:7 MemberRefExpr=field:11:9
\ No newline at end of file
index efe20e27d82272532a537802ea8058daa525f464..1b41e0066f575f039a2c16d81392fd6ed4a3742d 100644 (file)
@@ -2238,8 +2238,21 @@ void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
   // visit it.
   // FIXME: If we ever want to show these implicit accesses, this will be
   // unfortunate. However, clang_getCursor() relies on this behavior.
-  if (!M->isImplicitAccess())
-    AddStmt(M->getBase());
+  if (M->isImplicitAccess())
+    return;
+
+  // Ignore base anonymous struct/union fields, otherwise they will shadow the
+  // real field that that we are interested in.
+  if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
+    if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
+      if (FD->isAnonymousStructOrUnion()) {
+        AddStmt(SubME->getBase());
+        return;
+      }
+    }
+  }
+
+  AddStmt(M->getBase());
 }
 void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
   AddTypeLoc(E->getEncodedTypeSourceInfo());