blob: 54711e6332ab051b0c177c1e9e26acbd3a9e3800 [file] [log] [blame]
Argyrios Kyrtzidis4e7064f2011-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 Kyrtzidisdec35a92012-05-07 22:16:46 +000011#include "RecursiveASTVisitor.h"
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000012
13using namespace clang;
14using namespace cxindex;
15
16namespace {
17
Argyrios Kyrtzidis98180d42012-05-07 22:22:58 +000018class BodyIndexer : public cxindex::RecursiveASTVisitor<BodyIndexer> {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000019 IndexingContext &IndexCtx;
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000020 const NamedDecl *Parent;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000021 const DeclContext *ParentDC;
22
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000023 typedef RecursiveASTVisitor<BodyIndexer> base;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000024public:
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000025 BodyIndexer(IndexingContext &indexCtx,
26 const NamedDecl *Parent, const DeclContext *DC)
Argyrios Kyrtzidis746f5bc2012-01-12 02:34:39 +000027 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000028
29 bool shouldWalkTypesOfTypeLocs() const { return false; }
30
31 bool TraverseTypeLoc(TypeLoc TL) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000032 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000033 return true;
34 }
35
Argyrios Kyrtzidis55fa1d92012-01-23 16:58:38 +000036 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
37 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
38 return true;
39 }
40
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000041 bool VisitDeclRefExpr(DeclRefExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000042 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
43 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000044 return true;
45 }
46
47 bool VisitMemberExpr(MemberExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000048 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
49 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000050 return true;
51 }
52
Argyrios Kyrtzidise0d92a42012-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 Kyrtzidis4e7064f2011-10-17 19:48:19 +000064 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000065 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
66 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000067 return true;
68 }
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000069
70 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000071 if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000072 IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000073
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000074 if (ObjCMethodDecl *MD = E->getMethodDecl())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000075 IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
76 Parent, ParentDC, E,
Argyrios Kyrtzidis746f5bc2012-01-12 02:34:39 +000077 E->isImplicit() ? CXIdxEntityRef_Implicit
78 : CXIdxEntityRef_Direct);
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000079 return true;
80 }
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +000081
82 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
Ted Kremenekb3f75422012-03-06 20:06:06 +000083 if (E->isExplicitProperty())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000084 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
85 Parent, ParentDC, E);
Ted Kremenekb3f75422012-03-06 20:06:06 +000086
87 // No need to do a handleReference for the objc method, because there will
88 // be a message expr as part of PseudoObjectExpr.
89 return true;
90 }
91
John McCall76da55d2013-04-16 07:28:30 +000092 bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
93 IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
94 ParentDC, E, CXIdxEntityRef_Direct);
95 return true;
96 }
97
Argyrios Kyrtzidis7d24e282012-05-16 00:50:02 +000098 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
99 IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
100 Parent, ParentDC, E, CXIdxEntityRef_Direct);
101 return true;
102 }
103
Patrick Beardeb382ec2012-04-19 00:25:12 +0000104 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
105 if (ObjCMethodDecl *MD = E->getBoxingMethod())
Ted Kremenekb3f75422012-03-06 20:06:06 +0000106 IndexCtx.handleReference(MD, E->getLocStart(),
107 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
108 return true;
109 }
Patrick Beardeb382ec2012-04-19 00:25:12 +0000110
Ted Kremenekb3f75422012-03-06 20:06:06 +0000111 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
112 if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
113 IndexCtx.handleReference(MD, E->getLocStart(),
114 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
115 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);
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +0000122 return true;
123 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000124
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000125 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000126 IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
127 Parent, ParentDC, E);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000128 return true;
129 }
Argyrios Kyrtzidis22490742012-01-14 00:11:49 +0000130
Argyrios Kyrtzidise377d712012-05-07 22:16:49 +0000131 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
132 if (E->getOperatorLoc().isInvalid())
133 return true; // implicit.
134 return base::TraverseCXXOperatorCallExpr(E);
135 }
136
Argyrios Kyrtzidis22490742012-01-14 00:11:49 +0000137 bool VisitDeclStmt(DeclStmt *S) {
Argyrios Kyrtzidis3bed3d12012-09-10 22:58:04 +0000138 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
Argyrios Kyrtzidis22490742012-01-14 00:11:49 +0000139 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
Argyrios Kyrtzidis3bed3d12012-09-10 22:58:04 +0000140 return true;
141 }
142
143 DeclGroupRef DG = S->getDeclGroup();
144 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
145 const Decl *D = *I;
146 if (!D)
147 continue;
148 if (!IndexCtx.isFunctionLocalDecl(D))
149 IndexCtx.indexTopLevelDecl(D);
150 }
151
Argyrios Kyrtzidis22490742012-01-14 00:11:49 +0000152 return true;
153 }
Richard Smith5677eaf2012-02-15 02:07:05 +0000154
Douglas Gregor011d8b92012-02-15 00:54:55 +0000155 bool TraverseLambdaCapture(LambdaExpr::Capture C) {
156 if (C.capturesThis())
157 return true;
Richard Smith5677eaf2012-02-15 02:07:05 +0000158
159 if (IndexCtx.shouldIndexFunctionLocalSymbols())
Douglas Gregor011d8b92012-02-15 00:54:55 +0000160 IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(),
161 Parent, ParentDC);
162 return true;
163 }
164
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000165};
166
167} // anonymous namespace
168
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000169void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
170 const DeclContext *DC) {
171 if (!S)
172 return;
173
174 if (DC == 0)
175 DC = Parent->getLexicalDeclContext();
176 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000177}