IndexDecl.cpp 29 KB

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