]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/libclang/IndexBody.cpp
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
[FreeBSD/FreeBSD.git] / tools / libclang / IndexBody.cpp
1 //===- 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 #include "RecursiveASTVisitor.h"
12
13 using namespace clang;
14 using namespace cxindex;
15
16 namespace {
17
18 class BodyIndexer : public cxindex::RecursiveASTVisitor<BodyIndexer> {
19   IndexingContext &IndexCtx;
20   const NamedDecl *Parent;
21   const DeclContext *ParentDC;
22
23   typedef RecursiveASTVisitor<BodyIndexer> base;
24 public:
25   BodyIndexer(IndexingContext &indexCtx,
26               const NamedDecl *Parent, const DeclContext *DC)
27     : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
28   
29   bool shouldWalkTypesOfTypeLocs() const { return false; }
30
31   bool TraverseTypeLoc(TypeLoc TL) {
32     IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
33     return true;
34   }
35
36   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
37     IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
38     return true;
39   }
40
41   bool VisitDeclRefExpr(DeclRefExpr *E) {
42     IndexCtx.handleReference(E->getDecl(), E->getLocation(),
43                              Parent, ParentDC, E);
44     return true;
45   }
46
47   bool VisitMemberExpr(MemberExpr *E) {
48     IndexCtx.handleReference(E->getMemberDecl(), E->getMemberLoc(),
49                              Parent, ParentDC, E);
50     return true;
51   }
52
53   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
64   bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
65     IndexCtx.handleReference(E->getDecl(), E->getLocation(),
66                              Parent, ParentDC, E);
67     return true;
68   }
69
70   bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
71     if (ObjCMethodDecl *MD = E->getMethodDecl())
72       IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
73                                Parent, ParentDC, E,
74                                E->isImplicit() ? CXIdxEntityRef_Implicit
75                                                : CXIdxEntityRef_Direct);
76     return true;
77   }
78
79   bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
80     if (E->isExplicitProperty())
81       IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
82                                Parent, ParentDC, E);
83
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
89   bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
90     IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(), Parent,
91                              ParentDC, E, CXIdxEntityRef_Direct);
92     return true;
93   }
94
95   bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
96     IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
97                              Parent, ParentDC, E, CXIdxEntityRef_Direct);
98     return true;
99   }
100
101   bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
102     if (ObjCMethodDecl *MD = E->getBoxingMethod())
103       IndexCtx.handleReference(MD, E->getLocStart(),
104                                Parent, ParentDC, E, CXIdxEntityRef_Implicit);
105     return true;
106   }
107   
108   bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
109     if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
110       IndexCtx.handleReference(MD, E->getLocStart(),
111                                Parent, ParentDC, E, CXIdxEntityRef_Implicit);
112     return true;
113   }
114
115   bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
116     if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod())
117       IndexCtx.handleReference(MD, E->getLocStart(),
118                                Parent, ParentDC, E, CXIdxEntityRef_Implicit);
119     return true;
120   }
121
122   bool VisitCXXConstructExpr(CXXConstructExpr *E) {
123     IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
124                              Parent, ParentDC, E);
125     return true;
126   }
127
128   bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
129     if (E->getOperatorLoc().isInvalid())
130       return true; // implicit.
131     return base::TraverseCXXOperatorCallExpr(E);
132   }
133
134   bool VisitDeclStmt(DeclStmt *S) {
135     if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
136       IndexCtx.indexDeclGroupRef(S->getDeclGroup());
137       return true;
138     }
139
140     DeclGroupRef DG = S->getDeclGroup();
141     for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
142       const Decl *D = *I;
143       if (!D)
144         continue;
145       if (!IndexCtx.isFunctionLocalDecl(D))
146         IndexCtx.indexTopLevelDecl(D);
147     }
148
149     return true;
150   }
151
152   bool TraverseLambdaCapture(LambdaExpr::Capture C) {
153     if (C.capturesThis())
154       return true;
155
156     if (C.capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
157       IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(),
158                                Parent, ParentDC);
159
160     // FIXME: Lambda init-captures.
161     return true;
162   }
163
164 };
165
166 } // anonymous namespace
167
168 void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
169                                 const DeclContext *DC) {
170   if (!S)
171     return;
172
173   if (DC == 0)
174     DC = Parent->getLexicalDeclContext();
175   BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
176 }