IndexDecl.cpp 30 KB

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