/*
 * Copyright 2015-2020 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_NAMESPACE
{
struct Resource
{
	// Resources are identified with their SPIR-V ID.
	// This is the ID of the OpVariable.
	ID 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.
	TypeID 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).
	TypeID 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
{
	SmallVector<Resource> uniform_buffers;
	SmallVector<Resource> storage_buffers;
	SmallVector<Resource> stage_inputs;
	SmallVector<Resource> stage_outputs;
	SmallVector<Resource> subpass_inputs;
	SmallVector<Resource> storage_images;
	SmallVector<Resource> sampled_images;
	SmallVector<Resource> atomic_counters;
	SmallVector<Resource> acceleration_structures;

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

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

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

struct SpecializationConstant
{
	// The ID of the specialization constant.
	ConstantID 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,
	BufferPackingScalar,
	BufferPackingScalarEnhancedLayout
};

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(ID id) const;

	// Applies a decoration to an ID. Effectively injects OpDecorate.
	void set_decoration(ID id, spv::Decoration decoration, uint32_t argument = 0);
	void set_decoration_string(ID 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(ID id, const std::string &name);

	// Gets a bitmask for the decorations which are applied to ID.
	// I.e. (1ull << spv::DecorationFoo) | (1ull << spv::DecorationBar)
	const Bitset &get_decoration_bitset(ID id) const;

	// Returns whether the decoration has been applied to the ID.
	bool has_decoration(ID 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(ID id, spv::Decoration decoration) const;
	const std::string &get_decoration_string(ID id, spv::Decoration decoration) const;

	// Removes the decoration for an ID.
	void unset_decoration(ID 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(TypeID id) const;

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

	// Gets the underlying storage class for an OpVariable.
	spv::StorageClass get_storage_class(VariableID 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(ID 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(VariableID 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(TypeID id, uint32_t index) const;

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

	// Sets the member identifier for OpTypeStruct ID, member number "index".
	void set_member_name(TypeID 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(TypeID type_id, uint32_t index) const;

	// Gets the decoration mask for a member of a struct, similar to get_decoration_mask.
	const Bitset &get_member_decoration_bitset(TypeID id, uint32_t index) const;

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

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

	// Unsets a member decoration, similar to unset_decoration.
	void unset_member_decoration(TypeID 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().
	SmallVector<BufferRange> get_active_buffer_ranges(VariableID 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.
	size_t get_declared_struct_member_size(const SPIRType &struct_type, uint32_t index) const;

	// 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<VariableID> 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<VariableID> 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<VariableID> &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(VariableID id, bool remap_enable);
	bool get_remapped_variable_state(VariableID 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(VariableID id, uint32_t components);
	uint32_t get_subpass_input_remapped_components(VariableID 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.

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

	// 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.
	SmallVector<EntryPoint> get_entry_points_and_stages() const;
	void set_entry_point(const std::string &entry, spv::ExecutionModel execution_model);

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

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

	// Query and modify OpExecutionMode.
	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;

	bool is_tessellation_shader() 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.
	VariableID 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 SmallVector<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.
	SmallVector<SpecializationConstant> get_specialization_constants() const;
	SPIRConstant &get_constant(ConstantID id);
	const SPIRConstant &get_constant(ConstantID 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(VariableID 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(VariableID 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(VariableID id, uint32_t &counter_id) const;

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

	// Gets the list of all SPIR-V extensions which were declared in the SPIR-V module.
	const SmallVector<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(VariableID 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(VariableID 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)
	SmallVector<uint32_t> global_variables;
	SmallVector<uint32_t> aliased_variables;

	SPIRFunction *current_function = nullptr;
	SPIRBlock *current_block = nullptr;
	std::unordered_set<VariableID> 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)
	{
		ir.add_typed_id(static_cast<Types>(T::type), id);
		auto &var = variant_set<T>(ir.ids[id], std::forward<P>(args)...);
		var.self = id;
		return var;
	}

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

	template <typename T>
	T *maybe_get(uint32_t id)
	{
		if (id >= ir.ids.size())
			return nullptr;
		else if (ir.ids[id].get_type() == static_cast<Types>(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[id]);
	}

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

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

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

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

	// Gets the ID of the SPIR-V type underlying a variable.
	uint32_t get_variable_data_type_id(const SPIRVariable &var) const;

	// Gets the SPIR-V type underlying a variable.
	SPIRType &get_variable_data_type(const SPIRVariable &var);

	// Gets the SPIR-V type underlying a variable.
	const SPIRType &get_variable_data_type(const SPIRVariable &var) const;

	// Gets the SPIR-V element type underlying an array variable.
	SPIRType &get_variable_element_type(const SPIRVariable &var);

	// Gets the SPIR-V element type underlying an array variable.
	const SPIRType &get_variable_element_type(const SPIRVariable &var) 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);
	void set_qualified_name(uint32_t id, const std::string &name);

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

	const SPIREntryPoint &get_entry_point() const;
	SPIREntryPoint &get_entry_point();
	static bool is_tessellation_shader(spv::ExecutionModel model);

	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);
	spv::StorageClass get_backing_variable_storage(uint32_t ptr);

	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 == ID(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);

	// A variant which takes two sets of names. The secondary is only used to verify there are no collisions,
	// but the set is not updated when we have found a new name.
	// Used primarily when adding block interface names.
	void update_name_cache(std::unordered_set<std::string> &cache_primary,
	                       const std::unordered_set<std::string> &cache_secondary, std::string &name);

	bool function_is_pure(const SPIRFunction &func);
	bool block_is_pure(const SPIRBlock &block);

	bool execution_is_branchless(const SPIRBlock &from, const SPIRBlock &to) const;
	bool execution_is_direct_branch(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;

	void force_recompile();
	void clear_force_recompile();
	bool is_forcing_recompilation() const;
	bool is_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);
	void add_implied_read_expression(SPIRExpression &e, uint32_t source);
	void add_implied_read_expression(SPIRAccessChain &e, 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;

	SmallVector<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 &)
		{
		}

		// Called after returning from a function or when entering a block,
		// can be called multiple times per block,
		// while set_current_block is only called on block entry.
		virtual void rearm_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_, SmallVector<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;
		SmallVector<BufferRange> &ranges;
		uint32_t id;

		std::unordered_set<uint32_t> seen;
	};

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

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

		const Compiler &compiler;
		std::unordered_set<VariableID> &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, VariableID combined_id, VariableID texture_id,
		                                     VariableID 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.
	SmallVector<uint32_t> global_struct_cache;

	ShaderResources get_shader_resources(const std::unordered_set<VariableID> *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> suppressed_usage_tracking;
	std::unordered_set<uint32_t> hoisted_temporaries;
	std::unordered_set<uint32_t> forced_invariant_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;

	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 add_dependency(uint32_t dst, uint32_t src);
	};

	void build_function_control_flow_graphs_and_analyze();
	std::unordered_map<uint32_t, std::unique_ptr<CFG>> function_cfgs;
	const CFG &get_cfg_for_current_function() const;
	const CFG &get_cfg_for_function(uint32_t id) const;

	struct CFGBuilder : OpcodeHandler
	{
		explicit 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;
		std::unordered_set<uint32_t> access_chain_expressions;
		// Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers.
		std::unordered_map<uint32_t, std::unordered_set<uint32_t>> access_chain_children;
		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;
	};

	struct PhysicalStorageBufferPointerHandler : OpcodeHandler
	{
		explicit PhysicalStorageBufferPointerHandler(Compiler &compiler_);
		bool handle(spv::Op op, const uint32_t *args, uint32_t length) override;
		Compiler &compiler;
		std::unordered_set<uint32_t> types;
	};
	void analyze_non_block_pointer_types();
	SmallVector<uint32_t> physical_storage_non_block_pointer_types;

	void analyze_variable_scope(SPIRFunction &function, AnalyzeVariableScopeAccessHandler &handler);
	void find_function_local_luts(SPIRFunction &function, const AnalyzeVariableScopeAccessHandler &handler,
	                              bool single_function);
	bool may_read_undefined_variable_in_block(const SPIRBlock &block, uint32_t var);

	// Finds all resources that are written to from inside the critical section, if present.
	// The critical section is delimited by OpBeginInvocationInterlockEXT and
	// OpEndInvocationInterlockEXT instructions. In MSL and HLSL, any resources written
	// while inside the critical section must be placed in a raster order group.
	struct InterlockedResourceAccessHandler : OpcodeHandler
	{
		InterlockedResourceAccessHandler(Compiler &compiler_, uint32_t entry_point_id)
		    : compiler(compiler_)
		{
			call_stack.push_back(entry_point_id);
		}

		bool handle(spv::Op op, 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;
		bool in_crit_sec = false;

		uint32_t interlock_function_id = 0;
		bool split_function_case = false;
		bool control_flow_interlock = false;
		bool use_critical_section = false;
		bool call_stack_is_interlocked = false;
		SmallVector<uint32_t> call_stack;

		void access_potential_resource(uint32_t id);
	};

	struct InterlockedResourceAccessPrepassHandler : OpcodeHandler
	{
		InterlockedResourceAccessPrepassHandler(Compiler &compiler_, uint32_t entry_point_id)
		    : compiler(compiler_)
		{
			call_stack.push_back(entry_point_id);
		}

		void rearm_current_block(const SPIRBlock &block) override;
		bool handle(spv::Op op, 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;
		uint32_t interlock_function_id = 0;
		uint32_t current_block_id = 0;
		bool split_function_case = false;
		bool control_flow_interlock = false;
		SmallVector<uint32_t> call_stack;
	};

	void analyze_interlocked_resource_usage();
	// The set of all resources written while inside the critical section, if present.
	std::unordered_set<uint32_t> interlocked_resources;
	bool interlocked_is_complex = false;

	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;

	void set_extended_decoration(uint32_t id, ExtendedDecorations decoration, uint32_t value = 0);
	uint32_t get_extended_decoration(uint32_t id, ExtendedDecorations decoration) const;
	bool has_extended_decoration(uint32_t id, ExtendedDecorations decoration) const;
	void unset_extended_decoration(uint32_t id, ExtendedDecorations decoration);

	void set_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration,
	                                    uint32_t value = 0);
	uint32_t get_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration) const;
	bool has_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration) const;
	void unset_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration);

	bool type_is_array_of_pointers(const SPIRType &type) const;
	bool type_is_block_like(const SPIRType &type) const;
	bool type_is_opaque_value(const SPIRType &type) const;

	bool reflection_ssbo_instance_name_is_significant() const;
	std::string get_remapped_declared_block_name(uint32_t id, bool fallback_prefer_instance_name) const;

	bool flush_phi_required(BlockID from, BlockID to) 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);
};
} // namespace SPIRV_CROSS_NAMESPACE

#endif
