IndexBody.cpp revision aca19be8731fc31cff68702de0dc7f30ce908979
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 DeclContext *ParentDC;
22
23public:
24  BodyIndexer(IndexingContext &indexCtx, const DeclContext *DC)
25    : IndexCtx(indexCtx), ParentDC(DC) { }
26
27  bool shouldWalkTypesOfTypeLocs() const { return false; }
28
29  bool TraverseTypeLoc(TypeLoc TL) {
30    IndexCtx.indexTypeLoc(TL, 0, ParentDC);
31    return true;
32  }
33
34  bool VisitDeclRefExpr(DeclRefExpr *E) {
35    const NamedDecl *D = E->getDecl();
36    if (!D)
37      return true;
38    if (D->getParentFunctionOrMethod())
39      return true;
40
41    IndexCtx.handleReference(D, E->getLocation(), 0, ParentDC, E);
42    return true;
43  }
44
45  bool VisitMemberExpr(MemberExpr *E) {
46    const NamedDecl *D = E->getMemberDecl();
47    if (!D)
48      return true;
49    if (D->getParentFunctionOrMethod())
50      return true;
51
52    IndexCtx.handleReference(D, E->getMemberLoc(), 0, ParentDC, E);
53    return true;
54  }
55
56  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
57    const NamedDecl *D = E->getDecl();
58    if (!D)
59      return true;
60    if (D->getParentFunctionOrMethod())
61      return true;
62
63    IndexCtx.handleReference(D, E->getLocation(), 0, ParentDC, E);
64    return true;
65  }
66
67  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
68    if (ObjCMethodDecl *MD = E->getMethodDecl())
69      IndexCtx.handleReference(MD, E->getSelectorStartLoc(), 0, ParentDC, E);
70    return true;
71  }
72
73  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
74    if (E->isImplicitProperty()) {
75      if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter())
76        IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E,
77                                 CXIdxEntityRef_ImplicitProperty);
78      if (ObjCMethodDecl *MD = E->getImplicitPropertySetter())
79        IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E,
80                                 CXIdxEntityRef_ImplicitProperty);
81    } else {
82      IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), 0,
83                               ParentDC, E);
84    }
85    return true;
86  }
87};
88
89} // anonymous namespace
90
91void IndexingContext::indexBody(const Stmt *S, const DeclContext *DC) {
92  BodyIndexer(*this, DC).TraverseStmt(const_cast<Stmt*>(S));
93}
94