IndexBody.cpp revision 58d2dbea680a75de266c5eff77cc15c323cfd48a
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 TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
38    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
39    return true;
40  }
41
42  bool VisitDeclRefExpr(DeclRefExpr *E) {
43    IndexCtx.handleReference(E->getDecl(), E->getLocation(),
44                             Parent, ParentDC, E);
45    return true;
46  }
47
48  bool VisitMemberExpr(MemberExpr *E) {
49    IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
50                             Parent, ParentDC, E);
51    return true;
52  }
53
54  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
55    IndexCtx.handleReference(E->getDecl(), E->getLocation(),
56                             Parent, ParentDC, E);
57    return true;
58  }
59
60  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
61    if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo())
62      IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC);
63
64    if (ObjCMethodDecl *MD = E->getMethodDecl())
65      IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
66                               Parent, ParentDC, E,
67                               E->isImplicit() ? CXIdxEntityRef_Implicit
68                                               : CXIdxEntityRef_Direct);
69    return true;
70  }
71
72  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
73    if (E->isImplicitProperty()) {
74      if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter())
75        IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E,
76                                 CXIdxEntityRef_Implicit);
77      if (ObjCMethodDecl *MD = E->getImplicitPropertySetter())
78        IndexCtx.handleReference(MD, E->getLocation(), Parent, ParentDC, E,
79                                 CXIdxEntityRef_Implicit);
80    } else {
81      IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
82                               Parent, ParentDC, E);
83    }
84    return true;
85  }
86
87  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
88    IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
89                             Parent, ParentDC, E);
90    return true;
91  }
92
93  bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
94    if (E->getOperatorLoc().isInvalid())
95      return true; // implicit.
96    return base::TraverseCXXOperatorCallExpr(E);
97  }
98
99  bool VisitDeclStmt(DeclStmt *S) {
100    if (IndexCtx.shouldIndexFunctionLocalSymbols())
101      IndexCtx.indexDeclGroupRef(S->getDeclGroup());
102    return true;
103  }
104};
105
106} // anonymous namespace
107
108void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
109                                const DeclContext *DC) {
110  if (!S)
111    return;
112
113  if (DC == 0)
114    DC = Parent->getLexicalDeclContext();
115  BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
116}
117