blob: 30e1bffbf2462f1fc7895746e1eae85c6376a67f [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"
Argyrios Kyrtzidis561fe542013-12-20 02:02:54 +000011#include "clang/AST/DataRecursiveASTVisitor.h"
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +000012
13using namespace clang;
14using namespace cxindex;
15
16namespace {
17
Argyrios Kyrtzidis561fe542013-12-20 02:02:54 +000018class BodyIndexer : public DataRecursiveASTVisitor<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
Argyrios Kyrtzidis561fe542013-12-20 02:02:54 +000023 typedef DataRecursiveASTVisitor<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);
Fariborz Jahanian413297c2014-08-06 18:13:46 +0000112 if (ObjCMethodDecl *MD = E->getDictAllocMethod())
113 IndexCtx.handleReference(MD, E->getLocStart(),
114 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
Ted Kremenek77006f62012-03-06 20:06:06 +0000115 return true;
116 }
117
118 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
119 if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
120 IndexCtx.handleReference(MD, E->getLocStart(),
121 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
Fariborz Jahanian413297c2014-08-06 18:13:46 +0000122 if (ObjCMethodDecl *MD = E->getArrayAllocMethod())
123 IndexCtx.handleReference(MD, E->getLocStart(),
124 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
Argyrios Kyrtzidis0c7735e52011-10-18 15:50:50 +0000125 return true;
126 }
Argyrios Kyrtzidiseffdbf52011-11-18 00:26:51 +0000127
Argyrios Kyrtzidis4c910b12011-11-22 07:24:51 +0000128 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +0000129 IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
130 Parent, ParentDC, E);
Argyrios Kyrtzidis4c910b12011-11-22 07:24:51 +0000131 return true;
132 }
Argyrios Kyrtzidisfb7d1452012-01-14 00:11:49 +0000133
Argyrios Kyrtzidis93e1d1c2012-05-07 22:16:49 +0000134 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
135 if (E->getOperatorLoc().isInvalid())
136 return true; // implicit.
137 return base::TraverseCXXOperatorCallExpr(E);
138 }
139
Argyrios Kyrtzidisfb7d1452012-01-14 00:11:49 +0000140 bool VisitDeclStmt(DeclStmt *S) {
Argyrios Kyrtzidis68e87e12012-09-10 22:58:04 +0000141 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
Argyrios Kyrtzidisfb7d1452012-01-14 00:11:49 +0000142 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
Argyrios Kyrtzidis68e87e12012-09-10 22:58:04 +0000143 return true;
144 }
145
146 DeclGroupRef DG = S->getDeclGroup();
147 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
148 const Decl *D = *I;
149 if (!D)
150 continue;
151 if (!IndexCtx.isFunctionLocalDecl(D))
152 IndexCtx.indexTopLevelDecl(D);
153 }
154
Argyrios Kyrtzidisfb7d1452012-01-14 00:11:49 +0000155 return true;
156 }
Richard Smith19582e82012-02-15 02:07:05 +0000157
Alp Tokerfdafb942014-05-20 22:03:39 +0000158 bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
Alexey Bataev39c81e22014-08-28 04:28:19 +0000159 if (C->capturesThis() || C->capturesVLAType())
Douglas Gregor30093832012-02-15 00:54:55 +0000160 return true;
Richard Smith19582e82012-02-15 02:07:05 +0000161
Alp Tokerfdafb942014-05-20 22:03:39 +0000162 if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
163 IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(), Parent,
164 ParentDC);
Richard Smithba71c082013-05-16 06:20:58 +0000165
166 // FIXME: Lambda init-captures.
Douglas Gregor30093832012-02-15 00:54:55 +0000167 return true;
168 }
169
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000170};
171
172} // anonymous namespace
173
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +0000174void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
175 const DeclContext *DC) {
176 if (!S)
177 return;
178
Craig Topper69186e72014-06-08 08:38:04 +0000179 if (!DC)
Argyrios Kyrtzidis25cb0ff2011-12-13 18:47:41 +0000180 DC = Parent->getLexicalDeclContext();
181 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
Argyrios Kyrtzidisdc199a32011-10-17 19:48:19 +0000182}