summaryrefslogtreecommitdiffstats
path: root/clang/tools/libclang
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2016-02-09 19:07:24 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2016-02-09 19:07:24 +0000
commitca4ad1937c92771e3f48b815c8e4e8b521ffc191 (patch)
tree141232df53fce2232b1aa7f56e7c1053aa28ae43 /clang/tools/libclang
parent49385e8bd5312704cc9ef8a24bd713cc3463529c (diff)
downloadbcm5719-llvm-ca4ad1937c92771e3f48b815c8e4e8b521ffc191.tar.gz
bcm5719-llvm-ca4ad1937c92771e3f48b815c8e4e8b521ffc191.zip
[libclang] indexing: make sure to not visit init-list expressions twice.
llvm-svn: 260255
Diffstat (limited to 'clang/tools/libclang')
-rw-r--r--clang/tools/libclang/IndexBody.cpp69
1 files changed, 58 insertions, 11 deletions
diff --git a/clang/tools/libclang/IndexBody.cpp b/clang/tools/libclang/IndexBody.cpp
index 64df4b85bea..58dc11722bf 100644
--- a/clang/tools/libclang/IndexBody.cpp
+++ b/clang/tools/libclang/IndexBody.cpp
@@ -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
OpenPOWER on IntegriCloud