/*
 * 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_common.hpp"

namespace spirv_cross
{
class CFG;
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.
	Compiler(std::vector<uint32_t> ir);
	Compiler(const uint32_t *ir, size_t word_count);

	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 a 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 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 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.
	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(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.
	std::string get_remapped_declared_block_name(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 > spirv.size())
			SPIRV_CROSS_THROW("Compiler::stream() out of range.");
		return &spirv[instr.offset];
	}
	std::vector<uint32_t> spirv;

	std::vector<Instruction> inst;
	std::vector<Variant> ids;
	std::vector<Meta> meta;

	SPIRFunction *current_function = nullptr;
	SPIRBlock *current_block = nullptr;
	std::vector<uint32_t> global_variables;
	std::vector<uint32_t> aliased_variables;
	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>(ids.at(id), std::forward<P>(args)...);
		var.self = id;
		return var;
	}

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

	template <typename T>
	T *maybe_get(uint32_t id)
	{
		if (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>(ids.at(id));
	}

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

	uint32_t entry_point = 0;
	// Normally, we'd stick SPIREntryPoint in ids array, but it conflicts with SPIRFunction.
	// Entry points can therefore be seen as some sort of meta structure.
	std::unordered_map<uint32_t, SPIREntryPoint> entry_points;
	const SPIREntryPoint &get_entry_point() const;
	SPIREntryPoint &get_entry_point();

	struct Source
	{
		uint32_t version = 0;
		bool es = false;
		bool known = false;
		bool hlsl = false;

		Source() = default;
	} source;

	std::unordered_set<uint32_t> loop_blocks;
	std::unordered_set<uint32_t> continue_blocks;
	std::unordered_set<uint32_t> loop_merge_targets;
	std::unordered_set<uint32_t> selection_merge_targets;
	std::unordered_set<uint32_t> multiselect_merge_targets;
	std::unordered_map<uint32_t, uint32_t> continue_block_to_loop_header;

	virtual std::string to_name(uint32_t id, bool allow_alias = true) const;
	bool is_builtin_variable(const SPIRVariable &var) 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 mark_used_as_array_length(uint32_t id);

	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 continue_blocks.find(next) != end(continue_blocks);
	}

	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 loop_merge_targets.find(next) != end(loop_merge_targets) ||
		       multiselect_merge_targets.find(next) != end(multiselect_merge_targets);
	}

	inline bool is_loop_break(uint32_t next) const
	{
		return loop_merge_targets.find(next) != end(loop_merge_targets);
	}

	inline bool is_conditional(uint32_t next) const
	{
		return selection_merge_targets.find(next) != end(selection_merge_targets) &&
		       multiselect_merge_targets.find(next) == end(multiselect_merge_targets);
	}

	// 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;

	uint32_t increase_bound_by(uint32_t incr_amount);

	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 analyze_variable_scope(SPIRFunction &function);

	void parse();
	void parse(const Instruction &i);

	// 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;

	Bitset get_buffer_block_flags(const SPIRVariable &var);
	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_samplers;
	std::unordered_set<uint32_t> comparison_images;
	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 CombinedImageSamplerUsageHandler : OpcodeHandler
	{
		CombinedImageSamplerUsageHandler(Compiler &compiler_)
		    : compiler(compiler_)
		{
		}

		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;

		std::unordered_map<uint32_t, std::unordered_set<uint32_t>> dependency_hierarchy;
		std::unordered_set<uint32_t> comparison_images;
		std::unordered_set<uint32_t> comparison_samplers;

		void add_hierarchy_to_comparison_samplers(uint32_t sampler);
		void add_hierarchy_to_comparison_images(uint32_t sampler);
		bool need_subpass_input = false;
	};

	void make_constant_null(uint32_t id, uint32_t type);

	std::vector<spv::Capability> declared_capabilities;
	std::vector<std::string> declared_extensions;
	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);

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
