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#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_AST_REPLACE_H_  // NOLINT
18292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_AST_REPLACE_H_
19292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
20292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "clang/AST/StmtVisitor.h"
21292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
22292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "slang_assert.h"
23292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "clang/AST/ASTContext.h"
24292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
25292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesnamespace clang {
26292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  class Diagnostic;
27292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  class Expr;
28292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  class Stmt;
29292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}
30292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
31292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesnamespace slang {
32292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
33292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesclass RSASTReplace : public clang::StmtVisitor<RSASTReplace> {
34292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines private:
35292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::ASTContext &C;
36292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::Stmt *mOuterStmt;
37292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::Stmt *mOldStmt;
38292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::Stmt *mNewStmt;
39292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::Expr *mOldExpr;
40292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  clang::Expr *mNewExpr;
41292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
42292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  inline bool matchesExpr(const clang::Expr *E) const {
43292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    bool retVal = mOldExpr && (mOldExpr == E);
44292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    if (retVal) {
45292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      slangAssert(mNewExpr &&
46292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines          "Cannot replace an expression if we don't have a new expression");
47292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    }
48292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    return retVal;
49292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
50292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
51292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  inline bool matchesStmt(const clang::Stmt *S) const {
52292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    slangAssert(mOldStmt);
53292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    return mOldStmt == S;
54292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
55292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
56292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void ReplaceInCompoundStmt(clang::CompoundStmt *CS);
57292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
58292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines public:
59292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  explicit RSASTReplace(clang::ASTContext &Con)
60292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      : C(Con),
61292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines        mOuterStmt(NULL),
62292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines        mOldStmt(NULL),
63292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines        mNewStmt(NULL),
64292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines        mOldExpr(NULL),
65292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines        mNewExpr(NULL) {
66292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines    return;
67292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  }
68292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
69292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitStmt(clang::Stmt *S);
70292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitCompoundStmt(clang::CompoundStmt *CS);
71292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitCaseStmt(clang::CaseStmt *CS);
72292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitDefaultStmt(clang::DefaultStmt *DS);
73292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitDoStmt(clang::DoStmt *DS);
74292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitForStmt(clang::ForStmt *FS);
75292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitIfStmt(clang::IfStmt *IS);
76292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitSwitchCase(clang::SwitchCase *SC);
77292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitSwitchStmt(clang::SwitchStmt *SS);
78292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void VisitWhileStmt(clang::WhileStmt *WS);
79292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
80292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  // Replace all instances of OldStmt in OuterStmt with NewStmt.
81292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines  void ReplaceStmt(
82292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      clang::Stmt *OuterStmt,
83292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      clang::Stmt *OldStmt,
84292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines      clang::Stmt *NewStmt);
85292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines};
86292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
87292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines}  // namespace slang
88292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines
89292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_AST_REPLACE_H_  NOLINT
90