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