1 //===- CIndexHigh.cpp - Higher level API functions ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "IndexingContext.h"
11 #include "RecursiveASTVisitor.h"
13 using namespace clang;
14 using namespace cxindex;
18 class BodyIndexer : public cxindex::RecursiveASTVisitor<BodyIndexer> {
19 IndexingContext &IndexCtx;
20 const NamedDecl *Parent;
21 const DeclContext *ParentDC;
23 typedef RecursiveASTVisitor<BodyIndexer> base;
25 BodyIndexer(IndexingContext &indexCtx,
26 const NamedDecl *Parent, const DeclContext *DC)
27 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
29 bool shouldWalkTypesOfTypeLocs() const { return false; }
31 bool TraverseTypeLoc(TypeLoc TL) {
32 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
36 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
37 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
41 bool VisitDeclRefExpr(DeclRefExpr *E) {
42 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
47 bool VisitMemberExpr(MemberExpr *E) {
48 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
53 bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
54 for (DesignatedInitExpr::reverse_designators_iterator
55 D = E->designators_rbegin(), DEnd = E->designators_rend();
57 if (D->isFieldDesignator())
58 IndexCtx.handleReference(D->getField(), D->getFieldLoc(),
64 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
65 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
70 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
71 if (ObjCMethodDecl *MD = E->getMethodDecl())
72 IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
74 E->isImplicit() ? CXIdxEntityRef_Implicit
75 : CXIdxEntityRef_Direct);
79 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
80 if (E->isExplicitProperty())
81 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
84 // No need to do a handleReference for the objc method, because there will
85 // be a message expr as part of PseudoObjectExpr.
89 bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
90 IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
91 ParentDC, E, CXIdxEntityRef_Direct);
95 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
96 IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
97 Parent, ParentDC, E, CXIdxEntityRef_Direct);
101 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
102 if (ObjCMethodDecl *MD = E->getBoxingMethod())
103 IndexCtx.handleReference(MD, E->getLocStart(),
104 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
108 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
109 if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
110 IndexCtx.handleReference(MD, E->getLocStart(),
111 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
115 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
116 if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
117 IndexCtx.handleReference(MD, E->getLocStart(),
118 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
122 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
123 IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
124 Parent, ParentDC, E);
128 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
129 if (E->getOperatorLoc().isInvalid())
130 return true; // implicit.
131 return base::TraverseCXXOperatorCallExpr(E);
134 bool VisitDeclStmt(DeclStmt *S) {
135 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
136 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
140 DeclGroupRef DG = S->getDeclGroup();
141 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
145 if (!IndexCtx.isFunctionLocalDecl(D))
146 IndexCtx.indexTopLevelDecl(D);
152 bool TraverseLambdaCapture(LambdaExpr::Capture C) {
153 if (C.capturesThis())
156 if (C.capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
157 IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(),
160 // FIXME: Lambda init-captures.
166 } // anonymous namespace
168 void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
169 const DeclContext *DC) {
174 DC = Parent->getLexicalDeclContext();
175 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));