/*
 * Copyright 2015-2018 ARM Limited
 *
 * 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 SPIRV_CROSS_HPP
#define SPIRV_CROSS_HPP

#include "spirv.hpp"
#include "spirv_cfg.hpp"
#include "spirv_cross_parsed_ir.hpp"

namespace spirv_cross
{
struct Resource
{
	// Resources are identified with their SPIR-V ID.
	// This is the ID of the OpVariable.
	uint32_t id;

	// The type ID of the variable which includes arrays and all type modifications.
	// This type ID is not suitable for parsing OpMemberDecoration of a struct and other decorations in general
	// since these modifications typically happen on the base_type_id.
	uint32_t type_id;

	// The base type of the declared resource.
	// This type is the base type which ignores pointers and arrays of the type_id.
	// This is mostly useful to parse decorations of the underlying type.
	// base_type_id can also be obtained with get_type(get_type(type_id).self).
	uint32_t base_type_id;

	// The declared name (OpName) of the resource.
	// For Buffer blocks, the name actually reflects the externally
	// visible Block name.
	//
	// This name can be retrieved again by using either
	// get_name(id) or get_name(base_type_id) depending if it's a buffer block or not.
	//
	// This name can be an empty string in which case get_fallback_name(id) can be
	// used which obtains a suitable fallback identifier for an ID.
	std::string name;
};

struct ShaderResources
{
	std::vector<Resource> uniform_buffers;
	std::vector<Resource> storage_buffers;
	std::vector<Resource> stage_inputs;
	std::vector<Resource> stage_outputs;
	std::vector<Resource> subpass_inputs;
	std::vector<Resource> storage_images;
	std::vector<Resource> sampled_images;
	std::vector<Resource> atomic_counters;

	// There can only be one push constant block,
	// but keep the vector in case this restriction is lifted in the future.
	std::vector<Resource> push_constant_buffers;

	// For Vulkan GLSL and HLSL source,
	// these correspond to separate texture2D and samplers respectively.
	std::vector<Resource> separate_images;
	std::vector<Resource> separate_samplers;
};

struct CombinedImageSampler
{
	// The ID of the sampler2D variable.
	uint32_t combined_id;
	// The ID of the texture2D variable.
	uint32_t image_id;
	// The ID of the sampler variable.
	uint32_t sampler_id;
};

struct SpecializationConstant
{
	// The ID of the specialization constant.
	uint32_t id;
	// The constant ID of the constant, used in Vulkan during pipeline creation.
	uint32_t constant_id;
};

struct BufferRange
{
	unsigned index;
	size_t offset;
	size_t range;
};

enum BufferPackingStandard
{
	BufferPackingStd140,
	BufferPackingStd430,
	BufferPackingStd140EnhancedLayout,
	BufferPackingStd430EnhancedLayout,
	BufferPackingHLSLCbuffer,
	BufferPackingHLSLCbufferPackOffset
};

struct EntryPoint
{
	std::string name;
	spv::ExecutionModel execution_model;
};

class Compiler
{
public:
	friend class CFG;
	friend class DominatorBuilder;

	// The constructor takes a buffer of SPIR-V words and parses it.
	// It will create its own parser, parse the SPIR-V and move the parsed IR
	// as if you had called the constructors taking ParsedIR directly.
	explicit Compiler(std::vector<uint32_t> ir);
	Compiler(const uint32_t *ir, size_t word_count);

	// This is more modular. We can also consume a ParsedIR structure directly, either as a move, or copy.
	// With copy, we can reuse the same parsed IR for multiple Compiler instances.
	explicit Compiler(const ParsedIR &ir);
	explicit Compiler(ParsedIR &&ir);

	virtual ~Compiler() = default;

	// After parsing, API users can modify the SPIR-V via reflection and call this
	// to disassemble the SPIR-V into the desired langauage.
	// Sub-classes actually implement this.
	virtual std::string compile();

	// Gets the identifier (OpName) of an ID. If not defined, an empty string will be returned.
	const std::string &get_name(uint32_t id) const;

	// Applies a decoration to an ID. Effectively injects OpDecorate.
	void set_decoration(uint32_t id, spv::Decoration decoration, uint32_t argument = 0);
	void set_decoration_string(uint32_t id, spv::Decoration decoration, const std::string &argument);

	// Overrides the identifier OpName of an ID.
	// Identifiers beginning with underscores or identifiers which contain double underscores
	// are reserved by the implementation.
	void set_name(uint32_t id, const std::string &name);

	// Gets a bitmask for the decorations which are applied to ID.
	// I.e. (1ull << spv::DecorationFoo) | (1ull << spv::DecorationBar)
	SPIRV_CROSS_DEPRECATED("Please use get_decoration_bitset instead.")
	uint64_t get_decoration_mask(uint32_t id) const;
	const Bitset &get_decoration_bitset(uint32_t id) const;

	// Returns whether the decoration has been applied to the ID.
	bool has_decoration(uint32_t id, spv::Decoration decoration) const;

	// Gets the value for decorations which take arguments.
	// If the decoration is a boolean (i.e. spv::DecorationNonWritable),
	// 1 will be returned.
	// If decoration doesn't exist or decoration is not recognized,
	// 0 will be returned.
	uint32_t get_decoration(uint32_t id, spv::Decoration decoration) const;
	const std::string &get_decoration_string(uint32_t id, spv::Decoration decoration) const;

	// Removes the decoration for an ID.
	void unset_decoration(uint32_t id, spv::Decoration decoration);

	// Gets the SPIR-V type associated with ID.
	// Mostly used with Resource::type_id and Resource::base_type_id to parse the underlying type of a resource.
	const SPIRType &get_type(uint32_t id) const;

	// Gets the SPIR-V type of a variable.
	const SPIRType &get_type_from_variable(uint32_t id) const;

	// Gets the id of SPIR-V type underlying the given type_id, which might be a pointer.
	uint32_t get_non_pointer_type_id(uint32_t type_id) const;

	// Gets the SPIR-V type underlying the given type, which might be a pointer.
	const SPIRType &get_non_pointer_type(const SPIRType &type) const;

	// Gets the SPIR-V type underlying the given type_id, which might be a pointer.
	const SPIRType &get_non_pointer_type(uint32_t type_id) const;

	// Returns if the given type refers to a sampled image.
	bool is_sampled_image_type(const SPIRType &type);

	// Gets the underlying storage class for an OpVariable.
	spv::StorageClass get_storage_class(uint32_t id) const;

	// If get_name() is an empty string, get the fallback name which will be used
	// instead in the disassembled source.
	virtual const std::string get_fallback_name(uint32_t id) const;

	// If get_name() of a Block struct is an empty string, get the fallback name.
	// This needs to be per-variable as multiple variables can use the same block type.
	virtual const std::string get_block_fallback_name(uint32_t id) const;

	// Given an OpTypeStruct in ID, obtain the identifier for member number "index".
	// This may be an empty string.
	const std::string &get_member_name(uint32_t id, uint32_t index) const;

	// Given an OpTypeStruct in ID, obtain the OpMemberDecoration for member number "index".
	uint32_t get_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration) const;
	const std::string &get_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration) const;

	// Sets the member identifier for OpTypeStruct ID, member number "index".
	void set_member_name(uint32_t id, uint32_t index, const std::string &name);

	// Returns the qualified member identifier for OpTypeStruct ID, member number "index",
	// or an empty string if no qualified alias exists
	const std::string &get_member_qualified_name(uint32_t type_id, uint32_t index) const;

	// Sets the qualified member identifier for OpTypeStruct ID, member number "index".
	void set_member_qualified_name(uint32_t type_id, uint32_t index, const std::string &name);

	// Gets the decoration mask for a member of a struct, similar to get_decoration_mask.
	SPIRV_CROSS_DEPRECATED("Please use get_member_decoration_bitset instead.")
	uint64_t get_member_decoration_mask(uint32_t id, uint32_t index) const;
	const Bitset &get_member_decoration_bitset(uint32_t id, uint32_t index) const;

	// Returns whether the decoration has been applied to a member of a struct.
	bool has_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration) const;

	// Similar to set_decoration, but for struct members.
	void set_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration, uint32_t argument = 0);
	void set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,
	                                  const std::string &argument);

	// Unsets a member decoration, similar to unset_decoration.
	void unset_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration);

	// Gets the fallback name for a member, similar to get_fallback_name.
	virtual const std::string get_fallback_member_name(uint32_t index) const
	{
		return join("_", index);
	}

	// Returns a vector of which members of a struct are potentially in use by a
	// SPIR-V shader. The granularity of this analysis is per-member of a struct.
	// This can be used for Buffer (UBO), BufferBlock/StorageBuffer (SSBO) and PushConstant blocks.
	// ID is the Resource::id obtained from get_shader_resources().
	std::vector<BufferRange> get_active_buffer_ranges(uint32_t id) const;

	// Returns the effective size of a buffer block.
	size_t get_declared_struct_size(const SPIRType &struct_type) const;

	// Returns the effective size of a buffer block, with a given array size
	// for a runtime array.
	// SSBOs are typically declared as runtime arrays. get_declared_struct_size() will return 0 for the size.
	// This is not very helpful for applications which might need to know the array stride of its last member.
	// This can be done through the API, but it is not very intuitive how to accomplish this, so here we provide a helper function
	// to query the size of the buffer, assuming that the last member has a certain size.
	// If the buffer does not contain a runtime array, array_size is ignored, and the function will behave as
	// get_declared_struct_size().
	// To get the array stride of the last member, something like:
	// get_declared_struct_size_runtime_array(type, 1) - get_declared_struct_size_runtime_array(type, 0) will work.
	size_t get_declared_struct_size_runtime_array(const SPIRType &struct_type, size_t array_size) const;

	// Returns the effective size of a buffer block struct member.
	virtual size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const;

	// Legacy GLSL compatibility method. Deprecated in favor of CompilerGLSL::flatten_buffer_block
	SPIRV_CROSS_DEPRECATED("Please use flatten_buffer_block instead.") void flatten_interface_block(uint32_t id);

	// Returns a set of all global variables which are statically accessed
	// by the control flow graph from the current entry point.
	// Only variables which change the interface for a shader are returned, that is,
	// variables with storage class of Input, Output, Uniform, UniformConstant, PushConstant and AtomicCounter
	// storage classes are returned.
	//
	// To use the returned set as the filter for which variables are used during compilation,
	// this set can be moved to set_enabled_interface_variables().
	std::unordered_set<uint32_t> get_active_interface_variables() const;

	// Sets the interface variables which are used during compilation.
	// By default, all variables are used.
	// Once set, compile() will only consider the set in active_variables.
	void set_enabled_interface_variables(std::unordered_set<uint32_t> active_variables);

	// Query shader resources, use ids with reflection interface to modify or query binding points, etc.
	ShaderResources get_shader_resources() const;

	// Query shader resources, but only return the variables which are part of active_variables.
	// E.g.: get_shader_resources(get_active_variables()) to only return the variables which are statically
	// accessed.
	ShaderResources get_shader_resources(const std::unordered_set<uint32_t> &active_variables) const;

	// Remapped variables are considered built-in variables and a backend will
	// not emit a declaration for this variable.
	// This is mostly useful for making use of builtins which are dependent on extensions.
	void set_remapped_variable_state(uint32_t id, bool remap_enable);
	bool get_remapped_variable_state(uint32_t id) const;

	// For subpassInput variables which are remapped to plain variables,
	// the number of components in the remapped
	// variable must be specified as the backing type of subpass inputs are opaque.
	void set_subpass_input_remapped_components(uint32_t id, uint32_t components);
	uint32_t get_subpass_input_remapped_components(uint32_t id) const;

	// All operations work on the current entry point.
	// Entry points can be swapped out with set_entry_point().
	// Entry points should be set right after the constructor completes as some reflection functions traverse the graph from the entry point.
	// Resource reflection also depends on the entry point.
	// By default, the current entry point is set to the first OpEntryPoint which appears in the SPIR-V module.
	SPIRV_CROSS_DEPRECATED("Please use get_entry_points_and_stages instead.")
	std::vector<std::string> get_entry_points() const;
	SPIRV_CROSS_DEPRECATED("Please use set_entry_point(const std::string &, spv::ExecutionModel) instead.")
	void set_entry_point(const std::string &name);

	// Renames an entry point from old_name to new_name.
	// If old_name is currently selected as the current entry point, it will continue to be the current entry point,
	// albeit with a new name.
	// get_entry_points() is essentially invalidated at this point.
	SPIRV_CROSS_DEPRECATED(
	    "Please use rename_entry_point(const std::string&, const std::string&, spv::ExecutionModel) instead.")
	void rename_entry_point(const std::string &old_name, const std::string &new_name);

	// Returns the internal data structure for entry points to allow poking around.
	SPIRV_CROSS_DEPRECATED("Please use get_entry_point(const std::string &, spv::ExecutionModel instead.")
	const SPIREntryPoint &get_entry_point(const std::string &name) const;
	SPIRV_CROSS_DEPRECATED("Please use get_entry_point(const std::string &, spv::ExecutionModel instead.")
	SPIREntryPoint &get_entry_point(const std::string &name);

	// Some shader languages restrict the names that can be given to entry points, and the
	// corresponding backend will automatically rename an entry point name, during the call
	// to compile() if it is illegal. For example, the common entry point name main() is
	// illegal in MSL, and is renamed to an alternate name by the MSL backend.
	// Given the original entry point name contained in the SPIR-V, this function returns
	// the name, as updated by the backend during the call to compile(). If the name is not
	// illegal, and has not been renamed, or if this function is called before compile(),
	// this function will simply return the same name.
	SPIRV_CROSS_DEPRECATED(
	    "Please use get_cleansed_entry_point_name(const std::string &, spv::ExecutionModel) instead.")
	const std::string &get_cleansed_entry_point_name(const std::string &name) const;

	// New variants of entry point query and reflection.
	// Names for entry points in the SPIR-V module may alias if they belong to different execution models.
	// To disambiguate, we must pass along with the entry point names the execution model.
	std::vector<EntryPoint> get_entry_points_and_stages() const;
	void set_entry_point(const std::string &entry, spv::ExecutionModel execution_model);
	void rename_entry_point(const std::string &old_name, const std::string &new_name,
	                        spv::ExecutionModel execution_model);
	const SPIREntryPoint &get_entry_point(const std::string &name, spv::ExecutionModel execution_model) const;
	SPIREntryPoint &get_entry_point(const std::string &name, spv::ExecutionModel execution_model);
	const std::string &get_cleansed_entry_point_name(const std::string &name,
	                                                 spv::ExecutionModel execution_model) const;

	// Query and modify OpExecutionMode.
	SPIRV_CROSS_DEPRECATED("Please use get_execution_mode_bitset instead.")
	uint64_t get_execution_mode_mask() const;
	const Bitset &get_execution_mode_bitset() const;

	void unset_execution_mode(spv::ExecutionMode mode);
	void set_execution_mode(spv::ExecutionMode mode, uint32_t arg0 = 0, uint32_t arg1 = 0, uint32_t arg2 = 0);

	// Gets argument for an execution mode (LocalSize, Invocations, OutputVertices).
	// For LocalSize, the index argument is used to select the dimension (X = 0, Y = 1, Z = 2).
	// For execution modes which do not have arguments, 0 is returned.
	uint32_t get_execution_mode_argument(spv::ExecutionMode mode, uint32_t index = 0) const;
	spv::ExecutionModel get_execution_model() const;

	// In SPIR-V, the compute work group size can be represented by a constant vector, in which case
	// the LocalSize execution mode is ignored.
	//
	// This constant vector can be a constant vector, specialization constant vector, or partly specialized constant vector.
	// To modify and query work group dimensions which are specialization constants, SPIRConstant values must be modified
	// directly via get_constant() rather than using LocalSize directly. This function will return which constants should be modified.
	//
	// To modify dimensions which are *not* specialization constants, set_execution_mode should be used directly.
	// Arguments to set_execution_mode which are specialization constants are effectively ignored during compilation.
	// NOTE: This is somewhat different from how SPIR-V works. In SPIR-V, the constant vector will completely replace LocalSize,
	// while in this interface, LocalSize is only ignored for specialization constants.
	//
	// The specialization constant will be written to x, y and z arguments.
	// If the component is not a specialization constant, a zeroed out struct will be written.
	// The return value is the constant ID of the builtin WorkGroupSize, but this is not expected to be useful
	// for most use cases.
	uint32_t get_work_group_size_specialization_constants(SpecializationConstant &x, SpecializationConstant &y,
	                                                      SpecializationConstant &z) const;

	// Analyzes all OpImageFetch (texelFetch) opcodes and checks if there are instances where
	// said instruction is used without a combined image sampler.
	// GLSL targets do not support the use of texelFetch without a sampler.
	// To workaround this, we must inject a dummy sampler which can be used to form a sampler2D at the call-site of
	// texelFetch as necessary.
	//
	// This must be called before build_combined_image_samplers().
	// build_combined_image_samplers() may refer to the ID returned by this method if the returned ID is non-zero.
	// The return value will be the ID of a sampler object if a dummy sampler is necessary, or 0 if no sampler object
	// is required.
	//
	// If the returned ID is non-zero, it can be decorated with set/bindings as desired before calling compile().
	// Calling this function also invalidates get_active_interface_variables(), so this should be called
	// before that function.
	uint32_t build_dummy_sampler_for_combined_images();

	// Analyzes all separate image and samplers used from the currently selected entry point,
	// and re-routes them all to a combined image sampler instead.
	// This is required to "support" separate image samplers in targets which do not natively support
	// this feature, like GLSL/ESSL.
	//
	// This must be called before compile() if such remapping is desired.
	// This call will add new sampled images to the SPIR-V,
	// so it will appear in reflection if get_shader_resources() is called after build_combined_image_samplers.
	//
	// If any image/sampler remapping was found, no separate image/samplers will appear in the decompiled output,
	// but will still appear in reflection.
	//
	// The resulting samplers will be void of any decorations like name, descriptor sets and binding points,
	// so this can be added before compile() if desired.
	//
	// Combined image samplers originating from this set are always considered active variables.
	// Arrays of separate samplers are not supported, but arrays of separate images are supported.
	// Array of images + sampler -> Array of combined image samplers.
	void build_combined_image_samplers();

	// Gets a remapping for the combined image samplers.
	const std::vector<CombinedImageSampler> &get_combined_image_samplers() const
	{
		return combined_image_samplers;
	}

	// Set a new variable type remap callback.
	// The type remapping is designed to allow global interface variable to assume more special types.
	// A typical example here is to remap sampler2D into samplerExternalOES, which currently isn't supported
	// directly by SPIR-V.
	//
	// In compile() while emitting code,
	// for every variable that is declared, including function parameters, the callback will be called
	// and the API user has a chance to change the textual representation of the type used to declare the variable.
	// The API user can detect special patterns in names to guide the remapping.
	void set_variable_type_remap_callback(VariableTypeRemapCallback cb)
	{
		variable_remap_callback = std::move(cb);
	}

	// API for querying which specialization constants exist.
	// To modify a specialization constant before compile(), use get_constant(constant.id),
	// then update constants directly in the SPIRConstant data structure.
	// For composite types, the subconstants can be iterated over and modified.
	// constant_type is the SPIRType for the specialization constant,
	// which can be queried to determine which fields in the unions should be poked at.
	std::vector<SpecializationConstant> get_specialization_constants() const;
	SPIRConstant &get_constant(uint32_t id);
	const SPIRConstant &get_constant(uint32_t id) const;

	uint32_t get_current_id_bound() const
	{
		return uint32_t(ir.ids.size());
	}

	// API for querying buffer objects.
	// The type passed in here should be the base type of a resource, i.e.
	// get_type(resource.base_type_id)
	// as decorations are set in the basic Block type.
	// The type passed in here must have these decorations set, or an exception is raised.
	// Only UBOs and SSBOs or sub-structs which are part of these buffer types will have these decorations set.
	uint32_t type_struct_member_offset(const SPIRType &type, uint32_t index) const;
	uint32_t type_struct_member_array_stride(const SPIRType &type, uint32_t index) const;
	uint32_t type_struct_member_matrix_stride(const SPIRType &type, uint32_t index) const;

	// Gets the offset in SPIR-V words (uint32_t) for a decoration which was originally declared in the SPIR-V binary.
	// The offset will point to one or more uint32_t literals which can be modified in-place before using the SPIR-V binary.
	// Note that adding or removing decorations using the reflection API will not change the behavior of this function.
	// If the decoration was declared, sets the word_offset to an offset into the provided SPIR-V binary buffer and returns true,
	// otherwise, returns false.
	// If the decoration does not have any value attached to it (e.g. DecorationRelaxedPrecision), this function will also return false.
	bool get_binary_offset_for_decoration(uint32_t id, spv::Decoration decoration, uint32_t &word_offset) const;

	// HLSL counter buffer reflection interface.
	// Append/Consume/Increment/Decrement in HLSL is implemented as two "neighbor" buffer objects where
	// one buffer implements the storage, and a single buffer containing just a lone "int" implements the counter.
	// To SPIR-V these will be exposed as two separate buffers, but glslang HLSL frontend emits a special indentifier
	// which lets us link the two buffers together.

	// Queries if a variable ID is a counter buffer which "belongs" to a regular buffer object.

	// If SPV_GOOGLE_hlsl_functionality1 is used, this can be used even with a stripped SPIR-V module.
	// Otherwise, this query is purely based on OpName identifiers as found in the SPIR-V module, and will
	// only return true if OpSource was reported HLSL.
	// To rely on this functionality, ensure that the SPIR-V module is not stripped.

	bool buffer_is_hlsl_counter_buffer(uint32_t id) const;

	// Queries if a buffer object has a neighbor "counter" buffer.
	// If so, the ID of that counter buffer will be returned in counter_id.
	// If SPV_GOOGLE_hlsl_functionality1 is used, this can be used even with a stripped SPIR-V module.
	// Otherwise, this query is purely based on OpName identifiers as found in the SPIR-V module, and will
	// only return true if OpSource was reported HLSL.
	// To rely on this functionality, ensure that the SPIR-V module is not stripped.
	bool buffer_get_hlsl_counter_buffer(uint32_t id, uint32_t &counter_id) const;

	// Gets the list of all SPIR-V Capabilities which were declared in the SPIR-V module.
	const std::vector<spv::Capability> &get_declared_capabilities() const;

	// Gets the list of all SPIR-V extensions which were declared in the SPIR-V module.
	const std::vector<std::string> &get_declared_extensions() const;

	// When declaring buffer blocks in GLSL, the name declared in the GLSL source
	// might not be the same as the name declared in the SPIR-V module due to naming conflicts.
	// In this case, SPIRV-Cross needs to find a fallback-name, and it might only
	// be possible to know this name after compiling to GLSL.
	// This is particularly important for HLSL input and UAVs which tends to reuse the same block type
	// for multiple distinct blocks. For these cases it is not possible to modify the name of the type itself
	// because it might be unique. Instead, you can use this interface to check after compilation which
	// name was actually used if your input SPIR-V tends to have this problem.
	// For other names like remapped names for variables, etc, it's generally enough to query the name of the variables
	// after compiling, block names are an exception to this rule.
	// ID is the name of a variable as returned by Resource::id, and must be a variable with a Block-like type.
	//
	// This also applies to HLSL cbuffers.
	std::string get_remapped_declared_block_name(uint32_t id) const;

	// For buffer block variables, get the decorations for that variable.
	// Sometimes, decorations for buffer blocks are found in member decorations instead
	// of direct decorations on the variable itself.
	// The most common use here is to check if a buffer is readonly or writeonly.
	Bitset get_buffer_block_flags(uint32_t id) const;

protected:
	const uint32_t *stream(const Instruction &instr) const
	{
		// If we're not going to use any arguments, just return nullptr.
		// We want to avoid case where we return an out of range pointer
		// that trips debug assertions on some platforms.
		if (!instr.length)
			return nullptr;

		if (instr.offset + instr.length > ir.spirv.size())
			SPIRV_CROSS_THROW("Compiler::stream() out of range.");
		return &ir.spirv[instr.offset];
	}

	ParsedIR ir;
	// Marks variables which have global scope and variables which can alias with other variables
	// (SSBO, image load store, etc)
	std::vector<uint32_t> global_variables;
	std::vector<uint32_t> aliased_variables;

	SPIRFunction *current_function = nullptr;
	SPIRBlock *current_block = nullptr;
	std::unordered_set<uint32_t> active_interface_variables;
	bool check_active_interface_variables = false;

	// If our IDs are out of range here as part of opcodes, throw instead of
	// undefined behavior.
	template <typename T, typename... P>
	T &set(uint32_t id, P &&... args)
	{
		auto &var = variant_set<T>(ir.ids.at(id), std::forward<P>(args)...);
		var.self = id;
		return var;
	}

	template <typename T>
	T &get(uint32_t id)
	{
		return variant_get<T>(ir.ids.at(id));
	}

	template <typename T>
	T *maybe_get(uint32_t id)
	{
		if (ir.ids.at(id).get_type() == T::type)
			return &get<T>(id);
		else
			return nullptr;
	}

	template <typename T>
	const T &get(uint32_t id) const
	{
		return variant_get<T>(ir.ids.at(id));
	}

	template <typename T>
	const T *maybe_get(uint32_t id) const
	{
		if (ir.ids.at(id).get_type() == T::type)
			return &get<T>(id);
		else
			return nullptr;
	}

	const SPIREntryPoint &get_entry_point() const;
	SPIREntryPoint &get_entry_point();

	virtual std::string to_name(uint32_t id, bool allow_alias = true) const;
	bool is_builtin_variable(const SPIRVariable &var) const;
	bool is_builtin_type(const SPIRType &type) const;
	bool is_hidden_variable(const SPIRVariable &var, bool include_builtins = false) const;
	bool is_immutable(uint32_t id) const;
	bool is_member_builtin(const SPIRType &type, uint32_t index, spv::BuiltIn *builtin) const;
	bool is_scalar(const SPIRType &type) const;
	bool is_vector(const SPIRType &type) const;
	bool is_matrix(const SPIRType &type) const;
	bool is_array(const SPIRType &type) const;
	uint32_t expression_type_id(uint32_t id) const;
	const SPIRType &expression_type(uint32_t id) const;
	bool expression_is_lvalue(uint32_t id) const;
	bool variable_storage_is_aliased(const SPIRVariable &var);
	SPIRVariable *maybe_get_backing_variable(uint32_t chain);

	void register_read(uint32_t expr, uint32_t chain, bool forwarded);
	void register_write(uint32_t chain);

	inline bool is_continue(uint32_t next) const
	{
		return (ir.block_meta[next] & ParsedIR::BLOCK_META_CONTINUE_BIT) != 0;
	}

	inline bool is_single_block_loop(uint32_t next) const
	{
		auto &block = get<SPIRBlock>(next);
		return block.merge == SPIRBlock::MergeLoop && block.continue_block == next;
	}

	inline bool is_break(uint32_t next) const
	{
		return (ir.block_meta[next] &
		        (ParsedIR::BLOCK_META_LOOP_MERGE_BIT | ParsedIR::BLOCK_META_MULTISELECT_MERGE_BIT)) != 0;
	}

	inline bool is_loop_break(uint32_t next) const
	{
		return (ir.block_meta[next] & ParsedIR::BLOCK_META_LOOP_MERGE_BIT) != 0;
	}

	inline bool is_conditional(uint32_t next) const
	{
		return (ir.block_meta[next] &
		        (ParsedIR::BLOCK_META_SELECTION_MERGE_BIT | ParsedIR::BLOCK_META_MULTISELECT_MERGE_BIT)) != 0;
	}

	// Dependency tracking for temporaries read from variables.
	void flush_dependees(SPIRVariable &var);
	void flush_all_active_variables();
	void flush_control_dependent_expressions(uint32_t block);
	void flush_all_atomic_capable_variables();
	void flush_all_aliased_variables();
	void register_global_read_dependencies(const SPIRBlock &func, uint32_t id);
	void register_global_read_dependencies(const SPIRFunction &func, uint32_t id);
	std::unordered_set<uint32_t> invalid_expressions;

	void update_name_cache(std::unordered_set<std::string> &cache, std::string &name);

	bool function_is_pure(const SPIRFunction &func);
	bool block_is_pure(const SPIRBlock &block);
	bool block_is_outside_flow_control_from_block(const SPIRBlock &from, const SPIRBlock &to);

	bool execution_is_branchless(const SPIRBlock &from, const SPIRBlock &to) const;
	bool execution_is_noop(const SPIRBlock &from, const SPIRBlock &to) const;
	SPIRBlock::ContinueBlockType continue_block_type(const SPIRBlock &continue_block) const;

	bool force_recompile = false;

	bool block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method method) const;

	bool types_are_logically_equivalent(const SPIRType &a, const SPIRType &b) const;
	void inherit_expression_dependencies(uint32_t dst, uint32_t source);

	// For proper multiple entry point support, allow querying if an Input or Output
	// variable is part of that entry points interface.
	bool interface_variable_exists_in_entry_point(uint32_t id) const;

	std::vector<CombinedImageSampler> combined_image_samplers;

	void remap_variable_type_name(const SPIRType &type, const std::string &var_name, std::string &type_name) const
	{
		if (variable_remap_callback)
			variable_remap_callback(type, var_name, type_name);
	}

	void set_ir(const ParsedIR &parsed);
	void set_ir(ParsedIR &&parsed);
	void parse_fixup();

	// Used internally to implement various traversals for queries.
	struct OpcodeHandler
	{
		virtual ~OpcodeHandler() = default;

		// Return true if traversal should continue.
		// If false, traversal will end immediately.
		virtual bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) = 0;

		virtual bool follow_function_call(const SPIRFunction &)
		{
			return true;
		}

		virtual void set_current_block(const SPIRBlock &)
		{
		}

		virtual bool begin_function_scope(const uint32_t *, uint32_t)
		{
			return true;
		}

		virtual bool end_function_scope(const uint32_t *, uint32_t)
		{
			return true;
		}
	};

	struct BufferAccessHandler : OpcodeHandler
	{
		BufferAccessHandler(const Compiler &compiler_, std::vector<BufferRange> &ranges_, uint32_t id_)
		    : compiler(compiler_)
		    , ranges(ranges_)
		    , id(id_)
		{
		}

		bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;

		const Compiler &compiler;
		std::vector<BufferRange> &ranges;
		uint32_t id;

		std::unordered_set<uint32_t> seen;
	};

	struct InterfaceVariableAccessHandler : OpcodeHandler
	{
		InterfaceVariableAccessHandler(const Compiler &compiler_, std::unordered_set<uint32_t> &variables_)
		    : compiler(compiler_)
		    , variables(variables_)
		{
		}

		bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;

		const Compiler &compiler;
		std::unordered_set<uint32_t> &variables;
	};

	struct CombinedImageSamplerHandler : OpcodeHandler
	{
		CombinedImageSamplerHandler(Compiler &compiler_)
		    : compiler(compiler_)
		{
		}
		bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
		bool begin_function_scope(const uint32_t *args, uint32_t length) override;
		bool end_function_scope(const uint32_t *args, uint32_t length) override;

		Compiler &compiler;

		// Each function in the call stack needs its own remapping for parameters so we can deduce which global variable each texture/sampler the parameter is statically bound to.
		std::stack<std::unordered_map<uint32_t, uint32_t>> parameter_remapping;
		std::stack<SPIRFunction *> functions;

		uint32_t remap_parameter(uint32_t id);
		void push_remap_parameters(const SPIRFunction &func, const uint32_t *args, uint32_t length);
		void pop_remap_parameters();
		void register_combined_image_sampler(SPIRFunction &caller, uint32_t texture_id, uint32_t sampler_id,
		                                     bool depth);
	};

	struct DummySamplerForCombinedImageHandler : OpcodeHandler
	{
		DummySamplerForCombinedImageHandler(Compiler &compiler_)
		    : compiler(compiler_)
		{
		}
		bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;

		Compiler &compiler;
		bool need_dummy_sampler = false;
	};

	struct ActiveBuiltinHandler : OpcodeHandler
	{
		ActiveBuiltinHandler(Compiler &compiler_)
		    : compiler(compiler_)
		{
		}

		bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
		Compiler &compiler;

		void handle_builtin(const SPIRType &type, spv::BuiltIn builtin, const Bitset &decoration_flags);
	};

	bool traverse_all_reachable_opcodes(const SPIRBlock &block, OpcodeHandler &handler) const;
	bool traverse_all_reachable_opcodes(const SPIRFunction &block, OpcodeHandler &handler) const;
	// This must be an ordered data structure so we always pick the same type aliases.
	std::vector<uint32_t> global_struct_cache;

	ShaderResources get_shader_resources(const std::unordered_set<uint32_t> *active_variables) const;

	VariableTypeRemapCallback variable_remap_callback;

	bool get_common_basic_type(const SPIRType &type, SPIRType::BaseType &base_type);

	std::unordered_set<uint32_t> forced_temporaries;
	std::unordered_set<uint32_t> forwarded_temporaries;
	std::unordered_set<uint32_t> hoisted_temporaries;

	Bitset active_input_builtins;
	Bitset active_output_builtins;
	uint32_t clip_distance_count = 0;
	uint32_t cull_distance_count = 0;
	bool position_invariant = false;

	// Traverses all reachable opcodes and sets active_builtins to a bitmask of all builtin variables which are accessed in the shader.
	void update_active_builtins();
	bool has_active_builtin(spv::BuiltIn builtin, spv::StorageClass storage);

	void analyze_parameter_preservation(
	    SPIRFunction &entry, const CFG &cfg,
	    const std::unordered_map<uint32_t, std::unordered_set<uint32_t>> &variable_to_blocks,
	    const std::unordered_map<uint32_t, std::unordered_set<uint32_t>> &complete_write_blocks);

	// If a variable ID or parameter ID is found in this set, a sampler is actually a shadow/comparison sampler.
	// SPIR-V does not support this distinction, so we must keep track of this information outside the type system.
	// There might be unrelated IDs found in this set which do not correspond to actual variables.
	// This set should only be queried for the existence of samplers which are already known to be variables or parameter IDs.
	// Similar is implemented for images, as well as if subpass inputs are needed.
	std::unordered_set<uint32_t> comparison_ids;
	bool need_subpass_input = false;

	// In certain backends, we will need to use a dummy sampler to be able to emit code.
	// GLSL does not support texelFetch on texture2D objects, but SPIR-V does,
	// so we need to workaround by having the application inject a dummy sampler.
	uint32_t dummy_sampler_id = 0;

	void analyze_image_and_sampler_usage();

	struct CombinedImageSamplerDrefHandler : OpcodeHandler
	{
		CombinedImageSamplerDrefHandler(Compiler &compiler_)
		    : compiler(compiler_)
		{
		}
		bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;

		Compiler &compiler;
		std::unordered_set<uint32_t> dref_combined_samplers;
	};

	struct CombinedImageSamplerUsageHandler : OpcodeHandler
	{
		CombinedImageSamplerUsageHandler(Compiler &compiler_,
		                                 const std::unordered_set<uint32_t> &dref_combined_samplers_)
		    : compiler(compiler_)
		    , dref_combined_samplers(dref_combined_samplers_)
		{
		}

		bool begin_function_scope(const uint32_t *args, uint32_t length) override;
		bool handle(spv::Op opcode, const uint32_t *args, uint32_t length) override;
		Compiler &compiler;
		const std::unordered_set<uint32_t> &dref_combined_samplers;

		std::unordered_map<uint32_t, std::unordered_set<uint32_t>> dependency_hierarchy;
		std::unordered_set<uint32_t> comparison_ids;

		void add_hierarchy_to_comparison_ids(uint32_t ids);
		bool need_subpass_input = false;
	};

	void build_function_control_flow_graphs_and_analyze();
	std::unordered_map<uint32_t, std::unique_ptr<CFG>> function_cfgs;
	struct CFGBuilder : OpcodeHandler
	{
		CFGBuilder(Compiler &compiler_);

		bool follow_function_call(const SPIRFunction &func) override;
		bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;
		Compiler &compiler;
		std::unordered_map<uint32_t, std::unique_ptr<CFG>> function_cfgs;
	};

	struct AnalyzeVariableScopeAccessHandler : OpcodeHandler
	{
		AnalyzeVariableScopeAccessHandler(Compiler &compiler_, SPIRFunction &entry_);

		bool follow_function_call(const SPIRFunction &) override;
		void set_current_block(const SPIRBlock &block) override;

		void notify_variable_access(uint32_t id, uint32_t block);
		bool id_is_phi_variable(uint32_t id) const;
		bool id_is_potential_temporary(uint32_t id) const;
		bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;

		Compiler &compiler;
		SPIRFunction &entry;
		std::unordered_map<uint32_t, std::unordered_set<uint32_t>> accessed_variables_to_block;
		std::unordered_map<uint32_t, std::unordered_set<uint32_t>> accessed_temporaries_to_block;
		std::unordered_map<uint32_t, uint32_t> result_id_to_type;
		std::unordered_map<uint32_t, std::unordered_set<uint32_t>> complete_write_variables_to_block;
		std::unordered_map<uint32_t, std::unordered_set<uint32_t>> partial_write_variables_to_block;
		const SPIRBlock *current_block = nullptr;
	};

	struct StaticExpressionAccessHandler : OpcodeHandler
	{
		StaticExpressionAccessHandler(Compiler &compiler_, uint32_t variable_id_);
		bool follow_function_call(const SPIRFunction &) override;
		bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;

		Compiler &compiler;
		uint32_t variable_id;
		uint32_t static_expression = 0;
		uint32_t write_count = 0;
	};

	void analyze_variable_scope(SPIRFunction &function, AnalyzeVariableScopeAccessHandler &handler);
	void find_function_local_luts(SPIRFunction &function, const AnalyzeVariableScopeAccessHandler &handler);

	void make_constant_null(uint32_t id, uint32_t type);

	std::unordered_map<uint32_t, std::string> declared_block_names;

	bool instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op, const uint32_t *args,
	                                uint32_t length);

	Bitset combined_decoration_for_member(const SPIRType &type, uint32_t index) const;
	static bool is_desktop_only_format(spv::ImageFormat format);

	bool image_is_comparison(const SPIRType &type, uint32_t id) const;

private:
	// Used only to implement the old deprecated get_entry_point() interface.
	const SPIREntryPoint &get_first_entry_point(const std::string &name) const;
	SPIREntryPoint &get_first_entry_point(const std::string &name);

	void fixup_type_alias();
	bool type_is_block_like(const SPIRType &type) const;
};
} // namespace spirv_cross

#endif
