blob: 3614206dee9282851a0ac326e8db0b7116b5e0e5 [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"
11
Argyrios Kyrtzidisdec35a92012-05-07 22:16:46 +000012#include "RecursiveASTVisitor.h"
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000013
14using namespace clang;
15using namespace cxindex;
16
17namespace {
18
Argyrios Kyrtzidis98180d42012-05-07 22:22:58 +000019class BodyIndexer : public cxindex::RecursiveASTVisitor<BodyIndexer> {
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000020 IndexingContext &IndexCtx;
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000021 const NamedDecl *Parent;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000022 const DeclContext *ParentDC;
23
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000024 typedef RecursiveASTVisitor<BodyIndexer> base;
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000025public:
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000026 BodyIndexer(IndexingContext &indexCtx,
27 const NamedDecl *Parent, const DeclContext *DC)
Argyrios Kyrtzidis746f5bc2012-01-12 02:34:39 +000028 : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000029
30 bool shouldWalkTypesOfTypeLocs() const { return false; }
31
32 bool TraverseTypeLoc(TypeLoc TL) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000033 IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000034 return true;
35 }
36
Argyrios Kyrtzidis55fa1d92012-01-23 16:58:38 +000037 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
38 IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
39 return true;
40 }
41
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000042 bool VisitDeclRefExpr(DeclRefExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000043 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
44 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000045 return true;
46 }
47
48 bool VisitMemberExpr(MemberExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000049 IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
50 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000051 return true;
52 }
53
Argyrios Kyrtzidise0d92a42012-02-22 02:10:41 +000054 bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
55 for (DesignatedInitExpr::reverse_designators_iterator
56 D = E->designators_rbegin(), DEnd = E->designators_rend();
57 D != DEnd; ++D) {
58 if (D->isFieldDesignator())
59 IndexCtx.handleReference(D->getField(), D->getFieldLoc(),
60 Parent, ParentDC, E);
61 }
62 return true;
63 }
64
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000065 bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000066 IndexCtx.handleReference(E->getDecl(), E->getLocation(),
67 Parent, ParentDC, E);
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +000068 return true;
69 }
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000070
71 bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000072 if (TypeSourceInfo *Cls = E->getClassReceiverTypeInfo())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000073 IndexCtx.indexTypeSourceInfo(Cls, Parent, ParentDC);
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +000074
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000075 if (ObjCMethodDecl *MD = E->getMethodDecl())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000076 IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
77 Parent, ParentDC, E,
Argyrios Kyrtzidis746f5bc2012-01-12 02:34:39 +000078 E->isImplicit() ? CXIdxEntityRef_Implicit
79 : CXIdxEntityRef_Direct);
Argyrios Kyrtzidis9fbbf142011-10-18 15:13:11 +000080 return true;
81 }
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +000082
83 bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
Ted Kremenekb3f75422012-03-06 20:06:06 +000084 if (E->isExplicitProperty())
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +000085 IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
86 Parent, ParentDC, E);
Ted Kremenekb3f75422012-03-06 20:06:06 +000087
88 // No need to do a handleReference for the objc method, because there will
89 // be a message expr as part of PseudoObjectExpr.
90 return true;
91 }
92
Argyrios Kyrtzidis7d24e282012-05-16 00:50:02 +000093 bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
94 IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
95 Parent, ParentDC, E, CXIdxEntityRef_Direct);
96 return true;
97 }
98
Patrick Beardeb382ec2012-04-19 00:25:12 +000099 bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
100 if (ObjCMethodDecl *MD = E->getBoxingMethod())
Ted Kremenekb3f75422012-03-06 20:06:06 +0000101 IndexCtx.handleReference(MD, E->getLocStart(),
102 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
103 return true;
104 }
Patrick Beardeb382ec2012-04-19 00:25:12 +0000105
Ted Kremenekb3f75422012-03-06 20:06:06 +0000106 bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
107 if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
108 IndexCtx.handleReference(MD, E->getLocStart(),
109 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
110 return true;
111 }
112
113 bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
114 if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
115 IndexCtx.handleReference(MD, E->getLocStart(),
116 Parent, ParentDC, E, CXIdxEntityRef_Implicit);
Argyrios Kyrtzidisaca19be2011-10-18 15:50:50 +0000117 return true;
118 }
Argyrios Kyrtzidisb395c632011-11-18 00:26:51 +0000119
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000120 bool VisitCXXConstructExpr(CXXConstructExpr *E) {
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000121 IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
122 Parent, ParentDC, E);
Argyrios Kyrtzidis2957e6f2011-11-22 07:24:51 +0000123 return true;
124 }
Argyrios Kyrtzidis22490742012-01-14 00:11:49 +0000125
Argyrios Kyrtzidise377d712012-05-07 22:16:49 +0000126 bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
127 if (E->getOperatorLoc().isInvalid())
128 return true; // implicit.
129 return base::TraverseCXXOperatorCallExpr(E);
130 }
131
Argyrios Kyrtzidis22490742012-01-14 00:11:49 +0000132 bool VisitDeclStmt(DeclStmt *S) {
Argyrios Kyrtzidis3bed3d12012-09-10 22:58:04 +0000133 if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
Argyrios Kyrtzidis22490742012-01-14 00:11:49 +0000134 IndexCtx.indexDeclGroupRef(S->getDeclGroup());
Argyrios Kyrtzidis3bed3d12012-09-10 22:58:04 +0000135 return true;
136 }
137
138 DeclGroupRef DG = S->getDeclGroup();
139 for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
140 const Decl *D = *I;
141 if (!D)
142 continue;
143 if (!IndexCtx.isFunctionLocalDecl(D))
144 IndexCtx.indexTopLevelDecl(D);
145 }
146
Argyrios Kyrtzidis22490742012-01-14 00:11:49 +0000147 return true;
148 }
Richard Smith5677eaf2012-02-15 02:07:05 +0000149
Douglas Gregor011d8b92012-02-15 00:54:55 +0000150 bool TraverseLambdaCapture(LambdaExpr::Capture C) {
151 if (C.capturesThis())
152 return true;
Richard Smith5677eaf2012-02-15 02:07:05 +0000153
154 if (IndexCtx.shouldIndexFunctionLocalSymbols())
Douglas Gregor011d8b92012-02-15 00:54:55 +0000155 IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(),
156 Parent, ParentDC);
157 return true;
158 }
159
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000160};
161
162} // anonymous namespace
163
Argyrios Kyrtzidise422e452011-12-13 18:47:41 +0000164void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
165 const DeclContext *DC) {
166 if (!S)
167 return;
168
169 if (DC == 0)
170 DC = Parent->getLexicalDeclContext();
171 BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
Argyrios Kyrtzidis4e7064f2011-10-17 19:48:19 +0000172}