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
37 if (OVMode == OV_Opaque && M[POE->getSyntacticForm()])
38 break;
39
40 // If we are rebuilding the map, clear out any existing state.
41 if (M[POE->getSyntacticForm()])
42 for (Stmt *SubStmt : S->children())
43 M[SubStmt] = nullptr;
44
45 M[POE->getSyntacticForm()] = S;
47
49 E = POE->semantics_end();
50 I != E; ++I) {
51 M[*I] = S;
53 }
54 break;
55 }
56 case Stmt::BinaryConditionalOperatorClass: {
57 assert(OVMode == OV_Transparent && "Should not appear alongside OVEs");
58 BinaryConditionalOperator *BCO = cast<BinaryConditionalOperator>(S);
59
60 M[BCO->getCommon()] = S;
62
63 M[BCO->getCond()] = S;
65
66 M[BCO->getTrueExpr()] = S;
68
69 M[BCO->getFalseExpr()] = S;
71
72 break;
73 }
74 case Stmt::OpaqueValueExprClass: {
75 // FIXME: This isn't correct; it assumes that multiple OpaqueValueExprs
76 // share a single source expression, but in the AST a single
77 // OpaqueValueExpr is shared among multiple parent expressions.
78 // The right thing to do is to give the OpaqueValueExpr its syntactic
79 // parent, then not reassign that when traversing the semantic expressions.
80 OpaqueValueExpr *OVE = cast<OpaqueValueExpr>(S);
81 if (OVMode == OV_Transparent || !M[OVE->getSourceExpr()]) {
82 M[OVE->getSourceExpr()] = S;
84 }
85 break;
86 }
87 case Stmt::CapturedStmtClass:
88 for (Stmt *SubStmt : S->children()) {
89 if (SubStmt) {
90 M[SubStmt] = S;
91 BuildParentMap(M, SubStmt, OVMode);
92 }
93 }
94 if (Stmt *SubStmt = cast<CapturedStmt>(S)->getCapturedStmt()) {
95 M[SubStmt] = S;
96 BuildParentMap(M, SubStmt, OVMode);
97 }
98 break;
99 default:
100 for (Stmt *SubStmt : S->children()) {
101 if (SubStmt) {
102 M[SubStmt] = S;
103 BuildParentMap(M, SubStmt, OVMode);
104 }
105 }
106 break;
107 }
108}
109
110ParentMap::ParentMap(Stmt *S) : Impl(nullptr) {
111 if (S) {
112 MapTy *M = new MapTy();
113 BuildParentMap(*M, S);
114 Impl = M;
115 }
116}
117
119 delete (MapTy*) Impl;
120}
121
123 if (S) {
124 BuildParentMap(*(MapTy*) Impl, S);
125 }
126}
127
128void ParentMap::setParent(const Stmt *S, const Stmt *Parent) {
129 assert(S);
130 assert(Parent);
131 MapTy *M = reinterpret_cast<MapTy *>(Impl);
132 M->insert(std::make_pair(const_cast<Stmt *>(S), const_cast<Stmt *>(Parent)));
133}
134
136 MapTy* M = (MapTy*) Impl;
137 return M->lookup(S);
138}
139
141 do {
142 S = getParent(S);
143 } while (isa_and_nonnull<ParenExpr>(S));
144 return S;
145}
146
148 do {
149 S = getParent(S);
150 }
151 while (S && (isa<ParenExpr>(S) || isa<CastExpr>(S)));
152
153 return S;
154}
155
157 do {
158 S = getParent(S);
159 } while (isa_and_nonnull<Expr>(S) &&
160 cast<Expr>(S)->IgnoreParenImpCasts() != S);
161
162 return S;
163}
164
166 Stmt *Paren = nullptr;
167 while (isa<ParenExpr>(S)) {
168 Paren = S;
169 S = getParent(S);
170 };
171 return Paren;
172}
173
175 Stmt *P = getParent(E);
176 Stmt *DirectChild = E;
177
178 // Ignore parents that don't guarantee consumption.
179 while (P && (isa<ParenExpr>(P) || isa<CastExpr>(P) ||
180 isa<FullExpr>(P))) {
181 DirectChild = P;
182 P = getParent(P);
183 }
184
185 if (!P)
186 return false;
187
188 switch (P->getStmtClass()) {
189 default:
190 return isa<Expr>(P);
191 case Stmt::DeclStmtClass:
192 return true;
193 case Stmt::BinaryOperatorClass: {
194 BinaryOperator *BE = cast<BinaryOperator>(P);
195 // If it is a comma, only the right side is consumed.
196 // If it isn't a comma, both sides are consumed.
197 return BE->getOpcode()!=BO_Comma ||DirectChild==BE->getRHS();
198 }
199 case Stmt::ForStmtClass:
200 return DirectChild == cast<ForStmt>(P)->getCond();
201 case Stmt::WhileStmtClass:
202 return DirectChild == cast<WhileStmt>(P)->getCond();
203 case Stmt::DoStmtClass:
204 return DirectChild == cast<DoStmt>(P)->getCond();
205 case Stmt::IfStmtClass:
206 return DirectChild == cast<IfStmt>(P)->getCond();
207 case Stmt::IndirectGotoStmtClass:
208 return DirectChild == cast<IndirectGotoStmt>(P)->getTarget();
209 case Stmt::SwitchStmtClass:
210 return DirectChild == cast<SwitchStmt>(P)->getCond();
211 case Stmt::ObjCForCollectionStmtClass:
212 return DirectChild == cast<ObjCForCollectionStmt>(P)->getCollection();
213 case Stmt::ReturnStmtClass:
214 return true;
215 }
216}
217
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
Expr * E
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:174
void addStmt(Stmt *S)
Adds and/or updates the parent/child-relations of the complete stmt tree of S.
Definition: ParentMap.cpp:122
void setParent(const Stmt *S, const Stmt *Parent)
Manually sets the parent of S to Parent.
Definition: ParentMap.cpp:128
Stmt * getOuterParenParent(Stmt *) const
Definition: ParentMap.cpp:165
Stmt * getParentIgnoreParenImpCasts(Stmt *) const
Definition: ParentMap.cpp:156
Stmt * getParentIgnoreParenCasts(Stmt *) const
Definition: ParentMap.cpp:147
Stmt * getParent(Stmt *) const
Definition: ParentMap.cpp:135
ParentMap(Stmt *ASTRoot)
Definition: ParentMap.cpp:110
Stmt * getParentIgnoreParens(Stmt *) const
Definition: ParentMap.cpp:140
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.