IndexBody.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. //===- IndexBody.cpp - Indexing statements --------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "IndexingContext.h"
  10. #include "clang/AST/RecursiveASTVisitor.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->getLocStart();
  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->getLocStart();
  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. if (auto *RecD = E->getReceiverInterface())
  234. Relations.emplace_back((unsigned)SymbolRole::RelationReceivedBy, RecD);
  235. }
  236. return IndexCtx.handleReference(MD, E->getSelectorStartLoc(),
  237. Parent, ParentDC, Roles, Relations, E);
  238. }
  239. return true;
  240. }
  241. bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
  242. if (E->isClassReceiver())
  243. IndexCtx.handleReference(E->getClassReceiver(), E->getReceiverLocation(),
  244. Parent, ParentDC);
  245. if (E->isExplicitProperty()) {
  246. SmallVector<SymbolRelation, 2> Relations;
  247. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  248. return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
  249. Parent, ParentDC, Roles, Relations, E);
  250. } else if (const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter()) {
  251. // Class properties that are explicitly defined using @property
  252. // declarations are represented implicitly as there is no ivar for class
  253. // properties.
  254. if (Getter->isClassMethod()) {
  255. if (const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
  256. SmallVector<SymbolRelation, 2> Relations;
  257. SymbolRoleSet Roles = getRolesForRef(E, Relations);
  258. return IndexCtx.handleReference(PD, E->getLocation(), Parent,
  259. ParentDC, Roles, Relations, E);
  260. }
  261. }
  262. }
  263. // No need to do a handleReference for the objc method, because there will
  264. // be a message expr as part of PseudoObjectExpr.
  265. return true;
  266. }
  267. bool VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
  268. return IndexCtx.handleReference(E->getPropertyDecl(), E->getMemberLoc(),
  269. Parent, ParentDC, SymbolRoleSet(), {}, E);
  270. }
  271. bool VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
  272. return IndexCtx.handleReference(E->getProtocol(), E->getProtocolIdLoc(),
  273. Parent, ParentDC, SymbolRoleSet(), {}, E);
  274. }
  275. bool passObjCLiteralMethodCall(const ObjCMethodDecl *MD, const Expr *E) {
  276. SymbolRoleSet Roles{};
  277. SmallVector<SymbolRelation, 2> Relations;
  278. addCallRole(Roles, Relations);
  279. Roles |= (unsigned)SymbolRole::Implicit;
  280. return IndexCtx.handleReference(MD, E->getLocStart(),
  281. Parent, ParentDC, Roles, Relations, E);
  282. }
  283. bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
  284. if (ObjCMethodDecl *MD = E->getBoxingMethod()) {
  285. return passObjCLiteralMethodCall(MD, E);
  286. }
  287. return true;
  288. }
  289. bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
  290. if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod()) {
  291. return passObjCLiteralMethodCall(MD, E);
  292. }
  293. return true;
  294. }
  295. bool VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
  296. if (ObjCMethodDecl *MD = E->getArrayWithObjectsMethod()) {
  297. return passObjCLiteralMethodCall(MD, E);
  298. }
  299. return true;
  300. }
  301. bool VisitCXXConstructExpr(CXXConstructExpr *E) {
  302. SymbolRoleSet Roles{};
  303. SmallVector<SymbolRelation, 2> Relations;
  304. addCallRole(Roles, Relations);
  305. return IndexCtx.handleReference(E->getConstructor(), E->getLocation(),
  306. Parent, ParentDC, Roles, Relations, E);
  307. }
  308. bool TraverseCXXOperatorCallExpr(CXXOperatorCallExpr *E,
  309. DataRecursionQueue *Q = nullptr) {
  310. if (E->getOperatorLoc().isInvalid())
  311. return true; // implicit.
  312. return base::TraverseCXXOperatorCallExpr(E, Q);
  313. }
  314. bool VisitDeclStmt(DeclStmt *S) {
  315. if (IndexCtx.shouldIndexFunctionLocalSymbols()) {
  316. IndexCtx.indexDeclGroupRef(S->getDeclGroup());
  317. return true;
  318. }
  319. DeclGroupRef DG = S->getDeclGroup();
  320. for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
  321. const Decl *D = *I;
  322. if (!D)
  323. continue;
  324. if (!isFunctionLocalSymbol(D))
  325. IndexCtx.indexTopLevelDecl(D);
  326. }
  327. return true;
  328. }
  329. bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
  330. Expr *Init) {
  331. if (C->capturesThis() || C->capturesVLAType())
  332. return true;
  333. if (C->capturesVariable() && IndexCtx.shouldIndexFunctionLocalSymbols())
  334. return IndexCtx.handleReference(C->getCapturedVar(), C->getLocation(),
  335. Parent, ParentDC, SymbolRoleSet());
  336. // FIXME: Lambda init-captures.
  337. return true;
  338. }
  339. // RecursiveASTVisitor visits both syntactic and semantic forms, duplicating
  340. // the things that we visit. Make sure to only visit the semantic form.
  341. // Also visit things that are in the syntactic form but not the semantic one,
  342. // for example the indices in DesignatedInitExprs.
  343. bool TraverseInitListExpr(InitListExpr *S, DataRecursionQueue *Q = nullptr) {
  344. auto visitForm = [&](InitListExpr *Form) {
  345. for (Stmt *SubStmt : Form->children()) {
  346. if (!TraverseStmt(SubStmt, Q))
  347. return false;
  348. }
  349. return true;
  350. };
  351. auto visitSyntacticDesignatedInitExpr = [&](DesignatedInitExpr *E) -> bool {
  352. for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
  353. if (D.isFieldDesignator())
  354. return IndexCtx.handleReference(D.getField(), D.getFieldLoc(),
  355. Parent, ParentDC, SymbolRoleSet(),
  356. {}, E);
  357. }
  358. return true;
  359. };
  360. InitListExpr *SemaForm = S->isSemanticForm() ? S : S->getSemanticForm();
  361. InitListExpr *SyntaxForm = S->isSemanticForm() ? S->getSyntacticForm() : S;
  362. if (SemaForm) {
  363. // Visit things present in syntactic form but not the semantic form.
  364. if (SyntaxForm) {
  365. for (Expr *init : SyntaxForm->inits()) {
  366. if (auto *DIE = dyn_cast<DesignatedInitExpr>(init))
  367. visitSyntacticDesignatedInitExpr(DIE);
  368. }
  369. }
  370. return visitForm(SemaForm);
  371. }
  372. // No semantic, try the syntactic.
  373. if (SyntaxForm) {
  374. return visitForm(SyntaxForm);
  375. }
  376. return true;
  377. }
  378. bool VisitOffsetOfExpr(OffsetOfExpr *S) {
  379. for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
  380. const OffsetOfNode &Component = S->getComponent(I);
  381. if (Component.getKind() == OffsetOfNode::Field)
  382. IndexCtx.handleReference(Component.getField(), Component.getLocEnd(),
  383. Parent, ParentDC, SymbolRoleSet(), {});
  384. // FIXME: Try to resolve dependent field references.
  385. }
  386. return true;
  387. }
  388. };
  389. } // anonymous namespace
  390. void IndexingContext::indexBody(const Stmt *S, const NamedDecl *Parent,
  391. const DeclContext *DC) {
  392. if (!S)
  393. return;
  394. if (!DC)
  395. DC = Parent->getLexicalDeclContext();
  396. BodyIndexer(*this, Parent, DC).TraverseStmt(const_cast<Stmt*>(S));
  397. }