IndexBody.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. //===- IndexBody.cpp - Indexing statements --------------------------------===//
  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/ASTLambda.h"
  11. #include "clang/AST/DeclCXX.h"
  12. #include "clang/AST/ExprConcepts.h"
  13. #include "clang/AST/RecursiveASTVisitor.h"
  14. #include "clang/AST/Type.h"
  15. using namespace clang;
  16. using namespace clang::index;
  17. namespace {
  18. class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
  19. IndexingContext &IndexCtx;
  20. const NamedDecl *Parent;
  21. const DeclContext *ParentDC;
  22. SmallVector<Stmt*, 16> StmtStack;
  23. typedef RecursiveASTVisitor<BodyIndexer> base;
  24. Stmt *getParentStmt() const {
  25. return StmtStack.size() < 2 ? nullptr : StmtStack.end()[-2];
  26. }
  27. public:
  28. BodyIndexer(IndexingContext &indexCtx,
  29. const NamedDecl *Parent, const DeclContext *DC)
  30. : IndexCtx(indexCtx), Parent(Parent), ParentDC(DC) { }
  31. bool shouldWalkTypesOfTypeLocs() const { return false; }
  32. bool dataTraverseStmtPre(Stmt *S) {
  33. StmtStack.push_back(S);
  34. return true;
  35. }
  36. bool dataTraverseStmtPost(Stmt *S) {
  37. assert(StmtStack.back() == S);
  38. StmtStack.pop_back();
  39. return true;
  40. }
  41. bool TraverseTypeLoc(TypeLoc TL) {
  42. IndexCtx.indexTypeLoc(TL, Parent, ParentDC);
  43. return true;
  44. }
  45. bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
  46. IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
  47. return true;
  48. }
  49. SymbolRoleSet getRolesForRef(const Expr *E,
  50. SmallVectorImpl<SymbolRelation> &Relations) {
  51. SymbolRoleSet Roles{};
  52. assert(!StmtStack.empty() && E == StmtStack.back());
  53. if (StmtStack.size() == 1)
  54. return Roles;
  55. auto It = StmtStack.end()-2;
  56. while (isa<CastExpr>(*It) || isa<ParenExpr>(*It)) {
  57. if (auto ICE = dyn_cast<ImplicitCastExpr>(*It)) {
  58. if (ICE->getCastKind() == CK_LValueToRValue)
  59. Roles |= (unsigned)(unsigned)SymbolRole::Read;
  60. }
  61. if (It == StmtStack.begin())
  62. break;
  63. --It;
  64. }
  65. const Stmt *Parent = *It;
  66. if (auto BO = dyn_cast<BinaryOperator>(Parent)) {
  67. if (BO->getOpcode() == BO_Assign && BO->getLHS()->IgnoreParenCasts() == E)
  68. Roles |= (unsigned)SymbolRole::Write;
  69. } else if (auto UO = dyn_cast<UnaryOperator>(Parent)) {
  70. if (UO->isIncrementDecrementOp()) {
  71. Roles |= (unsigned)SymbolRole::Read;
  72. Roles |= (unsigned)SymbolRole::Write;
  73. } else if (UO->getOpcode() == UO_AddrOf) {
  74. Roles |= (unsigned)SymbolRole::AddressOf;
  75. }
  76. } else if (auto CA = dyn_cast<CompoundAssignOperator>(Parent)) {
  77. if (CA->getLHS()->IgnoreParenCasts() == E) {
  78. Roles |= (unsigned)SymbolRole::Read;
  79. Roles |= (unsigned)SymbolRole::Write;
  80. }
  81. } else if (auto CE = dyn_cast<CallExpr>(Parent)) {
  82. if (CE->getCallee()->IgnoreParenCasts() == E) {
  83. addCallRole(Roles, Relations);
  84. if (auto *ME = dyn_cast<MemberExpr>(E)) {
  85. if (auto *CXXMD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
  86. if (CXXMD->isVirtual() && !ME->hasQualifier()) {
  87. Roles |= (unsigned)SymbolRole::Dynamic;
  88. auto BaseTy = ME->getBase()->IgnoreImpCasts()->getType();
  89. if (!BaseTy.isNull())
  90. if (auto *CXXRD = BaseTy->getPointeeCXXRecordDecl())
  91. Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
  92. CXXRD);
  93. }
  94. }
  95. } else if (auto CXXOp = dyn_cast<CXXOperatorCallExpr>(CE)) {
  96. if (CXXOp->getNumArgs() > 0 && CXXOp->getArg(0)->IgnoreParenCasts() == E) {
  97. OverloadedOperatorKind Op = CXXOp->getOperator();
  98. if (Op == OO_Equal) {
  99. Roles |= (unsigned)SymbolRole::Write;
  100. } else if ((Op >= OO_PlusEqual && Op <= OO_PipeEqual) ||
  101. Op == OO_LessLessEqual || Op == OO_GreaterGreaterEqual ||
  102. Op == OO_PlusPlus || Op == OO_MinusMinus) {
  103. Roles |= (unsigned)SymbolRole::Read;
  104. Roles |= (unsigned)SymbolRole::Write;
  105. } else if (Op == OO_Amp) {
  106. Roles |= (unsigned)SymbolRole::AddressOf;
  107. }
  108. }
  109. }
  110. }
  111. return Roles;
  112. }
  113. void addCallRole(SymbolRoleSet &Roles,
  114. SmallVectorImpl<SymbolRelation> &Relations) {
  115. Roles |= (unsigned)SymbolRole::Call;
  116. if (auto *FD = dyn_cast<FunctionDecl>(ParentDC))
  117. Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, FD);
  118. else if (auto *MD = dyn_cast<ObjCMethodDecl>(ParentDC))
  119. Relations.emplace_back((unsigned)SymbolRole::RelationCalledBy, MD);
  120. }
  121. bool VisitDeclRefExpr(DeclRefExpr *E) {
  122. SmallVector<SymbolRelation, 4> Relations;
  123. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  124. return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
  125. Parent, ParentDC, Roles, Relations, E);
  126. }
  127. bool VisitMemberExpr(MemberExpr *E) {
  128. SourceLocation Loc = E->getMemberLoc();
  129. if (Loc.isInvalid())
  130. Loc = E->getBeginLoc();
  131. SmallVector<SymbolRelation, 4> Relations;
  132. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  133. return IndexCtx.handleReference(E->getMemberDecl(), Loc,
  134. Parent, ParentDC, Roles, Relations, E);
  135. }
  136. bool indexDependentReference(
  137. const Expr *E, const Type *T, const DeclarationNameInfo &NameInfo,
  138. llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
  139. if (!T)
  140. return true;
  141. const TemplateSpecializationType *TST =
  142. T->getAs<TemplateSpecializationType>();
  143. if (!TST)
  144. return true;
  145. TemplateName TN = TST->getTemplateName();
  146. const ClassTemplateDecl *TD =
  147. dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
  148. if (!TD)
  149. return true;
  150. CXXRecordDecl *RD = TD->getTemplatedDecl();
  151. if (!RD->hasDefinition())
  152. return true;
  153. RD = RD->getDefinition();
  154. std::vector<const NamedDecl *> Symbols =
  155. RD->lookupDependentName(NameInfo.getName(), Filter);
  156. // FIXME: Improve overload handling.
  157. if (Symbols.size() != 1)
  158. return true;
  159. SourceLocation Loc = NameInfo.getLoc();
  160. if (Loc.isInvalid())
  161. Loc = E->getBeginLoc();
  162. SmallVector<SymbolRelation, 4> Relations;
  163. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  164. return IndexCtx.handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
  165. Relations, E);
  166. }
  167. bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
  168. const DeclarationNameInfo &Info = E->getMemberNameInfo();
  169. return indexDependentReference(
  170. E, E->getBaseType().getTypePtrOrNull(), Info,
  171. [](const NamedDecl *D) { return D->isCXXInstanceMember(); });
  172. }
  173. bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
  174. const DeclarationNameInfo &Info = E->getNameInfo();
  175. const NestedNameSpecifier *NNS = E->getQualifier();
  176. return indexDependentReference(
  177. E, NNS->getAsType(), Info,
  178. [](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
  179. }
  180. bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
  181. for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
  182. if (D.isFieldDesignator() && D.getField())
  183. return IndexCtx.handleReference(D.getField(), D.getFieldLoc(), Parent,
  184. ParentDC, SymbolRoleSet(), {}, E);
  185. }
  186. return true;
  187. }
  188. bool VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
  189. SmallVector<SymbolRelation, 4> Relations;
  190. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  191. return IndexCtx.handleReference(E->getDecl(), E->getLocation(),
  192. Parent, ParentDC, Roles, Relations, E);
  193. }
  194. bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
  195. auto isDynamic = [](const ObjCMessageExpr *MsgE)->bool {
  196. if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
  197. return false;
  198. if (auto *RecE = dyn_cast<ObjCMessageExpr>(
  199. MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
  200. if (RecE->getMethodFamily() == OMF_alloc)
  201. return false;
  202. }
  203. return true;
  204. };
  205. if (ObjCMethodDecl *MD = E->getMethodDecl()) {
  206. SymbolRoleSet Roles{};
  207. SmallVector<SymbolRelation, 2> Relations;
  208. addCallRole(Roles, Relations);
  209. Stmt *Containing = getParentStmt();
  210. auto IsImplicitProperty = [](const PseudoObjectExpr *POE) -> bool {
  211. const auto *E = POE->getSyntacticForm();
  212. if (const auto *BinOp = dyn_cast<BinaryOperator>(E))
  213. E = BinOp->getLHS();
  214. const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E);
  215. if (!PRE)
  216. return false;
  217. if (PRE->isExplicitProperty())
  218. return false;
  219. if (const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) {
  220. // Class properties that are explicitly defined using @property
  221. // declarations are represented implicitly as there is no ivar for
  222. // class properties.
  223. if (Getter->isClassMethod() &&
  224. Getter->getCanonicalDecl()->findPropertyDecl())
  225. return false;
  226. }
  227. return true;
  228. };
  229. bool IsPropCall = Containing && isa<PseudoObjectExpr>(Containing);
  230. // Implicit property message sends are not 'implicit'.
  231. if ((E->isImplicit() || IsPropCall) &&
  232. !(IsPropCall &&
  233. IsImplicitProperty(cast<PseudoObjectExpr>(Containing))))
  234. Roles |= (unsigned)SymbolRole::Implicit;
  235. if (isDynamic(E)) {
  236. Roles |= (unsigned)SymbolRole::Dynamic;
  237. auto addReceivers = [&](const ObjCObjectType *Ty) {
  238. if (!Ty)
  239. return;
  240. if (const auto *clsD = Ty->getInterface()) {
  241. Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
  242. clsD);
  243. }
  244. for (const auto *protD : Ty->quals()) {
  245. Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy,
  246. protD);
  247. }
  248. };
  249. QualType recT = E->getReceiverType();
  250. if (const auto *Ptr = recT->getAs<ObjCObjectPointerType>())
  251. addReceivers(Ptr->getObjectType());
  252. else
  253. addReceivers(recT->getAs<ObjCObjectType>());
  254. }
  255. return IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
  256. Parent, ParentDC, Roles, Relations, E);
  257. }
  258. return true;
  259. }
  260. bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
  261. if (E->isExplicitProperty()) {
  262. SmallVector<SymbolRelation, 2> Relations;
  263. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  264. return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
  265. Parent, ParentDC, Roles, Relations, E);
  266. } else if (const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter()) {
  267. // Class properties that are explicitly defined using @property
  268. // declarations are represented implicitly as there is no ivar for class
  269. // properties.
  270. if (Getter->isClassMethod()) {
  271. if (const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
  272. SmallVector<SymbolRelation, 2> Relations;
  273. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  274. return IndexCtx.handleReference(PD, E->getLocation(), Parent,
  275. ParentDC, Roles, Relations, E);
  276. }
  277. }
  278. }
  279. // No need to do a handleReference for the objc method, because there will
  280. // be a message expr as part of PseudoObjectExpr.
  281. return true;
  282. }
  283. bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
  284. return IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(),
  285. Parent, ParentDC, SymbolRoleSet(), {}, E);
  286. }
  287. bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
  288. return IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
  289. Parent, ParentDC, SymbolRoleSet(), {}, E);
  290. }
  291. bool passObjCLiteralMethodCall(const ObjCMethodDecl *MD, const Expr *E) {
  292. SymbolRoleSet Roles{};
  293. SmallVector<SymbolRelation, 2> Relations;
  294. addCallRole(Roles, Relations);
  295. Roles |= (unsigned)SymbolRole::Implicit;
  296. return IndexCtx.handleReference(MD, E->getBeginLoc(), Parent, ParentDC,
  297. Roles, Relations, E);
  298. }
  299. bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
  300. if (ObjCMethodDecl *MD = E->getBoxingMethod()) {
  301. return passObjCLiteralMethodCall(MD, E);
  302. }
  303. return true;
  304. }
  305. bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
  306. if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) {
  307. return passObjCLiteralMethodCall(MD, E);
  308. }
  309. return true;
  310. }
  311. bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
  312. if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) {
  313. return passObjCLiteralMethodCall(MD, E);
  314. }
  315. return true;
  316. }
  317. bool VisitCXXConstructExpr(CXXConstructExpr *E) {
  318. SymbolRoleSet Roles{};
  319. SmallVector<SymbolRelation, 2> Relations;
  320. addCallRole(Roles, Relations);
  321. return IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
  322. Parent, ParentDC, Roles, Relations, E);
  323. }
  324. bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
  325. DataRecursionQueue *Q = nullptr) {
  326. if (E->getOperatorLoc().isInvalid())
  327. return true; // implicit.
  328. return base::TraverseCXXOperatorCallExpr(E, Q);
  329. }
  330. bool VisitDeclStmt(DeclStmt *S) {
  331. if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
  332. IndexCtx.indexDeclGroupRef(S->getDeclGroup());
  333. return true;
  334. }
  335. DeclGroupRef DG = S->getDeclGroup();
  336. for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
  337. const Decl *D = *I;
  338. if (!D)
  339. continue;
  340. if (!isFunctionLocalSymbol(D))
  341. IndexCtx.indexTopLevelDecl(D);
  342. }
  343. return true;
  344. }
  345. bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
  346. Expr *Init) {
  347. if (C->capturesThis() || C->capturesVLAType())
  348. return true;
  349. if (!base::TraverseStmt(Init))
  350. return false;
  351. if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
  352. return IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(),
  353. Parent, ParentDC, SymbolRoleSet());
  354. return true;
  355. }
  356. // RecursiveASTVisitor visits both syntactic and semantic forms, duplicating
  357. // the things that we visit. Make sure to only visit the semantic form.
  358. // Also visit things that are in the syntactic form but not the semantic one,
  359. // for example the indices in DesignatedInitExprs.
  360. bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) {
  361. auto visitForm = [&](InitListExpr *Form) {
  362. for (Stmt *SubStmt : Form->children()) {
  363. if (!TraverseStmt(SubStmt, Q))
  364. return false;
  365. }
  366. return true;
  367. };
  368. auto visitSyntacticDesignatedInitExpr = [&](DesignatedInitExpr *E) -> bool {
  369. for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
  370. if (D.isFieldDesignator() && D.getField())
  371. return IndexCtx.handleReference(D.getField(), D.getFieldLoc(),
  372. Parent, ParentDC, SymbolRoleSet(),
  373. {}, E);
  374. }
  375. return true;
  376. };
  377. InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
  378. InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;
  379. if (SemaForm) {
  380. // Visit things present in syntactic form but not the semantic form.
  381. if (SyntaxForm) {
  382. for (Expr *init : SyntaxForm->inits()) {
  383. if (auto *DIE = dyn_cast<DesignatedInitExpr>(init))
  384. visitSyntacticDesignatedInitExpr(DIE);
  385. }
  386. }
  387. return visitForm(SemaForm);
  388. }
  389. // No semantic, try the syntactic.
  390. if (SyntaxForm) {
  391. return visitForm(SyntaxForm);
  392. }
  393. return true;
  394. }
  395. bool VisitOffsetOfExpr(OffsetOfExpr *S) {
  396. for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
  397. const OffsetOfNode &Component = S->getComponent(I);
  398. if (Component.getKind() == OffsetOfNode::Field)
  399. IndexCtx.handleReference(Component.getField(), Component.getEndLoc(),
  400. Parent, ParentDC, SymbolRoleSet(), {});
  401. // FIXME: Try to resolve dependent field references.
  402. }
  403. return true;
  404. }
  405. bool VisitParmVarDecl(ParmVarDecl* D) {
  406. // Index the parameters of lambda expression and requires expression.
  407. if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
  408. const auto *DC = D->getDeclContext();
  409. if (DC && (isLambdaCallOperator(DC) || isa<RequiresExprBodyDecl>(DC)))
  410. IndexCtx.handleDecl(D);
  411. }
  412. return true;
  413. }
  414. bool VisitOverloadExpr(OverloadExpr *E) {
  415. SmallVector<SymbolRelation, 4> Relations;
  416. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  417. for (auto *D : E->decls())
  418. IndexCtx.handleReference(D, E->getNameLoc(), Parent, ParentDC, Roles,
  419. Relations, E);
  420. return true;
  421. }
  422. bool VisitConceptSpecializationExpr(ConceptSpecializationExpr *R) {
  423. IndexCtx.handleReference(R->getNamedConcept(), R->getConceptNameLoc(),
  424. Parent, ParentDC);
  425. return true;
  426. }
  427. bool TraverseTypeConstraint(const TypeConstraint *C) {
  428. IndexCtx.handleReference(C->getNamedConcept(), C->getConceptNameLoc(),
  429. Parent, ParentDC);
  430. return RecursiveASTVisitor::TraverseTypeConstraint(C);
  431. }
  432. };
  433. } // anonymous namespace
  434. void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
  435. const DeclContext *DC) {
  436. if (!S)
  437. return;
  438. if (!DC)
  439. DC = Parent->getLexicalDeclContext();
  440. BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
  441. }