// Copyright 2021 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. #include "src/transform/unshadow.h" #include #include #include #include "src/program_builder.h" #include "src/sem/block_statement.h" #include "src/sem/function.h" #include "src/sem/statement.h" #include "src/sem/variable.h" TINT_INSTANTIATE_TYPEINFO(tint::transform::Unshadow); namespace tint { namespace transform { /// The PIMPL state for the Unshadow transform struct Unshadow::State { /// The clone context CloneContext& ctx; /// Constructor /// @param context the clone context explicit State(CloneContext& context) : ctx(context) {} /// Performs the transformation void Run() { auto& sem = ctx.src->Sem(); // Maps a variable to its new name. std::unordered_map renamed_to; auto rename = [&](const sem::Variable* var) -> const ast::Variable* { auto* decl = var->Declaration(); auto name = ctx.src->Symbols().NameFor(decl->symbol); auto symbol = ctx.dst->Symbols().New(name); renamed_to.emplace(var, symbol); auto source = ctx.Clone(decl->source); auto* type = ctx.Clone(decl->type); auto* constructor = ctx.Clone(decl->constructor); auto decorations = ctx.Clone(decl->decorations); return ctx.dst->create( source, symbol, decl->declared_storage_class, decl->declared_access, type, decl->is_const, constructor, decorations); }; ctx.ReplaceAll([&](const ast::Variable* var) -> const ast::Variable* { if (auto* local = sem.Get(var)) { if (local->Shadows()) { return rename(local); } } if (auto* param = sem.Get(var)) { if (param->Shadows()) { return rename(param); } } return nullptr; }); ctx.ReplaceAll([&](const ast::IdentifierExpression* ident) -> const tint::ast::IdentifierExpression* { if (auto* user = sem.Get(ident)) { auto it = renamed_to.find(user->Variable()); if (it != renamed_to.end()) { return ctx.dst->Expr(it->second); } } return nullptr; }); ctx.Clone(); } }; Unshadow::Unshadow() = default; Unshadow::~Unshadow() = default; void Unshadow::Run(CloneContext& ctx, const DataMap&, DataMap&) { State(ctx).Run(); } } // namespace transform } // namespace tint