14e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
24e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
34e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
44e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
54e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
64e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// License. See LICENSE.TXT for details.
74e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//
84e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
94e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis#include "IndexingContext.h"
11a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#include "clang/AST/RecursiveASTVisitor.h"
124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace clang;
144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisusing namespace cxindex;
154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisnamespace {
174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
18a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainarclass BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx;
20e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  const NamedDecl *Parent;
214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const DeclContext *ParentDC;
224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
23a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  typedef RecursiveASTVisitor<BodyIndexer> base;
244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
25e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  BodyIndexer(IndexingContext &indexCtx,
26e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis              const NamedDecl *Parent, const DeclContext *DC)
27746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis    : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool shouldWalkTypesOfTypeLocs() const { return false; }
304e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool TraverseTypeLoc(TypeLoc TL) {
32e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3655fa1d9b7ecb042d810b2f0f68d70492dc39e46fArgyrios Kyrtzidis  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
3755fa1d9b7ecb042d810b2f0f68d70492dc39e46fArgyrios Kyrtzidis    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
3855fa1d9b7ecb042d810b2f0f68d70492dc39e46fArgyrios Kyrtzidis    return true;
3955fa1d9b7ecb042d810b2f0f68d70492dc39e46fArgyrios Kyrtzidis  }
4055fa1d9b7ecb042d810b2f0f68d70492dc39e46fArgyrios Kyrtzidis
414e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitDeclRefExpr(DeclRefExpr *E) {
42e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    IndexCtx.handleReference(E->getDecl(), E->getLocation(),
43e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                             Parent, ParentDC, E);
444e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
454e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
464e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
474e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitMemberExpr(MemberExpr *E) {
48e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
49e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                             Parent, ParentDC, E);
504e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
524e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
53e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis  bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
54e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis    for (DesignatedInitExpr::reverse_designators_iterator
55e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis           D = E->designators_rbegin(), DEnd = E->designators_rend();
56e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis           D != DEnd; ++D) {
57e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis      if (D->isFieldDesignator())
58e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis        IndexCtx.handleReference(D->getField(), D->getFieldLoc(),
59e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis                                 Parent, ParentDC, E);
60e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis    }
61e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis    return true;
62e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis  }
63e0d92a43073d9a8eec220042651ccad9b0f71cc5Argyrios Kyrtzidis
644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
65e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    IndexCtx.handleReference(E->getDecl(), E->getLocation(),
66e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                             Parent, ParentDC, E);
674e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return true;
684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
699fbbf14af5582db9f2add3f66bf3da05fe8994a6Argyrios Kyrtzidis
709fbbf14af5582db9f2add3f66bf3da05fe8994a6Argyrios Kyrtzidis  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
719fbbf14af5582db9f2add3f66bf3da05fe8994a6Argyrios Kyrtzidis    if (ObjCMethodDecl *MD = E->getMethodDecl())
72e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis      IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
73e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                               Parent, ParentDC, E,
74746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis                               E->isImplicit() ? CXIdxEntityRef_Implicit
75746f5bcbfde5b25269169c63c66492311673b67dArgyrios Kyrtzidis                                               : CXIdxEntityRef_Direct);
769fbbf14af5582db9f2add3f66bf3da05fe8994a6Argyrios Kyrtzidis    return true;
779fbbf14af5582db9f2add3f66bf3da05fe8994a6Argyrios Kyrtzidis  }
78aca19be8731fc31cff68702de0dc7f30ce908979Argyrios Kyrtzidis
79aca19be8731fc31cff68702de0dc7f30ce908979Argyrios Kyrtzidis  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
80b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek    if (E->isExplicitProperty())
81e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis      IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
82e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                               Parent, ParentDC, E);
83b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek
84b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek    // No need to do a handleReference for the objc method, because there will
85b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek    // be a message expr as part of PseudoObjectExpr.
86b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek    return true;
87b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek  }
88b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek
8976da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall  bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
9076da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall    IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
9176da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall                             ParentDC, E, CXIdxEntityRef_Direct);
9276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall    return true;
9376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall  }
9476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall
957d24e289bea2accaaed79c6ca3e5cdd0c204ddc1Argyrios Kyrtzidis  bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
967d24e289bea2accaaed79c6ca3e5cdd0c204ddc1Argyrios Kyrtzidis    IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
977d24e289bea2accaaed79c6ca3e5cdd0c204ddc1Argyrios Kyrtzidis                             Parent, ParentDC, E, CXIdxEntityRef_Direct);
987d24e289bea2accaaed79c6ca3e5cdd0c204ddc1Argyrios Kyrtzidis    return true;
997d24e289bea2accaaed79c6ca3e5cdd0c204ddc1Argyrios Kyrtzidis  }
1007d24e289bea2accaaed79c6ca3e5cdd0c204ddc1Argyrios Kyrtzidis
101eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard  bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
102eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard    if (ObjCMethodDecl *MD = E->getBoxingMethod())
103b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek      IndexCtx.handleReference(MD, E->getLocStart(),
104b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek                               Parent, ParentDC, E, CXIdxEntityRef_Implicit);
105b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek    return true;
106b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek  }
107eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard
108b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek  bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
109b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek    if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
110b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek      IndexCtx.handleReference(MD, E->getLocStart(),
111b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek                               Parent, ParentDC, E, CXIdxEntityRef_Implicit);
112b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek    return true;
113b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek  }
114b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek
115b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek  bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
116b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek    if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
117b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek      IndexCtx.handleReference(MD, E->getLocStart(),
118b3f7542a950ac0d585a7783e825cfe670e05c553Ted Kremenek                               Parent, ParentDC, E, CXIdxEntityRef_Implicit);
119aca19be8731fc31cff68702de0dc7f30ce908979Argyrios Kyrtzidis    return true;
120aca19be8731fc31cff68702de0dc7f30ce908979Argyrios Kyrtzidis  }
121b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
1222957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
123e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
124e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                             Parent, ParentDC, E);
1252957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return true;
1262957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  }
12722490747c123a78feec089539f30426084d348cfArgyrios Kyrtzidis
128a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
129a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar                                   DataRecursionQueue *Q = nullptr) {
130e377d71d81e953939a17e94b9b684f77b5fff83dArgyrios Kyrtzidis    if (E->getOperatorLoc().isInvalid())
131e377d71d81e953939a17e94b9b684f77b5fff83dArgyrios Kyrtzidis      return true; // implicit.
132a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar    return base::TraverseCXXOperatorCallExpr(E, Q);
133e377d71d81e953939a17e94b9b684f77b5fff83dArgyrios Kyrtzidis  }
134e377d71d81e953939a17e94b9b684f77b5fff83dArgyrios Kyrtzidis
13522490747c123a78feec089539f30426084d348cfArgyrios Kyrtzidis  bool VisitDeclStmt(DeclStmt *S) {
1363bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis    if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
13722490747c123a78feec089539f30426084d348cfArgyrios Kyrtzidis      IndexCtx.indexDeclGroupRef(S->getDeclGroup());
1383bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis      return true;
1393bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis    }
1403bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis
1413bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis    DeclGroupRef DG = S->getDeclGroup();
1423bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
1433bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis      const Decl *D = *I;
1443bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis      if (!D)
1453bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis        continue;
1463bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis      if (!IndexCtx.isFunctionLocalDecl(D))
1473bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis        IndexCtx.indexTopLevelDecl(D);
1483bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis    }
1493bed3d196dbb5ad2ea7442da4b6c2fbf6bb5fcc6Argyrios Kyrtzidis
15022490747c123a78feec089539f30426084d348cfArgyrios Kyrtzidis    return true;
15122490747c123a78feec089539f30426084d348cfArgyrios Kyrtzidis  }
1525677eafb01b64ca83f671f3aee9de103a04c2c76Richard Smith
1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
154176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    if (C->capturesThis() || C->capturesVLAType())
155011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor      return true;
1565677eafb01b64ca83f671f3aee9de103a04c2c76Richard Smith
1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(), Parent,
1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                               ParentDC);
1600d8e9646bc000bab521ce52ed294209a92298cefRichard Smith
1610d8e9646bc000bab521ce52ed294209a92298cefRichard Smith    // FIXME: Lambda init-captures.
162011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor    return true;
163011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor  }
164011d8b93b7cfa8492b8a9c909a850d6577e08dcaDouglas Gregor
1654e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
1664e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
1674e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} // anonymous namespace
1684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
169e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidisvoid IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
170e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis                                const DeclContext *DC) {
171e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  if (!S)
172e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    return;
173e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis
174c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  if (!DC)
175e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis    DC = Parent->getLexicalDeclContext();
176e422e45a6a89d450b8eca10f671b49874e87617aArgyrios Kyrtzidis  BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
1774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
178