IndexDecl.cpp 31 KB

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