From: Argyrios Kyrtzidis Date: Fri, 13 Mar 2015 04:40:07 +0000 (+0000) Subject: [libclang] During member ref expression visitation, ignore base anonymous struct... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bf10152a8148b6c77d812c79ebabce5408a3f19f;p=clang [libclang] During member ref expression visitation, ignore base anonymous struct/union fields. 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 --- diff --git a/test/Index/annotate-tokens.c b/test/Index/annotate-tokens.c index ffe3f632f9..2f95ca6f45 100644 --- a/test/Index/annotate-tokens.c +++ b/test/Index/annotate-tokens.c @@ -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 diff --git a/test/Index/get-cursor.c b/test/Index/get-cursor.c index c0614af5dd..8671810394 100644 --- a/test/Index/get-cursor.c +++ b/test/Index/get-cursor.c @@ -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 diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index efe20e27d8..1b41e0066f 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -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(M->getBase())) { + if (auto *FD = dyn_cast_or_null(SubME->getMemberDecl())) { + if (FD->isAnonymousStructOrUnion()) { + AddStmt(SubME->getBase()); + return; + } + } + } + + AddStmt(M->getBase()); } void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { AddTypeLoc(E->getEncodedTypeSourceInfo());