IndexBody.cpp revision 2957e6f8c4c2e58a4b9cb639949fea801970fe36
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#include "clang/Analysis/Support/SaveAndRestore.h"
14
15using namespace clang;
16using namespace cxindex;
17
18namespace {
19
20class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
21  IndexingContext &IndexCtx;
22  const DeclContext *ParentDC;
23  bool InPseudoObject;
24
25  typedef RecursiveASTVisitor<BodyIndexer> base;
26public:
27  BodyIndexer(IndexingContext &indexCtx, const DeclContext *DC)
28    : IndexCtx(indexCtx), ParentDC(DC), InPseudoObject(false) { }
29
30  bool shouldWalkTypesOfTypeLocs() const { return false; }
31
32  bool TraverseTypeLoc(TypeLoc TL) {
33    IndexCtx.indexTypeLoc(TL, 0, ParentDC);
34    return true;
35  }
36
37  bool VisitDeclRefExpr(DeclRefExpr *E) {
38    IndexCtx.handleReference(E->getDecl(), E->getLocation(), 0, ParentDC, E);
39    return true;
40  }
41
42  bool VisitMemberExpr(MemberExpr *E) {
43    IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(), 0, ParentDC,
44                             E);
45    return true;
46  }
47
48  bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
49    IndexCtx.handleReference(E->getDecl(), E->getLocation(), 0, ParentDC, E);
50    return true;
51  }
52
53  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
54    if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo())
55      IndexCtx.indexTypeSourceInfo(Cls, 0, ParentDC);
56
57    if (ObjCMethodDecl *MD = E->getMethodDecl())
58      IndexCtx.handleReference(MD, E->getSelectorStartLoc(), 0, ParentDC, E,
59                               InPseudoObject ? CXIdxEntityRef_Implicit
60                                              : CXIdxEntityRef_Direct);
61    return true;
62  }
63
64  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
65    if (E->isImplicitProperty()) {
66      if (ObjCMethodDecl *MD = E->getImplicitPropertyGetter())
67        IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E,
68                                 CXIdxEntityRef_Implicit);
69      if (ObjCMethodDecl *MD = E->getImplicitPropertySetter())
70        IndexCtx.handleReference(MD, E->getLocation(), 0, ParentDC, E,
71                                 CXIdxEntityRef_Implicit);
72    } else {
73      IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(), 0,
74                               ParentDC, E);
75    }
76    return true;
77  }
78
79  bool TraversePseudoObjectExpr(PseudoObjectExpr *E) {
80    SaveAndRestore<bool> InPseudo(InPseudoObject, true);
81    return base::TraversePseudoObjectExpr(E);
82  }
83
84  bool VisitCXXConstructExpr(CXXConstructExpr *E) {
85    IndexCtx.handleReference(E->getConstructor(), E->getLocation(), 0,
86                             ParentDC, E);
87    return true;
88  }
89};
90
91} // anonymous namespace
92
93void IndexingContext::indexBody(const Stmt *S, const DeclContext *DC) {
94  BodyIndexer(*this, DC).TraverseStmt(const_cast<Stmt*>(S));
95}
96