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 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_AST_REPLACE_H_  // NOLINT
18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_AST_REPLACE_H_
19 
20 #include "clang/AST/StmtVisitor.h"
21 
22 #include "slang_assert.h"
23 #include "clang/AST/ASTContext.h"
24 
25 namespace clang {
26   class Diagnostic;
27   class Expr;
28   class Stmt;
29 }
30 
31 namespace slang {
32 
33 class RSASTReplace : public clang::StmtVisitor<RSASTReplace> {
34  private:
35   clang::ASTContext &C;
36   clang::Stmt *mOuterStmt;
37   clang::Stmt *mOldStmt;
38   clang::Stmt *mNewStmt;
39   clang::Expr *mOldExpr;
40   clang::Expr *mNewExpr;
41 
matchesExpr(const clang::Expr * E)42   inline bool matchesExpr(const clang::Expr *E) const {
43     bool retVal = mOldExpr && (mOldExpr == E);
44     if (retVal) {
45       slangAssert(mNewExpr &&
46           "Cannot replace an expression if we don't have a new expression");
47     }
48     return retVal;
49   }
50 
matchesStmt(const clang::Stmt * S)51   inline bool matchesStmt(const clang::Stmt *S) const {
52     slangAssert(mOldStmt);
53     return mOldStmt == S;
54   }
55 
56   void ReplaceInCompoundStmt(clang::CompoundStmt *CS);
57 
58  public:
RSASTReplace(clang::ASTContext & Con)59   explicit RSASTReplace(clang::ASTContext &Con)
60       : C(Con),
61         mOuterStmt(nullptr),
62         mOldStmt(nullptr),
63         mNewStmt(nullptr),
64         mOldExpr(nullptr),
65         mNewExpr(nullptr) {
66   }
67 
68   void VisitStmt(clang::Stmt *S);
69   void VisitCompoundStmt(clang::CompoundStmt *CS);
70   void VisitCaseStmt(clang::CaseStmt *CS);
71   void VisitDefaultStmt(clang::DefaultStmt *DS);
72   void VisitDoStmt(clang::DoStmt *DS);
73   void VisitForStmt(clang::ForStmt *FS);
74   void VisitIfStmt(clang::IfStmt *IS);
75   void VisitSwitchCase(clang::SwitchCase *SC);
76   void VisitSwitchStmt(clang::SwitchStmt *SS);
77   void VisitWhileStmt(clang::WhileStmt *WS);
78 
79   // Replace all instances of OldStmt in OuterStmt with NewStmt.
80   void ReplaceStmt(
81       clang::Stmt *OuterStmt,
82       clang::Stmt *OldStmt,
83       clang::Stmt *NewStmt);
84 };
85 
86 }  // namespace slang
87 
88 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_AST_REPLACE_H_  NOLINT
89