xref: /minix3/external/bsd/llvm/dist/clang/tools/libclang/IndexBody.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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