1 /* 2 * Copyright 2018-2021 Arm Limited 3 * SPDX-License-Identifier: Apache-2.0 OR MIT 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 /* 19 * At your option, you may choose to accept this material under either: 20 * 1. The Apache License, Version 2.0, found at <http://www.apache.org/licenses/LICENSE-2.0>, or 21 * 2. The MIT License, found at <http://opensource.org/licenses/MIT>. 22 */ 23 24 #ifndef SPIRV_CROSS_PARSER_HPP 25 #define SPIRV_CROSS_PARSER_HPP 26 27 #include "spirv_cross_parsed_ir.hpp" 28 #include <stdint.h> 29 30 namespace SPIRV_CROSS_NAMESPACE 31 { 32 class Parser 33 { 34 public: 35 Parser(const uint32_t *spirv_data, size_t word_count); 36 Parser(std::vector<uint32_t> spirv); 37 38 void parse(); 39 get_parsed_ir()40 ParsedIR &get_parsed_ir() 41 { 42 return ir; 43 } 44 45 private: 46 ParsedIR ir; 47 SPIRFunction *current_function = nullptr; 48 SPIRBlock *current_block = nullptr; 49 50 void parse(const Instruction &instr); 51 const uint32_t *stream(const Instruction &instr) const; 52 53 template <typename T, typename... P> set(uint32_t id,P &&...args)54 T &set(uint32_t id, P &&... args) 55 { 56 ir.add_typed_id(static_cast<Types>(T::type), id); 57 auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...); 58 var.self = id; 59 return var; 60 } 61 62 template <typename T> get(uint32_t id)63 T &get(uint32_t id) 64 { 65 return variant_get<T>(ir.ids[id]); 66 } 67 68 template <typename T> maybe_get(uint32_t id)69 T *maybe_get(uint32_t id) 70 { 71 if (ir.ids[id].get_type() == static_cast<Types>(T::type)) 72 return &get<T>(id); 73 else 74 return nullptr; 75 } 76 77 template <typename T> get(uint32_t id) const78 const T &get(uint32_t id) const 79 { 80 return variant_get<T>(ir.ids[id]); 81 } 82 83 template <typename T> maybe_get(uint32_t id) const84 const T *maybe_get(uint32_t id) const 85 { 86 if (ir.ids[id].get_type() == T::type) 87 return &get<T>(id); 88 else 89 return nullptr; 90 } 91 92 // This must be an ordered data structure so we always pick the same type aliases. 93 SmallVector<uint32_t> global_struct_cache; 94 SmallVector<std::pair<uint32_t, uint32_t>> forward_pointer_fixups; 95 96 bool types_are_logically_equivalent(const SPIRType &a, const SPIRType &b) const; 97 bool variable_storage_is_aliased(const SPIRVariable &v) const; 98 }; 99 } // namespace SPIRV_CROSS_NAMESPACE 100 101 #endif 102