ParentMap.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //===--- ParentMap.cpp - Mappings from Stmts to their Parents ---*- C++ -*-===//
  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. //
  9. // This file defines the ParentMap class.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/AST/ParentMap.h"
  13. #include "clang/AST/Decl.h"
  14. #include "clang/AST/Expr.h"
  15. #include "clang/AST/ExprCXX.h"
  16. #include "clang/AST/StmtObjC.h"
  17. #include "llvm/ADT/DenseMap.h"
  18. using namespace clang;
  19. typedef llvm::DenseMap<Stmt*, Stmt*> MapTy;
  20. enum OpaqueValueMode {
  21. OV_Transparent,
  22. OV_Opaque
  23. };
  24. static void BuildParentMap(MapTy& M, Stmt* S,
  25. OpaqueValueMode OVMode = OV_Transparent) {
  26. if (!S)
  27. return;
  28. switch (S->getStmtClass()) {
  29. case Stmt::PseudoObjectExprClass: {
  30. assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
  31. PseudoObjectExpr *POE = cast<PseudoObjectExpr>(S);
  32. // If we are rebuilding the map, clear out any existing state.
  33. if (M[POE->getSyntacticForm()])
  34. for (Stmt *SubStmt : S->children())
  35. M[SubStmt] = nullptr;
  36. M[POE->getSyntacticForm()] = S;
  37. BuildParentMap(M, POE->getSyntacticForm(), OV_Transparent);
  38. for (PseudoObjectExpr::semantics_iterator I = POE->semantics_begin(),
  39. E = POE->semantics_end();
  40. I != E; ++I) {
  41. M[*I] = S;
  42. BuildParentMap(M, *I, OV_Opaque);
  43. }
  44. break;
  45. }
  46. case Stmt::BinaryConditionalOperatorClass: {
  47. assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
  48. BinaryConditionalOperator *BCO = cast<BinaryConditionalOperator>(S);
  49. M[BCO->getCommon()] = S;
  50. BuildParentMap(M, BCO->getCommon(), OV_Transparent);
  51. M[BCO->getCond()] = S;
  52. BuildParentMap(M, BCO->getCond(), OV_Opaque);
  53. M[BCO->getTrueExpr()] = S;
  54. BuildParentMap(M, BCO->getTrueExpr(), OV_Opaque);
  55. M[BCO->getFalseExpr()] = S;
  56. BuildParentMap(M, BCO->getFalseExpr(), OV_Transparent);
  57. break;
  58. }
  59. case Stmt::OpaqueValueExprClass: {
  60. // FIXME: This isn't correct; it assumes that multiple OpaqueValueExprs
  61. // share a single source expression, but in the AST a single
  62. // OpaqueValueExpr is shared among multiple parent expressions.
  63. // The right thing to do is to give the OpaqueValueExpr its syntactic
  64. // parent, then not reassign that when traversing the semantic expressions.
  65. OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(S);
  66. if (OVMode == OV_Transparent || !M[OVE->getSourceExpr()]) {
  67. M[OVE->getSourceExpr()] = S;
  68. BuildParentMap(M, OVE->getSourceExpr(), OV_Transparent);
  69. }
  70. break;
  71. }
  72. case Stmt::CapturedStmtClass:
  73. for (Stmt *SubStmt : S->children()) {
  74. if (SubStmt) {
  75. M[SubStmt] = S;
  76. BuildParentMap(M, SubStmt, OVMode);
  77. }
  78. }
  79. if (Stmt *SubStmt = cast<CapturedStmt>(S)->getCapturedStmt()) {
  80. M[SubStmt] = S;
  81. BuildParentMap(M, SubStmt, OVMode);
  82. }
  83. break;
  84. default:
  85. for (Stmt *SubStmt : S->children()) {
  86. if (SubStmt) {
  87. M[SubStmt] = S;
  88. BuildParentMap(M, SubStmt, OVMode);
  89. }
  90. }
  91. break;
  92. }
  93. }
  94. ParentMap::ParentMap(Stmt *S) : Impl(nullptr) {
  95. if (S) {
  96. MapTy *M = new MapTy();
  97. BuildParentMap(*M, S);
  98. Impl = M;
  99. }
  100. }
  101. ParentMap::~ParentMap() {
  102. delete (MapTy*) Impl;
  103. }
  104. void ParentMap::addStmt(Stmt* S) {
  105. if (S) {
  106. BuildParentMap(*(MapTy*) Impl, S);
  107. }
  108. }
  109. void ParentMap::setParent(const Stmt *S, const Stmt *Parent) {
  110. assert(S);
  111. assert(Parent);
  112. MapTy *M = reinterpret_cast<MapTy *>(Impl);
  113. M->insert(std::make_pair(const_cast<Stmt *>(S), const_cast<Stmt *>(Parent)));
  114. }
  115. Stmt* ParentMap::getParent(Stmt* S) const {
  116. MapTy* M = (MapTy*) Impl;
  117. return M->lookup(S);
  118. }
  119. Stmt *ParentMap::getParentIgnoreParens(Stmt *S) const {
  120. do { S = getParent(S); } while (S && isa<ParenExpr>(S));
  121. return S;
  122. }
  123. Stmt *ParentMap::getParentIgnoreParenCasts(Stmt *S) const {
  124. do {
  125. S = getParent(S);
  126. }
  127. while (S && (isa<ParenExpr>(S) || isa<CastExpr>(S)));
  128. return S;
  129. }
  130. Stmt *ParentMap::getParentIgnoreParenImpCasts(Stmt *S) const {
  131. do {
  132. S = getParent(S);
  133. } while (S && isa<Expr>(S) && cast<Expr>(S)->IgnoreParenImpCasts() != S);
  134. return S;
  135. }
  136. Stmt *ParentMap::getOuterParenParent(Stmt *S) const {
  137. Stmt *Paren = nullptr;
  138. while (isa<ParenExpr>(S)) {
  139. Paren = S;
  140. S = getParent(S);
  141. };
  142. return Paren;
  143. }
  144. bool ParentMap::isConsumedExpr(Expr* E) const {
  145. Stmt *P = getParent(E);
  146. Stmt *DirectChild = E;
  147. // Ignore parents that don't guarantee consumption.
  148. while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P) ||
  149. isa<FullExpr>(P))) {
  150. DirectChild = P;
  151. P = getParent(P);
  152. }
  153. if (!P)
  154. return false;
  155. switch (P->getStmtClass()) {
  156. default:
  157. return isa<Expr>(P);
  158. case Stmt::DeclStmtClass:
  159. return true;
  160. case Stmt::BinaryOperatorClass: {
  161. BinaryOperator *BE = cast<BinaryOperator>(P);
  162. // If it is a comma, only the right side is consumed.
  163. // If it isn't a comma, both sides are consumed.
  164. return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS();
  165. }
  166. case Stmt::ForStmtClass:
  167. return DirectChild == cast<ForStmt>(P)->getCond();
  168. case Stmt::WhileStmtClass:
  169. return DirectChild == cast<WhileStmt>(P)->getCond();
  170. case Stmt::DoStmtClass:
  171. return DirectChild == cast<DoStmt>(P)->getCond();
  172. case Stmt::IfStmtClass:
  173. return DirectChild == cast<IfStmt>(P)->getCond();
  174. case Stmt::IndirectGotoStmtClass:
  175. return DirectChild == cast<IndirectGotoStmt>(P)->getTarget();
  176. case Stmt::SwitchStmtClass:
  177. return DirectChild == cast<SwitchStmt>(P)->getCond();
  178. case Stmt::ObjCForCollectionStmtClass:
  179. return DirectChild == cast<ObjCForCollectionStmt>(P)->getCollection();
  180. case Stmt::ReturnStmtClass:
  181. return true;
  182. }
  183. }