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 #include "clang/AST/RecursiveASTVisitor.h"
12
13 using namespace clang;
14 using namespace cxindex;
15
16 namespace {
17
18 class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
19 IndexingContext &IndexCtx;
20 const NamedDecl *Parent;
21 const DeclContext *ParentDC;
22
23 typedef RecursiveASTVisitor<BodyIndexer> base;
24 public:
BodyIndexer(IndexingContext & indexCtx,const NamedDecl * Parent,const DeclContext * DC)25 BodyIndexer(IndexingContext &indexCtx,
26 const NamedDecl *Parent, const DeclContext *DC)
27 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
28
shouldWalkTypesOfTypeLocs() const29 bool shouldWalkTypesOfTypeLocs() const { return false; }
30
TraverseTypeLoc(TypeLoc TL)31 bool TraverseTypeLoc(TypeLoc TL) {
32 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
33 return true;
34 }
35
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)36 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
37 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
38 return true;
39 }
40
VisitDeclRefExpr(DeclRefExpr * E)41 bool VisitDeclRefExpr(DeclRefExpr *E) {
42 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
43 Parent, ParentDC, E);
44 return true;
45 }
46
VisitMemberExpr(MemberExpr * E)47 bool VisitMemberExpr(MemberExpr *E) {
48 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
49 Parent, ParentDC, E);
50 return true;
51 }
52
VisitDesignatedInitExpr(DesignatedInitExpr * E)53 bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
54 for (DesignatedInitExpr::reverse_designators_iterator
55 D = E->designators_rbegin(), DEnd = E->designators_rend();
56 D != DEnd; ++D) {
57 if (D->isFieldDesignator())
58 IndexCtx.handleReference(D->getField(), D->getFieldLoc(),
59 Parent, ParentDC, E);
60 }
61 return true;
62 }
63
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)64 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
65 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
66 Parent, ParentDC, E);
67 return true;
68 }
69
VisitObjCMessageExpr(ObjCMessageExpr * E)70 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
71 if (ObjCMethodDecl *MD = E->getMethodDecl())
72 IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
73 Parent, ParentDC, E,
74 E->isImplicit() ? CXIdxEntityRef_Implicit
75 : CXIdxEntityRef_Direct);
76 return true;
77 }
78
VisitObjCPropertyRefExpr(ObjCPropertyRefExpr * E)79 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
80 if (E->isExplicitProperty())
81 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
82 Parent, ParentDC, E);
83
84 // No need to do a handleReference for the objc method, because there will
85 // be a message expr as part of PseudoObjectExpr.
86 return true;
87 }
88
VisitMSPropertyRefExpr(MSPropertyRefExpr * E)89 bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
90 IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
91 ParentDC, E, CXIdxEntityRef_Direct);
92 return true;
93 }
94
VisitObjCProtocolExpr(ObjCProtocolExpr * E)95 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
96 IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
97 Parent, ParentDC, E, CXIdxEntityRef_Direct);
98 return true;
99 }
100
VisitObjCBoxedExpr(ObjCBoxedExpr * E)101 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
102 if (ObjCMethodDecl *MD = E->getBoxingMethod())
103 IndexCtx.handleReference(MD, E->getLocStart(),
104 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
105 return true;
106 }
107
VisitObjCDictionaryLiteral(ObjCDictionaryLiteral * E)108 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
109 if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
110 IndexCtx.handleReference(MD, E->getLocStart(),
111 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
112 return true;
113 }
114
VisitObjCArrayLiteral(ObjCArrayLiteral * E)115 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
116 if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
117 IndexCtx.handleReference(MD, E->getLocStart(),
118 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
119 return true;
120 }
121
VisitCXXConstructExpr(CXXConstructExpr * E)122 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
123 IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
124 Parent, ParentDC, E);
125 return true;
126 }
127
TraverseCXXOperatorCallExpr(CXXOperatorCallExpr * E,DataRecursionQueue * Q=nullptr)128 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
129 DataRecursionQueue *Q = nullptr) {
130 if (E->getOperatorLoc().isInvalid())
131 return true; // implicit.
132 return base::TraverseCXXOperatorCallExpr(E, Q);
133 }
134
VisitDeclStmt(DeclStmt * S)135 bool VisitDeclStmt(DeclStmt *S) {
136 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
137 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
138 return true;
139 }
140
141 DeclGroupRef DG = S->getDeclGroup();
142 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
143 const Decl *D = *I;
144 if (!D)
145 continue;
146 if (!IndexCtx.isFunctionLocalDecl(D))
147 IndexCtx.indexTopLevelDecl(D);
148 }
149
150 return true;
151 }
152
TraverseLambdaCapture(LambdaExpr * LE,const LambdaCapture * C)153 bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
154 if (C->capturesThis() || C->capturesVLAType())
155 return true;
156
157 if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
158 IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(), Parent,
159 ParentDC);
160
161 // FIXME: Lambda init-captures.
162 return true;
163 }
164
165 };
166
167 } // anonymous namespace
168
indexBody(const Stmt * S,const NamedDecl * Parent,const DeclContext * DC)169 void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
170 const DeclContext *DC) {
171 if (!S)
172 return;
173
174 if (!DC)
175 DC = Parent->getLexicalDeclContext();
176 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
177 }
178