Coverage Report

Created: 2025-06-13 06:55

/src/spirv-cross/spirv_parser.hpp
Line
Count
Source
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
40
  ParsedIR &get_parsed_ir()
41
600
  {
42
600
    return ir;
43
600
  }
44
45
private:
46
  ParsedIR ir;
47
  SPIRFunction *current_function = nullptr;
48
  SPIRBlock *current_block = nullptr;
49
  // For workarounds.
50
  bool ignore_trailing_block_opcodes = false;
51
52
  void parse(const Instruction &instr);
53
  const uint32_t *stream(const Instruction &instr) const;
54
55
  template <typename T, typename... P>
56
  T &set(uint32_t id, P &&... args)
57
57.4k
  {
58
57.4k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
57.4k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
57.4k
    var.self = id;
61
57.4k
    return var;
62
57.4k
  }
spirv_cross::SPIRString& spirv_cross::Parser::set<spirv_cross::SPIRString, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(unsigned int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&&)
Line
Count
Source
57
886
  {
58
886
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
886
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
886
    var.self = id;
61
886
    return var;
62
886
  }
spirv_cross::SPIRUndef& spirv_cross::Parser::set<spirv_cross::SPIRUndef, unsigned int&>(unsigned int, unsigned int&)
Line
Count
Source
57
1.81k
  {
58
1.81k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
1.81k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
1.81k
    var.self = id;
61
1.81k
    return var;
62
1.81k
  }
spirv_cross::SPIRExtension& spirv_cross::Parser::set<spirv_cross::SPIRExtension, spirv_cross::SPIRExtension::Extension&>(unsigned int, spirv_cross::SPIRExtension::Extension&)
Line
Count
Source
57
508
  {
58
508
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
508
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
508
    var.self = id;
61
508
    return var;
62
508
  }
spirv_cross::SPIRType& spirv_cross::Parser::set<spirv_cross::SPIRType, spv::Op&>(unsigned int, spv::Op&)
Line
Count
Source
57
18.7k
  {
58
18.7k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
18.7k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
18.7k
    var.self = id;
61
18.7k
    return var;
62
18.7k
  }
spirv_cross::SPIRType& spirv_cross::Parser::set<spirv_cross::SPIRType, spirv_cross::SPIRType&>(unsigned int, spirv_cross::SPIRType&)
Line
Count
Source
57
3.45k
  {
58
3.45k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
3.45k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
3.45k
    var.self = id;
61
3.45k
    return var;
62
3.45k
  }
spirv_cross::SPIRFunctionPrototype& spirv_cross::Parser::set<spirv_cross::SPIRFunctionPrototype, unsigned int&>(unsigned int, unsigned int&)
Line
Count
Source
57
5.83k
  {
58
5.83k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
5.83k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
5.83k
    var.self = id;
61
5.83k
    return var;
62
5.83k
  }
spirv_cross::SPIRVariable& spirv_cross::Parser::set<spirv_cross::SPIRVariable, unsigned int&, spv::StorageClass&, unsigned int&>(unsigned int, unsigned int&, spv::StorageClass&, unsigned int&)
Line
Count
Source
57
6.43k
  {
58
6.43k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
6.43k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
6.43k
    var.self = id;
61
6.43k
    return var;
62
6.43k
  }
spirv_cross::SPIRVariable& spirv_cross::Parser::set<spirv_cross::SPIRVariable, unsigned int&, spv::StorageClass>(unsigned int, unsigned int&, spv::StorageClass&&)
Line
Count
Source
57
3.07k
  {
58
3.07k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
3.07k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
3.07k
    var.self = id;
61
3.07k
    return var;
62
3.07k
  }
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int const&, unsigned long, bool>(unsigned int, unsigned int const&, unsigned long&&, bool&&)
Line
Count
Source
57
18
  {
58
18
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
18
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
18
    var.self = id;
61
18
    return var;
62
18
  }
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int const&, unsigned int const&, bool>(unsigned int, unsigned int const&, unsigned int const&, bool&&)
Line
Count
Source
57
3.90k
  {
58
3.90k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
3.90k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
3.90k
    var.self = id;
61
3.90k
    return var;
62
3.90k
  }
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int const&, unsigned int, bool>(unsigned int, unsigned int const&, unsigned int&&, bool&&)
Line
Count
Source
57
613
  {
58
613
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
613
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
613
    var.self = id;
61
613
    return var;
62
613
  }
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int&, unsigned int const*, unsigned int, bool>(unsigned int, unsigned int&, unsigned int const*&&, unsigned int&&, bool&&)
Line
Count
Source
57
409
  {
58
409
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
409
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
409
    var.self = id;
61
409
    return var;
62
409
  }
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int&, spirv_cross::SPIRConstant const* (&) [4], unsigned int&, bool>(unsigned int, unsigned int&, spirv_cross::SPIRConstant const* (&) [4], unsigned int&, bool&&)
Line
Count
Source
57
669
  {
58
669
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
669
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
669
    var.self = id;
61
669
    return var;
62
669
  }
spirv_cross::SPIRFunction& spirv_cross::Parser::set<spirv_cross::SPIRFunction, unsigned int&, unsigned int&>(unsigned int, unsigned int&, unsigned int&)
Line
Count
Source
57
450
  {
58
450
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
450
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
450
    var.self = id;
61
450
    return var;
62
450
  }
spirv_cross::SPIRBlock& spirv_cross::Parser::set<spirv_cross::SPIRBlock>(unsigned int)
Line
Count
Source
57
9.80k
  {
58
9.80k
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
9.80k
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
9.80k
    var.self = id;
61
9.80k
    return var;
62
9.80k
  }
spirv_cross::SPIRType& spirv_cross::Parser::set<spirv_cross::SPIRType, spv::Op>(unsigned int, spv::Op&&)
Line
Count
Source
57
28
  {
58
28
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
28
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
28
    var.self = id;
61
28
    return var;
62
28
  }
spirv_cross::SPIRConstant& spirv_cross::Parser::set<spirv_cross::SPIRConstant, unsigned int&>(unsigned int, unsigned int&)
Line
Count
Source
57
28
  {
58
28
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
28
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
28
    var.self = id;
61
28
    return var;
62
28
  }
spirv_cross::SPIRConstantOp& spirv_cross::Parser::set<spirv_cross::SPIRConstantOp, unsigned int&, spv::Op&, unsigned int const*, unsigned int>(unsigned int, unsigned int&, spv::Op&, unsigned int const*&&, unsigned int&&)
Line
Count
Source
57
791
  {
58
791
    ir.add_typed_id(static_cast<Types>(T::type), id);
59
791
    auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
60
791
    var.self = id;
61
791
    return var;
62
791
  }
63
64
  template <typename T>
65
  T &get(uint32_t id)
66
41.3k
  {
67
41.3k
    return variant_get<T>(ir.ids[id]);
68
41.3k
  }
spirv_cross::SPIRType& spirv_cross::Parser::get<spirv_cross::SPIRType>(unsigned int)
Line
Count
Source
66
38.9k
  {
67
38.9k
    return variant_get<T>(ir.ids[id]);
68
38.9k
  }
Unexecuted instantiation: spirv_cross::SPIRConstantOp& spirv_cross::Parser::get<spirv_cross::SPIRConstantOp>(unsigned int)
Unexecuted instantiation: spirv_cross::SPIRUndef& spirv_cross::Parser::get<spirv_cross::SPIRUndef>(unsigned int)
spirv_cross::SPIRConstant& spirv_cross::Parser::get<spirv_cross::SPIRConstant>(unsigned int)
Line
Count
Source
66
2.36k
  {
67
2.36k
    return variant_get<T>(ir.ids[id]);
68
2.36k
  }
69
70
  template <typename T>
71
  T *maybe_get(uint32_t id)
72
36.7k
  {
73
36.7k
    if (ir.ids[id].get_type() == static_cast<Types>(T::type))
74
27.1k
      return &get<T>(id);
75
9.60k
    else
76
9.60k
      return nullptr;
77
36.7k
  }
spirv_cross::SPIRType* spirv_cross::Parser::maybe_get<spirv_cross::SPIRType>(unsigned int)
Line
Count
Source
72
32.4k
  {
73
32.4k
    if (ir.ids[id].get_type() == static_cast<Types>(T::type))
74
26.7k
      return &get<T>(id);
75
5.65k
    else
76
5.65k
      return nullptr;
77
32.4k
  }
spirv_cross::SPIRConstant* spirv_cross::Parser::maybe_get<spirv_cross::SPIRConstant>(unsigned int)
Line
Count
Source
72
383
  {
73
383
    if (ir.ids[id].get_type() == static_cast<Types>(T::type))
74
383
      return &get<T>(id);
75
0
    else
76
0
      return nullptr;
77
383
  }
spirv_cross::SPIRConstantOp* spirv_cross::Parser::maybe_get<spirv_cross::SPIRConstantOp>(unsigned int)
Line
Count
Source
72
1.97k
  {
73
1.97k
    if (ir.ids[id].get_type() == static_cast<Types>(T::type))
74
0
      return &get<T>(id);
75
1.97k
    else
76
1.97k
      return nullptr;
77
1.97k
  }
spirv_cross::SPIRUndef* spirv_cross::Parser::maybe_get<spirv_cross::SPIRUndef>(unsigned int)
Line
Count
Source
72
1.97k
  {
73
1.97k
    if (ir.ids[id].get_type() == static_cast<Types>(T::type))
74
0
      return &get<T>(id);
75
1.97k
    else
76
1.97k
      return nullptr;
77
1.97k
  }
78
79
  template <typename T>
80
  const T &get(uint32_t id) const
81
3.51k
  {
82
3.51k
    return variant_get<T>(ir.ids[id]);
83
3.51k
  }
84
85
  template <typename T>
86
  const T *maybe_get(uint32_t id) const
87
  {
88
    if (ir.ids[id].get_type() == T::type)
89
      return &get<T>(id);
90
    else
91
      return nullptr;
92
  }
93
94
  // This must be an ordered data structure so we always pick the same type aliases.
95
  SmallVector<uint32_t> global_struct_cache;
96
  SmallVector<std::pair<uint32_t, uint32_t>> forward_pointer_fixups;
97
98
  bool types_are_logically_equivalent(const SPIRType &a, const SPIRType &b) const;
99
  bool variable_storage_is_aliased(const SPIRVariable &v) const;
100
};
101
} // namespace SPIRV_CROSS_NAMESPACE
102
103
#endif