slang_rs_ast_replace.cpp revision 292e00a0259ac28cac1055cb6077cf6fc7c6743c
1/* 2 * Copyright 2011, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "slang_rs_ast_replace.h" 18 19#include "slang_assert.h" 20 21namespace slang { 22 23void RSASTReplace::ReplaceStmt( 24 clang::Stmt *OuterStmt, 25 clang::Stmt *OldStmt, 26 clang::Stmt *NewStmt) { 27 mOldStmt = OldStmt; 28 mNewStmt = NewStmt; 29 mOuterStmt = OuterStmt; 30 31 // This simplifies use in various Stmt visitor passes where the only 32 // valid type is an Expr. 33 mOldExpr = dyn_cast<clang::Expr>(OldStmt); 34 if (mOldExpr) { 35 mNewExpr = dyn_cast<clang::Expr>(NewStmt); 36 } 37 Visit(mOuterStmt); 38} 39 40void RSASTReplace::ReplaceInCompoundStmt(clang::CompoundStmt *CS) { 41 clang::Stmt **UpdatedStmtList = new clang::Stmt*[CS->size()]; 42 43 unsigned UpdatedStmtCount = 0; 44 clang::CompoundStmt::body_iterator bI = CS->body_begin(); 45 clang::CompoundStmt::body_iterator bE = CS->body_end(); 46 47 for ( ; bI != bE; bI++) { 48 if (matchesStmt(*bI)) { 49 UpdatedStmtList[UpdatedStmtCount++] = mNewStmt; 50 } else { 51 UpdatedStmtList[UpdatedStmtCount++] = *bI; 52 } 53 } 54 55 CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 56 57 delete [] UpdatedStmtList; 58 59 return; 60} 61 62void RSASTReplace::VisitStmt(clang::Stmt *S) { 63 // This function does the actual iteration through all sub-Stmt's within 64 // a given Stmt. Note that this function is skipped by all of the other 65 // Visit* functions if we have already found a higher-level match. 66 for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 67 I != E; 68 I++) { 69 if (clang::Stmt *Child = *I) { 70 if (!matchesStmt(Child)) { 71 Visit(Child); 72 } 73 } 74 } 75 return; 76} 77 78void RSASTReplace::VisitCompoundStmt(clang::CompoundStmt *CS) { 79 VisitStmt(CS); 80 ReplaceInCompoundStmt(CS); 81 return; 82} 83 84void RSASTReplace::VisitCaseStmt(clang::CaseStmt *CS) { 85 if (matchesStmt(CS->getSubStmt())) { 86 CS->setSubStmt(mNewStmt); 87 } else { 88 VisitStmt(CS); 89 } 90 return; 91} 92 93void RSASTReplace::VisitDefaultStmt(clang::DefaultStmt *DS) { 94 if (matchesStmt(DS->getSubStmt())) { 95 DS->setSubStmt(mNewStmt); 96 } else { 97 VisitStmt(DS); 98 } 99 return; 100} 101 102void RSASTReplace::VisitDoStmt(clang::DoStmt *DS) { 103 if (matchesExpr(DS->getCond())) { 104 DS->setCond(mNewExpr); 105 } else if (matchesStmt(DS->getBody())) { 106 DS->setBody(mNewStmt); 107 } else { 108 VisitStmt(DS); 109 } 110 return; 111} 112 113void RSASTReplace::VisitForStmt(clang::ForStmt *FS) { 114 if (matchesStmt(FS->getInit())) { 115 FS->setInit(mNewStmt); 116 } else if (matchesExpr(FS->getCond())) { 117 FS->setCond(mNewExpr); 118 } else if (matchesExpr(FS->getInc())) { 119 FS->setInc(mNewExpr); 120 } else if (matchesStmt(FS->getBody())) { 121 FS->setBody(mNewStmt); 122 } else { 123 VisitStmt(FS); 124 } 125 return; 126} 127 128void RSASTReplace::VisitIfStmt(clang::IfStmt *IS) { 129 if (matchesExpr(IS->getCond())) { 130 IS->setCond(mNewExpr); 131 } else if (matchesStmt(IS->getThen())) { 132 IS->setThen(mNewStmt); 133 } else if (matchesStmt(IS->getElse())) { 134 IS->setElse(mNewStmt); 135 } else { 136 VisitStmt(IS); 137 } 138 return; 139} 140 141void RSASTReplace::VisitSwitchCase(clang::SwitchCase *SC) { 142 slangAssert(false && "Both case and default have specialized handlers"); 143 VisitStmt(SC); 144 return; 145} 146 147void RSASTReplace::VisitSwitchStmt(clang::SwitchStmt *SS) { 148 if (matchesExpr(SS->getCond())) { 149 SS->setCond(mNewExpr); 150 } else { 151 VisitStmt(SS); 152 } 153 return; 154} 155 156void RSASTReplace::VisitWhileStmt(clang::WhileStmt *WS) { 157 if (matchesExpr(WS->getCond())) { 158 WS->setCond(mNewExpr); 159 } else if (matchesStmt(WS->getBody())) { 160 WS->setBody(mNewStmt); 161 } else { 162 VisitStmt(WS); 163 } 164 return; 165} 166 167} // namespace slang 168