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