IndexDecl.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. //===- IndexDecl.cpp - Indexing declarations ------------------------------===//
  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. #include "IndexingContext.h"
  10. #include "clang/Index/IndexDataConsumer.h"
  11. #include "clang/AST/DeclVisitor.h"
  12. using namespace clang;
  13. using namespace index;
  14. #define TRY_DECL(D,CALL_EXPR) \
  15. do { \
  16. if (!IndexCtx.shouldIndex(D)) return true; \
  17. if (!CALL_EXPR) \
  18. return false; \
  19. } while (0)
  20. #define TRY_TO(CALL_EXPR) \
  21. do { \
  22. if (!CALL_EXPR) \
  23. return false; \
  24. } while (0)
  25. namespace {
  26. class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
  27. IndexingContext &IndexCtx;
  28. public:
  29. explicit IndexingDeclVisitor(IndexingContext &indexCtx)
  30. : IndexCtx(indexCtx) { }
  31. bool Handled = true;
  32. bool VisitDecl(const Decl *D) {
  33. Handled = false;
  34. return true;
  35. }
  36. /// \brief Returns true if the given method has been defined explicitly by the
  37. /// user.
  38. static bool hasUserDefined(const ObjCMethodDecl *D,
  39. const ObjCImplDecl *Container) {
  40. const ObjCMethodDecl *MD = Container->getMethod(D->getSelector(),
  41. D->isInstanceMethod());
  42. return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
  43. }
  44. void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
  45. const NamedDecl *Parent,
  46. const DeclContext *DC) {
  47. const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
  48. switch (TALoc.getArgument().getKind()) {
  49. case TemplateArgument::Expression:
  50. IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
  51. break;
  52. case TemplateArgument::Type:
  53. IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
  54. break;
  55. case TemplateArgument::Template:
  56. case TemplateArgument::TemplateExpansion:
  57. IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(),
  58. Parent, DC);
  59. if (const TemplateDecl *TD = TALoc.getArgument()
  60. .getAsTemplateOrTemplatePattern()
  61. .getAsTemplateDecl()) {
  62. if (const NamedDecl *TTD = TD->getTemplatedDecl())
  63. IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
  64. }
  65. break;
  66. default:
  67. break;
  68. }
  69. }
  70. void handleDeclarator(const DeclaratorDecl *D,
  71. const NamedDecl *Parent = nullptr,
  72. bool isIBType = false) {
  73. if (!Parent) Parent = D;
  74. IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), Parent,
  75. Parent->getLexicalDeclContext(),
  76. /*isBase=*/false, isIBType);
  77. IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent);
  78. if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
  79. // Only index parameters in definitions, parameters in declarations are
  80. // not useful.
  81. if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
  82. auto *DC = Parm->getDeclContext();
  83. if (auto *FD = dyn_cast<FunctionDecl>(DC)) {
  84. if (FD->isThisDeclarationADefinition())
  85. IndexCtx.handleDecl(Parm);
  86. } else if (auto *MD = dyn_cast<ObjCMethodDecl>(DC)) {
  87. if (MD->isThisDeclarationADefinition())
  88. IndexCtx.handleDecl(Parm);
  89. } else {
  90. IndexCtx.handleDecl(Parm);
  91. }
  92. } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
  93. if (FD->isThisDeclarationADefinition()) {
  94. for (auto PI : FD->parameters()) {
  95. IndexCtx.handleDecl(PI);
  96. }
  97. }
  98. }
  99. } else {
  100. // Index the default parameter value for function definitions.
  101. if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
  102. if (FD->isThisDeclarationADefinition()) {
  103. for (const auto *PV : FD->parameters()) {
  104. if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
  105. !PV->hasUnparsedDefaultArg())
  106. IndexCtx.indexBody(PV->getDefaultArg(), D);
  107. }
  108. }
  109. }
  110. }
  111. }
  112. bool handleObjCMethod(const ObjCMethodDecl *D,
  113. const ObjCPropertyDecl *AssociatedProp = nullptr) {
  114. SmallVector<SymbolRelation, 4> Relations;
  115. SmallVector<const ObjCMethodDecl*, 4> Overriden;
  116. D->getOverriddenMethods(Overriden);
  117. for(auto overridden: Overriden) {
  118. Relations.emplace_back((unsigned) SymbolRole::RelationOverrideOf,
  119. overridden);
  120. }
  121. if (AssociatedProp)
  122. Relations.emplace_back((unsigned)SymbolRole::RelationAccessorOf,
  123. AssociatedProp);
  124. // getLocation() returns beginning token of a method declaration, but for
  125. // indexing purposes we want to point to the base name.
  126. SourceLocation MethodLoc = D->getSelectorStartLoc();
  127. if (MethodLoc.isInvalid())
  128. MethodLoc = D->getLocation();
  129. SourceLocation AttrLoc;
  130. // check for (getter=/setter=)
  131. if (AssociatedProp) {
  132. bool isGetter = !D->param_size();
  133. AttrLoc = isGetter ?
  134. AssociatedProp->getGetterNameLoc():
  135. AssociatedProp->getSetterNameLoc();
  136. }
  137. SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
  138. if (D->isImplicit()) {
  139. if (AttrLoc.isValid()) {
  140. MethodLoc = AttrLoc;
  141. } else {
  142. Roles |= (SymbolRoleSet)SymbolRole::Implicit;
  143. }
  144. } else if (AttrLoc.isValid()) {
  145. IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
  146. D->getDeclContext(), 0);
  147. }
  148. TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
  149. IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
  150. bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
  151. for (const auto *I : D->parameters()) {
  152. handleDeclarator(I, D, /*isIBType=*/hasIBActionAndFirst);
  153. hasIBActionAndFirst = false;
  154. }
  155. if (D->isThisDeclarationADefinition()) {
  156. const Stmt *Body = D->getBody();
  157. if (Body) {
  158. IndexCtx.indexBody(Body, D, D);
  159. }
  160. }
  161. return true;
  162. }
  163. /// Gather the declarations which the given declaration \D overrides in a
  164. /// pseudo-override manner.
  165. ///
  166. /// Pseudo-overrides occur when a class template specialization declares
  167. /// a declaration that has the same name as a similar declaration in the
  168. /// non-specialized template.
  169. void
  170. gatherTemplatePseudoOverrides(const NamedDecl *D,
  171. SmallVectorImpl<SymbolRelation> &Relations) {
  172. if (!IndexCtx.getLangOpts().CPlusPlus)
  173. return;
  174. const auto *CTSD =
  175. dyn_cast<ClassTemplateSpecializationDecl>(D->getLexicalDeclContext());
  176. if (!CTSD)
  177. return;
  178. llvm::PointerUnion<ClassTemplateDecl *,
  179. ClassTemplatePartialSpecializationDecl *>
  180. Template = CTSD->getSpecializedTemplateOrPartial();
  181. if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
  182. const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
  183. bool TypeOverride = isa<TypeDecl>(D);
  184. for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
  185. if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
  186. ND = CTD->getTemplatedDecl();
  187. if (ND->isImplicit())
  188. continue;
  189. // Types can override other types.
  190. if (!TypeOverride) {
  191. if (ND->getKind() != D->getKind())
  192. continue;
  193. } else if (!isa<TypeDecl>(ND))
  194. continue;
  195. if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
  196. const auto *DFD = cast<FunctionDecl>(D);
  197. // Function overrides are approximated using the number of parameters.
  198. if (FD->getStorageClass() != DFD->getStorageClass() ||
  199. FD->getNumParams() != DFD->getNumParams())
  200. continue;
  201. }
  202. Relations.emplace_back(
  203. SymbolRoleSet(SymbolRole::RelationSpecializationOf), ND);
  204. }
  205. }
  206. }
  207. bool VisitFunctionDecl(const FunctionDecl *D) {
  208. SymbolRoleSet Roles{};
  209. SmallVector<SymbolRelation, 4> Relations;
  210. if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
  211. if (CXXMD->isVirtual())
  212. Roles |= (unsigned)SymbolRole::Dynamic;
  213. for (auto I = CXXMD->begin_overridden_methods(),
  214. E = CXXMD->end_overridden_methods(); I != E; ++I) {
  215. Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I);
  216. }
  217. }
  218. gatherTemplatePseudoOverrides(D, Relations);
  219. if (const auto *Base = D->getPrimaryTemplate())
  220. Relations.push_back(
  221. SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
  222. Base->getTemplatedDecl()));
  223. TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
  224. handleDeclarator(D);
  225. if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
  226. IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
  227. Ctor->getParent(), Ctor->getDeclContext());
  228. // Constructor initializers.
  229. for (const auto *Init : Ctor->inits()) {
  230. if (Init->isWritten()) {
  231. IndexCtx.indexTypeSourceInfo(Init->getTypeSourceInfo(), D);
  232. if (const FieldDecl *Member = Init->getAnyMember())
  233. IndexCtx.handleReference(Member, Init->getMemberLocation(), D, D,
  234. (unsigned)SymbolRole::Write);
  235. IndexCtx.indexBody(Init->getInit(), D, D);
  236. }
  237. }
  238. } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
  239. if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
  240. IndexCtx.handleReference(Dtor->getParent(),
  241. TypeNameInfo->getTypeLoc().getLocStart(),
  242. Dtor->getParent(), Dtor->getDeclContext());
  243. }
  244. }
  245. // Template specialization arguments.
  246. if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
  247. D->getTemplateSpecializationArgsAsWritten()) {
  248. for (const auto &Arg : TemplateArgInfo->arguments())
  249. handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
  250. }
  251. if (D->isThisDeclarationADefinition()) {
  252. const Stmt *Body = D->getBody();
  253. if (Body) {
  254. IndexCtx.indexBody(Body, D, D);
  255. }
  256. }
  257. return true;
  258. }
  259. bool VisitVarDecl(const VarDecl *D) {
  260. SmallVector<SymbolRelation, 4> Relations;
  261. gatherTemplatePseudoOverrides(D, Relations);
  262. TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
  263. handleDeclarator(D);
  264. IndexCtx.indexBody(D->getInit(), D);
  265. return true;
  266. }
  267. bool VisitDecompositionDecl(const DecompositionDecl *D) {
  268. for (const auto *Binding : D->bindings())
  269. TRY_DECL(Binding, IndexCtx.handleDecl(Binding));
  270. return Base::VisitDecompositionDecl(D);
  271. }
  272. bool VisitFieldDecl(const FieldDecl *D) {
  273. SmallVector<SymbolRelation, 4> Relations;
  274. gatherTemplatePseudoOverrides(D, Relations);
  275. TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
  276. handleDeclarator(D);
  277. if (D->isBitField())
  278. IndexCtx.indexBody(D->getBitWidth(), D);
  279. else if (D->hasInClassInitializer())
  280. IndexCtx.indexBody(D->getInClassInitializer(), D);
  281. return true;
  282. }
  283. bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
  284. if (D->getSynthesize()) {
  285. // handled in VisitObjCPropertyImplDecl
  286. return true;
  287. }
  288. TRY_DECL(D, IndexCtx.handleDecl(D));
  289. handleDeclarator(D);
  290. return true;
  291. }
  292. bool VisitMSPropertyDecl(const MSPropertyDecl *D) {
  293. handleDeclarator(D);
  294. return true;
  295. }
  296. bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
  297. TRY_DECL(D, IndexCtx.handleDecl(D));
  298. IndexCtx.indexBody(D->getInitExpr(), D);
  299. return true;
  300. }
  301. bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
  302. if (!D->isTransparentTag()) {
  303. SmallVector<SymbolRelation, 4> Relations;
  304. gatherTemplatePseudoOverrides(D, Relations);
  305. TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
  306. IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
  307. }
  308. return true;
  309. }
  310. bool VisitTagDecl(const TagDecl *D) {
  311. // Non-free standing tags are handled in indexTypeSourceInfo.
  312. if (D->isFreeStanding()) {
  313. if (D->isThisDeclarationADefinition()) {
  314. SmallVector<SymbolRelation, 4> Relations;
  315. gatherTemplatePseudoOverrides(D, Relations);
  316. IndexCtx.indexTagDecl(D, Relations);
  317. } else {
  318. auto *Parent = dyn_cast<NamedDecl>(D->getDeclContext());
  319. SmallVector<SymbolRelation, 1> Relations;
  320. gatherTemplatePseudoOverrides(D, Relations);
  321. return IndexCtx.handleReference(D, D->getLocation(), Parent,
  322. D->getLexicalDeclContext(),
  323. SymbolRoleSet(), Relations);
  324. }
  325. }
  326. return true;
  327. }
  328. bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
  329. const ObjCContainerDecl *ContD,
  330. SourceLocation SuperLoc) {
  331. ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
  332. for (ObjCInterfaceDecl::protocol_iterator
  333. I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
  334. SourceLocation Loc = *LI;
  335. ObjCProtocolDecl *PD = *I;
  336. SymbolRoleSet roles{};
  337. if (Loc == SuperLoc)
  338. roles |= (SymbolRoleSet)SymbolRole::Implicit;
  339. TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
  340. SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
  341. }
  342. return true;
  343. }
  344. bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
  345. if (D->isThisDeclarationADefinition()) {
  346. TRY_DECL(D, IndexCtx.handleDecl(D));
  347. SourceLocation SuperLoc = D->getSuperClassLoc();
  348. if (auto *SuperD = D->getSuperClass()) {
  349. bool hasSuperTypedef = false;
  350. if (auto *TInfo = D->getSuperClassTInfo()) {
  351. if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
  352. if (auto *TD = TT->getDecl()) {
  353. hasSuperTypedef = true;
  354. TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
  355. SymbolRoleSet()));
  356. }
  357. }
  358. }
  359. SymbolRoleSet superRoles{};
  360. if (hasSuperTypedef)
  361. superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
  362. TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
  363. SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
  364. }
  365. TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
  366. SuperLoc));
  367. TRY_TO(IndexCtx.indexDeclContext(D));
  368. } else {
  369. return IndexCtx.handleReference(D, D->getLocation(), nullptr,
  370. D->getDeclContext(), SymbolRoleSet());
  371. }
  372. return true;
  373. }
  374. bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
  375. if (D->isThisDeclarationADefinition()) {
  376. TRY_DECL(D, IndexCtx.handleDecl(D));
  377. TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
  378. /*superLoc=*/SourceLocation()));
  379. TRY_TO(IndexCtx.indexDeclContext(D));
  380. } else {
  381. return IndexCtx.handleReference(D, D->getLocation(), nullptr,
  382. D->getDeclContext(), SymbolRoleSet());
  383. }
  384. return true;
  385. }
  386. bool VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
  387. const ObjCInterfaceDecl *Class = D->getClassInterface();
  388. if (!Class)
  389. return true;
  390. if (Class->isImplicitInterfaceDecl())
  391. IndexCtx.handleDecl(Class);
  392. TRY_DECL(D, IndexCtx.handleDecl(D));
  393. // Visit implicit @synthesize property implementations first as their
  394. // location is reported at the name of the @implementation block. This
  395. // serves no purpose other than to simplify the FileCheck-based tests.
  396. for (const auto *I : D->property_impls()) {
  397. if (I->getLocation().isInvalid())
  398. IndexCtx.indexDecl(I);
  399. }
  400. for (const auto *I : D->decls()) {
  401. if (!isa<ObjCPropertyImplDecl>(I) ||
  402. cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
  403. IndexCtx.indexDecl(I);
  404. }
  405. return true;
  406. }
  407. bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
  408. if (!IndexCtx.shouldIndex(D))
  409. return true;
  410. const ObjCInterfaceDecl *C = D->getClassInterface();
  411. if (!C)
  412. return true;
  413. TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D, SymbolRoleSet(),
  414. SymbolRelation{
  415. (unsigned)SymbolRole::RelationExtendedBy, D
  416. }));
  417. SourceLocation CategoryLoc = D->getCategoryNameLoc();
  418. if (!CategoryLoc.isValid())
  419. CategoryLoc = D->getLocation();
  420. TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
  421. TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
  422. /*superLoc=*/SourceLocation()));
  423. TRY_TO(IndexCtx.indexDeclContext(D));
  424. return true;
  425. }
  426. bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
  427. const ObjCCategoryDecl *Cat = D->getCategoryDecl();
  428. if (!Cat)
  429. return true;
  430. const ObjCInterfaceDecl *C = D->getClassInterface();
  431. if (C)
  432. TRY_TO(IndexCtx.handleReference(C, D->getLocation(), D, D,
  433. SymbolRoleSet()));
  434. SourceLocation CategoryLoc = D->getCategoryNameLoc();
  435. if (!CategoryLoc.isValid())
  436. CategoryLoc = D->getLocation();
  437. TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
  438. IndexCtx.indexDeclContext(D);
  439. return true;
  440. }
  441. bool VisitObjCMethodDecl(const ObjCMethodDecl *D) {
  442. // Methods associated with a property, even user-declared ones, are
  443. // handled when we handle the property.
  444. if (D->isPropertyAccessor())
  445. return true;
  446. handleObjCMethod(D);
  447. return true;
  448. }
  449. bool VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
  450. if (ObjCMethodDecl *MD = D->getGetterMethodDecl())
  451. if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
  452. handleObjCMethod(MD, D);
  453. if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
  454. if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
  455. handleObjCMethod(MD, D);
  456. TRY_DECL(D, IndexCtx.handleDecl(D));
  457. if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
  458. IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
  459. D->getLexicalDeclContext(), false, true);
  460. IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
  461. return true;
  462. }
  463. bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
  464. ObjCPropertyDecl *PD = D->getPropertyDecl();
  465. auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
  466. SourceLocation Loc = D->getLocation();
  467. SymbolRoleSet Roles = 0;
  468. SmallVector<SymbolRelation, 1> Relations;
  469. if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
  470. Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
  471. if (Loc.isInvalid()) {
  472. Loc = Container->getLocation();
  473. Roles |= (SymbolRoleSet)SymbolRole::Implicit;
  474. }
  475. TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
  476. if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
  477. return true;
  478. assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
  479. SymbolRoleSet AccessorMethodRoles =
  480. SymbolRoleSet(SymbolRole::Dynamic) | SymbolRoleSet(SymbolRole::Implicit);
  481. if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
  482. if (MD->isPropertyAccessor() &&
  483. !hasUserDefined(MD, Container))
  484. IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
  485. }
  486. if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
  487. if (MD->isPropertyAccessor() &&
  488. !hasUserDefined(MD, Container))
  489. IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
  490. }
  491. if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
  492. if (IvarD->getSynthesize()) {
  493. // For synthesized ivars, use the location of its name in the
  494. // corresponding @synthesize. If there isn't one, use the containing
  495. // @implementation's location, rather than the property's location,
  496. // otherwise the header file containing the @interface will have different
  497. // indexing contents based on whether the @implementation was present or
  498. // not in the translation unit.
  499. SymbolRoleSet IvarRoles = 0;
  500. SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
  501. if (D->getLocation().isInvalid()) {
  502. IvarLoc = Container->getLocation();
  503. IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
  504. } else if (D->getLocation() == IvarLoc) {
  505. IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
  506. }
  507. TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
  508. } else {
  509. IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
  510. D->getDeclContext(), SymbolRoleSet());
  511. }
  512. }
  513. return true;
  514. }
  515. bool VisitNamespaceDecl(const NamespaceDecl *D) {
  516. TRY_DECL(D, IndexCtx.handleDecl(D));
  517. IndexCtx.indexDeclContext(D);
  518. return true;
  519. }
  520. bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
  521. TRY_DECL(D, IndexCtx.handleDecl(D));
  522. IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
  523. IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D,
  524. D->getLexicalDeclContext());
  525. return true;
  526. }
  527. bool VisitUsingDecl(const UsingDecl *D) {
  528. const DeclContext *DC = D->getDeclContext()->getRedeclContext();
  529. const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
  530. IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
  531. D->getLexicalDeclContext());
  532. for (const auto *I : D->shadows())
  533. IndexCtx.handleReference(I->getUnderlyingDecl(), D->getLocation(), Parent,
  534. D->getLexicalDeclContext(), SymbolRoleSet());
  535. return true;
  536. }
  537. bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
  538. const DeclContext *DC = D->getDeclContext()->getRedeclContext();
  539. const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
  540. // NNS for the local 'using namespace' directives is visited by the body
  541. // visitor.
  542. if (!D->getParentFunctionOrMethod())
  543. IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
  544. D->getLexicalDeclContext());
  545. return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
  546. D->getLocation(), Parent,
  547. D->getLexicalDeclContext(),
  548. SymbolRoleSet());
  549. }
  550. bool VisitClassTemplateSpecializationDecl(const
  551. ClassTemplateSpecializationDecl *D) {
  552. // FIXME: Notify subsequent callbacks if info comes from implicit
  553. // instantiation.
  554. llvm::PointerUnion<ClassTemplateDecl *,
  555. ClassTemplatePartialSpecializationDecl *>
  556. Template = D->getSpecializedTemplateOrPartial();
  557. const Decl *SpecializationOf =
  558. Template.is<ClassTemplateDecl *>()
  559. ? (Decl *)Template.get<ClassTemplateDecl *>()
  560. : Template.get<ClassTemplatePartialSpecializationDecl *>();
  561. IndexCtx.indexTagDecl(
  562. D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
  563. SpecializationOf));
  564. if (TypeSourceInfo *TSI = D->getTypeAsWritten())
  565. IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
  566. D->getLexicalDeclContext());
  567. return true;
  568. }
  569. static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
  570. if (!D)
  571. return false;
  572. // We want to index the template parameters only once when indexing the
  573. // canonical declaration.
  574. if (const auto *FD = dyn_cast<FunctionDecl>(D))
  575. return FD->getCanonicalDecl() == FD;
  576. else if (const auto *TD = dyn_cast<TagDecl>(D))
  577. return TD->getCanonicalDecl() == TD;
  578. else if (const auto *VD = dyn_cast<VarDecl>(D))
  579. return VD->getCanonicalDecl() == VD;
  580. return true;
  581. }
  582. bool VisitTemplateDecl(const TemplateDecl *D) {
  583. // FIXME: Template parameters.
  584. // Index the default values for the template parameters.
  585. const NamedDecl *Parent = D->getTemplatedDecl();
  586. if (D->getTemplateParameters() &&
  587. shouldIndexTemplateParameterDefaultValue(Parent)) {
  588. const TemplateParameterList *Params = D->getTemplateParameters();
  589. for (const NamedDecl *TP : *Params) {
  590. if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
  591. if (TTP->hasDefaultArgument())
  592. IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
  593. } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
  594. if (NTTP->hasDefaultArgument())
  595. IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
  596. } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
  597. if (TTPD->hasDefaultArgument())
  598. handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
  599. /*DC=*/nullptr);
  600. }
  601. }
  602. }
  603. return Visit(D->getTemplatedDecl());
  604. }
  605. bool VisitFriendDecl(const FriendDecl *D) {
  606. if (auto ND = D->getFriendDecl()) {
  607. // FIXME: Ignore a class template in a dependent context, these are not
  608. // linked properly with their redeclarations, ending up with duplicate
  609. // USRs.
  610. // See comment "Friend templates are visible in fairly strange ways." in
  611. // SemaTemplate.cpp which precedes code that prevents the friend template
  612. // from becoming visible from the enclosing context.
  613. if (isa<ClassTemplateDecl>(ND) && D->getDeclContext()->isDependentContext())
  614. return true;
  615. return Visit(ND);
  616. }
  617. if (auto Ty = D->getFriendType()) {
  618. IndexCtx.indexTypeSourceInfo(Ty, cast<NamedDecl>(D->getDeclContext()));
  619. }
  620. return true;
  621. }
  622. bool VisitImportDecl(const ImportDecl *D) {
  623. return IndexCtx.importedModule(D);
  624. }
  625. bool VisitStaticAssertDecl(const StaticAssertDecl *D) {
  626. IndexCtx.indexBody(D->getAssertExpr(),
  627. dyn_cast<NamedDecl>(D->getDeclContext()),
  628. D->getLexicalDeclContext());
  629. return true;
  630. }
  631. };
  632. } // anonymous namespace
  633. bool IndexingContext::indexDecl(const Decl *D) {
  634. if (D->isImplicit() && shouldIgnoreIfImplicit(D))
  635. return true;
  636. if (isTemplateImplicitInstantiation(D))
  637. return true;
  638. IndexingDeclVisitor Visitor(*this);
  639. bool ShouldContinue = Visitor.Visit(D);
  640. if (!ShouldContinue)
  641. return false;
  642. if (!Visitor.Handled && isa<DeclContext>(D))
  643. return indexDeclContext(cast<DeclContext>(D));
  644. return true;
  645. }
  646. bool IndexingContext::indexDeclContext(const DeclContext *DC) {
  647. for (const auto *I : DC->decls())
  648. if (!indexDecl(I))
  649. return false;
  650. return true;
  651. }
  652. bool IndexingContext::indexTopLevelDecl(const Decl *D) {
  653. if (D->getLocation().isInvalid())
  654. return true;
  655. if (isa<ObjCMethodDecl>(D))
  656. return true; // Wait for the objc container.
  657. return indexDecl(D);
  658. }
  659. bool IndexingContext::indexDeclGroupRef(DeclGroupRef DG) {
  660. for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
  661. if (!indexTopLevelDecl(*I))
  662. return false;
  663. return true;
  664. }