| // Copyright 2020 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/reader/spirv/function.h" |
| |
| #include "source/opt/basic_block.h" |
| #include "source/opt/function.h" |
| #include "source/opt/instruction.h" |
| #include "source/opt/module.h" |
| #include "src/ast/variable.h" |
| #include "src/ast/variable_decl_statement.h" |
| #include "src/reader/spirv/fail_stream.h" |
| #include "src/reader/spirv/parser_impl.h" |
| |
| namespace tint { |
| namespace reader { |
| namespace spirv { |
| |
| FunctionEmitter::FunctionEmitter(ParserImpl* pi, |
| const spvtools::opt::Function& function) |
| : parser_impl_(*pi), |
| ast_module_(pi->get_module()), |
| ir_context_(*(pi->ir_context())), |
| fail_stream_(pi->fail_stream()), |
| namer_(pi->namer()), |
| function_(function) {} |
| |
| FunctionEmitter::~FunctionEmitter() = default; |
| |
| bool FunctionEmitter::Emit() { |
| // We only care about functions with bodies. |
| if (function_.cbegin() == function_.cend()) { |
| return true; |
| } |
| |
| const auto name = namer_.Name(function_.result_id()); |
| // Surprisingly, the "type id" on an OpFunction is the result type of the |
| // function, not the type of the function. This is the one exceptional case |
| // in SPIR-V where the type ID is not the type of the result ID. |
| auto* ret_ty = parser_impl_.ConvertType(function_.type_id()); |
| if (failed()) { |
| return false; |
| } |
| if (ret_ty == nullptr) { |
| return Fail() |
| << "internal error: unregistered return type for function with ID " |
| << function_.result_id(); |
| } |
| |
| std::vector<std::unique_ptr<ast::Variable>> ast_params; |
| function_.ForEachParam( |
| [this, &ast_params](const spvtools::opt::Instruction* param) { |
| auto* ast_type = parser_impl_.ConvertType(param->type_id()); |
| if (ast_type != nullptr) { |
| ast_params.emplace_back(parser_impl_.MakeVariable( |
| param->result_id(), ast::StorageClass::kNone, ast_type)); |
| } else { |
| // We've already logged an error and emitted a diagnostic. Do nothing |
| // here. |
| } |
| }); |
| if (failed()) { |
| return false; |
| } |
| |
| auto ast_fn = |
| std::make_unique<ast::Function>(name, std::move(ast_params), ret_ty); |
| ast_module_.AddFunction(std::move(ast_fn)); |
| |
| return success(); |
| } |
| |
| } // namespace spirv |
| } // namespace reader |
| } // namespace tint |