Author: akirtzidis Date: Tue Feb 9 13:07:24 2016 New Revision: 260255 URL: http://llvm.org/viewvc/llvm-project?rev=260255&view=rev Log: [libclang] indexing: make sure to not visit init-list expressions twice.
Modified: cfe/trunk/test/Index/index-refs.cpp cfe/trunk/tools/libclang/IndexBody.cpp Modified: cfe/trunk/test/Index/index-refs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/index-refs.cpp?rev=260255&r1=260254&r2=260255&view=diff ============================================================================== --- cfe/trunk/test/Index/index-refs.cpp (original) +++ cfe/trunk/test/Index/index-refs.cpp Tue Feb 9 13:07:24 2016 @@ -69,6 +69,8 @@ void foo5() { struct S2 s = { .y = 1, .x = 4}; } +int ginitlist[] = {EnumVal}; + // RUN: c-index-test -index-file %s | FileCheck %s // CHECK: [indexDeclaration]: kind: namespace | name: NS // CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx @@ -119,3 +121,9 @@ void foo5() { // CHECK: [indexEntityReference]: kind: field | name: y | {{.*}} | loc: 69:20 // CHECK-NEXT: [indexEntityReference]: kind: field | name: x | {{.*}} | loc: 69:28 +// CHECK-NOT: [indexEntityReference]: kind: field | name: y | {{.*}} | loc: 69:20 +// CHECK-NOT: [indexEntityReference]: kind: field | name: x | {{.*}} | loc: 69:28 + +// CHECK: [indexDeclaration]: kind: variable | name: ginitlist | +// CHECK: [indexEntityReference]: kind: enumerator | name: EnumVal | {{.*}} | loc: 72:20 +// CHECK-NOT: [indexEntityReference]: kind: enumerator | name: EnumVal | {{.*}} | loc: 72:20 Modified: cfe/trunk/tools/libclang/IndexBody.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/IndexBody.cpp?rev=260255&r1=260254&r2=260255&view=diff ============================================================================== --- cfe/trunk/tools/libclang/IndexBody.cpp (original) +++ cfe/trunk/tools/libclang/IndexBody.cpp Tue Feb 9 13:07:24 2016 @@ -50,17 +50,6 @@ public: return true; } - bool VisitDesignatedInitExpr(DesignatedInitExpr *E) { - for (DesignatedInitExpr::reverse_designators_iterator - D = E->designators_rbegin(), DEnd = E->designators_rend(); - D != DEnd; ++D) { - if (D->isFieldDesignator()) - IndexCtx.handleReference(D->getField(), D->getFieldLoc(), - Parent, ParentDC, E); - } - return true; - } - bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { IndexCtx.handleReference(E->getDecl(), E->getLocation(), Parent, ParentDC, E); @@ -162,6 +151,64 @@ public: return true; } + // RecursiveASTVisitor visits both syntactic and semantic forms, duplicating + // the things that we visit. Make sure to only visit the semantic form. + // Also visit things that are in the syntactic form but not the semantic one, + // for example the indices in DesignatedInitExprs. + bool TraverseInitListExpr(InitListExpr *S) { + + class SyntacticFormIndexer : + public RecursiveASTVisitor<SyntacticFormIndexer> { + IndexingContext &IndexCtx; + const NamedDecl *Parent; + const DeclContext *ParentDC; + + public: + SyntacticFormIndexer(IndexingContext &indexCtx, + const NamedDecl *Parent, const DeclContext *DC) + : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { } + + bool shouldWalkTypesOfTypeLocs() const { return false; } + + bool VisitDesignatedInitExpr(DesignatedInitExpr *E) { + for (DesignatedInitExpr::reverse_designators_iterator + D = E->designators_rbegin(), DEnd = E->designators_rend(); + D != DEnd; ++D) { + if (D->isFieldDesignator()) + IndexCtx.handleReference(D->getField(), D->getFieldLoc(), + Parent, ParentDC, E); + } + return true; + } + }; + + auto visitForm = [&](InitListExpr *Form) { + for (Stmt *SubStmt : Form->children()) { + if (!TraverseStmt(SubStmt)) + return false; + } + return true; + }; + + InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm(); + InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S; + + if (SemaForm) { + // Visit things present in syntactic form but not the semantic form. + if (SyntaxForm) { + SyntacticFormIndexer(IndexCtx, Parent, ParentDC).TraverseStmt(SyntaxForm); + } + return visitForm(SemaForm); + } + + // No semantic, try the syntactic. + if (SyntaxForm) { + return visitForm(SyntaxForm); + } + + return true; + } + }; } // anonymous namespace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits