From: Argyrios Kyrtzidis <akyrtzi@gmail.com>
Date: Mon, 31 Oct 2016 22:12:12 +0000 (+0000)
Subject: [index] Fix repeated visitation of the same InitListExpr for indexing.
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e30072cab95f2538755e30383349e91e20750eca;p=clang

[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
---

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 |
+          },
+        },
+      },
+    },
+  },
+};