blob: 64df4b85beac7b5d1487e2319b0f19691f079fd9 [file] [log] [blame]
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +00001//===- 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"
Richard Smith50668452015-11-24 03:55:01 +000011#include "clang/AST/RecursiveASTVisitor.h"
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000012
13using namespace clang;
14using namespace cxindex;
15
16namespace {
17
Richard Smith50668452015-11-24 03:55:01 +000018class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000019 IndexingContext &IndexCtx;
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +000020 const NamedDecl *Parent;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000021 const DeclContext *ParentDC;
22
Richard Smith50668452015-11-24 03:55:01 +000023 typedef RecursiveASTVisitor<BodyIndexer> base;
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000024public:
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +000025 BodyIndexer(IndexingContext &indexCtx,
26 const NamedDecl *Parent, const DeclContext *DC)
Argyrios Kyrtzidisa80f1bf2012-01-12 02:34:39 +000027 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000028
29 bool shouldWalkTypesOfTypeLocs() const { return false; }
30
31 bool TraverseTypeLoc(TypeLoc TL) {
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +000032 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000033 return true;
34 }
35
Argyrios Kyrtzidis9f777352012-01-23 16:58:38 +000036 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
37 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
38 return true;
39 }
40
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000041 bool VisitDeclRefExpr(DeclRefExpr *E) {
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +000042 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
43 Parent, ParentDC, E);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000044 return true;
45 }
46
47 bool VisitMemberExpr(MemberExpr *E) {
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +000048 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
49 Parent, ParentDC, E);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000050 return true;
51 }
52
Argyrios Kyrtzidisa1bed4c2012-02-22 02:10:41 +000053 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
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000064 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +000065 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
66 Parent, ParentDC, E);
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000067 return true;
68 }
Argyrios Kyrtzidis321e3022011-10-18 15:13:11 +000069
70 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
71 if (ObjCMethodDecl *MD = E->getMethodDecl())
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +000072 IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
73 Parent, ParentDC, E,
Argyrios Kyrtzidisa80f1bf2012-01-12 02:34:39 +000074 E->isImplicit() ? CXIdxEntityRef_Implicit
75 : CXIdxEntityRef_Direct);
Argyrios Kyrtzidis321e3022011-10-18 15:13:11 +000076 return true;
77 }
Argyrios Kyrtzidis0c7735e52011-10-18 15:50:50 +000078
79 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
Ted Kremenek77006f62012-03-06 20:06:06 +000080 if (E->isExplicitProperty())
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +000081 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
82 Parent, ParentDC, E);
Ted Kremenek77006f62012-03-06 20:06:06 +000083
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
John McCall5e77d762013-04-16 07:28:30 +000089 bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
90 IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
91 ParentDC, E, CXIdxEntityRef_Direct);
92 return true;
93 }
94
Argyrios Kyrtzidisb7e43672012-05-16 00:50:02 +000095 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
96 IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
97 Parent, ParentDC, E, CXIdxEntityRef_Direct);
98 return true;
99 }
100
Patrick Beard0caa3942012-04-19 00:25:12 +0000101 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
102 if (ObjCMethodDecl *MD = E->getBoxingMethod())
Ted Kremenek77006f62012-03-06 20:06:06 +0000103 IndexCtx.handleReference(MD, E->getLocStart(),
104 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
105 return true;
106 }
Patrick Beard0caa3942012-04-19 00:25:12 +0000107
Ted Kremenek77006f62012-03-06 20:06:06 +0000108 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
115 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
116 if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
117 IndexCtx.handleReference(MD, E->getLocStart(),
118 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
Argyrios Kyrtzidis0c7735e52011-10-18 15:50:50 +0000119 return true;
120 }
Argyrios Kyrtzidiseffdbf52011-11-18 00:26:51 +0000121
Argyrios Kyrtzidis4c910b12011-11-22 07:24:51 +0000122 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +0000123 IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
124 Parent, ParentDC, E);
Argyrios Kyrtzidis4c910b12011-11-22 07:24:51 +0000125 return true;
126 }
Argyrios Kyrtzidisfb7d1452012-01-14 00:11:49 +0000127
Richard Smitha2057192015-11-24 23:50:47 +0000128 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
129 DataRecursionQueue *Q = nullptr) {
Argyrios Kyrtzidis93e1d1c2012-05-07 22:16:49 +0000130 if (E->getOperatorLoc().isInvalid())
131 return true; // implicit.
Richard Smitha2057192015-11-24 23:50:47 +0000132 return base::TraverseCXXOperatorCallExpr(E, Q);
Argyrios Kyrtzidis93e1d1c2012-05-07 22:16:49 +0000133 }
134
Argyrios Kyrtzidisfb7d1452012-01-14 00:11:49 +0000135 bool VisitDeclStmt(DeclStmt *S) {
Argyrios Kyrtzidis68e87e12012-09-10 22:58:04 +0000136 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
Argyrios Kyrtzidisfb7d1452012-01-14 00:11:49 +0000137 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
Argyrios Kyrtzidis68e87e12012-09-10 22:58:04 +0000138 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
Argyrios Kyrtzidisfb7d1452012-01-14 00:11:49 +0000150 return true;
151 }
Richard Smith19582e82012-02-15 02:07:05 +0000152
Alp Tokerfdafb942014-05-20 22:03:39 +0000153 bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
Alexey Bataev39c81e22014-08-28 04:28:19 +0000154 if (C->capturesThis() || C->capturesVLAType())
Douglas Gregor30093832012-02-15 00:54:55 +0000155 return true;
Richard Smith19582e82012-02-15 02:07:05 +0000156
Alp Tokerfdafb942014-05-20 22:03:39 +0000157 if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
158 IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(), Parent,
159 ParentDC);
Richard Smithba71c082013-05-16 06:20:58 +0000160
161 // FIXME: Lambda init-captures.
Douglas Gregor30093832012-02-15 00:54:55 +0000162 return true;
163 }
164
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000165};
166
167} // anonymous namespace
168
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +0000169void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
170 const DeclContext *DC) {
171 if (!S)
172 return;
173
Craig Topper69186e72014-06-08 08:38:04 +0000174 if (!DC)
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +0000175 DC = Parent->getLexicalDeclContext();
176 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000177}