1f4a2713aSLionel Sambuc //===- CIndexHigh.cpp - Higher level API functions ------------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc
10f4a2713aSLionel Sambuc #include "IndexingContext.h"
11*0a6a1f1dSLionel Sambuc #include "clang/AST/DataRecursiveASTVisitor.h"
12f4a2713aSLionel Sambuc
13f4a2713aSLionel Sambuc using namespace clang;
14f4a2713aSLionel Sambuc using namespace cxindex;
15f4a2713aSLionel Sambuc
16f4a2713aSLionel Sambuc namespace {
17f4a2713aSLionel Sambuc
18*0a6a1f1dSLionel Sambuc class BodyIndexer : public DataRecursiveASTVisitor<BodyIndexer> {
19f4a2713aSLionel Sambuc IndexingContext &IndexCtx;
20f4a2713aSLionel Sambuc const NamedDecl *Parent;
21f4a2713aSLionel Sambuc const DeclContext *ParentDC;
22f4a2713aSLionel Sambuc
23*0a6a1f1dSLionel Sambuc typedef DataRecursiveASTVisitor<BodyIndexer> base;
24f4a2713aSLionel Sambuc public:
BodyIndexer(IndexingContext & indexCtx,const NamedDecl * Parent,const DeclContext * DC)25f4a2713aSLionel Sambuc BodyIndexer(IndexingContext &indexCtx,
26f4a2713aSLionel Sambuc const NamedDecl *Parent, const DeclContext *DC)
27f4a2713aSLionel Sambuc : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
28f4a2713aSLionel Sambuc
shouldWalkTypesOfTypeLocs() const29f4a2713aSLionel Sambuc bool shouldWalkTypesOfTypeLocs() const { return false; }
30f4a2713aSLionel Sambuc
TraverseTypeLoc(TypeLoc TL)31f4a2713aSLionel Sambuc bool TraverseTypeLoc(TypeLoc TL) {
32f4a2713aSLionel Sambuc IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
33f4a2713aSLionel Sambuc return true;
34f4a2713aSLionel Sambuc }
35f4a2713aSLionel Sambuc
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)36f4a2713aSLionel Sambuc bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
37f4a2713aSLionel Sambuc IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
38f4a2713aSLionel Sambuc return true;
39f4a2713aSLionel Sambuc }
40f4a2713aSLionel Sambuc
VisitDeclRefExpr(DeclRefExpr * E)41f4a2713aSLionel Sambuc bool VisitDeclRefExpr(DeclRefExpr *E) {
42f4a2713aSLionel Sambuc IndexCtx.handleReference(E->getDecl(), E->getLocation(),
43f4a2713aSLionel Sambuc Parent, ParentDC, E);
44f4a2713aSLionel Sambuc return true;
45f4a2713aSLionel Sambuc }
46f4a2713aSLionel Sambuc
VisitMemberExpr(MemberExpr * E)47f4a2713aSLionel Sambuc bool VisitMemberExpr(MemberExpr *E) {
48f4a2713aSLionel Sambuc IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
49f4a2713aSLionel Sambuc Parent, ParentDC, E);
50f4a2713aSLionel Sambuc return true;
51f4a2713aSLionel Sambuc }
52f4a2713aSLionel Sambuc
VisitDesignatedInitExpr(DesignatedInitExpr * E)53f4a2713aSLionel Sambuc bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
54f4a2713aSLionel Sambuc for (DesignatedInitExpr::reverse_designators_iterator
55f4a2713aSLionel Sambuc D = E->designators_rbegin(), DEnd = E->designators_rend();
56f4a2713aSLionel Sambuc D != DEnd; ++D) {
57f4a2713aSLionel Sambuc if (D->isFieldDesignator())
58f4a2713aSLionel Sambuc IndexCtx.handleReference(D->getField(), D->getFieldLoc(),
59f4a2713aSLionel Sambuc Parent, ParentDC, E);
60f4a2713aSLionel Sambuc }
61f4a2713aSLionel Sambuc return true;
62f4a2713aSLionel Sambuc }
63f4a2713aSLionel Sambuc
VisitObjCIvarRefExpr(ObjCIvarRefExpr * E)64f4a2713aSLionel Sambuc bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
65f4a2713aSLionel Sambuc IndexCtx.handleReference(E->getDecl(), E->getLocation(),
66f4a2713aSLionel Sambuc Parent, ParentDC, E);
67f4a2713aSLionel Sambuc return true;
68f4a2713aSLionel Sambuc }
69f4a2713aSLionel Sambuc
VisitObjCMessageExpr(ObjCMessageExpr * E)70f4a2713aSLionel Sambuc bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
71f4a2713aSLionel Sambuc if (ObjCMethodDecl *MD = E->getMethodDecl())
72f4a2713aSLionel Sambuc IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
73f4a2713aSLionel Sambuc Parent, ParentDC, E,
74f4a2713aSLionel Sambuc E->isImplicit() ? CXIdxEntityRef_Implicit
75f4a2713aSLionel Sambuc : CXIdxEntityRef_Direct);
76f4a2713aSLionel Sambuc return true;
77f4a2713aSLionel Sambuc }
78f4a2713aSLionel Sambuc
VisitObjCPropertyRefExpr(ObjCPropertyRefExpr * E)79f4a2713aSLionel Sambuc bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
80f4a2713aSLionel Sambuc if (E->isExplicitProperty())
81f4a2713aSLionel Sambuc IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
82f4a2713aSLionel Sambuc Parent, ParentDC, E);
83f4a2713aSLionel Sambuc
84f4a2713aSLionel Sambuc // No need to do a handleReference for the objc method, because there will
85f4a2713aSLionel Sambuc // be a message expr as part of PseudoObjectExpr.
86f4a2713aSLionel Sambuc return true;
87f4a2713aSLionel Sambuc }
88f4a2713aSLionel Sambuc
VisitMSPropertyRefExpr(MSPropertyRefExpr * E)89f4a2713aSLionel Sambuc bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
90f4a2713aSLionel Sambuc IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
91f4a2713aSLionel Sambuc ParentDC, E, CXIdxEntityRef_Direct);
92f4a2713aSLionel Sambuc return true;
93f4a2713aSLionel Sambuc }
94f4a2713aSLionel Sambuc
VisitObjCProtocolExpr(ObjCProtocolExpr * E)95f4a2713aSLionel Sambuc bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
96f4a2713aSLionel Sambuc IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
97f4a2713aSLionel Sambuc Parent, ParentDC, E, CXIdxEntityRef_Direct);
98f4a2713aSLionel Sambuc return true;
99f4a2713aSLionel Sambuc }
100f4a2713aSLionel Sambuc
VisitObjCBoxedExpr(ObjCBoxedExpr * E)101f4a2713aSLionel Sambuc bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
102f4a2713aSLionel Sambuc if (ObjCMethodDecl *MD = E->getBoxingMethod())
103f4a2713aSLionel Sambuc IndexCtx.handleReference(MD, E->getLocStart(),
104f4a2713aSLionel Sambuc Parent, ParentDC, E, CXIdxEntityRef_Implicit);
105f4a2713aSLionel Sambuc return true;
106f4a2713aSLionel Sambuc }
107f4a2713aSLionel Sambuc
VisitObjCDictionaryLiteral(ObjCDictionaryLiteral * E)108f4a2713aSLionel Sambuc bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
109f4a2713aSLionel Sambuc if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
110f4a2713aSLionel Sambuc IndexCtx.handleReference(MD, E->getLocStart(),
111f4a2713aSLionel Sambuc Parent, ParentDC, E, CXIdxEntityRef_Implicit);
112f4a2713aSLionel Sambuc return true;
113f4a2713aSLionel Sambuc }
114f4a2713aSLionel Sambuc
VisitObjCArrayLiteral(ObjCArrayLiteral * E)115f4a2713aSLionel Sambuc bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
116f4a2713aSLionel Sambuc if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
117f4a2713aSLionel Sambuc IndexCtx.handleReference(MD, E->getLocStart(),
118f4a2713aSLionel Sambuc Parent, ParentDC, E, CXIdxEntityRef_Implicit);
119f4a2713aSLionel Sambuc return true;
120f4a2713aSLionel Sambuc }
121f4a2713aSLionel Sambuc
VisitCXXConstructExpr(CXXConstructExpr * E)122f4a2713aSLionel Sambuc bool VisitCXXConstructExpr(CXXConstructExpr *E) {
123f4a2713aSLionel Sambuc IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
124f4a2713aSLionel Sambuc Parent, ParentDC, E);
125f4a2713aSLionel Sambuc return true;
126f4a2713aSLionel Sambuc }
127f4a2713aSLionel Sambuc
TraverseCXXOperatorCallExpr(CXXOperatorCallExpr * E)128f4a2713aSLionel Sambuc bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
129f4a2713aSLionel Sambuc if (E->getOperatorLoc().isInvalid())
130f4a2713aSLionel Sambuc return true; // implicit.
131f4a2713aSLionel Sambuc return base::TraverseCXXOperatorCallExpr(E);
132f4a2713aSLionel Sambuc }
133f4a2713aSLionel Sambuc
VisitDeclStmt(DeclStmt * S)134f4a2713aSLionel Sambuc bool VisitDeclStmt(DeclStmt *S) {
135f4a2713aSLionel Sambuc if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
136f4a2713aSLionel Sambuc IndexCtx.indexDeclGroupRef(S->getDeclGroup());
137f4a2713aSLionel Sambuc return true;
138f4a2713aSLionel Sambuc }
139f4a2713aSLionel Sambuc
140f4a2713aSLionel Sambuc DeclGroupRef DG = S->getDeclGroup();
141f4a2713aSLionel Sambuc for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
142f4a2713aSLionel Sambuc const Decl *D = *I;
143f4a2713aSLionel Sambuc if (!D)
144f4a2713aSLionel Sambuc continue;
145f4a2713aSLionel Sambuc if (!IndexCtx.isFunctionLocalDecl(D))
146f4a2713aSLionel Sambuc IndexCtx.indexTopLevelDecl(D);
147f4a2713aSLionel Sambuc }
148f4a2713aSLionel Sambuc
149f4a2713aSLionel Sambuc return true;
150f4a2713aSLionel Sambuc }
151f4a2713aSLionel Sambuc
TraverseLambdaCapture(LambdaExpr * LE,const LambdaCapture * C)152*0a6a1f1dSLionel Sambuc bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) {
153*0a6a1f1dSLionel Sambuc if (C->capturesThis() || C->capturesVLAType())
154f4a2713aSLionel Sambuc return true;
155f4a2713aSLionel Sambuc
156*0a6a1f1dSLionel Sambuc if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
157*0a6a1f1dSLionel Sambuc IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(), Parent,
158*0a6a1f1dSLionel Sambuc ParentDC);
159f4a2713aSLionel Sambuc
160f4a2713aSLionel Sambuc // FIXME: Lambda init-captures.
161f4a2713aSLionel Sambuc return true;
162f4a2713aSLionel Sambuc }
163f4a2713aSLionel Sambuc
164f4a2713aSLionel Sambuc };
165f4a2713aSLionel Sambuc
166f4a2713aSLionel Sambuc } // anonymous namespace
167f4a2713aSLionel Sambuc
indexBody(const Stmt * S,const NamedDecl * Parent,const DeclContext * DC)168f4a2713aSLionel Sambuc void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
169f4a2713aSLionel Sambuc const DeclContext *DC) {
170f4a2713aSLionel Sambuc if (!S)
171f4a2713aSLionel Sambuc return;
172f4a2713aSLionel Sambuc
173*0a6a1f1dSLionel Sambuc if (!DC)
174f4a2713aSLionel Sambuc DC = Parent->getLexicalDeclContext();
175f4a2713aSLionel Sambuc BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
176f4a2713aSLionel Sambuc }
177