IndexDecl.cpp revision 2c3e05c266de0d4c465b58ffd129bd0b31604368
19b414d3e2d0cb84512b55a3275a98490b090162aDaniel Dunbar//===- CIndexHigh.cpp - Higher level API functions ------------------------===//
2e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman//
3e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman//                     The LLVM Compiler Infrastructure
4e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman//
5e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman// This file is distributed under the University of Illinois Open Source
6e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman// License. See LICENSE.TXT for details.
7e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman//
8e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman//===----------------------------------------------------------------------===//
9e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman
105705a40c7ec62f1a903bf26e1e6a7f91b5b98ba3Ted Kremenek#include "IndexingContext.h"
115705a40c7ec62f1a903bf26e1e6a7f91b5b98ba3Ted Kremenek
12e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman#include "clang/AST/DeclVisitor.h"
13e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman#include "clang/Basic/Module.h"
14e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman
155705a40c7ec62f1a903bf26e1e6a7f91b5b98ba3Ted Kremenekusing namespace clang;
165705a40c7ec62f1a903bf26e1e6a7f91b5b98ba3Ted Kremenekusing namespace cxindex;
175746f1ff6286f5e5bd7fc28e5e2031f18e4676c9Daniel Dunbar
1881fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rosenamespace {
1945796b10d11869e86c6b85e24df165410536b313Ted Kremenek
2030a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruthclass IndexingDeclVisitor : public DeclVisitor<IndexingDeclVisitor, bool> {
217229d0011766c174beffe6a846d78f448f845b39Anna Zaks  IndexingContext &IndexCtx;
2230a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth
2330a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruthpublic:
24e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman  explicit IndexingDeclVisitor(IndexingContext &indexCtx)
25e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    : IndexCtx(indexCtx) { }
26e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman
27d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie  void handleDeclarator(DeclaratorDecl *D, const NamedDecl *Parent = 0) {
28e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    if (!Parent) Parent = D;
29e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman
30e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    if (!IndexCtx.shouldIndexFunctionLocalSymbols()) {
31e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman      IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent);
32e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman      IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
33e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    } else {
34987695a5ddd78beca784d4e503ffbc2dc879181aTed Kremenek      if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
35e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman        IndexCtx.handleVar(Parm);
36e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman      } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
37e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman        for (FunctionDecl::param_iterator
38e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman               PI = FD->param_begin(), PE = FD->param_end(); PI != PE; ++PI) {
39e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman          IndexCtx.handleVar(*PI);
40e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman        }
41987695a5ddd78beca784d4e503ffbc2dc879181aTed Kremenek      }
42e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    }
43e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman  }
44e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman
45e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman  void handleObjCMethod(ObjCMethodDecl *D) {
46e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    IndexCtx.handleObjCMethod(D);
47e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    if (D->isImplicit())
48987695a5ddd78beca784d4e503ffbc2dc879181aTed Kremenek      return;
49e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman
50e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    IndexCtx.indexTypeSourceInfo(D->getResultTypeSourceInfo(), D);
51e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    for (ObjCMethodDecl::param_iterator
52e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman           I = D->param_begin(), E = D->param_end(); I != E; ++I)
53e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman      handleDeclarator(*I, D);
54e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman
555fba5a789a238c29ef811a39a39be722443ec1b1Jordan Rose    if (D->isThisDeclarationADefinition()) {
56987695a5ddd78beca784d4e503ffbc2dc879181aTed Kremenek      const Stmt *Body = D->getBody();
57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (Body) {
58e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman        IndexCtx.indexBody(Body, D, D);
59e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman      }
60e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    }
61d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks  }
62d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks
63d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks  bool VisitFunctionDecl(FunctionDecl *D) {
64987695a5ddd78beca784d4e503ffbc2dc879181aTed Kremenek    IndexCtx.handleFunction(D);
65d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks    handleDeclarator(D);
66d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks
67d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks    if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
6866253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks      // Constructor initializers.
6966253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks      for (CXXConstructorDecl::init_iterator I = Ctor->init_begin(),
7066253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks                                             E = Ctor->init_end();
71987695a5ddd78beca784d4e503ffbc2dc879181aTed Kremenek           I != E; ++I) {
7266253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks        CXXCtorInitializer *Init = *I;
7366253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks        if (Init->isWritten()) {
7466253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks          IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
75de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose          if (const FieldDecl *Member = Init->getAnyMember())
76de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose            IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D);
77de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose          IndexCtx.indexBody(Init->getInit(), D, D);
78de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose        }
79de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      }
80de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    }
81de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
82de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    if (D->isThisDeclarationADefinition()) {
83de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      const Stmt *Body = D->getBody();
84de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      if (Body) {
85de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose        IndexCtx.indexBody(Body, D, D);
86de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      }
87de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    }
88de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    return true;
89de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose  }
90de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
91de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose  bool VisitVarDecl(VarDecl *D) {
92de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    IndexCtx.handleVar(D);
93de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    handleDeclarator(D);
94de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    IndexCtx.indexBody(D->getInit(), D);
95de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    return true;
96de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose  }
97de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
98de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose  bool VisitFieldDecl(FieldDecl *D) {
99bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    IndexCtx.handleField(D);
100bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    handleDeclarator(D);
101bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    if (D->isBitField())
102bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks      IndexCtx.indexBody(D->getBitWidth(), D);
103bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    else if (D->hasInClassInitializer())
104bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks      IndexCtx.indexBody(D->getInClassInitializer(), D);
105bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    return true;
106bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  }
107bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
108bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  bool VisitEnumConstantDecl(EnumConstantDecl *D) {
109d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    IndexCtx.handleEnumerator(D);
110bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    IndexCtx.indexBody(D->getInitExpr(), D);
111bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    return true;
112bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  }
113bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
114bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  bool VisitTypedefNameDecl(TypedefNameDecl *D) {
115bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    IndexCtx.handleTypedefName(D);
116bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
117bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    return true;
118bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks  }
119de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose
120cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  bool VisitTagDecl(TagDecl *D) {
121918ac48e315d42fed7fe856a3fce70d9d930cdcdDaniel Dunbar    // Non-free standing tags are handled in indexTypeSourceInfo.
122255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    if (D->isFreeStanding())
123255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek      IndexCtx.indexTagDecl(D);
12443dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis    return true;
12543dee220252ef0b42c5f8a3bb1eca97f84f2565fArgyrios Kyrtzidis  }
126255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek
127255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
128255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    IndexCtx.handleObjCInterface(D);
129e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman
130e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    if (D->isThisDeclarationADefinition()) {
131e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman      IndexCtx.indexTUDeclsInObjCContainer();
132d30952838421ddfb9f7e346b2ba8213889a5f789Anna Zaks      IndexCtx.indexDeclContext(D);
133255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    }
134e1718aff224e7da84720beb42a39362199ca83f3Eli Friedman    return true;
135255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek  }
136255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek
1372fa9d72d4d23ccdcd4137946e5ebafac7a04f04cTed Kremenek  bool VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
138255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    IndexCtx.handleObjCProtocol(D);
139255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek
140116f3640daee424dfcdbe55e80be5a67476be4b0Argyrios Kyrtzidis    if (D->isThisDeclarationADefinition()) {
141918ac48e315d42fed7fe856a3fce70d9d930cdcdDaniel Dunbar      IndexCtx.indexTUDeclsInObjCContainer();
142918ac48e315d42fed7fe856a3fce70d9d930cdcdDaniel Dunbar      IndexCtx.indexDeclContext(D);
143fc576514d06c46a7cac49500169411d82f38d04bTed Kremenek    }
144ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return true;
145255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek  }
146255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek
147255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek  bool VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1480caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek    const ObjCInterfaceDecl *Class = D->getClassInterface();
1490caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek    if (!Class)
1500caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek      return true;
1510caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek
1520caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek    if (Class->isImplicitInterfaceDecl())
1530caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek      IndexCtx.handleObjCInterface(Class);
1540caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek
155255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    IndexCtx.handleObjCImplementation(D);
156918ac48e315d42fed7fe856a3fce70d9d930cdcdDaniel Dunbar
1573b8a04004afa46057a9af4afbd086be71d619793Ted Kremenek    IndexCtx.indexTUDeclsInObjCContainer();
1583b8a04004afa46057a9af4afbd086be71d619793Ted Kremenek
1599b823e8e1ccb8a2cb49923bad22a80ca96f41f92Ted Kremenek    // Index the ivars first to make sure the synthesized ivars are indexed
16081fb169f42769e02c7425b23885a261c025fd5e6Anna Zaks    // before indexing the methods that can reference them.
161255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    for (ObjCImplementationDecl::ivar_iterator
162255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek           IvarI = D->ivar_begin(),
163255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek           IvarE = D->ivar_end(); IvarI != IvarE; ++IvarI) {
164b47dbcbc12430fdf3e5a5b9f59cdec5480e89e75Anna Zaks      IndexCtx.indexDecl(*IvarI);
165255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    }
166255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek    for (DeclContext::decl_iterator
1678235f9c9c8b3d1737d1c6bd57f7ba3f616b92392Anna Zaks           I = D->decls_begin(), E = D->decls_end(); I != E; ++I) {
168255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek      if (!isa<ObjCIvarDecl>(*I))
169255d4d4226b24036ceb11228fbb74286e58620f7Ted Kremenek        IndexCtx.indexDecl(*I);
17066253352131e3e7a22b3bfd0e180607aa2bfb988Anna Zaks    }
1717b99d12b4ca67fccdf5090761ba257732e954e75Zhongxing Xu
172de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    return true;
173d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  }
174d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks
175d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  bool VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
176d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    IndexCtx.handleObjCCategory(D);
177d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks
178d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    IndexCtx.indexTUDeclsInObjCContainer();
179d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    IndexCtx.indexDeclContext(D);
180d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    return true;
181d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  }
182d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks
183d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
184d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    const ObjCCategoryDecl *Cat = D->getCategoryDecl();
185d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    if (!Cat)
186d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks      return true;
187bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
188bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    IndexCtx.handleObjCCategoryImpl(D);
189bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
190de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    IndexCtx.indexTUDeclsInObjCContainer();
191de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    IndexCtx.indexDeclContext(D);
19281fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose    return true;
193978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose  }
194dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie
195978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose  bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
196978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose    // Methods associated with a property, even user-declared ones, are
197dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie    // handled when we handle the property.
198978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose    if (D->isSynthesized())
199978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose      return true;
200dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie
2017229d0011766c174beffe6a846d78f448f845b39Anna Zaks    handleObjCMethod(D);
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return true;
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
205ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  bool VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
206ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
207c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose      if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
20850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose        handleObjCMethod(MD);
20950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
21050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
21157330eed3fbe530cb05996e4a346cc5fc217c0d9Anna Zaks        handleObjCMethod(MD);
212dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie    IndexCtx.handleObjCProperty(D);
21357330eed3fbe530cb05996e4a346cc5fc217c0d9Anna Zaks    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
2147229d0011766c174beffe6a846d78f448f845b39Anna Zaks    return true;
2157229d0011766c174beffe6a846d78f448f845b39Anna Zaks  }
216dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie
217b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
2187ee8906295d56ceb84b8b3da502cdc8770509868Jordan Rose    ObjCPropertyDecl *PD = D->getPropertyDecl();
219dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie    IndexCtx.handleSynthesizedObjCProperty(D);
220b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
2216bbe1442a5f3f5f761582a9005e9edf1d49c4da2Anna Zaks    if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
222dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie      return true;
2236bbe1442a5f3f5f761582a9005e9edf1d49c4da2Anna Zaks    assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
2246a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
225dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie    if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
2267ee8906295d56ceb84b8b3da502cdc8770509868Jordan Rose      if (!IvarD->getSynthesize())
227713e07591995d761f65c7132289dce003a29870fAnna Zaks        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), 0,
228713e07591995d761f65c7132289dce003a29870fAnna Zaks                                 D->getDeclContext());
229713e07591995d761f65c7132289dce003a29870fAnna Zaks    }
230a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
231a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
232a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose      if (MD->isSynthesized())
233d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks        IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(),
234d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks                                             D->getLexicalDeclContext());
235d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks    }
236ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
237ef8225444452a1486bd721f3285301fe84643b00Stephen Hines      if (MD->isSynthesized())
238ef8225444452a1486bd721f3285301fe84643b00Stephen Hines        IndexCtx.handleSynthesizedObjCMethod(MD, D->getLocation(),
2394d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose                                             D->getLexicalDeclContext());
240dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie    }
2414d9e497a2b1eab3b1214848216050c64fc3acfd6Jordan Rose    return true;
2427959671d456c916706a5f61af609d8f1fc95decfAnna Zaks  }
243dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie
2447959671d456c916706a5f61af609d8f1fc95decfAnna Zaks  bool VisitNamespaceDecl(NamespaceDecl *D) {
245ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    IndexCtx.handleNamespace(D);
246dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie    IndexCtx.indexDeclContext(D);
247ac3a3e7a402cd349dd2b7d70cd92c5fe702ae831Anna Zaks    return true;
2488dae128d16bf98759b7a678ce3eebb613bd17109Ted Kremenek  }
249978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose
250978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose  bool VisitUsingDecl(UsingDecl *D) {
251978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose    // FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
252978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose    // we should do better.
253622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek
254de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
25548d05e6d776f4b68f3db4016eb5680ac041c2b7dTed Kremenek    for (UsingDecl::shadow_iterator
256dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie           I = D->shadow_begin(), E = D->shadow_end(); I != E; ++I) {
257dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie      IndexCtx.handleReference((*I)->getUnderlyingDecl(), D->getLocation(),
2587229d0011766c174beffe6a846d78f448f845b39Anna Zaks                               D, D->getLexicalDeclContext());
259cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    }
2607229d0011766c174beffe6a846d78f448f845b39Anna Zaks    return true;
261d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  }
262d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks
263d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks  bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
264d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    // FIXME: Parent for the following is CXIdxEntity_Unexposed with no USR,
265d130140cb7bce73b4350c5d50495443abe38418aAnna Zaks    // we should do better.
266bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks
267bfa9ab8183e2fdc74f8633d758cb0c6201314320Anna Zaks    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
26873f0563009a6715a5d3d41f664f5bfab5096d51fAnna Zaks    IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
269de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose                             D->getLocation(), D, D->getLexicalDeclContext());
270de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    return true;
271de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose  }
2725a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose
2735a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose  bool VisitClassTemplateDecl(ClassTemplateDecl *D) {
274de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose    IndexCtx.handleClassTemplate(D);
2759e28fe60bbfa5de196ce4aa396210bf10fc5c266Ted Kremenek    if (D->isThisDeclarationADefinition())
276de5277fc555551857602bd7a7e5e616274e2d4a6Jordan Rose      IndexCtx.indexDeclContext(D->getTemplatedDecl());
27757330eed3fbe530cb05996e4a346cc5fc217c0d9Anna Zaks    return true;
278622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek  }
27957330eed3fbe530cb05996e4a346cc5fc217c0d9Anna Zaks
2805a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose  bool VisitClassTemplateSpecializationDecl(
2815a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose                                           ClassTemplateSpecializationDecl *D) {
2825a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose    // FIXME: Notify subsequent callbacks if info comes from implicit
283978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose    // instantiation.
284978869aa6e31a4bc6afdf5446ffb717aad3f7d97Jordan Rose    if (D->isThisDeclarationADefinition() &&
285622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek        (IndexCtx.shouldIndexImplicitTemplateInsts() ||
2865a1ffe98b04120846a15f7105905b5f363b08635Jordan Rose         !IndexCtx.isTemplateImplicitInstantiation(D)))
28781fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose      IndexCtx.indexTagDecl(D);
28881fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose    return true;
28981fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose  }
29081fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose
29181fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose  bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
292622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek    IndexCtx.handleFunctionTemplate(D);
29381fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose    FunctionDecl *FD = D->getTemplatedDecl();
29481fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose    handleDeclarator(FD, D);
29581fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose    if (FD->isThisDeclarationADefinition()) {
29681fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose      const Stmt *Body = FD->getBody();
29781fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose      if (Body) {
298622b6fb0a1d280c16e135c7e427b79cafffbde1fTed Kremenek        IndexCtx.indexBody(Body, D, FD);
29981fb50e8b120fc95dc0245b4112972d4d7cca3b5Jordan Rose      }
300651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
301651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return true;
302651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
303651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
304651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    IndexCtx.handleTypeAliasTemplate(D);
306ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    IndexCtx.indexTypeSourceInfo(D->getTemplatedDecl()->getTypeSourceInfo(), D);
307ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    return true;
308c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose  }
309c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose
310c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose  bool VisitImportDecl(ImportDecl *D) {
311ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Module *Imported = D->getImportedModule();
312c63a460d78a7625ff38d2b3580f78030c44f07dbJordan Rose    if (Imported)
31350fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose      IndexCtx.importedModule(D->getLocation(), Imported->getFullModuleName(),
31450fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose                              /*isIncludeDirective=*/false, Imported);
31550fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose    return true;
31650fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  }
31750fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose};
31850fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
31950fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose} // anonymous namespace
32050fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose
32150fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rosevoid IndexingContext::indexDecl(const Decl *D) {
32250fa64d4411a42e0b4f373a84d8d4f5cbf339ea3Jordan Rose  if (D->isImplicit() && shouldIgnoreIfImplicit(D))
323b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    return;
324b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
325b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  bool Handled = IndexingDeclVisitor(*this).Visit(const_cast<Decl*>(D));
326b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  if (!Handled && isa<DeclContext>(D))
327b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    indexDeclContext(cast<DeclContext>(D));
328b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose}
329b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
330b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rosevoid IndexingContext::indexDeclContext(const DeclContext *DC) {
3317ee8906295d56ceb84b8b3da502cdc8770509868Jordan Rose  for (DeclContext::decl_iterator
332b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose         I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
3336a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    indexDecl(*I);
3346a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  }
3356a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose}
3367ee8906295d56ceb84b8b3da502cdc8770509868Jordan Rose
3376a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rosevoid IndexingContext::indexTopLevelDecl(const Decl *D) {
3386a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  if (isNotFromSourceFile(D->getLocation()))
3396a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    return;
3406a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
3416a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  if (isa<ObjCMethodDecl>(D))
3426a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    return; // Wait for the objc container.
3436a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
344713e07591995d761f65c7132289dce003a29870fAnna Zaks  indexDecl(D);
345713e07591995d761f65c7132289dce003a29870fAnna Zaks}
346713e07591995d761f65c7132289dce003a29870fAnna Zaks
347713e07591995d761f65c7132289dce003a29870fAnna Zaksvoid IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
348713e07591995d761f65c7132289dce003a29870fAnna Zaks  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
349713e07591995d761f65c7132289dce003a29870fAnna Zaks    indexTopLevelDecl(*I);
350713e07591995d761f65c7132289dce003a29870fAnna Zaks}
351a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
352a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rosevoid IndexingContext::indexTUDeclsInObjCContainer() {
353a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  while (!TUDeclsInObjCContainer.empty()) {
354a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    DeclGroupRef DG = TUDeclsInObjCContainer.front();
355a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    TUDeclsInObjCContainer.pop_front();
356a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    indexDeclGroupRef(DG);
357a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  }
358d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks}
359d95b70175646829c26344d5f0bda1ec3009f2a5bAnna Zaks