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/DataRecursiveASTVisitor.h"
12
13 using namespace clang;
14 using namespace cxindex;
15
16 namespace {
17
18 class BodyIndexer : public DataRecursiveASTVisitor<BodyIndexer> {
19 IndexingContext &IndexCtx;
20 const NamedDecl *Parent;
21 const DeclContext *ParentDC;
22
23 typedef DataRecursiveASTVisitor<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)128 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
129 if (E->getOperatorLoc().isInvalid())
130 return true; // implicit.
131 return base::TraverseCXXOperatorCallExpr(E);
132 }
133
VisitDeclStmt(DeclStmt * S)134 bool VisitDeclStmt(DeclStmt *S) {
135 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
136 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
137 return true;
138 }
139
140 DeclGroupRef DG = S->getDeclGroup();
141 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
142 const Decl *D = *I;
143 if (!D)
144 continue;
145 if (!IndexCtx.isFunctionLocalDecl(D))
146 IndexCtx.indexTopLevelDecl(D);
147 }
148
149 return true;
150 }
151
TraverseLambdaCapture(LambdaExpr * LE,const LambdaCapture * C)152 bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
153 if (C->capturesThis() || C->capturesVLAType())
154 return true;
155
156 if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
157 IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(), Parent,
158 ParentDC);
159
160 // FIXME: Lambda init-captures.
161 return true;
162 }
163
164 };
165
166 } // anonymous namespace
167
indexBody(const Stmt * S,const NamedDecl * Parent,const DeclContext * DC)168 void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
169 const DeclContext *DC) {
170 if (!S)
171 return;
172
173 if (!DC)
174 DC = Parent->getLexicalDeclContext();
175 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
176 }
177