clang  19.0.0git
ParentMap.cpp
Go to the documentation of this file.
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 
13 #include "clang/AST/ParentMap.h"
14 #include "clang/AST/Decl.h"
15 #include "clang/AST/Expr.h"
16 #include "clang/AST/ExprCXX.h"
17 #include "clang/AST/StmtObjC.h"
18 #include "llvm/ADT/DenseMap.h"
19 
20 using namespace clang;
21 
22 typedef llvm::DenseMap<Stmt*, Stmt*> MapTy;
23 
26  OV_Opaque
27 };
28 
29 static void BuildParentMap(MapTy& M, Stmt* S,
31  if (!S)
32  return;
33 
34  switch (S->getStmtClass()) {
35  case Stmt::PseudoObjectExprClass: {
36  PseudoObjectExpr *POE = cast<PseudoObjectExpr>(S);
37 
38  if (OVMode == OV_Opaque && M[POE->getSyntacticForm()])
39  break;
40 
41  // If we are rebuilding the map, clear out any existing state.
42  if (M[POE->getSyntacticForm()])
43  for (Stmt *SubStmt : S->children())
44  M[SubStmt] = nullptr;
45 
46  M[POE->getSyntacticForm()] = S;
48 
50  E = POE->semantics_end();
51  I != E; ++I) {
52  M[*I] = S;
53  BuildParentMap(M, *I, OV_Opaque);
54  }
55  break;
56  }
57  case Stmt::BinaryConditionalOperatorClass: {
58  assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
59  BinaryConditionalOperator *BCO = cast<BinaryConditionalOperator>(S);
60 
61  M[BCO->getCommon()] = S;
63 
64  M[BCO->getCond()] = S;
65  BuildParentMap(M, BCO->getCond(), OV_Opaque);
66 
67  M[BCO->getTrueExpr()] = S;
69 
70  M[BCO->getFalseExpr()] = S;
72 
73  break;
74  }
75  case Stmt::OpaqueValueExprClass: {
76  // FIXME: This isn't correct; it assumes that multiple OpaqueValueExprs
77  // share a single source expression, but in the AST a single
78  // OpaqueValueExpr is shared among multiple parent expressions.
79  // The right thing to do is to give the OpaqueValueExpr its syntactic
80  // parent, then not reassign that when traversing the semantic expressions.
81  OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(S);
82  if (OVMode == OV_Transparent || !M[OVE->getSourceExpr()]) {
83  M[OVE->getSourceExpr()] = S;
85  }
86  break;
87  }
88  case Stmt::CapturedStmtClass:
89  for (Stmt *SubStmt : S->children()) {
90  if (SubStmt) {
91  M[SubStmt] = S;
92  BuildParentMap(M, SubStmt, OVMode);
93  }
94  }
95  if (Stmt *SubStmt = cast<CapturedStmt>(S)->getCapturedStmt()) {
96  M[SubStmt] = S;
97  BuildParentMap(M, SubStmt, OVMode);
98  }
99  break;
100  case Stmt::CXXDefaultArgExprClass:
101  if (auto *Arg = dyn_cast<CXXDefaultArgExpr>(S)) {
102  if (Arg->hasRewrittenInit()) {
103  M[Arg->getExpr()] = S;
104  BuildParentMap(M, Arg->getExpr(), OVMode);
105  }
106  }
107  break;
108  case Stmt::CXXDefaultInitExprClass:
109  if (auto *Init = dyn_cast<CXXDefaultInitExpr>(S)) {
110  if (Init->hasRewrittenInit()) {
111  M[Init->getExpr()] = S;
112  BuildParentMap(M, Init->getExpr(), OVMode);
113  }
114  }
115  break;
116  default:
117  for (Stmt *SubStmt : S->children()) {
118  if (SubStmt) {
119  M[SubStmt] = S;
120  BuildParentMap(M, SubStmt, OVMode);
121  }
122  }
123  break;
124  }
125 }
126 
127 ParentMap::ParentMap(Stmt *S) : Impl(nullptr) {
128  if (S) {
129  MapTy *M = new MapTy();
130  BuildParentMap(*M, S);
131  Impl = M;
132  }
133 }
134 
136  delete (MapTy*) Impl;
137 }
138 
140  if (S) {
141  BuildParentMap(*(MapTy*) Impl, S);
142  }
143 }
144 
145 void ParentMap::setParent(const Stmt *S, const Stmt *Parent) {
146  assert(S);
147  assert(Parent);
148  MapTy *M = reinterpret_cast<MapTy *>(Impl);
149  M->insert(std::make_pair(const_cast<Stmt *>(S), const_cast<Stmt *>(Parent)));
150 }
151 
153  MapTy* M = (MapTy*) Impl;
154  return M->lookup(S);
155 }
156 
158  do { S = getParent(S); } while (S && isa<ParenExpr>(S));
159  return S;
160 }
161 
163  do {
164  S = getParent(S);
165  }
166  while (S && (isa<ParenExpr>(S) || isa<CastExpr>(S)));
167 
168  return S;
169 }
170 
172  do {
173  S = getParent(S);
174  } while (S && isa<Expr>(S) && cast<Expr>(S)->IgnoreParenImpCasts() != S);
175 
176  return S;
177 }
178 
180  Stmt *Paren = nullptr;
181  while (isa<ParenExpr>(S)) {
182  Paren = S;
183  S = getParent(S);
184  };
185  return Paren;
186 }
187 
189  Stmt *P = getParent(E);
190  Stmt *DirectChild = E;
191 
192  // Ignore parents that don't guarantee consumption.
193  while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P) ||
194  isa<FullExpr>(P))) {
195  DirectChild = P;
196  P = getParent(P);
197  }
198 
199  if (!P)
200  return false;
201 
202  switch (P->getStmtClass()) {
203  default:
204  return isa<Expr>(P);
205  case Stmt::DeclStmtClass:
206  return true;
207  case Stmt::BinaryOperatorClass: {
208  BinaryOperator *BE = cast<BinaryOperator>(P);
209  // If it is a comma, only the right side is consumed.
210  // If it isn't a comma, both sides are consumed.
211  return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS();
212  }
213  case Stmt::ForStmtClass:
214  return DirectChild == cast<ForStmt>(P)->getCond();
215  case Stmt::WhileStmtClass:
216  return DirectChild == cast<WhileStmt>(P)->getCond();
217  case Stmt::DoStmtClass:
218  return DirectChild == cast<DoStmt>(P)->getCond();
219  case Stmt::IfStmtClass:
220  return DirectChild == cast<IfStmt>(P)->getCond();
221  case Stmt::IndirectGotoStmtClass:
222  return DirectChild == cast<IndirectGotoStmt>(P)->getTarget();
223  case Stmt::SwitchStmtClass:
224  return DirectChild == cast<SwitchStmt>(P)->getCond();
225  case Stmt::ObjCForCollectionStmtClass:
226  return DirectChild == cast<ObjCForCollectionStmt>(P)->getCollection();
227  case Stmt::ReturnStmtClass:
228  return true;
229  }
230 }
231 
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
Defines the clang::Expr interface and subclasses for C++ expressions.
OpaqueValueMode
Definition: ParentMap.cpp:24
@ OV_Opaque
Definition: ParentMap.cpp:26
@ OV_Transparent
Definition: ParentMap.cpp:25
static void BuildParentMap(MapTy &M, Stmt *S, OpaqueValueMode OVMode=OV_Transparent)
Definition: ParentMap.cpp:29
llvm::DenseMap< Stmt *, Stmt * > MapTy
Definition: ParentMap.cpp:22
Defines the Objective-C statement AST node classes.
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition: Expr.h:4293
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression which will be evaluated if the condition evaluates to true; th...
Definition: Expr.h:4340
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condnition evaluates to false;...
Definition: Expr.h:4347
Expr * getCommon() const
getCommon - Return the common expression, written to the left of the condition.
Definition: Expr.h:4328
Expr * getCond() const
getCond - Return the condition expression; this is defined in terms of the opaque value.
Definition: Expr.h:4335
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3892
Opcode getOpcode() const
Definition: Expr.h:3936
Expr * getRHS() const
Definition: Expr.h:3943
This represents one expression.
Definition: Expr.h:110
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1168
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1218
bool isConsumedExpr(Expr *E) const
Definition: ParentMap.cpp:188
void addStmt(Stmt *S)
Adds and/or updates the parent/child-relations of the complete stmt tree of S.
Definition: ParentMap.cpp:139
void setParent(const Stmt *S, const Stmt *Parent)
Manually sets the parent of S to Parent.
Definition: ParentMap.cpp:145
Stmt * getOuterParenParent(Stmt *) const
Definition: ParentMap.cpp:179
Stmt * getParentIgnoreParenImpCasts(Stmt *) const
Definition: ParentMap.cpp:171
Stmt * getParentIgnoreParenCasts(Stmt *) const
Definition: ParentMap.cpp:162
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:152
ParentMap(Stmt *ASTRoot)
Definition: ParentMap.cpp:127
Stmt * getParentIgnoreParens(Stmt *) const
Definition: ParentMap.cpp:157
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition: Expr.h:6346
semantics_iterator semantics_end()
Definition: Expr.h:6418
Expr * getSyntacticForm()
Return the syntactic form of this expression, i.e.
Definition: Expr.h:6388
semantics_iterator semantics_begin()
Definition: Expr.h:6412
Expr *const * semantics_iterator
Definition: Expr.h:6410
Stmt - This represents one statement.
Definition: Stmt.h:84
The JSON file list parser is used to communicate input to InstallAPI.