IndexBody.cpp revision 58d2dbea680a75de266c5eff77cc15c323cfd48a
1//===- CIndexHigh.cpp - Higher level API functions ------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "IndexingContext.h" 11 12#include "clang/AST/RecursiveASTVisitor.h" 13 14using namespace clang; 15using namespace cxindex; 16 17namespace { 18 19class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> { 20 IndexingContext &IndexCtx; 21 const NamedDecl *Parent; 22 const DeclContext *ParentDC; 23 24 typedef RecursiveASTVisitor<BodyIndexer> base; 25public: 26 BodyIndexer(IndexingContext &indexCtx, 27 const NamedDecl *Parent, const DeclContext *DC) 28 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { } 29 30 bool shouldWalkTypesOfTypeLocs() const { return false; } 31 32 bool TraverseTypeLoc(TypeLoc TL) { 33 IndexCtx.indexTypeLoc(TL, Parent, ParentDC); 34 return true; 35 } 36 37 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { 38 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC); 39 return true; 40 } 41 42 bool VisitDeclRefExpr(DeclRefExpr *E) { 43 IndexCtx.handleReference(E->getDecl(), E->getLocation(), 44 Parent, ParentDC, E); 45 return true; 46 } 47 48 bool VisitMemberExpr(MemberExpr *E) { 49 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(), 50 Parent, ParentDC, E); 51 return true; 52 } 53 54 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 55 IndexCtx.handleReference(E->getDecl(), E->getLocation(), 56 Parent, ParentDC, E); 57 return true; 58 } 59 60 bool VisitObjCMessageExpr(ObjCMessageExpr *E) { 61 if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo()) 62 IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC); 63 64 if (ObjCMethodDecl *MD = E->getMethodDecl()) 65 IndexCtx.handleReference(MD, E->getSelectorStartLoc(), 66 Parent, ParentDC, E, 67 E->isImplicit() ? CXIdxEntityRef_Implicit 68 : CXIdxEntityRef_Direct); 69 return true; 70 } 71 72 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { 73 if (E->isImplicitProperty()) { 74 if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter()) 75 IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E, 76 CXIdxEntityRef_Implicit); 77 if (ObjCMethodDecl *MD = E->getImplicitPropertySetter()) 78 IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E, 79 CXIdxEntityRef_Implicit); 80 } else { 81 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), 82 Parent, ParentDC, E); 83 } 84 return true; 85 } 86 87 bool VisitCXXConstructExpr(CXXConstructExpr *E) { 88 IndexCtx.handleReference(E->getConstructor(), E->getLocation(), 89 Parent, ParentDC, E); 90 return true; 91 } 92 93 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) { 94 if (E->getOperatorLoc().isInvalid()) 95 return true; // implicit. 96 return base::TraverseCXXOperatorCallExpr(E); 97 } 98 99 bool VisitDeclStmt(DeclStmt *S) { 100 if (IndexCtx.shouldIndexFunctionLocalSymbols()) 101 IndexCtx.indexDeclGroupRef(S->getDeclGroup()); 102 return true; 103 } 104}; 105 106} // anonymous namespace 107 108void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent, 109 const DeclContext *DC) { 110 if (!S) 111 return; 112 113 if (DC == 0) 114 DC = Parent->getLexicalDeclContext(); 115 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S)); 116} 117