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

#include "spirv_cpp.hpp"
#include "spirv_cross_util.hpp"
#include "spirv_glsl.hpp"
#include "spirv_hlsl.hpp"
#include "spirv_msl.hpp"
#include "spirv_parser.hpp"
#include "spirv_reflect.hpp"
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <functional>
#include <limits>
#include <memory>
#include <stdexcept>
#include <unordered_map>
#include <unordered_set>

#ifdef HAVE_SPIRV_CROSS_GIT_VERSION
#include "gitversion.h"
#endif

using namespace spv;
using namespace SPIRV_CROSS_NAMESPACE;
using namespace std;

#ifdef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
static inline void THROW(const char *str)
{
	fprintf(stderr, "SPIRV-Cross will abort: %s\n", str);
	fflush(stderr);
	abort();
}
#else
#define THROW(x) throw runtime_error(x)
#endif

struct CLIParser;
struct CLICallbacks
{
	void add(const char *cli, const function<void(CLIParser &)> &func)
	{
		callbacks[cli] = func;
	}
	unordered_map<string, function<void(CLIParser &)>> callbacks;
	function<void()> error_handler;
	function<void(const char *)> default_handler;
};

struct CLIParser
{
	CLIParser(CLICallbacks cbs_, int argc_, char *argv_[])
	    : cbs(move(cbs_))
	    , argc(argc_)
	    , argv(argv_)
	{
	}

	bool parse()
	{
#ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
		try
#endif
		{
			while (argc && !ended_state)
			{
				const char *next = *argv++;
				argc--;

				if (*next != '-' && cbs.default_handler)
				{
					cbs.default_handler(next);
				}
				else
				{
					auto itr = cbs.callbacks.find(next);
					if (itr == ::end(cbs.callbacks))
					{
						THROW("Invalid argument");
					}

					itr->second(*this);
				}
			}

			return true;
		}
#ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
		catch (...)
		{
			if (cbs.error_handler)
			{
				cbs.error_handler();
			}
			return false;
		}
#endif
	}

	void end()
	{
		ended_state = true;
	}

	uint32_t next_uint()
	{
		if (!argc)
		{
			THROW("Tried to parse uint, but nothing left in arguments");
		}

		uint64_t val = stoul(*argv);
		if (val > numeric_limits<uint32_t>::max())
		{
			THROW("next_uint() out of range");
		}

		argc--;
		argv++;

		return uint32_t(val);
	}

	uint32_t next_hex_uint()
	{
		if (!argc)
		{
			THROW("Tried to parse uint, but nothing left in arguments");
		}

		uint64_t val = stoul(*argv, nullptr, 16);
		if (val > numeric_limits<uint32_t>::max())
		{
			THROW("next_uint() out of range");
		}

		argc--;
		argv++;

		return uint32_t(val);
	}

	double next_double()
	{
		if (!argc)
		{
			THROW("Tried to parse double, but nothing left in arguments");
		}

		double val = stod(*argv);

		argc--;
		argv++;

		return val;
	}

	// Return a string only if it's not prefixed with `--`, otherwise return the default value
	const char *next_value_string(const char *default_value)
	{
		if (!argc)
		{
			return default_value;
		}

		if (0 == strncmp("--", *argv, 2))
		{
			return default_value;
		}

		return next_string();
	}

	const char *next_string()
	{
		if (!argc)
		{
			THROW("Tried to parse string, but nothing left in arguments");
		}

		const char *ret = *argv;
		argc--;
		argv++;
		return ret;
	}

	CLICallbacks cbs;
	int argc;
	char **argv;
	bool ended_state = false;
};

#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4996)
#endif

static vector<uint32_t> read_spirv_file(const char *path)
{
	FILE *file = fopen(path, "rb");
	if (!file)
	{
		fprintf(stderr, "Failed to open SPIR-V file: %s\n", path);
		return {};
	}

	fseek(file, 0, SEEK_END);
	long len = ftell(file) / sizeof(uint32_t);
	rewind(file);

	vector<uint32_t> spirv(len);
	if (fread(spirv.data(), sizeof(uint32_t), len, file) != size_t(len))
		spirv.clear();

	fclose(file);
	return spirv;
}

static bool write_string_to_file(const char *path, const char *string)
{
	FILE *file = fopen(path, "w");
	if (!file)
	{
		fprintf(stderr, "Failed to write file: %s\n", path);
		return false;
	}

	fprintf(file, "%s", string);
	fclose(file);
	return true;
}

#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic pop
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif

static void print_resources(const Compiler &compiler, const char *tag, const SmallVector<Resource> &resources)
{
	fprintf(stderr, "%s\n", tag);
	fprintf(stderr, "=============\n\n");
	bool print_ssbo = !strcmp(tag, "ssbos");

	for (auto &res : resources)
	{
		auto &type = compiler.get_type(res.type_id);

		if (print_ssbo && compiler.buffer_is_hlsl_counter_buffer(res.id))
			continue;

		// If we don't have a name, use the fallback for the type instead of the variable
		// for SSBOs and UBOs since those are the only meaningful names to use externally.
		// Push constant blocks are still accessed by name and not block name, even though they are technically Blocks.
		bool is_push_constant = compiler.get_storage_class(res.id) == StorageClassPushConstant;
		bool is_block = compiler.get_decoration_bitset(type.self).get(DecorationBlock) ||
		                compiler.get_decoration_bitset(type.self).get(DecorationBufferBlock);
		bool is_sized_block = is_block && (compiler.get_storage_class(res.id) == StorageClassUniform ||
		                                   compiler.get_storage_class(res.id) == StorageClassUniformConstant);
		ID fallback_id = !is_push_constant && is_block ? ID(res.base_type_id) : ID(res.id);

		uint32_t block_size = 0;
		uint32_t runtime_array_stride = 0;
		if (is_sized_block)
		{
			auto &base_type = compiler.get_type(res.base_type_id);
			block_size = uint32_t(compiler.get_declared_struct_size(base_type));
			runtime_array_stride = uint32_t(compiler.get_declared_struct_size_runtime_array(base_type, 1) -
			                                compiler.get_declared_struct_size_runtime_array(base_type, 0));
		}

		Bitset mask;
		if (print_ssbo)
			mask = compiler.get_buffer_block_flags(res.id);
		else
			mask = compiler.get_decoration_bitset(res.id);

		string array;
		for (auto arr : type.array)
			array = join("[", arr ? convert_to_string(arr) : "", "]") + array;

		fprintf(stderr, " ID %03u : %s%s", uint32_t(res.id),
		        !res.name.empty() ? res.name.c_str() : compiler.get_fallback_name(fallback_id).c_str(), array.c_str());

		if (mask.get(DecorationLocation))
			fprintf(stderr, " (Location : %u)", compiler.get_decoration(res.id, DecorationLocation));
		if (mask.get(DecorationDescriptorSet))
			fprintf(stderr, " (Set : %u)", compiler.get_decoration(res.id, DecorationDescriptorSet));
		if (mask.get(DecorationBinding))
			fprintf(stderr, " (Binding : %u)", compiler.get_decoration(res.id, DecorationBinding));
		if (static_cast<const CompilerGLSL &>(compiler).variable_is_depth_or_compare(res.id))
			fprintf(stderr, " (comparison)");
		if (mask.get(DecorationInputAttachmentIndex))
			fprintf(stderr, " (Attachment : %u)", compiler.get_decoration(res.id, DecorationInputAttachmentIndex));
		if (mask.get(DecorationNonReadable))
			fprintf(stderr, " writeonly");
		if (mask.get(DecorationNonWritable))
			fprintf(stderr, " readonly");
		if (is_sized_block)
		{
			fprintf(stderr, " (BlockSize : %u bytes)", block_size);
			if (runtime_array_stride)
				fprintf(stderr, " (Unsized array stride: %u bytes)", runtime_array_stride);
		}

		uint32_t counter_id = 0;
		if (print_ssbo && compiler.buffer_get_hlsl_counter_buffer(res.id, counter_id))
			fprintf(stderr, " (HLSL counter buffer ID: %u)", counter_id);
		fprintf(stderr, "\n");
	}
	fprintf(stderr, "=============\n\n");
}

static const char *execution_model_to_str(spv::ExecutionModel model)
{
	switch (model)
	{
	case spv::ExecutionModelVertex:
		return "vertex";
	case spv::ExecutionModelTessellationControl:
		return "tessellation control";
	case ExecutionModelTessellationEvaluation:
		return "tessellation evaluation";
	case ExecutionModelGeometry:
		return "geometry";
	case ExecutionModelFragment:
		return "fragment";
	case ExecutionModelGLCompute:
		return "compute";
	case ExecutionModelRayGenerationNV:
		return "raygenNV";
	case ExecutionModelIntersectionNV:
		return "intersectionNV";
	case ExecutionModelCallableNV:
		return "callableNV";
	case ExecutionModelAnyHitNV:
		return "anyhitNV";
	case ExecutionModelClosestHitNV:
		return "closesthitNV";
	case ExecutionModelMissNV:
		return "missNV";
	default:
		return "???";
	}
}

static void print_resources(const Compiler &compiler, const ShaderResources &res)
{
	auto &modes = compiler.get_execution_mode_bitset();

	fprintf(stderr, "Entry points:\n");
	auto entry_points = compiler.get_entry_points_and_stages();
	for (auto &e : entry_points)
		fprintf(stderr, "  %s (%s)\n", e.name.c_str(), execution_model_to_str(e.execution_model));
	fprintf(stderr, "\n");

	fprintf(stderr, "Execution modes:\n");
	modes.for_each_bit([&](uint32_t i) {
		auto mode = static_cast<ExecutionMode>(i);
		uint32_t arg0 = compiler.get_execution_mode_argument(mode, 0);
		uint32_t arg1 = compiler.get_execution_mode_argument(mode, 1);
		uint32_t arg2 = compiler.get_execution_mode_argument(mode, 2);

		switch (static_cast<ExecutionMode>(i))
		{
		case ExecutionModeInvocations:
			fprintf(stderr, "  Invocations: %u\n", arg0);
			break;

		case ExecutionModeLocalSize:
			fprintf(stderr, "  LocalSize: (%u, %u, %u)\n", arg0, arg1, arg2);
			break;

		case ExecutionModeOutputVertices:
			fprintf(stderr, "  OutputVertices: %u\n", arg0);
			break;

#define CHECK_MODE(m)                  \
	case ExecutionMode##m:             \
		fprintf(stderr, "  %s\n", #m); \
		break
			CHECK_MODE(SpacingEqual);
			CHECK_MODE(SpacingFractionalEven);
			CHECK_MODE(SpacingFractionalOdd);
			CHECK_MODE(VertexOrderCw);
			CHECK_MODE(VertexOrderCcw);
			CHECK_MODE(PixelCenterInteger);
			CHECK_MODE(OriginUpperLeft);
			CHECK_MODE(OriginLowerLeft);
			CHECK_MODE(EarlyFragmentTests);
			CHECK_MODE(PointMode);
			CHECK_MODE(Xfb);
			CHECK_MODE(DepthReplacing);
			CHECK_MODE(DepthGreater);
			CHECK_MODE(DepthLess);
			CHECK_MODE(DepthUnchanged);
			CHECK_MODE(LocalSizeHint);
			CHECK_MODE(InputPoints);
			CHECK_MODE(InputLines);
			CHECK_MODE(InputLinesAdjacency);
			CHECK_MODE(Triangles);
			CHECK_MODE(InputTrianglesAdjacency);
			CHECK_MODE(Quads);
			CHECK_MODE(Isolines);
			CHECK_MODE(OutputPoints);
			CHECK_MODE(OutputLineStrip);
			CHECK_MODE(OutputTriangleStrip);
			CHECK_MODE(VecTypeHint);
			CHECK_MODE(ContractionOff);

		default:
			break;
		}
	});
	fprintf(stderr, "\n");

	print_resources(compiler, "subpass inputs", res.subpass_inputs);
	print_resources(compiler, "inputs", res.stage_inputs);
	print_resources(compiler, "outputs", res.stage_outputs);
	print_resources(compiler, "textures", res.sampled_images);
	print_resources(compiler, "separate images", res.separate_images);
	print_resources(compiler, "separate samplers", res.separate_samplers);
	print_resources(compiler, "images", res.storage_images);
	print_resources(compiler, "ssbos", res.storage_buffers);
	print_resources(compiler, "ubos", res.uniform_buffers);
	print_resources(compiler, "push", res.push_constant_buffers);
	print_resources(compiler, "counters", res.atomic_counters);
	print_resources(compiler, "acceleration structures", res.acceleration_structures);
}

static void print_push_constant_resources(const Compiler &compiler, const SmallVector<Resource> &res)
{
	for (auto &block : res)
	{
		auto ranges = compiler.get_active_buffer_ranges(block.id);
		fprintf(stderr, "Active members in buffer: %s\n",
		        !block.name.empty() ? block.name.c_str() : compiler.get_fallback_name(block.id).c_str());

		fprintf(stderr, "==================\n\n");
		for (auto &range : ranges)
		{
			const auto &name = compiler.get_member_name(block.base_type_id, range.index);

			fprintf(stderr, "Member #%3u (%s): Offset: %4u, Range: %4u\n", range.index,
			        !name.empty() ? name.c_str() : compiler.get_fallback_member_name(range.index).c_str(),
			        unsigned(range.offset), unsigned(range.range));
		}
		fprintf(stderr, "==================\n\n");
	}
}

static void print_spec_constants(const Compiler &compiler)
{
	auto spec_constants = compiler.get_specialization_constants();
	fprintf(stderr, "Specialization constants\n");
	fprintf(stderr, "==================\n\n");
	for (auto &c : spec_constants)
		fprintf(stderr, "ID: %u, Spec ID: %u\n", uint32_t(c.id), c.constant_id);
	fprintf(stderr, "==================\n\n");
}

static void print_capabilities_and_extensions(const Compiler &compiler)
{
	fprintf(stderr, "Capabilities\n");
	fprintf(stderr, "============\n");
	for (auto &capability : compiler.get_declared_capabilities())
		fprintf(stderr, "Capability: %u\n", static_cast<unsigned>(capability));
	fprintf(stderr, "============\n\n");

	fprintf(stderr, "Extensions\n");
	fprintf(stderr, "============\n");
	for (auto &ext : compiler.get_declared_extensions())
		fprintf(stderr, "Extension: %s\n", ext.c_str());
	fprintf(stderr, "============\n\n");
}

struct PLSArg
{
	PlsFormat format;
	string name;
};

struct Remap
{
	string src_name;
	string dst_name;
	unsigned components;
};

struct VariableTypeRemap
{
	string variable_name;
	string new_variable_type;
};

struct InterfaceVariableRename
{
	StorageClass storageClass;
	uint32_t location;
	string variable_name;
};

struct CLIArguments
{
	const char *input = nullptr;
	const char *output = nullptr;
	const char *cpp_interface_name = nullptr;
	uint32_t version = 0;
	uint32_t shader_model = 0;
	uint32_t msl_version = 0;
	bool es = false;
	bool set_version = false;
	bool set_shader_model = false;
	bool set_msl_version = false;
	bool set_es = false;
	bool dump_resources = false;
	bool force_temporary = false;
	bool flatten_ubo = false;
	bool fixup = false;
	bool yflip = false;
	bool sso = false;
	bool support_nonzero_baseinstance = true;
	bool msl_capture_output_to_buffer = false;
	bool msl_swizzle_texture_samples = false;
	bool msl_ios = false;
	bool msl_pad_fragment_output = false;
	bool msl_domain_lower_left = false;
	bool msl_argument_buffers = false;
	bool msl_texture_buffer_native = false;
	bool msl_framebuffer_fetch = false;
	bool msl_invariant_float_math = false;
	bool msl_emulate_cube_array = false;
	bool msl_multiview = false;
	bool msl_view_index_from_device_index = false;
	bool msl_dispatch_base = false;
	bool msl_decoration_binding = false;
	bool msl_force_active_argument_buffer_resources = false;
	bool msl_force_native_arrays = false;
	bool msl_enable_frag_depth_builtin = true;
	bool msl_enable_frag_stencil_ref_builtin = true;
	uint32_t msl_enable_frag_output_mask = 0xffffffff;
	bool msl_enable_clip_distance_user_varying = true;
	bool glsl_emit_push_constant_as_ubo = false;
	bool glsl_emit_ubo_as_plain_uniforms = false;
	SmallVector<pair<uint32_t, uint32_t>> glsl_ext_framebuffer_fetch;
	bool vulkan_glsl_disable_ext_samplerless_texture_functions = false;
	bool emit_line_directives = false;
	bool enable_storage_image_qualifier_deduction = true;
	bool force_zero_initialized_variables = false;
	SmallVector<uint32_t> msl_discrete_descriptor_sets;
	SmallVector<uint32_t> msl_device_argument_buffers;
	SmallVector<pair<uint32_t, uint32_t>> msl_dynamic_buffers;
	SmallVector<pair<uint32_t, uint32_t>> msl_inline_uniform_blocks;
	SmallVector<PLSArg> pls_in;
	SmallVector<PLSArg> pls_out;
	SmallVector<Remap> remaps;
	SmallVector<string> extensions;
	SmallVector<VariableTypeRemap> variable_type_remaps;
	SmallVector<InterfaceVariableRename> interface_variable_renames;
	SmallVector<HLSLVertexAttributeRemap> hlsl_attr_remap;
	string entry;
	string entry_stage;

	struct Rename
	{
		string old_name;
		string new_name;
		ExecutionModel execution_model;
	};
	SmallVector<Rename> entry_point_rename;

	uint32_t iterations = 1;
	bool cpp = false;
	string reflect;
	bool msl = false;
	bool hlsl = false;
	bool hlsl_compat = false;
	bool hlsl_support_nonzero_base = false;
	bool hlsl_force_storage_buffer_as_uav = false;
	bool hlsl_nonwritable_uav_texture_as_srv = false;
	HLSLBindingFlags hlsl_binding_flags = 0;
	bool vulkan_semantics = false;
	bool flatten_multidimensional_arrays = false;
	bool use_420pack_extension = true;
	bool remove_unused = false;
	bool combined_samplers_inherit_bindings = false;
};

static void print_version()
{
#ifdef HAVE_SPIRV_CROSS_GIT_VERSION
	fprintf(stderr, "%s\n", SPIRV_CROSS_GIT_REVISION);
#else
	fprintf(stderr, "Git revision unknown. Build with CMake to create timestamp and revision info.\n");
#endif
}

static void print_help()
{
	print_version();

	fprintf(stderr, "Usage: spirv-cross\n"
	                "\t[--output <output path>]\n"
	                "\t[SPIR-V file]\n"
	                "\t[--es]\n"
	                "\t[--no-es]\n"
	                "\t[--version <GLSL version>]\n"
	                "\t[--dump-resources]\n"
	                "\t[--help]\n"
	                "\t[--revision]\n"
	                "\t[--force-temporary]\n"
	                "\t[--vulkan-semantics] or [-V]\n"
	                "\t[--flatten-ubo]\n"
	                "\t[--fixup-clipspace]\n"
	                "\t[--flip-vert-y]\n"
	                "\t[--iterations iter]\n"
	                "\t[--cpp]\n"
	                "\t[--cpp-interface-name <name>]\n"
	                "\t[--disable-storage-image-qualifier-deduction]\n"
	                "\t[--force-zero-initialized-variables]\n"
	                "\t[--glsl-emit-push-constant-as-ubo]\n"
	                "\t[--glsl-emit-ubo-as-plain-uniforms]\n"
	                "\t[--glsl-remap-ext-framebuffer-fetch input-attachment color-location]\n"
	                "\t[--vulkan-glsl-disable-ext-samplerless-texture-functions]\n"
	                "\t[--msl]\n"
	                "\t[--msl-version <MMmmpp>]\n"
	                "\t[--msl-capture-output]\n"
	                "\t[--msl-swizzle-texture-samples]\n"
	                "\t[--msl-ios]\n"
	                "\t[--msl-pad-fragment-output]\n"
	                "\t[--msl-domain-lower-left]\n"
	                "\t[--msl-argument-buffers]\n"
	                "\t[--msl-texture-buffer-native]\n"
	                "\t[--msl-framebuffer-fetch]\n"
	                "\t[--msl-emulate-cube-array]\n"
	                "\t[--msl-discrete-descriptor-set <index>]\n"
	                "\t[--msl-device-argument-buffer <index>]\n"
	                "\t[--msl-multiview]\n"
	                "\t[--msl-view-index-from-device-index]\n"
	                "\t[--msl-dispatch-base]\n"
	                "\t[--msl-dynamic-buffer <set index> <binding>]\n"
	                "\t[--msl-inline-uniform-block <set index> <binding>]\n"
	                "\t[--msl-decoration-binding]\n"
	                "\t[--msl-force-active-argument-buffer-resources]\n"
	                "\t[--msl-force-native-arrays]\n"
	                "\t[--msl-disable-frag-depth-builtin]\n"
	                "\t[--msl-disable-frag-stencil-ref-builtin]\n"
	                "\t[--msl-enable-frag-output-mask <mask>]\n"
	                "\t[--msl-no-clip-distance-user-varying]\n"
	                "\t[--hlsl]\n"
	                "\t[--reflect]\n"
	                "\t[--shader-model]\n"
	                "\t[--hlsl-enable-compat]\n"
	                "\t[--hlsl-support-nonzero-basevertex-baseinstance]\n"
	                "\t[--hlsl-auto-binding (push, cbv, srv, uav, sampler, all)]\n"
	                "\t[--hlsl-force-storage-buffer-as-uav]\n"
	                "\t[--hlsl-nonwritable-uav-texture-as-srv]\n"
	                "\t[--separate-shader-objects]\n"
	                "\t[--pls-in format input-name]\n"
	                "\t[--pls-out format output-name]\n"
	                "\t[--remap source_name target_name components]\n"
	                "\t[--extension ext]\n"
	                "\t[--entry name]\n"
	                "\t[--stage <stage (vert, frag, geom, tesc, tese comp)>]\n"
	                "\t[--remove-unused-variables]\n"
	                "\t[--flatten-multidimensional-arrays]\n"
	                "\t[--no-420pack-extension]\n"
	                "\t[--remap-variable-type <variable_name> <new_variable_type>]\n"
	                "\t[--rename-interface-variable <in|out> <location> <new_variable_name>]\n"
	                "\t[--set-hlsl-vertex-input-semantic <location> <semantic>]\n"
	                "\t[--rename-entry-point <old> <new> <stage>]\n"
	                "\t[--combined-samplers-inherit-bindings]\n"
	                "\t[--no-support-nonzero-baseinstance]\n"
	                "\t[--emit-line-directives]\n"
	                "\n");
}

static bool remap_generic(Compiler &compiler, const SmallVector<Resource> &resources, const Remap &remap)
{
	auto itr =
	    find_if(begin(resources), end(resources), [&remap](const Resource &res) { return res.name == remap.src_name; });

	if (itr != end(resources))
	{
		compiler.set_remapped_variable_state(itr->id, true);
		compiler.set_name(itr->id, remap.dst_name);
		compiler.set_subpass_input_remapped_components(itr->id, remap.components);
		return true;
	}
	else
		return false;
}

static vector<PlsRemap> remap_pls(const SmallVector<PLSArg> &pls_variables, const SmallVector<Resource> &resources,
                                  const SmallVector<Resource> *secondary_resources)
{
	vector<PlsRemap> ret;

	for (auto &pls : pls_variables)
	{
		bool found = false;
		for (auto &res : resources)
		{
			if (res.name == pls.name)
			{
				ret.push_back({ res.id, pls.format });
				found = true;
				break;
			}
		}

		if (!found && secondary_resources)
		{
			for (auto &res : *secondary_resources)
			{
				if (res.name == pls.name)
				{
					ret.push_back({ res.id, pls.format });
					found = true;
					break;
				}
			}
		}

		if (!found)
			fprintf(stderr, "Did not find stage input/output/target with name \"%s\".\n", pls.name.c_str());
	}

	return ret;
}

static PlsFormat pls_format(const char *str)
{
	if (!strcmp(str, "r11f_g11f_b10f"))
		return PlsR11FG11FB10F;
	else if (!strcmp(str, "r32f"))
		return PlsR32F;
	else if (!strcmp(str, "rg16f"))
		return PlsRG16F;
	else if (!strcmp(str, "rg16"))
		return PlsRG16;
	else if (!strcmp(str, "rgb10_a2"))
		return PlsRGB10A2;
	else if (!strcmp(str, "rgba8"))
		return PlsRGBA8;
	else if (!strcmp(str, "rgba8i"))
		return PlsRGBA8I;
	else if (!strcmp(str, "rgba8ui"))
		return PlsRGBA8UI;
	else if (!strcmp(str, "rg16i"))
		return PlsRG16I;
	else if (!strcmp(str, "rgb10_a2ui"))
		return PlsRGB10A2UI;
	else if (!strcmp(str, "rg16ui"))
		return PlsRG16UI;
	else if (!strcmp(str, "r32ui"))
		return PlsR32UI;
	else
		return PlsNone;
}

static ExecutionModel stage_to_execution_model(const std::string &stage)
{
	if (stage == "vert")
		return ExecutionModelVertex;
	else if (stage == "frag")
		return ExecutionModelFragment;
	else if (stage == "comp")
		return ExecutionModelGLCompute;
	else if (stage == "tesc")
		return ExecutionModelTessellationControl;
	else if (stage == "tese")
		return ExecutionModelTessellationEvaluation;
	else if (stage == "geom")
		return ExecutionModelGeometry;
	else
		SPIRV_CROSS_THROW("Invalid stage.");
}

static HLSLBindingFlags hlsl_resource_type_to_flag(const std::string &arg)
{
	if (arg == "push")
		return HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT;
	else if (arg == "cbv")
		return HLSL_BINDING_AUTO_CBV_BIT;
	else if (arg == "srv")
		return HLSL_BINDING_AUTO_SRV_BIT;
	else if (arg == "uav")
		return HLSL_BINDING_AUTO_UAV_BIT;
	else if (arg == "sampler")
		return HLSL_BINDING_AUTO_SAMPLER_BIT;
	else if (arg == "all")
		return HLSL_BINDING_AUTO_ALL;
	else
	{
		fprintf(stderr, "Invalid resource type for --hlsl-auto-binding: %s\n", arg.c_str());
		return 0;
	}
}

static string compile_iteration(const CLIArguments &args, std::vector<uint32_t> spirv_file)
{
	Parser spirv_parser(move(spirv_file));
	spirv_parser.parse();

	unique_ptr<CompilerGLSL> compiler;
	bool combined_image_samplers = false;
	bool build_dummy_sampler = false;

	if (args.cpp)
	{
		compiler.reset(new CompilerCPP(move(spirv_parser.get_parsed_ir())));
		if (args.cpp_interface_name)
			static_cast<CompilerCPP *>(compiler.get())->set_interface_name(args.cpp_interface_name);
	}
	else if (args.msl)
	{
		compiler.reset(new CompilerMSL(move(spirv_parser.get_parsed_ir())));

		auto *msl_comp = static_cast<CompilerMSL *>(compiler.get());
		auto msl_opts = msl_comp->get_msl_options();
		if (args.set_msl_version)
			msl_opts.msl_version = args.msl_version;
		msl_opts.capture_output_to_buffer = args.msl_capture_output_to_buffer;
		msl_opts.swizzle_texture_samples = args.msl_swizzle_texture_samples;
		msl_opts.invariant_float_math = args.msl_invariant_float_math;
		if (args.msl_ios)
		{
			msl_opts.platform = CompilerMSL::Options::iOS;
			msl_opts.ios_use_framebuffer_fetch_subpasses = args.msl_framebuffer_fetch;
			msl_opts.emulate_cube_array = args.msl_emulate_cube_array;
		}
		msl_opts.pad_fragment_output_components = args.msl_pad_fragment_output;
		msl_opts.tess_domain_origin_lower_left = args.msl_domain_lower_left;
		msl_opts.argument_buffers = args.msl_argument_buffers;
		msl_opts.texture_buffer_native = args.msl_texture_buffer_native;
		msl_opts.multiview = args.msl_multiview;
		msl_opts.view_index_from_device_index = args.msl_view_index_from_device_index;
		msl_opts.dispatch_base = args.msl_dispatch_base;
		msl_opts.enable_decoration_binding = args.msl_decoration_binding;
		msl_opts.force_active_argument_buffer_resources = args.msl_force_active_argument_buffer_resources;
		msl_opts.force_native_arrays = args.msl_force_native_arrays;
		msl_opts.enable_frag_depth_builtin = args.msl_enable_frag_depth_builtin;
		msl_opts.enable_frag_stencil_ref_builtin = args.msl_enable_frag_stencil_ref_builtin;
		msl_opts.enable_frag_output_mask = args.msl_enable_frag_output_mask;
		msl_opts.enable_clip_distance_user_varying = args.msl_enable_clip_distance_user_varying;
		msl_comp->set_msl_options(msl_opts);
		for (auto &v : args.msl_discrete_descriptor_sets)
			msl_comp->add_discrete_descriptor_set(v);
		for (auto &v : args.msl_device_argument_buffers)
			msl_comp->set_argument_buffer_device_address_space(v, true);
		uint32_t i = 0;
		for (auto &v : args.msl_dynamic_buffers)
			msl_comp->add_dynamic_buffer(v.first, v.second, i++);
		for (auto &v : args.msl_inline_uniform_blocks)
			msl_comp->add_inline_uniform_block(v.first, v.second);
	}
	else if (args.hlsl)
		compiler.reset(new CompilerHLSL(move(spirv_parser.get_parsed_ir())));
	else
	{
		combined_image_samplers = !args.vulkan_semantics;
		if (!args.vulkan_semantics || args.vulkan_glsl_disable_ext_samplerless_texture_functions)
			build_dummy_sampler = true;
		compiler.reset(new CompilerGLSL(move(spirv_parser.get_parsed_ir())));
	}

	if (!args.variable_type_remaps.empty())
	{
		auto remap_cb = [&](const SPIRType &, const string &name, string &out) -> void {
			for (const VariableTypeRemap &remap : args.variable_type_remaps)
				if (name == remap.variable_name)
					out = remap.new_variable_type;
		};

		compiler->set_variable_type_remap_callback(move(remap_cb));
	}

	for (auto &rename : args.entry_point_rename)
		compiler->rename_entry_point(rename.old_name, rename.new_name, rename.execution_model);

	auto entry_points = compiler->get_entry_points_and_stages();
	auto entry_point = args.entry;
	ExecutionModel model = ExecutionModelMax;

	if (!args.entry_stage.empty())
	{
		model = stage_to_execution_model(args.entry_stage);
		if (entry_point.empty())
		{
			// Just use the first entry point with this stage.
			for (auto &e : entry_points)
			{
				if (e.execution_model == model)
				{
					entry_point = e.name;
					break;
				}
			}

			if (entry_point.empty())
			{
				fprintf(stderr, "Could not find an entry point with stage: %s\n", args.entry_stage.c_str());
				exit(EXIT_FAILURE);
			}
		}
		else
		{
			// Make sure both stage and name exists.
			bool exists = false;
			for (auto &e : entry_points)
			{
				if (e.execution_model == model && e.name == entry_point)
				{
					exists = true;
					break;
				}
			}

			if (!exists)
			{
				fprintf(stderr, "Could not find an entry point %s with stage: %s\n", entry_point.c_str(),
				        args.entry_stage.c_str());
				exit(EXIT_FAILURE);
			}
		}
	}
	else if (!entry_point.empty())
	{
		// Make sure there is just one entry point with this name, or the stage
		// is ambiguous.
		uint32_t stage_count = 0;
		for (auto &e : entry_points)
		{
			if (e.name == entry_point)
			{
				stage_count++;
				model = e.execution_model;
			}
		}

		if (stage_count == 0)
		{
			fprintf(stderr, "There is no entry point with name: %s\n", entry_point.c_str());
			exit(EXIT_FAILURE);
		}
		else if (stage_count > 1)
		{
			fprintf(stderr, "There is more than one entry point with name: %s. Use --stage.\n", entry_point.c_str());
			exit(EXIT_FAILURE);
		}
	}

	if (!entry_point.empty())
		compiler->set_entry_point(entry_point, model);

	if (!args.set_version && !compiler->get_common_options().version)
	{
		fprintf(stderr, "Didn't specify GLSL version and SPIR-V did not specify language.\n");
		print_help();
		exit(EXIT_FAILURE);
	}

	CompilerGLSL::Options opts = compiler->get_common_options();
	if (args.set_version)
		opts.version = args.version;
	if (args.set_es)
		opts.es = args.es;
	opts.force_temporary = args.force_temporary;
	opts.separate_shader_objects = args.sso;
	opts.flatten_multidimensional_arrays = args.flatten_multidimensional_arrays;
	opts.enable_420pack_extension = args.use_420pack_extension;
	opts.vulkan_semantics = args.vulkan_semantics;
	opts.vertex.fixup_clipspace = args.fixup;
	opts.vertex.flip_vert_y = args.yflip;
	opts.vertex.support_nonzero_base_instance = args.support_nonzero_baseinstance;
	opts.emit_push_constant_as_uniform_buffer = args.glsl_emit_push_constant_as_ubo;
	opts.emit_uniform_buffer_as_plain_uniforms = args.glsl_emit_ubo_as_plain_uniforms;
	opts.emit_line_directives = args.emit_line_directives;
	opts.enable_storage_image_qualifier_deduction = args.enable_storage_image_qualifier_deduction;
	opts.force_zero_initialized_variables = args.force_zero_initialized_variables;
	compiler->set_common_options(opts);

	for (auto &fetch : args.glsl_ext_framebuffer_fetch)
		compiler->remap_ext_framebuffer_fetch(fetch.first, fetch.second);

	// Set HLSL specific options.
	if (args.hlsl)
	{
		auto *hlsl = static_cast<CompilerHLSL *>(compiler.get());
		auto hlsl_opts = hlsl->get_hlsl_options();
		if (args.set_shader_model)
		{
			if (args.shader_model < 30)
			{
				fprintf(stderr, "Shader model earlier than 30 (3.0) not supported.\n");
				exit(EXIT_FAILURE);
			}

			hlsl_opts.shader_model = args.shader_model;
		}

		if (args.hlsl_compat)
		{
			// Enable all compat options.
			hlsl_opts.point_size_compat = true;
			hlsl_opts.point_coord_compat = true;
		}

		if (hlsl_opts.shader_model <= 30)
		{
			combined_image_samplers = true;
			build_dummy_sampler = true;
		}

		hlsl_opts.support_nonzero_base_vertex_base_instance = args.hlsl_support_nonzero_base;
		hlsl_opts.force_storage_buffer_as_uav = args.hlsl_force_storage_buffer_as_uav;
		hlsl_opts.nonwritable_uav_texture_as_srv = args.hlsl_nonwritable_uav_texture_as_srv;
		hlsl->set_hlsl_options(hlsl_opts);
		hlsl->set_resource_binding_flags(args.hlsl_binding_flags);
	}

	if (build_dummy_sampler)
	{
		uint32_t sampler = compiler->build_dummy_sampler_for_combined_images();
		if (sampler != 0)
		{
			// Set some defaults to make validation happy.
			compiler->set_decoration(sampler, DecorationDescriptorSet, 0);
			compiler->set_decoration(sampler, DecorationBinding, 0);
		}
	}

	ShaderResources res;
	if (args.remove_unused)
	{
		auto active = compiler->get_active_interface_variables();
		res = compiler->get_shader_resources(active);
		compiler->set_enabled_interface_variables(move(active));
	}
	else
		res = compiler->get_shader_resources();

	if (args.flatten_ubo)
	{
		for (auto &ubo : res.uniform_buffers)
			compiler->flatten_buffer_block(ubo.id);
		for (auto &ubo : res.push_constant_buffers)
			compiler->flatten_buffer_block(ubo.id);
	}

	auto pls_inputs = remap_pls(args.pls_in, res.stage_inputs, &res.subpass_inputs);
	auto pls_outputs = remap_pls(args.pls_out, res.stage_outputs, nullptr);
	compiler->remap_pixel_local_storage(move(pls_inputs), move(pls_outputs));

	for (auto &ext : args.extensions)
		compiler->require_extension(ext);

	for (auto &remap : args.remaps)
	{
		if (remap_generic(*compiler, res.stage_inputs, remap))
			continue;
		if (remap_generic(*compiler, res.stage_outputs, remap))
			continue;
		if (remap_generic(*compiler, res.subpass_inputs, remap))
			continue;
	}

	for (auto &rename : args.interface_variable_renames)
	{
		if (rename.storageClass == StorageClassInput)
			spirv_cross_util::rename_interface_variable(*compiler, res.stage_inputs, rename.location,
			                                            rename.variable_name);
		else if (rename.storageClass == StorageClassOutput)
			spirv_cross_util::rename_interface_variable(*compiler, res.stage_outputs, rename.location,
			                                            rename.variable_name);
		else
		{
			fprintf(stderr, "error at --rename-interface-variable <in|out> ...\n");
			exit(EXIT_FAILURE);
		}
	}

	if (combined_image_samplers)
	{
		compiler->build_combined_image_samplers();
		if (args.combined_samplers_inherit_bindings)
			spirv_cross_util::inherit_combined_sampler_bindings(*compiler);

		// Give the remapped combined samplers new names.
		for (auto &remap : compiler->get_combined_image_samplers())
		{
			compiler->set_name(remap.combined_id, join("SPIRV_Cross_Combined", compiler->get_name(remap.image_id),
			                                           compiler->get_name(remap.sampler_id)));
		}
	}

	if (args.hlsl)
	{
		auto *hlsl_compiler = static_cast<CompilerHLSL *>(compiler.get());
		uint32_t new_builtin = hlsl_compiler->remap_num_workgroups_builtin();
		if (new_builtin)
		{
			hlsl_compiler->set_decoration(new_builtin, DecorationDescriptorSet, 0);
			hlsl_compiler->set_decoration(new_builtin, DecorationBinding, 0);
		}
	}

	if (args.hlsl)
	{
		for (auto &remap : args.hlsl_attr_remap)
			static_cast<CompilerHLSL *>(compiler.get())->add_vertex_attribute_remap(remap);
	}

	auto ret = compiler->compile();

	if (args.dump_resources)
	{
		print_resources(*compiler, res);
		print_push_constant_resources(*compiler, res.push_constant_buffers);
		print_spec_constants(*compiler);
		print_capabilities_and_extensions(*compiler);
	}

	return ret;
}

static int main_inner(int argc, char *argv[])
{
	CLIArguments args;
	CLICallbacks cbs;

	cbs.add("--help", [](CLIParser &parser) {
		print_help();
		parser.end();
	});
	cbs.add("--revision", [](CLIParser &parser) {
		print_version();
		parser.end();
	});
	cbs.add("--output", [&args](CLIParser &parser) { args.output = parser.next_string(); });
	cbs.add("--es", [&args](CLIParser &) {
		args.es = true;
		args.set_es = true;
	});
	cbs.add("--no-es", [&args](CLIParser &) {
		args.es = false;
		args.set_es = true;
	});
	cbs.add("--version", [&args](CLIParser &parser) {
		args.version = parser.next_uint();
		args.set_version = true;
	});
	cbs.add("--dump-resources", [&args](CLIParser &) { args.dump_resources = true; });
	cbs.add("--force-temporary", [&args](CLIParser &) { args.force_temporary = true; });
	cbs.add("--flatten-ubo", [&args](CLIParser &) { args.flatten_ubo = true; });
	cbs.add("--fixup-clipspace", [&args](CLIParser &) { args.fixup = true; });
	cbs.add("--flip-vert-y", [&args](CLIParser &) { args.yflip = true; });
	cbs.add("--iterations", [&args](CLIParser &parser) { args.iterations = parser.next_uint(); });
	cbs.add("--cpp", [&args](CLIParser &) { args.cpp = true; });
	cbs.add("--reflect", [&args](CLIParser &parser) { args.reflect = parser.next_value_string("json"); });
	cbs.add("--cpp-interface-name", [&args](CLIParser &parser) { args.cpp_interface_name = parser.next_string(); });
	cbs.add("--metal", [&args](CLIParser &) { args.msl = true; }); // Legacy compatibility
	cbs.add("--glsl-emit-push-constant-as-ubo", [&args](CLIParser &) { args.glsl_emit_push_constant_as_ubo = true; });
	cbs.add("--glsl-emit-ubo-as-plain-uniforms", [&args](CLIParser &) { args.glsl_emit_ubo_as_plain_uniforms = true; });
	cbs.add("--glsl-remap-ext-framebuffer-fetch", [&args](CLIParser &parser) {
		uint32_t input_index = parser.next_uint();
		uint32_t color_attachment = parser.next_uint();
		args.glsl_ext_framebuffer_fetch.push_back({ input_index, color_attachment });
	});
	cbs.add("--vulkan-glsl-disable-ext-samplerless-texture-functions",
	        [&args](CLIParser &) { args.vulkan_glsl_disable_ext_samplerless_texture_functions = true; });
	cbs.add("--disable-storage-image-qualifier-deduction",
	        [&args](CLIParser &) { args.enable_storage_image_qualifier_deduction = false; });
	cbs.add("--force-zero-initialized-variables",
	        [&args](CLIParser &) { args.force_zero_initialized_variables = true; });
	cbs.add("--msl", [&args](CLIParser &) { args.msl = true; });
	cbs.add("--hlsl", [&args](CLIParser &) { args.hlsl = true; });
	cbs.add("--hlsl-enable-compat", [&args](CLIParser &) { args.hlsl_compat = true; });
	cbs.add("--hlsl-support-nonzero-basevertex-baseinstance",
	        [&args](CLIParser &) { args.hlsl_support_nonzero_base = true; });
	cbs.add("--hlsl-auto-binding", [&args](CLIParser &parser) {
		args.hlsl_binding_flags |= hlsl_resource_type_to_flag(parser.next_string());
	});
	cbs.add("--hlsl-force-storage-buffer-as-uav",
	        [&args](CLIParser &) { args.hlsl_force_storage_buffer_as_uav = true; });
	cbs.add("--hlsl-nonwritable-uav-texture-as-srv",
	        [&args](CLIParser &) { args.hlsl_nonwritable_uav_texture_as_srv = true; });
	cbs.add("--vulkan-semantics", [&args](CLIParser &) { args.vulkan_semantics = true; });
	cbs.add("-V", [&args](CLIParser &) { args.vulkan_semantics = true; });
	cbs.add("--flatten-multidimensional-arrays", [&args](CLIParser &) { args.flatten_multidimensional_arrays = true; });
	cbs.add("--no-420pack-extension", [&args](CLIParser &) { args.use_420pack_extension = false; });
	cbs.add("--msl-capture-output", [&args](CLIParser &) { args.msl_capture_output_to_buffer = true; });
	cbs.add("--msl-swizzle-texture-samples", [&args](CLIParser &) { args.msl_swizzle_texture_samples = true; });
	cbs.add("--msl-ios", [&args](CLIParser &) { args.msl_ios = true; });
	cbs.add("--msl-pad-fragment-output", [&args](CLIParser &) { args.msl_pad_fragment_output = true; });
	cbs.add("--msl-domain-lower-left", [&args](CLIParser &) { args.msl_domain_lower_left = true; });
	cbs.add("--msl-argument-buffers", [&args](CLIParser &) { args.msl_argument_buffers = true; });
	cbs.add("--msl-discrete-descriptor-set",
	        [&args](CLIParser &parser) { args.msl_discrete_descriptor_sets.push_back(parser.next_uint()); });
	cbs.add("--msl-device-argument-buffer",
	        [&args](CLIParser &parser) { args.msl_device_argument_buffers.push_back(parser.next_uint()); });
	cbs.add("--msl-texture-buffer-native", [&args](CLIParser &) { args.msl_texture_buffer_native = true; });
	cbs.add("--msl-framebuffer-fetch", [&args](CLIParser &) { args.msl_framebuffer_fetch = true; });
	cbs.add("--msl-invariant-float-math", [&args](CLIParser &) { args.msl_invariant_float_math = true; });
	cbs.add("--msl-emulate-cube-array", [&args](CLIParser &) { args.msl_emulate_cube_array = true; });
	cbs.add("--msl-multiview", [&args](CLIParser &) { args.msl_multiview = true; });
	cbs.add("--msl-view-index-from-device-index",
	        [&args](CLIParser &) { args.msl_view_index_from_device_index = true; });
	cbs.add("--msl-dispatch-base", [&args](CLIParser &) { args.msl_dispatch_base = true; });
	cbs.add("--msl-dynamic-buffer", [&args](CLIParser &parser) {
		args.msl_argument_buffers = true;
		// Make sure next_uint() is called in-order.
		uint32_t desc_set = parser.next_uint();
		uint32_t binding = parser.next_uint();
		args.msl_dynamic_buffers.push_back(make_pair(desc_set, binding));
	});
	cbs.add("--msl-decoration-binding", [&args](CLIParser &) { args.msl_decoration_binding = true; });
	cbs.add("--msl-force-active-argument-buffer-resources",
	        [&args](CLIParser &) { args.msl_force_active_argument_buffer_resources = true; });
	cbs.add("--msl-inline-uniform-block", [&args](CLIParser &parser) {
		args.msl_argument_buffers = true;
		// Make sure next_uint() is called in-order.
		uint32_t desc_set = parser.next_uint();
		uint32_t binding = parser.next_uint();
		args.msl_inline_uniform_blocks.push_back(make_pair(desc_set, binding));
	});
	cbs.add("--msl-force-native-arrays", [&args](CLIParser &) { args.msl_force_native_arrays = true; });
	cbs.add("--msl-disable-frag-depth-builtin", [&args](CLIParser &) { args.msl_enable_frag_depth_builtin = false; });
	cbs.add("--msl-disable-frag-stencil-ref-builtin",
	        [&args](CLIParser &) { args.msl_enable_frag_stencil_ref_builtin = false; });
	cbs.add("--msl-enable-frag-output-mask",
	        [&args](CLIParser &parser) { args.msl_enable_frag_output_mask = parser.next_hex_uint(); });
	cbs.add("--msl-no-clip-distance-user-varying",
	        [&args](CLIParser &) { args.msl_enable_clip_distance_user_varying = false; });
	cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); });
	cbs.add("--rename-entry-point", [&args](CLIParser &parser) {
		auto old_name = parser.next_string();
		auto new_name = parser.next_string();
		auto model = stage_to_execution_model(parser.next_string());
		args.entry_point_rename.push_back({ old_name, new_name, move(model) });
	});
	cbs.add("--entry", [&args](CLIParser &parser) { args.entry = parser.next_string(); });
	cbs.add("--stage", [&args](CLIParser &parser) { args.entry_stage = parser.next_string(); });
	cbs.add("--separate-shader-objects", [&args](CLIParser &) { args.sso = true; });
	cbs.add("--set-hlsl-vertex-input-semantic", [&args](CLIParser &parser) {
		HLSLVertexAttributeRemap remap;
		remap.location = parser.next_uint();
		remap.semantic = parser.next_string();
		args.hlsl_attr_remap.push_back(move(remap));
	});

	cbs.add("--remap", [&args](CLIParser &parser) {
		string src = parser.next_string();
		string dst = parser.next_string();
		uint32_t components = parser.next_uint();
		args.remaps.push_back({ move(src), move(dst), components });
	});

	cbs.add("--remap-variable-type", [&args](CLIParser &parser) {
		string var_name = parser.next_string();
		string new_type = parser.next_string();
		args.variable_type_remaps.push_back({ move(var_name), move(new_type) });
	});

	cbs.add("--rename-interface-variable", [&args](CLIParser &parser) {
		StorageClass cls = StorageClassMax;
		string clsStr = parser.next_string();
		if (clsStr == "in")
			cls = StorageClassInput;
		else if (clsStr == "out")
			cls = StorageClassOutput;

		uint32_t loc = parser.next_uint();
		string var_name = parser.next_string();
		args.interface_variable_renames.push_back({ cls, loc, move(var_name) });
	});

	cbs.add("--pls-in", [&args](CLIParser &parser) {
		auto fmt = pls_format(parser.next_string());
		auto name = parser.next_string();
		args.pls_in.push_back({ move(fmt), move(name) });
	});
	cbs.add("--pls-out", [&args](CLIParser &parser) {
		auto fmt = pls_format(parser.next_string());
		auto name = parser.next_string();
		args.pls_out.push_back({ move(fmt), move(name) });
	});
	cbs.add("--shader-model", [&args](CLIParser &parser) {
		args.shader_model = parser.next_uint();
		args.set_shader_model = true;
	});
	cbs.add("--msl-version", [&args](CLIParser &parser) {
		args.msl_version = parser.next_uint();
		args.set_msl_version = true;
	});

	cbs.add("--remove-unused-variables", [&args](CLIParser &) { args.remove_unused = true; });
	cbs.add("--combined-samplers-inherit-bindings",
	        [&args](CLIParser &) { args.combined_samplers_inherit_bindings = true; });

	cbs.add("--no-support-nonzero-baseinstance", [&](CLIParser &) { args.support_nonzero_baseinstance = false; });
	cbs.add("--emit-line-directives", [&args](CLIParser &) { args.emit_line_directives = true; });

	cbs.default_handler = [&args](const char *value) { args.input = value; };
	cbs.error_handler = [] { print_help(); };

	CLIParser parser{ move(cbs), argc - 1, argv + 1 };
	if (!parser.parse())
		return EXIT_FAILURE;
	else if (parser.ended_state)
		return EXIT_SUCCESS;

	if (!args.input)
	{
		fprintf(stderr, "Didn't specify input file.\n");
		print_help();
		return EXIT_FAILURE;
	}

	auto spirv_file = read_spirv_file(args.input);
	if (spirv_file.empty())
		return EXIT_FAILURE;

	// Special case reflection because it has little to do with the path followed by code-outputting compilers
	if (!args.reflect.empty())
	{
		Parser spirv_parser(move(spirv_file));
		spirv_parser.parse();

		CompilerReflection compiler(move(spirv_parser.get_parsed_ir()));
		compiler.set_format(args.reflect);
		auto json = compiler.compile();
		if (args.output)
			write_string_to_file(args.output, json.c_str());
		else
			printf("%s", json.c_str());
		return EXIT_SUCCESS;
	}

	string compiled_output;

	if (args.iterations == 1)
		compiled_output = compile_iteration(args, move(spirv_file));
	else
	{
		for (unsigned i = 0; i < args.iterations; i++)
			compiled_output = compile_iteration(args, spirv_file);
	}

	if (args.output)
		write_string_to_file(args.output, compiled_output.c_str());
	else
		printf("%s", compiled_output.c_str());

	return EXIT_SUCCESS;
}

int main(int argc, char *argv[])
{
#ifdef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
	return main_inner(argc, argv);
#else
	// Make sure we catch the exception or it just disappears into the aether on Windows.
	try
	{
		return main_inner(argc, argv);
	}
	catch (const std::exception &e)
	{
		fprintf(stderr, "SPIRV-Cross threw an exception: %s\n", e.what());
		return EXIT_FAILURE;
	}
#endif
}
