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