<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Oct 31, 2016 at 3:12 PM, Argyrios Kyrtzidis via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: akirtzidis<br>
Date: Mon Oct 31 17:12:12 2016<br>
New Revision: 285647<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=285647&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=285647&view=rev</a><br>
Log:<br>
[index] Fix repeated visitation of the same InitListExpr for indexing.<br>
<br>
It was visited multiple times unnecessarily.<br>
<br>
rdar://28985038<br>
<br>
Added:<br>
cfe/trunk/test/Index/Core/<wbr>designated-inits.c<br>
Modified:<br>
cfe/trunk/lib/Index/IndexBody.<wbr>cpp<br>
<br>
Modified: cfe/trunk/lib/Index/IndexBody.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexBody.cpp?rev=285647&r1=285646&r2=285647&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Index/<wbr>IndexBody.cpp?rev=285647&r1=<wbr>285646&r2=285647&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Index/IndexBody.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Index/IndexBody.<wbr>cpp Mon Oct 31 17:12:12 2016<br>
@@ -300,6 +300,7 @@ public:<br>
IndexingContext &IndexCtx;<br>
const NamedDecl *Parent;<br>
const DeclContext *ParentDC;<br>
+ bool Visited = false;<br>
<br>
public:<br>
SyntacticFormIndexer(<wbr>IndexingContext &indexCtx,<br></blockquote><div><br></div><div>Do we need SyntacticFromIndexer to be a RecursiveASTVisitor at all? It looks like you would get the desired effect by simply walking the elements of the syntactic form looking for DesignatedInitExprs (which will always be at the top level of the InitListExpr's element if they exist). Right now, it looks like you still traverse expression E twice in cases like this:</div><div><br></div><div> int arr[] = { [0] = 0, E };</div><div><br></div><div>... and you'd still get a quadratic traversal for a case like { [0] = {}, { [0] = {}, { [0] = {}, ... } } }.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
@@ -308,6 +309,22 @@ public:<br>
<br>
bool shouldWalkTypesOfTypeLocs() const { return false; }<br>
<br>
+ bool TraverseInitListExpr(<wbr>InitListExpr *S, DataRecursionQueue *Q = nullptr) {<br>
+ // Don't visit nested InitListExprs, this visitor will be called again<br>
+ // later on for the nested ones.<br>
+ if (Visited)<br>
+ return true;<br>
+ Visited = true;<br>
+ InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;<br>
+ if (SyntaxForm) {<br>
+ for (Stmt *SubStmt : SyntaxForm->children()) {<br>
+ if (!TraverseStmt(SubStmt, Q))<br>
+ return false;<br>
+ }<br>
+ }<br>
+ return true;<br>
+ }<br>
+<br>
bool VisitDesignatedInitExpr(<wbr>DesignatedInitExpr *E) {<br>
for (DesignatedInitExpr::<wbr>Designator &D : llvm::reverse(E->designators()<wbr>)) {<br>
if (D.isFieldDesignator())<br>
<br>
Added: cfe/trunk/test/Index/Core/<wbr>designated-inits.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/designated-inits.c?rev=285647&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Index/<wbr>Core/designated-inits.c?rev=<wbr>285647&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Index/Core/<wbr>designated-inits.c (added)<br>
+++ cfe/trunk/test/Index/Core/<wbr>designated-inits.c Mon Oct 31 17:12:12 2016<br>
@@ -0,0 +1,33 @@<br>
+// RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s<br>
+<br>
+struct MyStruct {<br>
+ int myfield;<br>
+};<br>
+<br>
+enum {<br>
+ MyValToSet;<br>
+};<br>
+<br>
+// CHECK: [[@LINE+1]]:14 | struct/C | MyStruct |<br>
+const struct MyStruct _MyStruct[]<br>
+ [16]<br>
+ [3]<br>
+ [3]<br>
+ [2]<br>
+ [2] = {<br>
+ [0] = {<br>
+ [0] = {<br>
+ [0] = {<br>
+ [0][0] = {<br>
+ [0] = {<br>
+ // CHECK: [[@LINE+2]]:14 | field/C | myfield | {{.*}} | Ref |<br>
+ // CHECK: [[@LINE+1]]:24 | enumerator/C | MyValToSet |<br>
+ .myfield = MyValToSet,<br>
+ // CHECK-NOT: | field/C | myfield |<br>
+ // CHECK-NOT: | enumerator/C | MyValToSet |<br>
+ },<br>
+ },<br>
+ },<br>
+ },<br>
+ },<br>
+};<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>