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