From e30072cab95f2538755e30383349e91e20750eca Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Mon, 31 Oct 2016 22:12:12 +0000 Subject: [PATCH] [index] Fix repeated visitation of the same InitListExpr for indexing. It was visited multiple times unnecessarily. rdar://28985038 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@285647 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Index/IndexBody.cpp | 17 +++++++++++++++ test/Index/Core/designated-inits.c | 33 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 test/Index/Core/designated-inits.c diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp index 0606873167..a0e9131136 100644 --- a/lib/Index/IndexBody.cpp +++ b/lib/Index/IndexBody.cpp @@ -300,6 +300,7 @@ public: IndexingContext &IndexCtx; const NamedDecl *Parent; const DeclContext *ParentDC; + bool Visited = false; public: SyntacticFormIndexer(IndexingContext &indexCtx, @@ -308,6 +309,22 @@ public: bool shouldWalkTypesOfTypeLocs() const { return false; } + bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) { + // Don't visit nested InitListExprs, this visitor will be called again + // later on for the nested ones. + if (Visited) + return true; + Visited = true; + InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S; + if (SyntaxForm) { + for (Stmt *SubStmt : SyntaxForm->children()) { + if (!TraverseStmt(SubStmt, Q)) + return false; + } + } + return true; + } + bool VisitDesignatedInitExpr(DesignatedInitExpr *E) { for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) { if (D.isFieldDesignator()) diff --git a/test/Index/Core/designated-inits.c b/test/Index/Core/designated-inits.c new file mode 100644 index 0000000000..24bb9a9acd --- /dev/null +++ b/test/Index/Core/designated-inits.c @@ -0,0 +1,33 @@ +// RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s + +struct MyStruct { + int myfield; +}; + +enum { + MyValToSet; +}; + +// CHECK: [[@LINE+1]]:14 | struct/C | MyStruct | +const struct MyStruct _MyStruct[] + [16] + [3] + [3] + [2] + [2] = { + [0] = { + [0] = { + [0] = { + [0][0] = { + [0] = { + // CHECK: [[@LINE+2]]:14 | field/C | myfield | {{.*}} | Ref | + // CHECK: [[@LINE+1]]:24 | enumerator/C | MyValToSet | + .myfield = MyValToSet, + // CHECK-NOT: | field/C | myfield | + // CHECK-NOT: | enumerator/C | MyValToSet | + }, + }, + }, + }, + }, +}; -- 2.40.0