IndexBody.cpp revision 2957e6f8c4c2e58a4b9cb639949fea801970fe36
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#include "clang/Analysis/Support/SaveAndRestore.h" 14 15using namespace clang; 16using namespace cxindex; 17 18namespace { 19 20class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> { 21 IndexingContext &IndexCtx; 22 const DeclContext *ParentDC; 23 bool InPseudoObject; 24 25 typedef RecursiveASTVisitor<BodyIndexer> base; 26public: 27 BodyIndexer(IndexingContext &indexCtx, const DeclContext *DC) 28 : IndexCtx(indexCtx), ParentDC(DC), InPseudoObject(false) { } 29 30 bool shouldWalkTypesOfTypeLocs() const { return false; } 31 32 bool TraverseTypeLoc(TypeLoc TL) { 33 IndexCtx.indexTypeLoc(TL, 0, ParentDC); 34 return true; 35 } 36 37 bool VisitDeclRefExpr(DeclRefExpr *E) { 38 IndexCtx.handleReference(E->getDecl(), E->getLocation(), 0, ParentDC, E); 39 return true; 40 } 41 42 bool VisitMemberExpr(MemberExpr *E) { 43 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(), 0, ParentDC, 44 E); 45 return true; 46 } 47 48 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { 49 IndexCtx.handleReference(E->getDecl(), E->getLocation(), 0, ParentDC, E); 50 return true; 51 } 52 53 bool VisitObjCMessageExpr(ObjCMessageExpr *E) { 54 if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo()) 55 IndexCtx.indexTypeSourceInfo(Cls, 0, ParentDC); 56 57 if (ObjCMethodDecl *MD = E->getMethodDecl()) 58 IndexCtx.handleReference(MD, E->getSelectorStartLoc(), 0, ParentDC, E, 59 InPseudoObject ? CXIdxEntityRef_Implicit 60 : CXIdxEntityRef_Direct); 61 return true; 62 } 63 64 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { 65 if (E->isImplicitProperty()) { 66 if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter()) 67 IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E, 68 CXIdxEntityRef_Implicit); 69 if (ObjCMethodDecl *MD = E->getImplicitPropertySetter()) 70 IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E, 71 CXIdxEntityRef_Implicit); 72 } else { 73 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), 0, 74 ParentDC, E); 75 } 76 return true; 77 } 78 79 bool TraversePseudoObjectExpr(PseudoObjectExpr *E) { 80 SaveAndRestore<bool> InPseudo(InPseudoObject, true); 81 return base::TraversePseudoObjectExpr(E); 82 } 83 84 bool VisitCXXConstructExpr(CXXConstructExpr *E) { 85 IndexCtx.handleReference(E->getConstructor(), E->getLocation(), 0, 86 ParentDC, E); 87 return true; 88 } 89}; 90 91} // anonymous namespace 92 93void IndexingContext::indexBody(const Stmt *S, const DeclContext *DC) { 94 BodyIndexer(*this, DC).TraverseStmt(const_cast<Stmt*>(S)); 95} 96