blob: d0b96e029f0fccc55a67d145b1a827acc58301ec [file] [log] [blame]
// Copyright 2022 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_TINT_TRANSFORM_UTILS_HOIST_TO_DECL_BEFORE_H_
#define SRC_TINT_TRANSFORM_UTILS_HOIST_TO_DECL_BEFORE_H_
#include <memory>
#include "src/tint/sem/expression.h"
#include "src/tint/transform/transform.h"
namespace tint::transform {
/// Utility class that can be used to hoist expressions before other
/// expressions, possibly converting 'for-loop's to 'loop's and 'else-if's to
// 'else {if}'s.
class HoistToDeclBefore {
public:
/// Constructor
/// @param ctx the clone context
explicit HoistToDeclBefore(CloneContext& ctx);
/// Destructor
~HoistToDeclBefore();
/// Hoists `expr` to a `let` or `var` with optional `decl_name`, inserting it
/// before `before_expr`.
/// @param before_expr expression to insert `expr` before
/// @param expr expression to hoist
/// @param as_const hoist to `let` if true, otherwise to `var`
/// @param decl_name optional name to use for the variable/constant name
/// @return true on success
bool Add(const sem::Expression* before_expr,
const ast::Expression* expr,
bool as_const,
const char* decl_name = "");
/// Inserts `stmt` before `before_stmt`, possibly converting 'for-loop's to
/// 'loop's if necessary.
/// @param before_stmt statement to insert `stmt` before
/// @param stmt statement to insert
/// @return true on success
bool InsertBefore(const sem::Statement* before_stmt, const ast::Statement* stmt);
/// Use to signal that we plan on hoisting a decl before `before_expr`. This
/// will convert 'for-loop's to 'loop's and 'else-if's to 'else {if}'s if
/// needed.
/// @param before_expr expression we would hoist a decl before
/// @return true on success
bool Prepare(const sem::Expression* before_expr);
/// Applies any scheduled insertions from previous calls to Add() to
/// CloneContext. Call this once before ctx.Clone().
/// @return true on success
bool Apply();
private:
class State;
std::unique_ptr<State> state_;
};
} // namespace tint::transform
#endif // SRC_TINT_TRANSFORM_UTILS_HOIST_TO_DECL_BEFORE_H_