IndexBody.cpp 17 KB

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