10 #include "clang/AST/ParentMapContext.h"
29 ASTContext *Context) {
30 SmallVector<const Stmt *, 1> Result;
32 TraversalKindScope RAII(*Context, ast_type_traits::TK_AsIs);
33 DynTypedNodeList Parents = Context->getParents(*S);
35 SmallVector<ast_type_traits::DynTypedNode, 1> NodesToProcess(Parents.begin(),
38 while (!NodesToProcess.empty()) {
39 ast_type_traits::DynTypedNode Node = NodesToProcess.back();
40 NodesToProcess.pop_back();
42 if (
const auto *S = Node.get<Stmt>()) {
45 Parents = Context->getParents(Node);
46 NodesToProcess.append(Parents.begin(), Parents.end());
54 bool isDescendantOrEqual(
const Stmt *Descendant,
const Stmt *Ancestor,
55 ASTContext *Context) {
56 if (Descendant == Ancestor)
59 if (isDescendantOrEqual(
Parent, Ancestor, Context))
68 ASTContext *TheContext)
69 : Context(TheContext), Root(Root) {
70 for (
const auto &SyntheticStmt : TheCFG->synthetic_stmts()) {
71 SyntheticStmtSourceMap[SyntheticStmt.first] = SyntheticStmt.second;
76 Before = resolveSyntheticStmt(Before);
77 After = resolveSyntheticStmt(After);
81 for (
const Stmt *Successor = getSequenceSuccessor(Before); Successor;
82 Successor = getSequenceSuccessor(Successor)) {
83 if (isDescendantOrEqual(After, Successor, Context))
98 const Stmt *Before)
const {
102 const Stmt *ExprSequence::getSequenceSuccessor(
const Stmt *S)
const {
106 if (!isDescendantOrEqual(
Parent, Root, Context))
109 if (
const auto *BO = dyn_cast<BinaryOperator>(
Parent)) {
111 if (BO->getLHS() == S && BO->getOpcode() == BO_Comma)
113 }
else if (
const auto *InitList = dyn_cast<InitListExpr>(
Parent)) {
116 for (
unsigned I = 1; I < InitList->getNumInits(); ++I) {
117 if (InitList->getInit(I - 1) == S)
118 return InitList->getInit(I);
120 }
else if (
const auto *Compound = dyn_cast<CompoundStmt>(
Parent)) {
123 const Stmt *Previous =
nullptr;
124 for (
const auto *Child : Compound->body()) {
129 }
else if (
const auto *TheDeclStmt = dyn_cast<DeclStmt>(
Parent)) {
132 const Expr *PreviousInit =
nullptr;
134 if (
const auto *TheVarDecl = dyn_cast<VarDecl>(
TheDecl)) {
135 if (
const Expr *Init = TheVarDecl->getInit()) {
136 if (PreviousInit == S)
142 }
else if (
const auto *ForRange = dyn_cast<CXXForRangeStmt>(
Parent)) {
146 if (S == ForRange->getLoopVarStmt())
147 return ForRange->getBody();
148 }
else if (
const auto *TheIfStmt = dyn_cast<IfStmt>(
Parent)) {
154 if (S == TheIfStmt->getInit()) {
155 if (TheIfStmt->getConditionVariableDeclStmt() !=
nullptr)
156 return TheIfStmt->getConditionVariableDeclStmt();
157 return TheIfStmt->getCond();
159 if (S == TheIfStmt->getConditionVariableDeclStmt())
160 return TheIfStmt->getCond();
161 }
else if (
const auto *TheSwitchStmt = dyn_cast<SwitchStmt>(
Parent)) {
163 if (S == TheSwitchStmt->getInit()) {
164 if (TheSwitchStmt->getConditionVariableDeclStmt() !=
nullptr)
165 return TheSwitchStmt->getConditionVariableDeclStmt();
166 return TheSwitchStmt->getCond();
168 if (S == TheSwitchStmt->getConditionVariableDeclStmt())
169 return TheSwitchStmt->getCond();
170 }
else if (
const auto *TheWhileStmt = dyn_cast<WhileStmt>(
Parent)) {
174 if (S == TheWhileStmt->getConditionVariableDeclStmt())
175 return TheWhileStmt->getCond();
182 const Stmt *ExprSequence::resolveSyntheticStmt(
const Stmt *S)
const {
183 if (SyntheticStmtSourceMap.count(S))
184 return SyntheticStmtSourceMap.lookup(S);
189 : Context(TheContext) {
190 for (
const auto *B : *TheCFG) {
191 for (
const auto &Elem : *B) {
192 if (Optional<CFGStmt> S = Elem.getAs<CFGStmt>())
193 Map[S->getStmt()] = B;
199 while (!Map.count(S)) {
200 SmallVector<const Stmt *, 1> Parents =
getParentStmts(S, Context);
206 return Map.lookup(S);