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