//===- CIndexHigh.cpp - Higher level API functions ------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "IndexingContext.h" #include "clang/AST/RecursiveASTVisitor.h" using namespace clang; using namespace cxindex; namespace { class BodyIndexer : public RecursiveASTVisitor { IndexingContext &IndexCtx; const NamedDecl *Parent; const DeclContext *ParentDC; typedef RecursiveASTVisitor base; public: BodyIndexer(IndexingContext &indexCtx, const NamedDecl *Parent, const DeclContext *DC) : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { } bool shouldWalkTypesOfTypeLocs() const { return false; } bool TraverseTypeLoc(TypeLoc TL) { IndexCtx.indexTypeLoc(TL, Parent, ParentDC); return true; } bool VisitDeclRefExpr(DeclRefExpr *E) { IndexCtx.handleReference(E->getDecl(), E->getLocation(), Parent, ParentDC, E); return true; } bool VisitMemberExpr(MemberExpr *E) { IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(), Parent, ParentDC, E); return true; } bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) { IndexCtx.handleReference(E->getDecl(), E->getLocation(), Parent, ParentDC, E); return true; } bool VisitObjCMessageExpr(ObjCMessageExpr *E) { if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo()) IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC); if (ObjCMethodDecl *MD = E->getMethodDecl()) IndexCtx.handleReference(MD, E->getSelectorStartLoc(), Parent, ParentDC, E, E->isImplicit() ? CXIdxEntityRef_Implicit : CXIdxEntityRef_Direct); return true; } bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { if (E->isImplicitProperty()) { if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter()) IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E, CXIdxEntityRef_Implicit); if (ObjCMethodDecl *MD = E->getImplicitPropertySetter()) IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E, CXIdxEntityRef_Implicit); } else { IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), Parent, ParentDC, E); } return true; } bool VisitCXXConstructExpr(CXXConstructExpr *E) { IndexCtx.handleReference(E->getConstructor(), E->getLocation(), Parent, ParentDC, E); return true; } bool VisitDeclStmt(DeclStmt *S) { if (IndexCtx.indexFunctionLocalSymbols()) IndexCtx.indexDeclGroupRef(S->getDeclGroup()); return true; } }; } // anonymous namespace void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent, const DeclContext *DC) { if (!S) return; if (DC == 0) DC = Parent->getLexicalDeclContext(); BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast(S)); }