Skip to content
Snippets Groups Projects
Commit 1172fe22 authored by Argyrios Kyrtzidis's avatar Argyrios Kyrtzidis
Browse files

[libclang] indexing: make sure to not visit init-list expressions twice.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260255 91177308-0d34-0410-b5e6-96231b3b80d8
parent f3e7af6d
No related branches found
No related tags found
No related merge requests found
...@@ -69,6 +69,8 @@ void foo5() { ...@@ -69,6 +69,8 @@ void foo5() {
struct S2 s = { .y = 1, .x = 4}; struct S2 s = { .y = 1, .x = 4};
} }
int ginitlist[] = {EnumVal};
// RUN: c-index-test -index-file %s | FileCheck %s // RUN: c-index-test -index-file %s | FileCheck %s
// CHECK: [indexDeclaration]: kind: namespace | name: NS // CHECK: [indexDeclaration]: kind: namespace | name: NS
// CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx // CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx
...@@ -119,3 +121,9 @@ void foo5() { ...@@ -119,3 +121,9 @@ void foo5() {
// CHECK: [indexEntityReference]: kind: field | name: y | {{.*}} | loc: 69:20 // CHECK: [indexEntityReference]: kind: field | name: y | {{.*}} | loc: 69:20
// CHECK-NEXT: [indexEntityReference]: kind: field | name: x | {{.*}} | loc: 69:28 // 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
...@@ -50,17 +50,6 @@ public: ...@@ -50,17 +50,6 @@ public:
return true; 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) { bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
IndexCtx.handleReference(E->getDecl(), E->getLocation(), IndexCtx.handleReference(E->getDecl(), E->getLocation(),
Parent, ParentDC, E); Parent, ParentDC, E);
...@@ -162,6 +151,64 @@ public: ...@@ -162,6 +151,64 @@ public:
return true; 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 } // anonymous namespace
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment