1292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines/*
2292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * Copyright 2011, The Android Open Source Project
3292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines *
4292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * you may not use this file except in compliance with the License.
6292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * You may obtain a copy of the License at
7292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines *
8292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
9292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines *
10292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * Unless required by applicable law or agreed to in writing, software
11292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * See the License for the specific language governing permissions and
14292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines * limitations under the License.
15292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines */
16292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
17292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "slang_rs_ast_replace.h"
18292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
19292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "slang_assert.h"
20292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
21ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien#include "llvm/Support/Casting.h"
22ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien
23292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesnamespace slang {
24292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
25292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::ReplaceStmt(
26292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    clang::Stmt *OuterStmt,
27292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    clang::Stmt *OldStmt,
28292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    clang::Stmt *NewStmt) {
29292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  mOldStmt = OldStmt;
30292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  mNewStmt = NewStmt;
31292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  mOuterStmt = OuterStmt;
32292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
33292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  // This simplifies use in various Stmt visitor passes where the only
34292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  // valid type is an Expr.
35ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien  mOldExpr = llvm::dyn_cast<clang::Expr>(OldStmt);
36292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  if (mOldExpr) {
37ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    mNewExpr = llvm::dyn_cast<clang::Expr>(NewStmt);
38292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
39292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  Visit(mOuterStmt);
40292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
41292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
42292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::ReplaceInCompoundStmt(clang::CompoundStmt *CS) {
43292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::Stmt **UpdatedStmtList = new clang::Stmt*[CS->size()];
44292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
45292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  unsigned UpdatedStmtCount = 0;
46292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::CompoundStmt::body_iterator bI = CS->body_begin();
47292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::CompoundStmt::body_iterator bE = CS->body_end();
48292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
49292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  for ( ; bI != bE; bI++) {
50292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    if (matchesStmt(*bI)) {
51292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      UpdatedStmtList[UpdatedStmtCount++] = mNewStmt;
52292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    } else {
53292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      UpdatedStmtList[UpdatedStmtCount++] = *bI;
54292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    }
55292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
56292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
57292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount);
58292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
59292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  delete [] UpdatedStmtList;
60292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
61292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
62292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitStmt(clang::Stmt *S) {
63292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  // This function does the actual iteration through all sub-Stmt's within
64292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  // a given Stmt. Note that this function is skipped by all of the other
65292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  // Visit* functions if we have already found a higher-level match.
66292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end();
67292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines       I != E;
68292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines       I++) {
69292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    if (clang::Stmt *Child = *I) {
70292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      if (!matchesStmt(Child)) {
71292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines        Visit(Child);
72292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      }
73292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    }
74292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
75292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
76292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
77292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitCompoundStmt(clang::CompoundStmt *CS) {
78292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  VisitStmt(CS);
79292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  ReplaceInCompoundStmt(CS);
80292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
81292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
82292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitCaseStmt(clang::CaseStmt *CS) {
83292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  if (matchesStmt(CS->getSubStmt())) {
84292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    CS->setSubStmt(mNewStmt);
85292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else {
86292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    VisitStmt(CS);
87292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
88292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
89292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
90292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitDefaultStmt(clang::DefaultStmt *DS) {
91292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  if (matchesStmt(DS->getSubStmt())) {
92292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    DS->setSubStmt(mNewStmt);
93292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else {
94292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    VisitStmt(DS);
95292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
96292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
97292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
98292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitDoStmt(clang::DoStmt *DS) {
99292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  if (matchesExpr(DS->getCond())) {
100292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    DS->setCond(mNewExpr);
101292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else if (matchesStmt(DS->getBody())) {
102292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    DS->setBody(mNewStmt);
103292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else {
104292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    VisitStmt(DS);
105292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
106292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
107292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
108292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitForStmt(clang::ForStmt *FS) {
109292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  if (matchesStmt(FS->getInit())) {
110292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    FS->setInit(mNewStmt);
111292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else if (matchesExpr(FS->getCond())) {
112292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    FS->setCond(mNewExpr);
113292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else if (matchesExpr(FS->getInc())) {
114292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    FS->setInc(mNewExpr);
115292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else if (matchesStmt(FS->getBody())) {
116292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    FS->setBody(mNewStmt);
117292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else {
118292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    VisitStmt(FS);
119292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
120292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
121292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
122292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitIfStmt(clang::IfStmt *IS) {
123292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  if (matchesExpr(IS->getCond())) {
124292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    IS->setCond(mNewExpr);
125292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else if (matchesStmt(IS->getThen())) {
126292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    IS->setThen(mNewStmt);
127292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else if (matchesStmt(IS->getElse())) {
128292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    IS->setElse(mNewStmt);
129292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else {
130292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    VisitStmt(IS);
131292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
132292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
133292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
134292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitSwitchCase(clang::SwitchCase *SC) {
135292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  slangAssert(false && "Both case and default have specialized handlers");
136292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  VisitStmt(SC);
137292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
138292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
139292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitSwitchStmt(clang::SwitchStmt *SS) {
140292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  if (matchesExpr(SS->getCond())) {
141292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    SS->setCond(mNewExpr);
142292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else {
143292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    VisitStmt(SS);
144292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
145292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
146292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
147292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid RSASTReplace::VisitWhileStmt(clang::WhileStmt *WS) {
148292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  if (matchesExpr(WS->getCond())) {
149292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    WS->setCond(mNewExpr);
150292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else if (matchesStmt(WS->getBody())) {
151292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    WS->setBody(mNewStmt);
152292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  } else {
153292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    VisitStmt(WS);
154292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
155292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
156292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
157292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}  // namespace slang
158