Quellcode durchsuchen

[spirv] Remove remains of old code.

Ehsan vor 6 Jahren
Ursprung
Commit
aa695490bf

+ 0 - 439
tools/clang/include/clang/SPIRV/InstBuilder.h

@@ -1,439 +0,0 @@
-//===-- InstBuilder.h - SPIR-V instruction builder --------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// AUTOMATICALLY GENERATED from the SPIR-V JSON grammar:
-//   spirv.core.grammar.json.
-// DO NOT MODIFY!
-
-#ifndef LLVM_CLANG_SPIRV_INSTBUILDER_H
-#define LLVM_CLANG_SPIRV_INSTBUILDER_H
-
-#include <deque>
-#include <functional>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "spirv/unified1/spirv.hpp11"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace spirv {
-
-/// \brief SPIR-V word consumer.
-using WordConsumer = std::function<void(std::vector<uint32_t> &&)>;
-
-/// \brief A low-level SPIR-V instruction builder that generates SPIR-V words
-/// directly. All generated SPIR-V words will be fed into the WordConsumer
-/// passed in the constructor.
-///
-/// The methods of this builder reflects the layouts of the corresponding
-/// SPIR-V instructions. For example, to construct an "OpMemoryModel Logical
-/// Simple" instruction, just call InstBuilder::opMemoryModel(
-/// spv::AddressingModel::Logical, spv::MemoryModel::Simple).
-///
-/// For SPIR-V instructions that may take additional parameters depending on
-/// the value of some previous parameters, additional methods are provided to
-/// "fix up" the instruction under building. For example, to construct an
-/// "OpDecorate <target-id> ArrayStride 0" instruction, just call InstBuilder::
-/// opDecorate(<target-id>, spv::Decoration::ArrayStride).literalInteger(0).
-///
-/// .x() is required to finalize the building and feed the result to the
-/// consumer. On failure, if additional parameters are needed, the first missing
-/// one will be reported by .x() via InstBuilder::Status.
-class InstBuilder {
-public:
-  /// Status of instruction building.
-  enum class Status : int32_t {
-    Success = 0,
-    NullConsumer = -1,
-    NestedInst = -2,
-    ZeroResultType = -3,
-    ZeroResultId = -4,
-    ExpectBuiltIn = -5,
-    ExpectFPFastMathMode = -6,
-    ExpectFPRoundingMode = -7,
-    ExpectFunctionParameterAttribute = -8,
-    ExpectIdRef = -9,
-    ExpectLinkageType = -10,
-    ExpectLiteralInteger = -11,
-    ExpectLiteralString = -12
-  };
-
-  explicit InstBuilder(WordConsumer);
-
-  // Disable copy constructor/assignment.
-  InstBuilder(const InstBuilder &) = delete;
-  InstBuilder &operator=(const InstBuilder &) = delete;
-
-  // Allow move constructor/assignment.
-  InstBuilder(InstBuilder &&that) = default;
-  InstBuilder &operator=(InstBuilder &&that) = default;
-
-  void setConsumer(WordConsumer);
-  const WordConsumer &getConsumer() const;
-
-  /// \brief Finalizes the building and feeds the generated SPIR-V words
-  /// to the consumer.
-  Status x();
-  /// \brief Finalizes the building and returns the generated SPIR-V words.
-  /// Returns an empty vector if errors happened during the construction.
-  std::vector<uint32_t> take();
-
-  /// \brief Clears the current instruction under building.
-  void clear();
-
-  // Instruction building methods.
-  InstBuilder &opSourceContinued(llvm::StringRef continued_source);
-  InstBuilder &opSource(spv::SourceLanguage source_language, uint32_t version,
-                        llvm::Optional<uint32_t> file,
-                        llvm::Optional<llvm::StringRef> source);
-  InstBuilder &opName(uint32_t target, std::string name);
-  InstBuilder &opMemberName(uint32_t type, uint32_t member, std::string name);
-  InstBuilder &opString(uint32_t result_id, std::string string);
-  InstBuilder &opLine(uint32_t file, uint32_t line, uint32_t column);
-  InstBuilder &opExtension(std::string name);
-  InstBuilder &opExtInstImport(uint32_t result_id, std::string name);
-  InstBuilder &opExtInst(uint32_t result_type, uint32_t result_id, uint32_t set,
-                         uint32_t instruction,
-                         llvm::ArrayRef<uint32_t> operand_1_operand_2_);
-  InstBuilder &opMemoryModel(spv::AddressingModel addressing_model,
-                             spv::MemoryModel memory_model);
-  InstBuilder &opEntryPoint(spv::ExecutionModel execution_model,
-                            uint32_t entry_point, std::string name,
-                            llvm::ArrayRef<uint32_t> interface);
-  InstBuilder &opExecutionMode(uint32_t entry_point, spv::ExecutionMode mode);
-  InstBuilder &opCapability(spv::Capability capability);
-  InstBuilder &opTypeVoid(uint32_t result_id);
-  InstBuilder &opTypeBool(uint32_t result_id);
-  InstBuilder &opTypeInt(uint32_t result_id, uint32_t width,
-                         uint32_t signedness);
-  InstBuilder &opTypeFloat(uint32_t result_id, uint32_t width);
-  InstBuilder &opTypeVector(uint32_t result_id, uint32_t component_type,
-                            uint32_t component_count);
-  InstBuilder &opTypeMatrix(uint32_t result_id, uint32_t column_type,
-                            uint32_t column_count);
-  InstBuilder &
-  opTypeImage(uint32_t result_id, uint32_t sampled_type, spv::Dim dim,
-              uint32_t depth, uint32_t arrayed, uint32_t ms, uint32_t sampled,
-              spv::ImageFormat image_format,
-              llvm::Optional<spv::AccessQualifier> access_qualifier);
-  InstBuilder &opTypeSampler(uint32_t result_id);
-  InstBuilder &opTypeSampledImage(uint32_t result_id, uint32_t image_type);
-  InstBuilder &opTypeArray(uint32_t result_id, uint32_t element_type,
-                           uint32_t length);
-  InstBuilder &opTypeRuntimeArray(uint32_t result_id, uint32_t element_type);
-  InstBuilder &
-  opTypeStruct(uint32_t result_id,
-               llvm::ArrayRef<uint32_t> member_0_type_member_1_type_);
-  InstBuilder &opTypeOpaque(uint32_t result_id,
-                            std::string the_name_of_the_opaque_type);
-  InstBuilder &opTypePointer(uint32_t result_id,
-                             spv::StorageClass storage_class, uint32_t type);
-  InstBuilder &
-  opTypeFunction(uint32_t result_id, uint32_t return_type,
-                 llvm::ArrayRef<uint32_t> parameter_0_type_parameter_1_type_);
-  InstBuilder &opTypeEvent(uint32_t result_id);
-  InstBuilder &opTypeDeviceEvent(uint32_t result_id);
-  InstBuilder &opTypeReserveId(uint32_t result_id);
-  InstBuilder &opTypeQueue(uint32_t result_id);
-  InstBuilder &opTypePipe(uint32_t result_id, spv::AccessQualifier qualifier);
-  InstBuilder &opTypeForwardPointer(uint32_t pointer_type,
-                                    spv::StorageClass storage_class);
-  InstBuilder &opConstantTrue(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opConstantFalse(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opConstantComposite(uint32_t result_type, uint32_t result_id,
-                                   llvm::ArrayRef<uint32_t> constituents);
-  InstBuilder &opConstantNull(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opSpecConstantTrue(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opSpecConstantFalse(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opSpecConstantComposite(uint32_t result_type, uint32_t result_id,
-                                       llvm::ArrayRef<uint32_t> constituents);
-  InstBuilder &opFunction(uint32_t result_type, uint32_t result_id,
-                          spv::FunctionControlMask function_control,
-                          uint32_t function_type);
-  InstBuilder &opFunctionParameter(uint32_t result_type, uint32_t result_id);
-  InstBuilder &opFunctionEnd();
-  InstBuilder &opFunctionCall(uint32_t result_type, uint32_t result_id,
-                              uint32_t function,
-                              llvm::ArrayRef<uint32_t> argument_0_argument_1_);
-  InstBuilder &opVariable(uint32_t result_type, uint32_t result_id,
-                          spv::StorageClass storage_class,
-                          llvm::Optional<uint32_t> initializer);
-  InstBuilder &opImageTexelPointer(uint32_t result_type, uint32_t result_id,
-                                   uint32_t image, uint32_t coordinate,
-                                   uint32_t sample);
-  InstBuilder &opLoad(uint32_t result_type, uint32_t result_id,
-                      uint32_t pointer,
-                      llvm::Optional<spv::MemoryAccessMask> memory_access);
-  InstBuilder &opStore(uint32_t pointer, uint32_t object,
-                       llvm::Optional<spv::MemoryAccessMask> memory_access);
-  InstBuilder &opAccessChain(uint32_t result_type, uint32_t result_id,
-                             uint32_t base, llvm::ArrayRef<uint32_t> indexes);
-  InstBuilder &opDecorate(uint32_t target, spv::Decoration decoration);
-  InstBuilder &opMemberDecorate(uint32_t structure_type, uint32_t member,
-                                spv::Decoration decoration);
-  InstBuilder &opDecorationGroup(uint32_t result_id);
-  InstBuilder &opGroupDecorate(uint32_t decoration_group,
-                               llvm::ArrayRef<uint32_t> targets);
-  InstBuilder &
-  opGroupMemberDecorate(uint32_t decoration_group,
-                        llvm::ArrayRef<std::pair<uint32_t, uint32_t>> targets);
-  InstBuilder &opVectorShuffle(uint32_t result_type, uint32_t result_id,
-                               uint32_t vector_1, uint32_t vector_2,
-                               llvm::ArrayRef<uint32_t> components);
-  InstBuilder &opCompositeConstruct(uint32_t result_type, uint32_t result_id,
-                                    llvm::ArrayRef<uint32_t> constituents);
-  InstBuilder &opCompositeExtract(uint32_t result_type, uint32_t result_id,
-                                  uint32_t composite,
-                                  llvm::ArrayRef<uint32_t> indexes);
-  InstBuilder &opCompositeInsert(uint32_t result_type, uint32_t result_id,
-                                 uint32_t object, uint32_t composite,
-                                 llvm::ArrayRef<uint32_t> indexes);
-  InstBuilder &opTranspose(uint32_t result_type, uint32_t result_id,
-                           uint32_t matrix);
-  InstBuilder &opSampledImage(uint32_t result_type, uint32_t result_id,
-                              uint32_t image, uint32_t sampler);
-  InstBuilder &opImageSampleImplicitLod(
-      uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-      uint32_t coordinate,
-      llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &opImageSampleExplicitLod(uint32_t result_type,
-                                        uint32_t result_id,
-                                        uint32_t sampled_image,
-                                        uint32_t coordinate,
-                                        spv::ImageOperandsMask image_operands);
-  InstBuilder &opImageSampleDrefImplicitLod(
-      uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-      uint32_t coordinate, uint32_t dref,
-      llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &
-  opImageSampleDrefExplicitLod(uint32_t result_type, uint32_t result_id,
-                               uint32_t sampled_image, uint32_t coordinate,
-                               uint32_t dref,
-                               spv::ImageOperandsMask image_operands);
-  InstBuilder &
-  opImageFetch(uint32_t result_type, uint32_t result_id, uint32_t image,
-               uint32_t coordinate,
-               llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &
-  opImageGather(uint32_t result_type, uint32_t result_id,
-                uint32_t sampled_image, uint32_t coordinate, uint32_t component,
-                llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &
-  opImageDrefGather(uint32_t result_type, uint32_t result_id,
-                    uint32_t sampled_image, uint32_t coordinate, uint32_t dref,
-                    llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &
-  opImageRead(uint32_t result_type, uint32_t result_id, uint32_t image,
-              uint32_t coordinate,
-              llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &
-  opImageWrite(uint32_t image, uint32_t coordinate, uint32_t texel,
-               llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &opImageQueryFormat(uint32_t result_type, uint32_t result_id,
-                                  uint32_t image);
-  InstBuilder &opImageQueryOrder(uint32_t result_type, uint32_t result_id,
-                                 uint32_t image);
-  InstBuilder &opImageQuerySizeLod(uint32_t result_type, uint32_t result_id,
-                                   uint32_t image, uint32_t level_of_detail);
-  InstBuilder &opImageQuerySize(uint32_t result_type, uint32_t result_id,
-                                uint32_t image);
-  InstBuilder &opImageQueryLod(uint32_t result_type, uint32_t result_id,
-                               uint32_t sampled_image, uint32_t coordinate);
-  InstBuilder &opImageQueryLevels(uint32_t result_type, uint32_t result_id,
-                                  uint32_t image);
-  InstBuilder &opImageQuerySamples(uint32_t result_type, uint32_t result_id,
-                                   uint32_t image);
-  InstBuilder &opSelect(uint32_t result_type, uint32_t result_id,
-                        uint32_t condition, uint32_t object_1,
-                        uint32_t object_2);
-  InstBuilder &opBitFieldInsert(uint32_t result_type, uint32_t result_id,
-                                uint32_t base, uint32_t insert, uint32_t offset,
-                                uint32_t count);
-  InstBuilder &opBitFieldSExtract(uint32_t result_type, uint32_t result_id,
-                                  uint32_t base, uint32_t offset,
-                                  uint32_t count);
-  InstBuilder &opBitFieldUExtract(uint32_t result_type, uint32_t result_id,
-                                  uint32_t base, uint32_t offset,
-                                  uint32_t count);
-  InstBuilder &opBitReverse(uint32_t result_type, uint32_t result_id,
-                            uint32_t base);
-  InstBuilder &opBitCount(uint32_t result_type, uint32_t result_id,
-                          uint32_t base);
-  InstBuilder &opDPdx(uint32_t result_type, uint32_t result_id, uint32_t p);
-  InstBuilder &opDPdy(uint32_t result_type, uint32_t result_id, uint32_t p);
-  InstBuilder &opFwidth(uint32_t result_type, uint32_t result_id, uint32_t p);
-  InstBuilder &opDPdxFine(uint32_t result_type, uint32_t result_id, uint32_t p);
-  InstBuilder &opDPdyFine(uint32_t result_type, uint32_t result_id, uint32_t p);
-  InstBuilder &opFwidthFine(uint32_t result_type, uint32_t result_id,
-                            uint32_t p);
-  InstBuilder &opDPdxCoarse(uint32_t result_type, uint32_t result_id,
-                            uint32_t p);
-  InstBuilder &opDPdyCoarse(uint32_t result_type, uint32_t result_id,
-                            uint32_t p);
-  InstBuilder &opFwidthCoarse(uint32_t result_type, uint32_t result_id,
-                              uint32_t p);
-  InstBuilder &opEmitVertex();
-  InstBuilder &opEndPrimitive();
-  InstBuilder &opControlBarrier(uint32_t execution, uint32_t memory,
-                                uint32_t semantics);
-  InstBuilder &opMemoryBarrier(uint32_t memory, uint32_t semantics);
-  InstBuilder &opAtomicExchange(uint32_t result_type, uint32_t result_id,
-                                uint32_t pointer, uint32_t scope,
-                                uint32_t semantics, uint32_t value);
-  InstBuilder &opAtomicCompareExchange(uint32_t result_type, uint32_t result_id,
-                                       uint32_t pointer, uint32_t scope,
-                                       uint32_t equal, uint32_t unequal,
-                                       uint32_t value, uint32_t comparator);
-  InstBuilder &opLoopMerge(uint32_t merge_block, uint32_t continue_target,
-                           spv::LoopControlMask loop_control);
-  InstBuilder &opSelectionMerge(uint32_t merge_block,
-                                spv::SelectionControlMask selection_control);
-  InstBuilder &opLabel(uint32_t result_id);
-  InstBuilder &opBranch(uint32_t target_label);
-  InstBuilder &opBranchConditional(uint32_t condition, uint32_t true_label,
-                                   uint32_t false_label,
-                                   llvm::ArrayRef<uint32_t> branch_weights);
-  InstBuilder &opSwitch(uint32_t selector, uint32_t default_target,
-                        llvm::ArrayRef<std::pair<uint32_t, uint32_t>> target);
-  InstBuilder &opKill();
-  InstBuilder &opReturn();
-  InstBuilder &opReturnValue(uint32_t value);
-  InstBuilder &opUnreachable();
-  InstBuilder &opImageSparseSampleImplicitLod(
-      uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-      uint32_t coordinate,
-      llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &
-  opImageSparseSampleExplicitLod(uint32_t result_type, uint32_t result_id,
-                                 uint32_t sampled_image, uint32_t coordinate,
-                                 spv::ImageOperandsMask image_operands);
-  InstBuilder &opImageSparseSampleDrefImplicitLod(
-      uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-      uint32_t coordinate, uint32_t dref,
-      llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &
-  opImageSparseSampleDrefExplicitLod(uint32_t result_type, uint32_t result_id,
-                                     uint32_t sampled_image,
-                                     uint32_t coordinate, uint32_t dref,
-                                     spv::ImageOperandsMask image_operands);
-  InstBuilder &
-  opImageSparseFetch(uint32_t result_type, uint32_t result_id, uint32_t image,
-                     uint32_t coordinate,
-                     llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &
-  opImageSparseGather(uint32_t result_type, uint32_t result_id,
-                      uint32_t sampled_image, uint32_t coordinate,
-                      uint32_t component,
-                      llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &opImageSparseDrefGather(
-      uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-      uint32_t coordinate, uint32_t dref,
-      llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &opImageSparseTexelsResident(uint32_t result_type,
-                                           uint32_t result_id,
-                                           uint32_t resident_code);
-  InstBuilder &
-  opImageSparseRead(uint32_t result_type, uint32_t result_id, uint32_t image,
-                    uint32_t coordinate,
-                    llvm::Optional<spv::ImageOperandsMask> image_operands);
-  InstBuilder &opModuleProcessed(std::string process);
-  InstBuilder &opExecutionModeId(uint32_t entry_point, spv::ExecutionMode mode);
-  InstBuilder &opDecorateId(uint32_t target, spv::Decoration decoration);
-  InstBuilder &opDecorateStringGOOGLE(uint32_t target,
-                                      spv::Decoration decoration);
-  InstBuilder &opMemberDecorateStringGOOGLE(uint32_t struct_type,
-                                            uint32_t member,
-                                            spv::Decoration decoration);
-
-  // All-in-one methods for creating unary and binary operations.
-  InstBuilder &unaryOp(spv::Op op, uint32_t result_type, uint32_t result_id,
-                       uint32_t operand);
-  InstBuilder &binaryOp(spv::Op op, uint32_t result_type, uint32_t result_id,
-                        uint32_t lhs, uint32_t rhs);
-  InstBuilder &specConstantBinaryOp(spv::Op op, uint32_t result_type,
-                                    uint32_t result_id, uint32_t lhs,
-                                    uint32_t rhs);
-  InstBuilder &atomicOp(spv::Op op, uint32_t result_type, uint32_t result_id,
-                        uint32_t pointer, uint32_t scope, uint32_t semantics,
-                        uint32_t value);
-
-  // All-in-one methods for creating OpGroupNonUniform* operations.
-  InstBuilder &groupNonUniformOp(spv::Op op, uint32_t result_type,
-                                 uint32_t result_id, uint32_t exec_scope);
-  InstBuilder &groupNonUniformUnaryOp(
-      spv::Op op, uint32_t result_type, uint32_t result_id, uint32_t exec_scope,
-      llvm::Optional<spv::GroupOperation> groupOp, uint32_t operand);
-  InstBuilder &groupNonUniformBinaryOp(spv::Op op, uint32_t result_type,
-                                       uint32_t result_id, uint32_t exec_scope,
-                                       uint32_t operand1, uint32_t operand2);
-
-  // Methods for building constants.
-  InstBuilder &opConstant(uint32_t result_type, uint32_t result_id,
-                          uint32_t value);
-  InstBuilder &opSpecConstant(uint32_t result_type, uint32_t result_id,
-                              uint32_t value);
-
-  // All-in-one method for creating different types of OpImageSample*.
-  InstBuilder &
-  opImageSample(uint32_t result_type, uint32_t result_id,
-                uint32_t sampled_image, uint32_t coordinate, uint32_t dref,
-                llvm::Optional<spv::ImageOperandsMask> image_operands,
-                bool is_explicit, bool is_sparse);
-
-  // All-in-one method for creating different types of
-  // OpImageRead*/OpImageFetch*.
-  InstBuilder &
-  opImageFetchRead(uint32_t result_type, uint32_t result_id, uint32_t image,
-                   uint32_t coordinate,
-                   llvm::Optional<spv::ImageOperandsMask> image_operands,
-                   bool is_fetch, bool is_sparse);
-
-  // Methods for supplying additional parameters.
-  InstBuilder &fPFastMathMode(spv::FPFastMathModeMask);
-  InstBuilder &fPRoundingMode(spv::FPRoundingMode);
-  InstBuilder &linkageType(spv::LinkageType);
-  InstBuilder &functionParameterAttribute(spv::FunctionParameterAttribute);
-  InstBuilder &builtIn(spv::BuiltIn);
-  InstBuilder &idRef(uint32_t);
-  InstBuilder &literalInteger(uint32_t);
-  InstBuilder &literalString(std::string);
-
-private:
-  enum class OperandKind {
-    BuiltIn,
-    FPFastMathMode,
-    FPRoundingMode,
-    FunctionParameterAttribute,
-    IdRef,
-    LinkageType,
-    LiteralInteger,
-    LiteralString
-  };
-
-  void encodeImageOperands(spv::ImageOperandsMask value);
-  void encodeLoopControl(spv::LoopControlMask value);
-  void encodeMemoryAccess(spv::MemoryAccessMask value);
-  void encodeExecutionMode(spv::ExecutionMode value);
-  void encodeDecoration(spv::Decoration value);
-  void encodeString(llvm::StringRef value);
-
-  WordConsumer TheConsumer;
-  std::vector<uint32_t> TheInst;       ///< The instruction under construction.
-  std::deque<OperandKind> Expectation; ///< Expected additional parameters.
-  Status TheStatus;                    ///< Current building status.
-};
-
-} // end namespace spirv
-} // end namespace clang
-
-#endif

+ 0 - 583
tools/clang/include/clang/SPIRV/ModuleBuilder.h

@@ -1,583 +0,0 @@
-//===-- ModuleBuilder.h - SPIR-V builder ----------------------*- C++ -*---===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SPIRV_MODULEBUILDER_H
-#define LLVM_CLANG_SPIRV_MODULEBUILDER_H
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "clang/AST/Type.h"
-#include "clang/SPIRV/FeatureManager.h"
-#include "clang/SPIRV/InstBuilder.h"
-#include "clang/SPIRV/SPIRVContext.h"
-#include "clang/SPIRV/Structure.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace spirv {
-
-/// \brief SPIR-V module builder.
-///
-/// This class exports API for constructing SPIR-V binary interactively.
-/// At any time, there can only exist at most one function under building;
-/// but there can exist multiple basic blocks under construction.
-///
-/// Call `takeModule()` to get the SPIR-V words after finishing building the
-/// module.
-class ModuleBuilder {
-public:
-  /// \brief Constructs a ModuleBuilder with the given SPIR-V context.
-  ModuleBuilder(SPIRVContext *, FeatureManager *features,
-                const SpirvCodeGenOptions &opts);
-
-  /// \brief Returns the associated SPIRVContext.
-  inline SPIRVContext *getSPIRVContext();
-
-  /// \brief Takes the SPIR-V module under building. This will consume the
-  /// module under construction.
-  std::vector<uint32_t> takeModule();
-
-  // === Function and Basic Block ===
-
-  /// \brief Begins building a SPIR-V function. Returns the <result-id> for the
-  /// function on success. Returns zero on failure.
-  ///
-  /// If the resultId supplied is not zero, the created function will use it;
-  /// otherwise, an unused <result-id> will be assgined.
-  /// At any time, there can only exist at most one function under building.
-  uint32_t beginFunction(uint32_t funcType, uint32_t returnType,
-                         llvm::StringRef name = "", uint32_t resultId = 0);
-
-  /// \brief Registers a function parameter of the given pointer type in the
-  /// current function and returns its <result-id>.
-  uint32_t addFnParam(uint32_t ptrType, llvm::StringRef name = "");
-
-  /// \brief Creates a local variable of the given type in the current
-  /// function and returns its <result-id>.
-  ///
-  /// The corresponding pointer type of the given type will be constructed in
-  /// this method for the variable itself.
-  uint32_t addFnVar(uint32_t valueType, llvm::StringRef name = "",
-                    llvm::Optional<uint32_t> init = llvm::None);
-
-  /// \brief Ends building of the current function. Returns true of success,
-  /// false on failure. All basic blocks constructed from the beginning or
-  /// after ending the previous function will be collected into this function.
-  bool endFunction();
-
-  /// \brief Creates a SPIR-V basic block. On success, returns the <label-id>
-  /// for the basic block. On failure, returns zero.
-  uint32_t createBasicBlock(llvm::StringRef name = "");
-
-  /// \brief Adds the basic block with the given label as a successor to the
-  /// current basic block.
-  void addSuccessor(uint32_t successorLabel);
-
-  /// \brief Sets the merge target to the basic block with the given <label-id>.
-  /// The caller must make sure the current basic block contains an
-  /// OpSelectionMerge or OpLoopMerge instruction.
-  void setMergeTarget(uint32_t mergeLabel);
-
-  /// \brief Sets the continue target to the basic block with the given
-  /// <label-id>. The caller must make sure the current basic block contains an
-  /// OpLoopMerge instruction.
-  void setContinueTarget(uint32_t continueLabel);
-
-  /// \brief Returns true if the current basic block inserting into is
-  /// terminated.
-  inline bool isCurrentBasicBlockTerminated() const;
-
-  /// \brief Sets insertion point to the basic block with the given <label-id>.
-  void setInsertPoint(uint32_t labelId);
-
-  // === Instruction at the current Insertion Point ===
-
-  /// \brief Creates a composite construct instruction with the given
-  /// <result-type> and constituents and returns the <result-id> for the
-  /// composite.
-  uint32_t createCompositeConstruct(uint32_t resultType,
-                                    llvm::ArrayRef<uint32_t> constituents);
-
-  /// \brief Creates a composite extract instruction. The given composite is
-  /// indexed using the given literal indexes to obtain the resulting element.
-  /// Returns the <result-id> for the extracted element.
-  uint32_t createCompositeExtract(uint32_t resultType, uint32_t composite,
-                                  llvm::ArrayRef<uint32_t> indexes);
-
-  /// \brief Creates a composite insert instruction. The given object will
-  /// replace the component in the composite at the given indices. Returns the
-  /// <result-id> for the new composite.
-  uint32_t createCompositeInsert(uint32_t resultType, uint32_t composite,
-                                 llvm::ArrayRef<uint32_t> indices,
-                                 uint32_t object);
-
-  /// \brief Creates a vector shuffle instruction of selecting from the two
-  /// vectors using selectors and returns the <result-id> of the result vector.
-  uint32_t createVectorShuffle(uint32_t resultType, uint32_t vector1,
-                               uint32_t vector2,
-                               llvm::ArrayRef<uint32_t> selectors);
-
-  /// \brief Creates a load instruction loading the value of the given
-  /// <result-type> from the given pointer. Returns the <result-id> for the
-  /// loaded value.
-  uint32_t createLoad(uint32_t resultType, uint32_t pointer);
-  /// \brief Creates a store instruction storing the given value into the given
-  /// address.
-  void createStore(uint32_t address, uint32_t value);
-
-  /// \brief Creates a function call instruction and returns the <result-id> for
-  /// the return value.
-  uint32_t createFunctionCall(uint32_t returnType, uint32_t functionId,
-                              llvm::ArrayRef<uint32_t> params);
-
-  /// \brief Creates an access chain instruction to retrieve the element from
-  /// the given base by walking through the given indexes. Returns the
-  /// <result-id> for the pointer to the element.
-  uint32_t createAccessChain(uint32_t resultType, uint32_t base,
-                             llvm::ArrayRef<uint32_t> indexes);
-
-  /// \brief Creates a unary operation with the given SPIR-V opcode. Returns
-  /// the <result-id> for the result.
-  uint32_t createUnaryOp(spv::Op op, uint32_t resultType, uint32_t operand);
-
-  /// \brief Creates a binary operation with the given SPIR-V opcode. Returns
-  /// the <result-id> for the result.
-  uint32_t createBinaryOp(spv::Op op, uint32_t resultType, uint32_t lhs,
-                          uint32_t rhs);
-  uint32_t createSpecConstantBinaryOp(spv::Op op, uint32_t resultType,
-                                      uint32_t lhs, uint32_t rhs);
-
-  /// \brief Creates an operation with the given OpGroupNonUniform* SPIR-V
-  /// opcode. Returns the <result-id> for the result.
-  uint32_t createGroupNonUniformOp(spv::Op op, uint32_t resultType,
-                                   uint32_t execScope);
-  uint32_t createGroupNonUniformUnaryOp(
-      spv::Op op, uint32_t resultType, uint32_t execScope, uint32_t operand,
-      llvm::Optional<spv::GroupOperation> groupOp = llvm::None);
-  uint32_t createGroupNonUniformBinaryOp(spv::Op op, uint32_t resultType,
-                                         uint32_t execScope, uint32_t operand1,
-                                         uint32_t operand2);
-
-  /// \brief Creates an atomic instruction with the given parameters.
-  /// Returns the <result-id> for the result.
-  uint32_t createAtomicOp(spv::Op opcode, uint32_t resultType,
-                          uint32_t orignalValuePtr, uint32_t scopeId,
-                          uint32_t memorySemanticsId, uint32_t valueToOp);
-  uint32_t createAtomicCompareExchange(uint32_t resultType,
-                                       uint32_t orignalValuePtr,
-                                       uint32_t scopeId,
-                                       uint32_t equalMemorySemanticsId,
-                                       uint32_t unequalMemorySemanticsId,
-                                       uint32_t valueToOp, uint32_t comparator);
-
-  /// \brief Creates an OpImageTexelPointer SPIR-V instruction with the given
-  /// parameters.
-  uint32_t createImageTexelPointer(uint32_t resultType, uint32_t imageId,
-                                   uint32_t coordinate, uint32_t sample);
-
-  /// \brief Creates SPIR-V instructions for sampling the given image.
-  ///
-  /// If compareVal is given a non-zero value, *Dref* variants of OpImageSample*
-  /// will be generated.
-  ///
-  /// If lod or grad is given a non-zero value, *ExplicitLod variants of
-  /// OpImageSample* will be generated; otherwise, *ImplicitLod variant will
-  /// be generated.
-  ///
-  /// If bias, lod, grad, or minLod is given a non-zero value, an additional
-  /// image operands, Bias, Lod, Grad, or MinLod will be attached to the current
-  /// instruction, respectively. Panics if both lod and minLod are non-zero.
-  ///
-  /// If residencyCodeId is not zero, the sparse version of the instructions
-  /// will be used, and the SPIR-V instruction for storing the resulting
-  /// residency code will also be emitted.
-  ///
-  /// If isNonUniform is true, the sampled image will be decorated with
-  /// NonUniformEXT.
-  uint32_t createImageSample(uint32_t texelType, uint32_t imageType,
-                             uint32_t image, uint32_t sampler,
-                             bool isNonUniform, uint32_t coordinate,
-                             uint32_t compareVal, uint32_t bias, uint32_t lod,
-                             std::pair<uint32_t, uint32_t> grad,
-                             uint32_t constOffset, uint32_t varOffset,
-                             uint32_t constOffsets, uint32_t sample,
-                             uint32_t minLod, uint32_t residencyCodeId);
-
-  /// \brief Creates SPIR-V instructions for reading a texel from an image. If
-  /// doImageFetch is true, OpImageFetch is used. OpImageRead is used otherwise.
-  /// OpImageFetch should be used for sampled images. OpImageRead should be used
-  /// for images without a sampler.
-  ///
-  /// If residencyCodeId is not zero, the sparse version of the instructions
-  /// will be used, and the SPIR-V instruction for storing the resulting
-  /// residency code will also be emitted.
-  uint32_t createImageFetchOrRead(bool doImageFetch, uint32_t texelType,
-                                  QualType imageType, uint32_t image,
-                                  uint32_t coordinate, uint32_t lod,
-                                  uint32_t constOffset, uint32_t varOffset,
-                                  uint32_t constOffsets, uint32_t sample,
-                                  uint32_t residencyCodeId);
-
-  /// \brief Creates SPIR-V instructions for writing to the given image.
-  void createImageWrite(QualType imageType, uint32_t imageId, uint32_t coordId,
-                        uint32_t texelId);
-
-  /// \brief Creates SPIR-V instructions for gathering the given image.
-  ///
-  /// If compareVal is given a non-zero value, OpImageDrefGather or
-  /// OpImageSparseDrefGather will be generated; otherwise, OpImageGather or
-  /// OpImageSparseGather will be generated.
-  /// If residencyCodeId is not zero, the sparse version of the instructions
-  /// will be used, and the SPIR-V instruction for storing the resulting
-  /// residency code will also be emitted.
-  /// If isNonUniform is true, the sampled image will be decorated with
-  /// NonUniformEXT.
-  uint32_t createImageGather(uint32_t texelType, uint32_t imageType,
-                             uint32_t image, uint32_t sampler,
-                             bool isNonUniform, uint32_t coordinate,
-                             uint32_t component, uint32_t compareVal,
-                             uint32_t constOffset, uint32_t varOffset,
-                             uint32_t constOffsets, uint32_t sample,
-                             uint32_t residencyCodeId);
-
-  /// \brief Creates an OpImageSparseTexelsResident SPIR-V instruction for the
-  /// given Resident Code and returns the <result-id> of the instruction.
-  uint32_t createImageSparseTexelsResident(uint32_t resident_code);
-
-  /// \brief Creates a select operation with the given values for true and false
-  /// cases and returns the <result-id> for the result.
-  uint32_t createSelect(uint32_t resultType, uint32_t condition,
-                        uint32_t trueValue, uint32_t falseValue);
-
-  /// \brief Creates a switch statement for the given selector, default, and
-  /// branches. Results in OpSelectionMerge followed by OpSwitch.
-  void createSwitch(uint32_t mergeLabel, uint32_t selector,
-                    uint32_t defaultLabel,
-                    llvm::ArrayRef<std::pair<uint32_t, uint32_t>> target);
-
-  /// \brief Creates a fragment-shader discard via by emitting OpKill.
-  void createKill();
-
-  /// \brief Creates an unconditional branch to the given target label.
-  /// If mergeBB and continueBB are non-zero, it creates an OpLoopMerge
-  /// instruction followed by an unconditional branch to the given target label.
-  void createBranch(
-      uint32_t targetLabel, uint32_t mergeBB = 0, uint32_t continueBB = 0,
-      spv::LoopControlMask loopControl = spv::LoopControlMask::MaskNone);
-
-  /// \brief Creates a conditional branch. An OpSelectionMerge instruction
-  /// will be created if mergeLabel is not 0 and continueLabel is 0.
-  /// An OpLoopMerge instruction will also be created if both continueLabel
-  /// and mergeLabel are not 0. For other cases, mergeLabel and continueLabel
-  /// will be ignored. If selection control mask and/or loop control mask are
-  /// provided, they will be applied to the corresponding SPIR-V instruction.
-  /// Otherwise, MaskNone will be used.
-  void createConditionalBranch(
-      uint32_t condition, uint32_t trueLabel, uint32_t falseLabel,
-      uint32_t mergeLabel = 0, uint32_t continueLabel = 0,
-      spv::SelectionControlMask selectionControl =
-          spv::SelectionControlMask::MaskNone,
-      spv::LoopControlMask loopControl = spv::LoopControlMask::MaskNone);
-
-  /// \brief Creates a return instruction.
-  void createReturn();
-  /// \brief Creates a return value instruction.
-  void createReturnValue(uint32_t value);
-
-  /// \brief Creates an OpExtInst instruction with the given instruction set id,
-  /// instruction number, and operands. Returns the <result-id> of the
-  /// instruction.
-  uint32_t createExtInst(uint32_t resultType, uint32_t setId, uint32_t instId,
-                         llvm::ArrayRef<uint32_t> operands);
-
-  /// \brief Creates an OpMemoryBarrier or OpControlBarrier instruction with the
-  /// given flags. If execution scope id (exec) is non-zero, an OpControlBarrier
-  /// is created; otherwise an OpMemoryBarrier is created.
-  void createBarrier(uint32_t exec, uint32_t memory, uint32_t semantics);
-
-  /// \brief Creates an OpBitFieldInsert SPIR-V instruction for the given
-  /// arguments.
-  uint32_t createBitFieldInsert(uint32_t resultType, uint32_t base,
-                                uint32_t insert, uint32_t offset,
-                                uint32_t count);
-
-  /// \brief Creates an OpBitFieldUExtract or OpBitFieldSExtract SPIR-V
-  /// instruction for the given arguments.
-  uint32_t createBitFieldExtract(uint32_t resultType, uint32_t base,
-                                 uint32_t offset, uint32_t count,
-                                 bool isSigned);
-
-  /// \brief Creates an OpEmitVertex instruction.
-  void createEmitVertex();
-
-  /// \brief Creates an OpEndPrimitive instruction.
-  void createEndPrimitive();
-
-  // === SPIR-V Module Structure ===
-
-  inline void requireCapability(spv::Capability);
-
-  inline void setAddressingModel(spv::AddressingModel);
-  inline void setMemoryModel(spv::MemoryModel);
-
-  /// \brief Adds an entry point for the module under construction. We only
-  /// support a single entry point per module for now.
-  inline void addEntryPoint(spv::ExecutionModel em, uint32_t targetId,
-                            std::string targetName,
-                            llvm::ArrayRef<uint32_t> interfaces);
-
-  inline void setShaderModelVersion(uint32_t major, uint32_t minor);
-
-  /// \brief Sets the source file name and the <result-id> for the OpString for
-  /// the file name.
-  inline void setSourceFileName(uint32_t id, std::string name);
-  /// \brief Sets the main source file content.
-  inline void setSourceFileContent(llvm::StringRef content);
-
-  /// \brief Adds an execution mode to the module under construction.
-  void addExecutionMode(uint32_t entryPointId, spv::ExecutionMode em,
-                        llvm::ArrayRef<uint32_t> params);
-
-  /// \brief Adds an extension to the module under construction for translating
-  /// the given target at the given source location.
-  void addExtension(Extension, llvm::StringRef target, SourceLocation);
-
-  /// \brief If not added already, adds an OpExtInstImport (import of extended
-  /// instruction set) of the GLSL instruction set. Returns the <result-id> for
-  /// the imported GLSL instruction set.
-  uint32_t getGLSLExtInstSet();
-
-  /// \brief Adds a stage input/ouput variable whose value is of the given type.
-  ///
-  /// The corresponding pointer type of the given type will be constructed in
-  /// this method for the variable itself.
-  uint32_t addStageIOVar(uint32_t type, spv::StorageClass storageClass,
-                         std::string name);
-
-  /// \brief Adds a stage builtin variable whose value is of the given type.
-  ///
-  /// The corresponding pointer type of the given type will be constructed in
-  /// this method for the variable itself.
-  uint32_t addStageBuiltinVar(uint32_t type, spv::StorageClass storageClass,
-                              spv::BuiltIn);
-
-  /// \brief Adds a module variable. This variable should not have the Function
-  /// storage class.
-  ///
-  /// The corresponding pointer type of the given type will be constructed in
-  /// this method for the variable itself.
-  uint32_t addModuleVar(uint32_t valueType, spv::StorageClass storageClass,
-                        llvm::StringRef name = "",
-                        llvm::Optional<uint32_t> init = llvm::None);
-
-  /// \brief Decorates the given target <result-id> with the given location.
-  void decorateLocation(uint32_t targetId, uint32_t location);
-
-  /// \brief Decorates the given target <result-id> with the given index.
-  void decorateIndex(uint32_t targetId, uint32_t index);
-
-  /// \brief Decorates the given target <result-id> with the given descriptor
-  /// set and binding number.
-  void decorateDSetBinding(uint32_t targetId, uint32_t setNumber,
-                           uint32_t bindingNumber);
-
-  /// \brief Decorates the given target <result-id> with the given SpecId.
-  void decorateSpecId(uint32_t targetId, uint32_t specId);
-
-  /// \brief Decorates the given target <result-id> with the given input
-  /// attchment index number.
-  void decorateInputAttachmentIndex(uint32_t targetId, uint32_t indexNumber);
-
-  /// \brief Decorates the given main buffer with the given counter buffer.
-  void decorateCounterBufferId(uint32_t mainBufferId, uint32_t counterBufferId);
-
-  /// \brief Decorates the given target <result-id> with the given HLSL semantic
-  /// string.
-  void decorateHlslSemantic(uint32_t targetId, llvm::StringRef semantic,
-                            llvm::Optional<uint32_t> memberIdx = llvm::None);
-
-  /// \brief Decorates the given target <result-id> with centroid
-  void decorateCentroid(uint32_t targetId);
-
-  /// \brief Decorates the given target <result-id> with flat
-  void decorateFlat(uint32_t targetId);
-
-  /// \brief Decorates the given target <result-id> with noperspective
-  void decorateNoPerspective(uint32_t targetId);
-
-  /// \brief Decorates the given target <result-id> with sample
-  void decorateSample(uint32_t targetId);
-
-  /// \brief Decorates the given target <result-id> with block
-  void decorateBlock(uint32_t targetId);
-
-  /// \brief Decorates the given target <result-id> with relaxedprecision
-  void decorateRelaxedPrecision(uint32_t targetId);
-
-  /// \brief Decorates the given target <result-id> with patch
-  void decoratePatch(uint32_t targetId);
-
-  /// \brief Decorates the given target <result-id> with nonuniformEXT
-  void decorateNonUniformEXT(uint32_t targetId);
-
-  /// \brief Decorates the given target <result-id> with NoContraction
-  void decorateNoContraction(uint32_t targetId);
-
-  // === Type ===
-
-  uint32_t getVoidType();
-  uint32_t getBoolType();
-  uint32_t getInt16Type();
-  uint32_t getInt32Type();
-  uint32_t getInt64Type();
-  uint32_t getUint16Type();
-  uint32_t getUint32Type();
-  uint32_t getUint64Type();
-  uint32_t getFloat16Type();
-  uint32_t getFloat32Type();
-  uint32_t getFloat64Type();
-  uint32_t getVecType(uint32_t elemType, uint32_t elemCount);
-  uint32_t getMatType(QualType elemType, uint32_t colType, uint32_t colCount,
-                      Type::DecorationSet decorations = {});
-  uint32_t getPointerType(uint32_t pointeeType, spv::StorageClass);
-  uint32_t getStructType(llvm::ArrayRef<uint32_t> fieldTypes,
-                         llvm::StringRef structName = "",
-                         llvm::ArrayRef<llvm::StringRef> fieldNames = {},
-                         Type::DecorationSet decorations = {});
-  uint32_t getArrayType(uint32_t elemType, uint32_t count,
-                        Type::DecorationSet decorations = {});
-  uint32_t getRuntimeArrayType(uint32_t elemType,
-                               Type::DecorationSet decorations = {});
-  uint32_t getFunctionType(uint32_t returnType,
-                           llvm::ArrayRef<uint32_t> paramTypes);
-  uint32_t getImageType(uint32_t sampledType, spv::Dim, uint32_t depth,
-                        bool isArray, uint32_t ms = 0, uint32_t sampled = 1,
-                        spv::ImageFormat format = spv::ImageFormat::Unknown);
-  uint32_t getSamplerType();
-  uint32_t getSampledImageType(uint32_t imageType);
-  uint32_t getByteAddressBufferType(bool isRW);
-
-  /// \brief Returns a struct type with 2 members. The first member is an
-  /// unsigned integer type which can hold the 'Residency Code'. The second
-  /// member will be of the given type.
-  uint32_t getSparseResidencyStructType(uint32_t type);
-
-  // === Constant ===
-  uint32_t getConstantBool(bool value, bool isSpecConst = false);
-  uint32_t getConstantInt16(int16_t value);
-  uint32_t getConstantInt32(int32_t value, bool isSpecConst = false);
-  uint32_t getConstantInt64(int64_t value);
-  uint32_t getConstantUint16(uint16_t value);
-  uint32_t getConstantUint32(uint32_t value, bool isSpecConst = false);
-  uint32_t getConstantUint64(uint64_t value);
-  uint32_t getConstantFloat16(int16_t value);
-  uint32_t getConstantFloat32(float value, bool isSpecConst = false);
-  uint32_t getConstantFloat64(double value);
-  uint32_t getConstantComposite(uint32_t typeId,
-                                llvm::ArrayRef<uint32_t> constituents);
-  uint32_t getConstantNull(uint32_t type);
-
-  // === Debug ===
-  void debugLine(uint32_t file, uint32_t line, uint32_t column);
-
-private:
-  /// \brief Map from basic blocks' <label-id> to their structured
-  /// representation.
-  ///
-  /// We need MapVector here to remember the order of insertion. Order matters
-  /// here since, for example, we'll know for sure the first basic block is the
-  /// entry block.
-  using OrderedBasicBlockMap =
-      llvm::MapVector<uint32_t, std::unique_ptr<BasicBlock>>;
-
-  /// \brief Returns the basic block with the given <label-id>.
-  BasicBlock *getBasicBlock(uint32_t label);
-
-  /// \brief Returns the composed ImageOperandsMask from non-zero parameters
-  /// and pushes non-zero parameters to *orderedParams in the expected order.
-  spv::ImageOperandsMask composeImageOperandsMask(
-      uint32_t bias, uint32_t lod, const std::pair<uint32_t, uint32_t> &grad,
-      uint32_t constOffset, uint32_t varOffset, uint32_t constOffsets,
-      uint32_t sample, uint32_t minLod,
-      llvm::SmallVectorImpl<uint32_t> *orderedParams);
-
-  SPIRVContext &theContext;       ///< The SPIR-V context.
-  FeatureManager *featureManager; ///< SPIR-V version/extension manager.
-  const SpirvCodeGenOptions &spirvOptions; ///< Command line options.
-
-  SPIRVModule theModule;                 ///< The module under building.
-  std::unique_ptr<Function> theFunction; ///< The function under building.
-  OrderedBasicBlockMap basicBlocks;      ///< The basic blocks under building.
-  BasicBlock *insertPoint;               ///< The current insertion point.
-
-  /// An InstBuilder associated with the current ModuleBuilder.
-  /// It can be used to contruct instructions on the fly.
-  /// The constructed instruction will appear in constructSite.
-  InstBuilder instBuilder;
-  std::vector<uint32_t> constructSite; ///< InstBuilder construction site.
-  uint32_t glslExtSetId; ///< The <result-id> of GLSL extended instruction set.
-
-  /// A struct containing information regarding a builtin variable.
-  struct BuiltInVarInfo {
-    BuiltInVarInfo(spv::StorageClass s, spv::BuiltIn b, uint32_t v)
-        : sc(s), builtIn(b), variable(v) {}
-
-    spv::StorageClass sc;
-    spv::BuiltIn builtIn;
-    uint32_t variable;
-  };
-
-  /// Used as caches for all created builtin variables to avoid duplication.
-  llvm::SmallVector<BuiltInVarInfo, 16> builtinVars;
-};
-
-SPIRVContext *ModuleBuilder::getSPIRVContext() { return &theContext; }
-
-bool ModuleBuilder::isCurrentBasicBlockTerminated() const {
-  return insertPoint && insertPoint->isTerminated();
-}
-
-void ModuleBuilder::setAddressingModel(spv::AddressingModel am) {
-  theModule.setAddressingModel(am);
-}
-
-void ModuleBuilder::setMemoryModel(spv::MemoryModel mm) {
-  theModule.setMemoryModel(mm);
-}
-
-void ModuleBuilder::requireCapability(spv::Capability cap) {
-  if (cap != spv::Capability::Max)
-    theModule.addCapability(cap);
-}
-
-void ModuleBuilder::addEntryPoint(spv::ExecutionModel em, uint32_t targetId,
-                                  std::string targetName,
-                                  llvm::ArrayRef<uint32_t> interfaces) {
-  theModule.addEntryPoint(em, targetId, std::move(targetName), interfaces);
-}
-
-void ModuleBuilder::setShaderModelVersion(uint32_t major, uint32_t minor) {
-  theModule.setShaderModelVersion(major * 100 + minor * 10);
-}
-
-void ModuleBuilder::setSourceFileName(uint32_t id, std::string name) {
-  theModule.setSourceFileName(id, std::move(name));
-}
-
-void ModuleBuilder::setSourceFileContent(llvm::StringRef content) {
-  theModule.setSourceFileContent(content);
-}
-
-} // end namespace spirv
-} // end namespace clang
-
-#endif

+ 0 - 2
tools/clang/lib/SPIRV/CMakeLists.txt

@@ -13,8 +13,6 @@ add_clang_library(clangSPIRV
   FeatureManager.cpp
   GlPerVertex.cpp
   InitListHandler.cpp
-  InstBuilderAuto.cpp
-  InstBuilderManual.cpp
   LiteralTypeVisitor.cpp
   LowerTypeVisitor.cpp
   SPIRVContext.cpp

+ 0 - 3047
tools/clang/lib/SPIRV/InstBuilderAuto.cpp

@@ -1,3047 +0,0 @@
-//===-- InstBuilder.cpp - SPIR-V instruction builder ------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// AUTOMATICALLY GENERATED from the SPIR-V JSON grammar:
-//   spirv.core.grammar.json.
-// DO NOT MODIFY!
-
-#include "clang/SPIRV/InstBuilder.h"
-
-namespace clang {
-namespace spirv {
-
-static_assert(spv::Version == 0x00010300 && spv::Revision == 6,
-              "Needs to regenerate outdated InstBuilder");
-
-namespace {
-inline bool bitEnumContains(spv::ImageOperandsMask bits,
-                            spv::ImageOperandsMask bit) {
-  return (uint32_t(bits) & uint32_t(bit)) != 0;
-}
-inline bool bitEnumContains(spv::LoopControlMask bits,
-                            spv::LoopControlMask bit) {
-  return (uint32_t(bits) & uint32_t(bit)) != 0;
-}
-inline bool bitEnumContains(spv::MemoryAccessMask bits,
-                            spv::MemoryAccessMask bit) {
-  return (uint32_t(bits) & uint32_t(bit)) != 0;
-}
-} // namespace
-
-InstBuilder::InstBuilder(WordConsumer consumer)
-    : TheConsumer(consumer), TheStatus(Status::Success) {}
-
-void InstBuilder::setConsumer(WordConsumer consumer) { TheConsumer = consumer; }
-const WordConsumer &InstBuilder::getConsumer() const { return TheConsumer; }
-
-InstBuilder::Status InstBuilder::x() {
-  if (TheConsumer == nullptr)
-    return Status::NullConsumer;
-
-  if (TheStatus != Status::Success)
-    return TheStatus;
-
-  if (!Expectation.empty()) {
-    switch (Expectation.front()) {
-    case OperandKind::BuiltIn:
-      return Status::ExpectBuiltIn;
-    case OperandKind::FPFastMathMode:
-      return Status::ExpectFPFastMathMode;
-    case OperandKind::FPRoundingMode:
-      return Status::ExpectFPRoundingMode;
-    case OperandKind::FunctionParameterAttribute:
-      return Status::ExpectFunctionParameterAttribute;
-    case OperandKind::IdRef:
-      return Status::ExpectIdRef;
-    case OperandKind::LinkageType:
-      return Status::ExpectLinkageType;
-    case OperandKind::LiteralInteger:
-      return Status::ExpectLiteralInteger;
-    case OperandKind::LiteralString:
-      return Status::ExpectLiteralString;
-    }
-  }
-
-  if (!TheInst.empty())
-    TheInst.front() |= uint32_t(TheInst.size()) << 16;
-  TheConsumer(std::move(TheInst));
-  TheInst.clear();
-
-  return TheStatus;
-}
-
-void InstBuilder::clear() {
-  TheInst.clear();
-  Expectation.clear();
-  TheStatus = Status::Success;
-}
-
-InstBuilder &InstBuilder::opSourceContinued(llvm::StringRef continued_source) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSourceContinued));
-  encodeString(continued_source);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opSource(spv::SourceLanguage source_language,
-                                   uint32_t version,
-                                   llvm::Optional<uint32_t> file,
-                                   llvm::Optional<llvm::StringRef> source) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSource));
-  TheInst.emplace_back(static_cast<uint32_t>(source_language));
-  TheInst.emplace_back(version);
-  if (file.hasValue()) {
-    const auto &val = file.getValue();
-    TheInst.emplace_back(val);
-  }
-  if (source.hasValue()) {
-    const auto &val = source.getValue();
-    encodeString(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opName(uint32_t target, std::string name) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpName));
-  TheInst.emplace_back(target);
-  encodeString(name);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opMemberName(uint32_t type, uint32_t member,
-                                       std::string name) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpMemberName));
-  TheInst.emplace_back(type);
-  TheInst.emplace_back(member);
-  encodeString(name);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opString(uint32_t result_id, std::string string) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpString));
-  TheInst.emplace_back(result_id);
-  encodeString(string);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opLine(uint32_t file, uint32_t line,
-                                 uint32_t column) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpLine));
-  TheInst.emplace_back(file);
-  TheInst.emplace_back(line);
-  TheInst.emplace_back(column);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opExtension(std::string name) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpExtension));
-  encodeString(name);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opExtInstImport(uint32_t result_id,
-                                          std::string name) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpExtInstImport));
-  TheInst.emplace_back(result_id);
-  encodeString(name);
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opExtInst(uint32_t result_type, uint32_t result_id, uint32_t set,
-                       uint32_t instruction,
-                       llvm::ArrayRef<uint32_t> operand_1_operand_2_) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpExtInst));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(set);
-  TheInst.emplace_back(instruction);
-  TheInst.insert(TheInst.end(), operand_1_operand_2_.begin(),
-                 operand_1_operand_2_.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opMemoryModel(spv::AddressingModel addressing_model,
-                                        spv::MemoryModel memory_model) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpMemoryModel));
-  TheInst.emplace_back(static_cast<uint32_t>(addressing_model));
-  TheInst.emplace_back(static_cast<uint32_t>(memory_model));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opEntryPoint(spv::ExecutionModel execution_model,
-                                       uint32_t entry_point, std::string name,
-                                       llvm::ArrayRef<uint32_t> interface) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpEntryPoint));
-  TheInst.emplace_back(static_cast<uint32_t>(execution_model));
-  TheInst.emplace_back(entry_point);
-  encodeString(name);
-  TheInst.insert(TheInst.end(), interface.begin(), interface.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opExecutionMode(uint32_t entry_point,
-                                          spv::ExecutionMode mode) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpExecutionMode));
-  TheInst.emplace_back(entry_point);
-  encodeExecutionMode(mode);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opCapability(spv::Capability capability) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpCapability));
-  TheInst.emplace_back(static_cast<uint32_t>(capability));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeVoid(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeVoid));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeBool(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeBool));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeInt(uint32_t result_id, uint32_t width,
-                                    uint32_t signedness) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeInt));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(width);
-  TheInst.emplace_back(signedness);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeFloat(uint32_t result_id, uint32_t width) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeFloat));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(width);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeVector(uint32_t result_id,
-                                       uint32_t component_type,
-                                       uint32_t component_count) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeVector));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(component_type);
-  TheInst.emplace_back(component_count);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeMatrix(uint32_t result_id, uint32_t column_type,
-                                       uint32_t column_count) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeMatrix));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(column_type);
-  TheInst.emplace_back(column_count);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeImage(
-    uint32_t result_id, uint32_t sampled_type, spv::Dim dim, uint32_t depth,
-    uint32_t arrayed, uint32_t ms, uint32_t sampled,
-    spv::ImageFormat image_format,
-    llvm::Optional<spv::AccessQualifier> access_qualifier) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(10);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeImage));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_type);
-  TheInst.emplace_back(static_cast<uint32_t>(dim));
-  TheInst.emplace_back(depth);
-  TheInst.emplace_back(arrayed);
-  TheInst.emplace_back(ms);
-  TheInst.emplace_back(sampled);
-  TheInst.emplace_back(static_cast<uint32_t>(image_format));
-  if (access_qualifier.hasValue()) {
-    const auto &val = access_qualifier.getValue();
-    TheInst.emplace_back(static_cast<uint32_t>(val));
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeSampler(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeSampler));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeSampledImage(uint32_t result_id,
-                                             uint32_t image_type) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeSampledImage));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image_type);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeArray(uint32_t result_id, uint32_t element_type,
-                                      uint32_t length) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeArray));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(element_type);
-  TheInst.emplace_back(length);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeRuntimeArray(uint32_t result_id,
-                                             uint32_t element_type) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeRuntimeArray));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(element_type);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeStruct(
-    uint32_t result_id, llvm::ArrayRef<uint32_t> member_0_type_member_1_type_) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeStruct));
-  TheInst.emplace_back(result_id);
-  TheInst.insert(TheInst.end(), member_0_type_member_1_type_.begin(),
-                 member_0_type_member_1_type_.end());
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opTypeOpaque(uint32_t result_id,
-                          std::string the_name_of_the_opaque_type) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeOpaque));
-  TheInst.emplace_back(result_id);
-  encodeString(the_name_of_the_opaque_type);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypePointer(uint32_t result_id,
-                                        spv::StorageClass storage_class,
-                                        uint32_t type) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypePointer));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(static_cast<uint32_t>(storage_class));
-  TheInst.emplace_back(type);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeFunction(
-    uint32_t result_id, uint32_t return_type,
-    llvm::ArrayRef<uint32_t> parameter_0_type_parameter_1_type_) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeFunction));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(return_type);
-  TheInst.insert(TheInst.end(), parameter_0_type_parameter_1_type_.begin(),
-                 parameter_0_type_parameter_1_type_.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeEvent(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeEvent));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeDeviceEvent(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeDeviceEvent));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeReserveId(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeReserveId));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypeQueue(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeQueue));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTypePipe(uint32_t result_id,
-                                     spv::AccessQualifier qualifier) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypePipe));
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(static_cast<uint32_t>(qualifier));
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opTypeForwardPointer(uint32_t pointer_type,
-                                  spv::StorageClass storage_class) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTypeForwardPointer));
-  TheInst.emplace_back(pointer_type);
-  TheInst.emplace_back(static_cast<uint32_t>(storage_class));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opConstantTrue(uint32_t result_type,
-                                         uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpConstantTrue));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opConstantFalse(uint32_t result_type,
-                                          uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpConstantFalse));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opConstantComposite(uint32_t result_type, uint32_t result_id,
-                                 llvm::ArrayRef<uint32_t> constituents) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpConstantComposite));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.insert(TheInst.end(), constituents.begin(), constituents.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opConstantNull(uint32_t result_type,
-                                         uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpConstantNull));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opSpecConstantTrue(uint32_t result_type,
-                                             uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSpecConstantTrue));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opSpecConstantFalse(uint32_t result_type,
-                                              uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSpecConstantFalse));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opSpecConstantComposite(uint32_t result_type, uint32_t result_id,
-                                     llvm::ArrayRef<uint32_t> constituents) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSpecConstantComposite));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.insert(TheInst.end(), constituents.begin(), constituents.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opFunction(uint32_t result_type, uint32_t result_id,
-                                     spv::FunctionControlMask function_control,
-                                     uint32_t function_type) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpFunction));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(static_cast<uint32_t>(function_control));
-  TheInst.emplace_back(function_type);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opFunctionParameter(uint32_t result_type,
-                                              uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpFunctionParameter));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opFunctionEnd() {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(1);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpFunctionEnd));
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opFunctionCall(uint32_t result_type, uint32_t result_id,
-                            uint32_t function,
-                            llvm::ArrayRef<uint32_t> argument_0_argument_1_) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpFunctionCall));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(function);
-  TheInst.insert(TheInst.end(), argument_0_argument_1_.begin(),
-                 argument_0_argument_1_.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opVariable(uint32_t result_type, uint32_t result_id,
-                                     spv::StorageClass storage_class,
-                                     llvm::Optional<uint32_t> initializer) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpVariable));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(static_cast<uint32_t>(storage_class));
-  if (initializer.hasValue()) {
-    const auto &val = initializer.getValue();
-    TheInst.emplace_back(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageTexelPointer(uint32_t result_type,
-                                              uint32_t result_id,
-                                              uint32_t image,
-                                              uint32_t coordinate,
-                                              uint32_t sample) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageTexelPointer));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(sample);
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opLoad(uint32_t result_type, uint32_t result_id, uint32_t pointer,
-                    llvm::Optional<spv::MemoryAccessMask> memory_access) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpLoad));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(pointer);
-  if (memory_access.hasValue()) {
-    const auto &val = memory_access.getValue();
-    encodeMemoryAccess(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opStore(uint32_t pointer, uint32_t object,
-                     llvm::Optional<spv::MemoryAccessMask> memory_access) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpStore));
-  TheInst.emplace_back(pointer);
-  TheInst.emplace_back(object);
-  if (memory_access.hasValue()) {
-    const auto &val = memory_access.getValue();
-    encodeMemoryAccess(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opAccessChain(uint32_t result_type,
-                                        uint32_t result_id, uint32_t base,
-                                        llvm::ArrayRef<uint32_t> indexes) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpAccessChain));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(base);
-  TheInst.insert(TheInst.end(), indexes.begin(), indexes.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDecorate(uint32_t target,
-                                     spv::Decoration decoration) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDecorate));
-  TheInst.emplace_back(target);
-  encodeDecoration(decoration);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opMemberDecorate(uint32_t structure_type,
-                                           uint32_t member,
-                                           spv::Decoration decoration) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpMemberDecorate));
-  TheInst.emplace_back(structure_type);
-  TheInst.emplace_back(member);
-  encodeDecoration(decoration);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDecorationGroup(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDecorationGroup));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opGroupDecorate(uint32_t decoration_group,
-                                          llvm::ArrayRef<uint32_t> targets) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpGroupDecorate));
-  TheInst.emplace_back(decoration_group);
-  TheInst.insert(TheInst.end(), targets.begin(), targets.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opGroupMemberDecorate(
-    uint32_t decoration_group,
-    llvm::ArrayRef<std::pair<uint32_t, uint32_t>> targets) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpGroupMemberDecorate));
-  TheInst.emplace_back(decoration_group);
-  for (const auto &param : targets) {
-    TheInst.emplace_back(param.first);
-    TheInst.emplace_back(param.second);
-    ;
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opVectorShuffle(uint32_t result_type,
-                                          uint32_t result_id, uint32_t vector_1,
-                                          uint32_t vector_2,
-                                          llvm::ArrayRef<uint32_t> components) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpVectorShuffle));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(vector_1);
-  TheInst.emplace_back(vector_2);
-  for (const auto &param : components) {
-    TheInst.emplace_back(param);
-    ;
-  }
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opCompositeConstruct(uint32_t result_type, uint32_t result_id,
-                                  llvm::ArrayRef<uint32_t> constituents) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpCompositeConstruct));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.insert(TheInst.end(), constituents.begin(), constituents.end());
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opCompositeExtract(uint32_t result_type,
-                                             uint32_t result_id,
-                                             uint32_t composite,
-                                             llvm::ArrayRef<uint32_t> indexes) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpCompositeExtract));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(composite);
-  for (const auto &param : indexes) {
-    TheInst.emplace_back(param);
-    ;
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opCompositeInsert(uint32_t result_type,
-                                            uint32_t result_id, uint32_t object,
-                                            uint32_t composite,
-                                            llvm::ArrayRef<uint32_t> indexes) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpCompositeInsert));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(object);
-  TheInst.emplace_back(composite);
-  for (const auto &param : indexes) {
-    TheInst.emplace_back(param);
-    ;
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opTranspose(uint32_t result_type, uint32_t result_id,
-                                      uint32_t matrix) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpTranspose));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(matrix);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opSampledImage(uint32_t result_type,
-                                         uint32_t result_id, uint32_t image,
-                                         uint32_t sampler) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSampledImage));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(sampler);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSampleImplicitLod(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSampleImplicitLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSampleExplicitLod(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, spv::ImageOperandsMask image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSampleExplicitLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  encodeImageOperands(image_operands);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSampleDrefImplicitLod(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t dref,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSampleDrefImplicitLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(dref);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSampleDrefExplicitLod(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t dref, spv::ImageOperandsMask image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSampleDrefExplicitLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(dref);
-  encodeImageOperands(image_operands);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageFetch(
-    uint32_t result_type, uint32_t result_id, uint32_t image,
-    uint32_t coordinate,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageFetch));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(coordinate);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageGather(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t component,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageGather));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(component);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageDrefGather(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t dref,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageDrefGather));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(dref);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageRead(
-    uint32_t result_type, uint32_t result_id, uint32_t image,
-    uint32_t coordinate,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageRead));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(coordinate);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageWrite(
-    uint32_t image, uint32_t coordinate, uint32_t texel,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageWrite));
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(texel);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageQueryFormat(uint32_t result_type,
-                                             uint32_t result_id,
-                                             uint32_t image) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageQueryFormat));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageQueryOrder(uint32_t result_type,
-                                            uint32_t result_id,
-                                            uint32_t image) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageQueryOrder));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageQuerySizeLod(uint32_t result_type,
-                                              uint32_t result_id,
-                                              uint32_t image,
-                                              uint32_t level_of_detail) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageQuerySizeLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(level_of_detail);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageQuerySize(uint32_t result_type,
-                                           uint32_t result_id, uint32_t image) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageQuerySize));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageQueryLod(uint32_t result_type,
-                                          uint32_t result_id,
-                                          uint32_t sampled_image,
-                                          uint32_t coordinate) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageQueryLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageQueryLevels(uint32_t result_type,
-                                             uint32_t result_id,
-                                             uint32_t image) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageQueryLevels));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageQuerySamples(uint32_t result_type,
-                                              uint32_t result_id,
-                                              uint32_t image) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageQuerySamples));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opSelect(uint32_t result_type, uint32_t result_id,
-                                   uint32_t condition, uint32_t object_1,
-                                   uint32_t object_2) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSelect));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(condition);
-  TheInst.emplace_back(object_1);
-  TheInst.emplace_back(object_2);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opBitFieldInsert(uint32_t result_type,
-                                           uint32_t result_id, uint32_t base,
-                                           uint32_t insert, uint32_t offset,
-                                           uint32_t count) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpBitFieldInsert));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(base);
-  TheInst.emplace_back(insert);
-  TheInst.emplace_back(offset);
-  TheInst.emplace_back(count);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opBitFieldSExtract(uint32_t result_type,
-                                             uint32_t result_id, uint32_t base,
-                                             uint32_t offset, uint32_t count) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpBitFieldSExtract));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(base);
-  TheInst.emplace_back(offset);
-  TheInst.emplace_back(count);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opBitFieldUExtract(uint32_t result_type,
-                                             uint32_t result_id, uint32_t base,
-                                             uint32_t offset, uint32_t count) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpBitFieldUExtract));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(base);
-  TheInst.emplace_back(offset);
-  TheInst.emplace_back(count);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opBitReverse(uint32_t result_type, uint32_t result_id,
-                                       uint32_t base) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpBitReverse));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(base);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opBitCount(uint32_t result_type, uint32_t result_id,
-                                     uint32_t base) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpBitCount));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(base);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDPdx(uint32_t result_type, uint32_t result_id,
-                                 uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDPdx));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDPdy(uint32_t result_type, uint32_t result_id,
-                                 uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDPdy));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opFwidth(uint32_t result_type, uint32_t result_id,
-                                   uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpFwidth));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDPdxFine(uint32_t result_type, uint32_t result_id,
-                                     uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDPdxFine));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDPdyFine(uint32_t result_type, uint32_t result_id,
-                                     uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDPdyFine));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opFwidthFine(uint32_t result_type, uint32_t result_id,
-                                       uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpFwidthFine));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDPdxCoarse(uint32_t result_type, uint32_t result_id,
-                                       uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDPdxCoarse));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDPdyCoarse(uint32_t result_type, uint32_t result_id,
-                                       uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDPdyCoarse));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opFwidthCoarse(uint32_t result_type,
-                                         uint32_t result_id, uint32_t p) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpFwidthCoarse));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(p);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opEmitVertex() {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(1);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpEmitVertex));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opEndPrimitive() {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(1);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpEndPrimitive));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opControlBarrier(uint32_t execution, uint32_t memory,
-                                           uint32_t semantics) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpControlBarrier));
-  TheInst.emplace_back(execution);
-  TheInst.emplace_back(memory);
-  TheInst.emplace_back(semantics);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opMemoryBarrier(uint32_t memory, uint32_t semantics) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpMemoryBarrier));
-  TheInst.emplace_back(memory);
-  TheInst.emplace_back(semantics);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opAtomicExchange(uint32_t result_type,
-                                           uint32_t result_id, uint32_t pointer,
-                                           uint32_t scope, uint32_t semantics,
-                                           uint32_t value) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpAtomicExchange));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(pointer);
-  TheInst.emplace_back(scope);
-  TheInst.emplace_back(semantics);
-  TheInst.emplace_back(value);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opAtomicCompareExchange(
-    uint32_t result_type, uint32_t result_id, uint32_t pointer, uint32_t scope,
-    uint32_t equal, uint32_t unequal, uint32_t value, uint32_t comparator) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(9);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpAtomicCompareExchange));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(pointer);
-  TheInst.emplace_back(scope);
-  TheInst.emplace_back(equal);
-  TheInst.emplace_back(unequal);
-  TheInst.emplace_back(value);
-  TheInst.emplace_back(comparator);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opLoopMerge(uint32_t merge_block,
-                                      uint32_t continue_target,
-                                      spv::LoopControlMask loop_control) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpLoopMerge));
-  TheInst.emplace_back(merge_block);
-  TheInst.emplace_back(continue_target);
-  encodeLoopControl(loop_control);
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opSelectionMerge(uint32_t merge_block,
-                              spv::SelectionControlMask selection_control) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSelectionMerge));
-  TheInst.emplace_back(merge_block);
-  TheInst.emplace_back(static_cast<uint32_t>(selection_control));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opLabel(uint32_t result_id) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpLabel));
-  TheInst.emplace_back(result_id);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opBranch(uint32_t target_label) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpBranch));
-  TheInst.emplace_back(target_label);
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opBranchConditional(uint32_t condition, uint32_t true_label,
-                                 uint32_t false_label,
-                                 llvm::ArrayRef<uint32_t> branch_weights) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpBranchConditional));
-  TheInst.emplace_back(condition);
-  TheInst.emplace_back(true_label);
-  TheInst.emplace_back(false_label);
-  for (const auto &param : branch_weights) {
-    TheInst.emplace_back(param);
-    ;
-  }
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opSwitch(uint32_t selector, uint32_t default_target,
-                      llvm::ArrayRef<std::pair<uint32_t, uint32_t>> target) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSwitch));
-  TheInst.emplace_back(selector);
-  TheInst.emplace_back(default_target);
-  for (const auto &param : target) {
-    TheInst.emplace_back(param.first);
-    TheInst.emplace_back(param.second);
-    ;
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opKill() {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(1);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpKill));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opReturn() {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(1);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpReturn));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opReturnValue(uint32_t value) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpReturnValue));
-  TheInst.emplace_back(value);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opUnreachable() {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(1);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpUnreachable));
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseSampleImplicitLod(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSparseSampleImplicitLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseSampleExplicitLod(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, spv::ImageOperandsMask image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSparseSampleExplicitLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  encodeImageOperands(image_operands);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseSampleDrefImplicitLod(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t dref,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSparseSampleDrefImplicitLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(dref);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseSampleDrefExplicitLod(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t dref, spv::ImageOperandsMask image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSparseSampleDrefExplicitLod));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(dref);
-  encodeImageOperands(image_operands);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseFetch(
-    uint32_t result_type, uint32_t result_id, uint32_t image,
-    uint32_t coordinate,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageSparseFetch));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(coordinate);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseGather(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t component,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageSparseGather));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(component);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseDrefGather(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t dref,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageSparseDrefGather));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  TheInst.emplace_back(dref);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseTexelsResident(uint32_t result_type,
-                                                      uint32_t result_id,
-                                                      uint32_t resident_code) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpImageSparseTexelsResident));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(resident_code);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSparseRead(
-    uint32_t result_type, uint32_t result_id, uint32_t image,
-    uint32_t coordinate,
-    llvm::Optional<spv::ImageOperandsMask> image_operands) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpImageSparseRead));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(coordinate);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opModuleProcessed(std::string process) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(2);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpModuleProcessed));
-  encodeString(process);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opExecutionModeId(uint32_t entry_point,
-                                            spv::ExecutionMode mode) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpExecutionModeId));
-  TheInst.emplace_back(entry_point);
-  encodeExecutionMode(mode);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDecorateId(uint32_t target,
-                                       spv::Decoration decoration) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDecorateId));
-  TheInst.emplace_back(target);
-  encodeDecoration(decoration);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opDecorateStringGOOGLE(uint32_t target,
-                                                 spv::Decoration decoration) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(3);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpDecorateStringGOOGLE));
-  TheInst.emplace_back(target);
-  encodeDecoration(decoration);
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::opMemberDecorateStringGOOGLE(uint32_t struct_type, uint32_t member,
-                                          spv::Decoration decoration) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(
-      static_cast<uint32_t>(spv::Op::OpMemberDecorateStringGOOGLE));
-  TheInst.emplace_back(struct_type);
-  TheInst.emplace_back(member);
-  encodeDecoration(decoration);
-
-  return *this;
-}
-
-void InstBuilder::encodeImageOperands(spv::ImageOperandsMask value) {
-  if (bitEnumContains(value, spv::ImageOperandsMask::Bias)) {
-    Expectation.emplace_back(OperandKind::IdRef);
-  }
-  if (bitEnumContains(value, spv::ImageOperandsMask::Lod)) {
-    Expectation.emplace_back(OperandKind::IdRef);
-  }
-  if (bitEnumContains(value, spv::ImageOperandsMask::Grad)) {
-    Expectation.emplace_back(OperandKind::IdRef);
-    Expectation.emplace_back(OperandKind::IdRef);
-  }
-  if (bitEnumContains(value, spv::ImageOperandsMask::ConstOffset)) {
-    Expectation.emplace_back(OperandKind::IdRef);
-  }
-  if (bitEnumContains(value, spv::ImageOperandsMask::Offset)) {
-    Expectation.emplace_back(OperandKind::IdRef);
-  }
-  if (bitEnumContains(value, spv::ImageOperandsMask::ConstOffsets)) {
-    Expectation.emplace_back(OperandKind::IdRef);
-  }
-  if (bitEnumContains(value, spv::ImageOperandsMask::Sample)) {
-    Expectation.emplace_back(OperandKind::IdRef);
-  }
-  if (bitEnumContains(value, spv::ImageOperandsMask::MinLod)) {
-    Expectation.emplace_back(OperandKind::IdRef);
-  }
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-}
-
-void InstBuilder::encodeLoopControl(spv::LoopControlMask value) {
-  if (bitEnumContains(value, spv::LoopControlMask::DependencyLength)) {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  }
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-}
-
-void InstBuilder::encodeMemoryAccess(spv::MemoryAccessMask value) {
-  if (bitEnumContains(value, spv::MemoryAccessMask::Aligned)) {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  }
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-}
-
-void InstBuilder::encodeExecutionMode(spv::ExecutionMode value) {
-  switch (value) {
-  case spv::ExecutionMode::Invocations: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::ExecutionMode::LocalSize: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::ExecutionMode::LocalSizeHint: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::ExecutionMode::OutputVertices: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::ExecutionMode::VecTypeHint: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::ExecutionMode::SubgroupSize: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::ExecutionMode::SubgroupsPerWorkgroup: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::ExecutionMode::SubgroupsPerWorkgroupId: {
-    Expectation.emplace_back(OperandKind::IdRef);
-  } break;
-  case spv::ExecutionMode::LocalSizeId: {
-    Expectation.emplace_back(OperandKind::IdRef);
-    Expectation.emplace_back(OperandKind::IdRef);
-    Expectation.emplace_back(OperandKind::IdRef);
-  } break;
-  case spv::ExecutionMode::LocalSizeHintId: {
-    Expectation.emplace_back(OperandKind::IdRef);
-  } break;
-  default:
-    break;
-  }
-
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-}
-
-void InstBuilder::encodeDecoration(spv::Decoration value) {
-  switch (value) {
-  case spv::Decoration::SpecId: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::ArrayStride: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::MatrixStride: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::BuiltIn: {
-    Expectation.emplace_back(OperandKind::BuiltIn);
-  } break;
-  case spv::Decoration::Stream: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::Location: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::Component: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::Index: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::Binding: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::DescriptorSet: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::Offset: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::XfbBuffer: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::XfbStride: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::FuncParamAttr: {
-    Expectation.emplace_back(OperandKind::FunctionParameterAttribute);
-  } break;
-  case spv::Decoration::FPRoundingMode: {
-    Expectation.emplace_back(OperandKind::FPRoundingMode);
-  } break;
-  case spv::Decoration::FPFastMathMode: {
-    Expectation.emplace_back(OperandKind::FPFastMathMode);
-  } break;
-  case spv::Decoration::LinkageAttributes: {
-    Expectation.emplace_back(OperandKind::LiteralString);
-    Expectation.emplace_back(OperandKind::LinkageType);
-  } break;
-  case spv::Decoration::InputAttachmentIndex: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::Alignment: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::MaxByteOffset: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::AlignmentId: {
-    Expectation.emplace_back(OperandKind::IdRef);
-  } break;
-  case spv::Decoration::MaxByteOffsetId: {
-    Expectation.emplace_back(OperandKind::IdRef);
-  } break;
-  case spv::Decoration::SecondaryViewportRelativeNV: {
-    Expectation.emplace_back(OperandKind::LiteralInteger);
-  } break;
-  case spv::Decoration::HlslCounterBufferGOOGLE: {
-    Expectation.emplace_back(OperandKind::IdRef);
-  } break;
-  case spv::Decoration::HlslSemanticGOOGLE: {
-    Expectation.emplace_back(OperandKind::LiteralString);
-  } break;
-  default:
-    break;
-  }
-
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-}
-
-InstBuilder &InstBuilder::fPFastMathMode(spv::FPFastMathModeMask value) {
-  if (Expectation.front() != OperandKind::FPFastMathMode) {
-    TheStatus = Status::ExpectFPFastMathMode;
-    return *this;
-  }
-  Expectation.pop_front();
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-  return *this;
-}
-
-InstBuilder &InstBuilder::fPRoundingMode(spv::FPRoundingMode value) {
-  if (Expectation.front() != OperandKind::FPRoundingMode) {
-    TheStatus = Status::ExpectFPRoundingMode;
-    return *this;
-  }
-  Expectation.pop_front();
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-  return *this;
-}
-
-InstBuilder &InstBuilder::linkageType(spv::LinkageType value) {
-  if (Expectation.front() != OperandKind::LinkageType) {
-    TheStatus = Status::ExpectLinkageType;
-    return *this;
-  }
-  Expectation.pop_front();
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::functionParameterAttribute(spv::FunctionParameterAttribute value) {
-  if (Expectation.front() != OperandKind::FunctionParameterAttribute) {
-    TheStatus = Status::ExpectFunctionParameterAttribute;
-    return *this;
-  }
-  Expectation.pop_front();
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-  return *this;
-}
-
-InstBuilder &InstBuilder::builtIn(spv::BuiltIn value) {
-  if (Expectation.front() != OperandKind::BuiltIn) {
-    TheStatus = Status::ExpectBuiltIn;
-    return *this;
-  }
-  Expectation.pop_front();
-  TheInst.emplace_back(static_cast<uint32_t>(value));
-  return *this;
-}
-
-InstBuilder &InstBuilder::idRef(uint32_t value) {
-  if (Expectation.front() != OperandKind::IdRef) {
-    TheStatus = Status::ExpectIdRef;
-    return *this;
-  }
-  Expectation.pop_front();
-  TheInst.emplace_back(value);
-  return *this;
-}
-
-InstBuilder &InstBuilder::literalInteger(uint32_t value) {
-  if (Expectation.front() != OperandKind::LiteralInteger) {
-    TheStatus = Status::ExpectLiteralInteger;
-    return *this;
-  }
-  Expectation.pop_front();
-  TheInst.emplace_back(value);
-  return *this;
-}
-
-InstBuilder &InstBuilder::literalString(std::string value) {
-  if (Expectation.front() != OperandKind::LiteralString) {
-    TheStatus = Status::ExpectLiteralString;
-    return *this;
-  }
-  Expectation.pop_front();
-  encodeString(value);
-  return *this;
-}
-
-} // end namespace spirv
-} // end namespace clang

+ 0 - 272
tools/clang/lib/SPIRV/InstBuilderManual.cpp

@@ -1,272 +0,0 @@
-//===-- InstBuilder.cpp - SPIR-V instruction builder ------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/SPIRV/InstBuilder.h"
-#include "clang/SPIRV/String.h"
-
-#include "llvm/llvm_assert/assert.h"
-
-namespace clang {
-namespace spirv {
-
-std::vector<uint32_t> InstBuilder::take() {
-  std::vector<uint32_t> result;
-
-  if (TheStatus == Status::Success && Expectation.empty() && !TheInst.empty()) {
-    TheInst.front() |= uint32_t(TheInst.size()) << 16;
-    result.swap(TheInst);
-  }
-
-  return result;
-}
-
-InstBuilder &InstBuilder::unaryOp(spv::Op op, uint32_t result_type,
-                                  uint32_t result_id, uint32_t operand) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  // TODO: check op range
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(operand);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::binaryOp(spv::Op op, uint32_t result_type,
-                                   uint32_t result_id, uint32_t lhs,
-                                   uint32_t rhs) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  // TODO: check op range
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(lhs);
-  TheInst.emplace_back(rhs);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::specConstantBinaryOp(spv::Op op, uint32_t result_type,
-                                               uint32_t result_id, uint32_t lhs,
-                                               uint32_t rhs) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  // TODO: check op range
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSpecConstantOp));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(lhs);
-  TheInst.emplace_back(rhs);
-  return *this;
-}
-
-InstBuilder &InstBuilder::atomicOp(spv::Op op, uint32_t result_type,
-                                   uint32_t result_id, uint32_t pointer,
-                                   uint32_t scope, uint32_t semantics,
-                                   uint32_t value) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-  if (result_type == 0) {
-    TheStatus = Status::ZeroResultType;
-    return *this;
-  }
-  if (result_id == 0) {
-    TheStatus = Status::ZeroResultId;
-    return *this;
-  }
-
-  TheInst.reserve(7);
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(pointer);
-  TheInst.emplace_back(scope);
-  TheInst.emplace_back(semantics);
-  TheInst.emplace_back(value);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::groupNonUniformOp(spv::Op op, uint32_t result_type,
-                                            uint32_t result_id,
-                                            uint32_t exec_scope) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  // TODO: check op range
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(exec_scope);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::groupNonUniformUnaryOp(
-    spv::Op op, uint32_t result_type, uint32_t result_id, uint32_t exec_scope,
-    llvm::Optional<spv::GroupOperation> groupOp, uint32_t operand) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  // TODO: check op range
-
-  TheInst.reserve(5);
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(exec_scope);
-  if (groupOp.hasValue())
-    TheInst.emplace_back(static_cast<uint32_t>(groupOp.getValue()));
-  TheInst.emplace_back(operand);
-
-  return *this;
-}
-
-InstBuilder &
-InstBuilder::groupNonUniformBinaryOp(spv::Op op, uint32_t result_type,
-                                     uint32_t result_id, uint32_t exec_scope,
-                                     uint32_t operand1, uint32_t operand2) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  // TODO: check op range
-
-  TheInst.reserve(6);
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(exec_scope);
-  TheInst.emplace_back(operand1);
-  TheInst.emplace_back(operand2);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opConstant(uint32_t resultType, uint32_t resultId,
-                                     uint32_t value) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpConstant));
-  TheInst.emplace_back(resultType);
-  TheInst.emplace_back(resultId);
-  TheInst.emplace_back(value);
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageSample(
-    uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
-    uint32_t coordinate, uint32_t dref,
-    llvm::Optional<spv::ImageOperandsMask> image_operands, bool is_explicit,
-    bool is_sparse) {
-  spv::Op op = spv::Op::Max;
-  if (dref) {
-    op = is_explicit ? (is_sparse ? spv::Op::OpImageSparseSampleDrefExplicitLod
-                                  : spv::Op::OpImageSampleDrefExplicitLod)
-                     : (is_sparse ? spv::Op::OpImageSparseSampleDrefImplicitLod
-                                  : spv::Op::OpImageSampleDrefImplicitLod);
-  } else {
-    op = is_explicit ? (is_sparse ? spv::Op::OpImageSparseSampleExplicitLod
-                                  : spv::Op::OpImageSampleExplicitLod)
-                     : (is_sparse ? spv::Op::OpImageSparseSampleImplicitLod
-                                  : spv::Op::OpImageSampleImplicitLod);
-  }
-
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(sampled_image);
-  TheInst.emplace_back(coordinate);
-  if (dref)
-    TheInst.emplace_back(dref);
-  if (image_operands.hasValue() &&
-      image_operands.getValue() != spv::ImageOperandsMask::MaskNone) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-  return *this;
-}
-
-InstBuilder &InstBuilder::opImageFetchRead(
-    uint32_t result_type, uint32_t result_id, uint32_t image,
-    uint32_t coordinate, llvm::Optional<spv::ImageOperandsMask> image_operands,
-    bool is_fetch, bool is_sparse) {
-  spv::Op op =
-      is_fetch
-          ? (is_sparse ? spv::Op::OpImageSparseFetch : spv::Op::OpImageFetch)
-          : (is_sparse ? spv::Op::OpImageSparseRead : spv::Op::OpImageRead);
-
-  TheInst.emplace_back(static_cast<uint32_t>(op));
-  TheInst.emplace_back(result_type);
-  TheInst.emplace_back(result_id);
-  TheInst.emplace_back(image);
-  TheInst.emplace_back(coordinate);
-  if (image_operands.hasValue()) {
-    const auto &val = image_operands.getValue();
-    encodeImageOperands(val);
-  }
-
-  return *this;
-}
-
-InstBuilder &InstBuilder::opSpecConstant(uint32_t resultType, uint32_t resultId,
-                                         uint32_t value) {
-  if (!TheInst.empty()) {
-    TheStatus = Status::NestedInst;
-    return *this;
-  }
-
-  TheInst.reserve(4);
-  TheInst.emplace_back(static_cast<uint32_t>(spv::Op::OpSpecConstant));
-  TheInst.emplace_back(resultType);
-  TheInst.emplace_back(resultId);
-  TheInst.emplace_back(value);
-
-  return *this;
-}
-
-void InstBuilder::encodeString(llvm::StringRef value) {
-  const auto &words = string::encodeSPIRVString(value);
-  TheInst.insert(TheInst.end(), words.begin(), words.end());
-}
-
-} // end namespace spirv
-} // end namespace clang

+ 0 - 1289
tools/clang/lib/SPIRV/ModuleBuilder.cpp

@@ -1,1289 +0,0 @@
-//===--- ModuleBuilder.cpp - SPIR-V builder implementation ----*- C++ -*---===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/SPIRV/ModuleBuilder.h"
-
-#include "TypeTranslator.h"
-#include "spirv/unified1/spirv.hpp11"
-#include "clang/SPIRV/BitwiseCast.h"
-#include "clang/SPIRV/InstBuilder.h"
-
-namespace clang {
-namespace spirv {
-
-ModuleBuilder::ModuleBuilder(SPIRVContext *C, FeatureManager *features,
-                             const SpirvCodeGenOptions &opts)
-    : theContext(*C), featureManager(features), spirvOptions(opts),
-      theModule(opts), theFunction(nullptr), insertPoint(nullptr),
-      instBuilder(nullptr), glslExtSetId(0) {
-  instBuilder.setConsumer([this](std::vector<uint32_t> &&words) {
-    this->constructSite = std::move(words);
-  });
-}
-
-std::vector<uint32_t> ModuleBuilder::takeModule() {
-  theModule.setBound(theContext.getNextId());
-
-  std::vector<uint32_t> binary;
-  auto ib = InstBuilder([&binary](std::vector<uint32_t> &&words) {
-    binary.insert(binary.end(), words.begin(), words.end());
-  });
-
-  theModule.take(&ib);
-  return binary;
-}
-
-uint32_t ModuleBuilder::beginFunction(uint32_t funcType, uint32_t returnType,
-                                      llvm::StringRef funcName, uint32_t fId) {
-  if (theFunction) {
-    assert(false && "found nested function");
-    return 0;
-  }
-
-  // If the caller doesn't supply a function <result-id>, we need to get one.
-  if (!fId)
-    fId = theContext.takeNextId();
-
-  theFunction = llvm::make_unique<Function>(
-      returnType, fId, spv::FunctionControlMask::MaskNone, funcType);
-  theModule.addDebugName(fId, funcName);
-
-  return fId;
-}
-
-uint32_t ModuleBuilder::addFnParam(uint32_t ptrType, llvm::StringRef name) {
-  assert(theFunction && "found detached parameter");
-
-  const uint32_t paramId = theContext.takeNextId();
-  theFunction->addParameter(ptrType, paramId);
-  theModule.addDebugName(paramId, name);
-
-  return paramId;
-}
-
-uint32_t ModuleBuilder::addFnVar(uint32_t varType, llvm::StringRef name,
-                                 llvm::Optional<uint32_t> init) {
-  assert(theFunction && "found detached local variable");
-
-  const uint32_t ptrType = getPointerType(varType, spv::StorageClass::Function);
-  const uint32_t varId = theContext.takeNextId();
-  theFunction->addVariable(ptrType, varId, init);
-  theModule.addDebugName(varId, name);
-  return varId;
-}
-
-bool ModuleBuilder::endFunction() {
-  if (theFunction == nullptr) {
-    assert(false && "no active function");
-    return false;
-  }
-
-  // Move all basic blocks into the current function.
-  // TODO: we should adjust the order the basic blocks according to
-  // SPIR-V validation rules.
-  for (auto &bb : basicBlocks) {
-    theFunction->addBasicBlock(std::move(bb.second));
-  }
-  basicBlocks.clear();
-
-  theModule.addFunction(std::move(theFunction));
-  theFunction.reset(nullptr);
-
-  insertPoint = nullptr;
-
-  return true;
-}
-
-uint32_t ModuleBuilder::createBasicBlock(llvm::StringRef name) {
-  if (theFunction == nullptr) {
-    assert(false && "found detached basic block");
-    return 0;
-  }
-
-  const uint32_t labelId = theContext.takeNextId();
-  basicBlocks[labelId] = llvm::make_unique<BasicBlock>(labelId, name);
-  return labelId;
-}
-
-void ModuleBuilder::addSuccessor(uint32_t successorLabel) {
-  assert(insertPoint && "null insert point");
-  insertPoint->addSuccessor(getBasicBlock(successorLabel));
-}
-
-void ModuleBuilder::setMergeTarget(uint32_t mergeLabel) {
-  assert(insertPoint && "null insert point");
-  insertPoint->setMergeTarget(getBasicBlock(mergeLabel));
-}
-
-void ModuleBuilder::setContinueTarget(uint32_t continueLabel) {
-  assert(insertPoint && "null insert point");
-  insertPoint->setContinueTarget(getBasicBlock(continueLabel));
-}
-
-void ModuleBuilder::setInsertPoint(uint32_t labelId) {
-  insertPoint = getBasicBlock(labelId);
-}
-
-uint32_t
-ModuleBuilder::createCompositeConstruct(uint32_t resultType,
-                                        llvm::ArrayRef<uint32_t> constituents) {
-  assert(insertPoint && "null insert point");
-  const uint32_t resultId = theContext.takeNextId();
-  instBuilder.opCompositeConstruct(resultType, resultId, constituents).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return resultId;
-}
-
-uint32_t
-ModuleBuilder::createCompositeExtract(uint32_t resultType, uint32_t composite,
-                                      llvm::ArrayRef<uint32_t> indexes) {
-  assert(insertPoint && "null insert point");
-  const uint32_t resultId = theContext.takeNextId();
-  instBuilder.opCompositeExtract(resultType, resultId, composite, indexes).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return resultId;
-}
-
-uint32_t ModuleBuilder::createCompositeInsert(uint32_t resultType,
-                                              uint32_t composite,
-                                              llvm::ArrayRef<uint32_t> indices,
-                                              uint32_t object) {
-  assert(insertPoint && "null insert point");
-  const uint32_t resultId = theContext.takeNextId();
-  instBuilder
-      .opCompositeInsert(resultType, resultId, object, composite, indices)
-      .x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return resultId;
-}
-
-uint32_t
-ModuleBuilder::createVectorShuffle(uint32_t resultType, uint32_t vector1,
-                                   uint32_t vector2,
-                                   llvm::ArrayRef<uint32_t> selectors) {
-  assert(insertPoint && "null insert point");
-  const uint32_t resultId = theContext.takeNextId();
-  instBuilder.opVectorShuffle(resultType, resultId, vector1, vector2, selectors)
-      .x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return resultId;
-}
-
-uint32_t ModuleBuilder::createLoad(uint32_t resultType, uint32_t pointer) {
-  assert(insertPoint && "null insert point");
-  const uint32_t resultId = theContext.takeNextId();
-  instBuilder.opLoad(resultType, resultId, pointer, llvm::None).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return resultId;
-}
-
-void ModuleBuilder::createStore(uint32_t address, uint32_t value) {
-  assert(insertPoint && "null insert point");
-  instBuilder.opStore(address, value, llvm::None).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-uint32_t ModuleBuilder::createFunctionCall(uint32_t returnType,
-                                           uint32_t functionId,
-                                           llvm::ArrayRef<uint32_t> params) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.opFunctionCall(returnType, id, functionId, params).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createAccessChain(uint32_t resultType, uint32_t base,
-                                          llvm::ArrayRef<uint32_t> indexes) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.opAccessChain(resultType, id, base, indexes).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createUnaryOp(spv::Op op, uint32_t resultType,
-                                      uint32_t operand) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.unaryOp(op, resultType, id, operand).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  switch (op) {
-  case spv::Op::OpImageQuerySize:
-  case spv::Op::OpImageQueryLevels:
-  case spv::Op::OpImageQuerySamples:
-    requireCapability(spv::Capability::ImageQuery);
-    break;
-  default:
-    // Only checking for ImageQueries, the other Ops can be ignored.
-    break;
-  }
-  return id;
-}
-
-uint32_t ModuleBuilder::createBinaryOp(spv::Op op, uint32_t resultType,
-                                       uint32_t lhs, uint32_t rhs) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.binaryOp(op, resultType, id, lhs, rhs).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  switch (op) {
-  case spv::Op::OpImageQueryLod:
-  case spv::Op::OpImageQuerySizeLod:
-    requireCapability(spv::Capability::ImageQuery);
-    break;
-  default:
-    // Only checking for ImageQueries, the other Ops can be ignored.
-    break;
-  }
-  return id;
-}
-
-uint32_t ModuleBuilder::createSpecConstantBinaryOp(spv::Op op,
-                                                   uint32_t resultType,
-                                                   uint32_t lhs, uint32_t rhs) {
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.specConstantBinaryOp(op, resultType, id, lhs, rhs).x();
-  theModule.addVariable(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createGroupNonUniformOp(spv::Op op, uint32_t resultType,
-                                                uint32_t execScope) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.groupNonUniformOp(op, resultType, id, execScope).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createGroupNonUniformUnaryOp(
-    spv::Op op, uint32_t resultType, uint32_t execScope, uint32_t operand,
-    llvm::Optional<spv::GroupOperation> groupOp) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder
-      .groupNonUniformUnaryOp(op, resultType, id, execScope, groupOp, operand)
-      .x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createGroupNonUniformBinaryOp(spv::Op op,
-                                                      uint32_t resultType,
-                                                      uint32_t execScope,
-                                                      uint32_t operand1,
-                                                      uint32_t operand2) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder
-      .groupNonUniformBinaryOp(op, resultType, id, execScope, operand1,
-                               operand2)
-      .x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createAtomicOp(spv::Op opcode, uint32_t resultType,
-                                       uint32_t orignalValuePtr,
-                                       uint32_t scopeId,
-                                       uint32_t memorySemanticsId,
-                                       uint32_t valueToOp) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder
-      .atomicOp(opcode, resultType, id, orignalValuePtr, scopeId,
-                memorySemanticsId, valueToOp)
-      .x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createAtomicCompareExchange(
-    uint32_t resultType, uint32_t orignalValuePtr, uint32_t scopeId,
-    uint32_t equalMemorySemanticsId, uint32_t unequalMemorySemanticsId,
-    uint32_t valueToOp, uint32_t comparator) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.opAtomicCompareExchange(
-      resultType, id, orignalValuePtr, scopeId, equalMemorySemanticsId,
-      unequalMemorySemanticsId, valueToOp, comparator);
-  instBuilder.x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-spv::ImageOperandsMask ModuleBuilder::composeImageOperandsMask(
-    uint32_t bias, uint32_t lod, const std::pair<uint32_t, uint32_t> &grad,
-    uint32_t constOffset, uint32_t varOffset, uint32_t constOffsets,
-    uint32_t sample, uint32_t minLod,
-    llvm::SmallVectorImpl<uint32_t> *orderedParams) {
-  using spv::ImageOperandsMask;
-  // SPIR-V Image Operands from least significant bit to most significant bit
-  // Bias, Lod, Grad, ConstOffset, Offset, ConstOffsets, Sample, MinLod
-
-  auto mask = ImageOperandsMask::MaskNone;
-  orderedParams->clear();
-
-  if (bias) {
-    mask = mask | ImageOperandsMask::Bias;
-    orderedParams->push_back(bias);
-  }
-
-  if (lod) {
-    mask = mask | ImageOperandsMask::Lod;
-    orderedParams->push_back(lod);
-  }
-
-  if (grad.first && grad.second) {
-    mask = mask | ImageOperandsMask::Grad;
-    orderedParams->push_back(grad.first);
-    orderedParams->push_back(grad.second);
-  }
-
-  if (constOffset) {
-    mask = mask | ImageOperandsMask::ConstOffset;
-    orderedParams->push_back(constOffset);
-  }
-
-  if (varOffset) {
-    mask = mask | ImageOperandsMask::Offset;
-    requireCapability(spv::Capability::ImageGatherExtended);
-    orderedParams->push_back(varOffset);
-  }
-
-  if (constOffsets) {
-    mask = mask | ImageOperandsMask::ConstOffsets;
-    requireCapability(spv::Capability::ImageGatherExtended);
-    orderedParams->push_back(constOffsets);
-  }
-
-  if (sample) {
-    mask = mask | ImageOperandsMask::Sample;
-    orderedParams->push_back(sample);
-  }
-
-  if (minLod) {
-    requireCapability(spv::Capability::MinLod);
-    mask = mask | ImageOperandsMask::MinLod;
-    orderedParams->push_back(minLod);
-  }
-
-  return mask;
-}
-
-uint32_t
-ModuleBuilder::createImageSparseTexelsResident(uint32_t resident_code) {
-  assert(insertPoint && "null insert point");
-  // Result type must be a boolean
-  const uint32_t result_type = getBoolType();
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.opImageSparseTexelsResident(result_type, id, resident_code).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createImageTexelPointer(uint32_t resultType,
-                                                uint32_t imageId,
-                                                uint32_t coordinate,
-                                                uint32_t sample) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.opImageTexelPointer(resultType, id, imageId, coordinate, sample)
-      .x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-uint32_t ModuleBuilder::createImageSample(
-    uint32_t texelType, uint32_t imageType, uint32_t image, uint32_t sampler,
-    bool isNonUniform, uint32_t coordinate, uint32_t compareVal, uint32_t bias,
-    uint32_t lod, std::pair<uint32_t, uint32_t> grad, uint32_t constOffset,
-    uint32_t varOffset, uint32_t constOffsets, uint32_t sample, uint32_t minLod,
-    uint32_t residencyCodeId) {
-  assert(insertPoint && "null insert point");
-
-  // The Lod and Grad image operands requires explicit-lod instructions.
-  // Otherwise we use implicit-lod instructions.
-  const bool isExplicit = lod || (grad.first && grad.second);
-  const bool isSparse = (residencyCodeId != 0);
-
-  // minLod is only valid with Implicit instructions and Grad instructions.
-  // This means that we cannot have Lod and minLod together because Lod requires
-  // explicit insturctions. So either lod or minLod or both must be zero.
-  assert(lod == 0 || minLod == 0);
-
-  uint32_t retType = texelType;
-  if (isSparse) {
-    requireCapability(spv::Capability::SparseResidency);
-    retType = getSparseResidencyStructType(texelType);
-  }
-
-  // An OpSampledImage is required to do the image sampling.
-  const uint32_t sampledImgId = theContext.takeNextId();
-  const uint32_t sampledImgTy = getSampledImageType(imageType);
-  instBuilder.opSampledImage(sampledImgTy, sampledImgId, image, sampler).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-
-  if (isNonUniform) {
-    // The sampled image will be used to access resource's memory, so we need
-    // to decorate it with NonUniformEXT.
-    decorateNonUniformEXT(sampledImgId);
-  }
-
-  uint32_t texelId = theContext.takeNextId();
-  llvm::SmallVector<uint32_t, 4> params;
-  const auto mask =
-      composeImageOperandsMask(bias, lod, grad, constOffset, varOffset,
-                               constOffsets, sample, minLod, &params);
-
-  instBuilder.opImageSample(retType, texelId, sampledImgId, coordinate,
-                            compareVal, mask, isExplicit, isSparse);
-
-  for (const auto param : params)
-    instBuilder.idRef(param);
-  instBuilder.x();
-  insertPoint->appendInstruction(std::move(constructSite));
-
-  if (isSparse) {
-    // Write the Residency Code
-    const auto status = createCompositeExtract(getUint32Type(), texelId, {0});
-    createStore(residencyCodeId, status);
-    // Extract the real result from the struct
-    texelId = createCompositeExtract(texelType, texelId, {1});
-  }
-
-  return texelId;
-}
-
-void ModuleBuilder::createImageWrite(QualType imageType, uint32_t imageId,
-                                     uint32_t coordId, uint32_t texelId) {
-  assert(insertPoint && "null insert point");
-  requireCapability(
-      TypeTranslator::getCapabilityForStorageImageReadWrite(imageType));
-  instBuilder.opImageWrite(imageId, coordId, texelId, llvm::None).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-uint32_t ModuleBuilder::createImageFetchOrRead(
-    bool doImageFetch, uint32_t texelType, QualType imageType, uint32_t image,
-    uint32_t coordinate, uint32_t lod, uint32_t constOffset, uint32_t varOffset,
-    uint32_t constOffsets, uint32_t sample, uint32_t residencyCodeId) {
-  assert(insertPoint && "null insert point");
-
-  llvm::SmallVector<uint32_t, 2> params;
-  const auto mask =
-      llvm::Optional<spv::ImageOperandsMask>(composeImageOperandsMask(
-          /*bias*/ 0, lod, std::make_pair(0, 0), constOffset, varOffset,
-          constOffsets, sample, /*minLod*/ 0, &params));
-
-  const bool isSparse = (residencyCodeId != 0);
-  uint32_t retType = texelType;
-  if (isSparse) {
-    requireCapability(spv::Capability::SparseResidency);
-    retType = getSparseResidencyStructType(texelType);
-  }
-
-  if (!doImageFetch) {
-    requireCapability(
-        TypeTranslator::getCapabilityForStorageImageReadWrite(imageType));
-  }
-
-  uint32_t texelId = theContext.takeNextId();
-  instBuilder.opImageFetchRead(retType, texelId, image, coordinate, mask,
-                               doImageFetch, isSparse);
-
-  for (const auto param : params)
-    instBuilder.idRef(param);
-  instBuilder.x();
-  insertPoint->appendInstruction(std::move(constructSite));
-
-  if (isSparse) {
-    // Write the Residency Code
-    const auto status = createCompositeExtract(getUint32Type(), texelId, {0});
-    createStore(residencyCodeId, status);
-    // Extract the real result from the struct
-    texelId = createCompositeExtract(texelType, texelId, {1});
-  }
-
-  return texelId;
-}
-
-uint32_t ModuleBuilder::createImageGather(
-    uint32_t texelType, uint32_t imageType, uint32_t image, uint32_t sampler,
-    bool isNonUniform, uint32_t coordinate, uint32_t component,
-    uint32_t compareVal, uint32_t constOffset, uint32_t varOffset,
-    uint32_t constOffsets, uint32_t sample, uint32_t residencyCodeId) {
-  assert(insertPoint && "null insert point");
-
-  uint32_t sparseRetType = 0;
-  if (residencyCodeId) {
-    requireCapability(spv::Capability::SparseResidency);
-    sparseRetType = getSparseResidencyStructType(texelType);
-  }
-
-  // An OpSampledImage is required to do the image sampling.
-  const uint32_t sampledImgId = theContext.takeNextId();
-  const uint32_t sampledImgTy = getSampledImageType(imageType);
-  instBuilder.opSampledImage(sampledImgTy, sampledImgId, image, sampler).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-
-  if (isNonUniform) {
-    // The sampled image will be used to access resource's memory, so we need
-    // to decorate it with NonUniformEXT.
-    decorateNonUniformEXT(sampledImgId);
-  }
-
-  llvm::SmallVector<uint32_t, 2> params;
-
-  // TODO: Update ImageGather to accept minLod if necessary.
-  const auto mask =
-      llvm::Optional<spv::ImageOperandsMask>(composeImageOperandsMask(
-          /*bias*/ 0, /*lod*/ 0, std::make_pair(0, 0), constOffset, varOffset,
-          constOffsets, sample, /*minLod*/ 0, &params));
-  uint32_t texelId = theContext.takeNextId();
-
-  if (compareVal) {
-    if (residencyCodeId) {
-      // Note: OpImageSparseDrefGather does not take the component parameter.
-      instBuilder.opImageSparseDrefGather(sparseRetType, texelId, sampledImgId,
-                                          coordinate, compareVal, mask);
-    } else {
-      // Note: OpImageDrefGather does not take the component parameter.
-      instBuilder.opImageDrefGather(texelType, texelId, sampledImgId,
-                                    coordinate, compareVal, mask);
-    }
-  } else {
-    if (residencyCodeId) {
-      instBuilder.opImageSparseGather(sparseRetType, texelId, sampledImgId,
-                                      coordinate, component, mask);
-    } else {
-      instBuilder.opImageGather(texelType, texelId, sampledImgId, coordinate,
-                                component, mask);
-    }
-  }
-
-  for (const auto param : params)
-    instBuilder.idRef(param);
-  instBuilder.x();
-  insertPoint->appendInstruction(std::move(constructSite));
-
-  if (residencyCodeId) {
-    // Write the Residency Code
-    const auto status = createCompositeExtract(getUint32Type(), texelId, {0});
-    createStore(residencyCodeId, status);
-    // Extract the real result from the struct
-    texelId = createCompositeExtract(texelType, texelId, {1});
-  }
-
-  return texelId;
-}
-
-uint32_t ModuleBuilder::createSelect(uint32_t resultType, uint32_t condition,
-                                     uint32_t trueValue, uint32_t falseValue) {
-  assert(insertPoint && "null insert point");
-  const uint32_t id = theContext.takeNextId();
-  instBuilder.opSelect(resultType, id, condition, trueValue, falseValue).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return id;
-}
-
-void ModuleBuilder::createSwitch(
-    uint32_t mergeLabel, uint32_t selector, uint32_t defaultLabel,
-    llvm::ArrayRef<std::pair<uint32_t, uint32_t>> target) {
-  assert(insertPoint && "null insert point");
-  // Create the OpSelectioMerege.
-  instBuilder.opSelectionMerge(mergeLabel, spv::SelectionControlMask::MaskNone)
-      .x();
-  insertPoint->appendInstruction(std::move(constructSite));
-
-  // Create the OpSwitch.
-  instBuilder.opSwitch(selector, defaultLabel, target).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-void ModuleBuilder::createKill() {
-  assert(insertPoint && "null insert point");
-  assert(!isCurrentBasicBlockTerminated());
-  instBuilder.opKill().x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-void ModuleBuilder::createBranch(uint32_t targetLabel, uint32_t mergeBB,
-                                 uint32_t continueBB,
-                                 spv::LoopControlMask loopControl) {
-  assert(insertPoint && "null insert point");
-
-  if (mergeBB && continueBB) {
-    instBuilder.opLoopMerge(mergeBB, continueBB, loopControl).x();
-    insertPoint->appendInstruction(std::move(constructSite));
-  }
-
-  instBuilder.opBranch(targetLabel).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-void ModuleBuilder::createConditionalBranch(
-    uint32_t condition, uint32_t trueLabel, uint32_t falseLabel,
-    uint32_t mergeLabel, uint32_t continueLabel,
-    spv::SelectionControlMask selectionControl,
-    spv::LoopControlMask loopControl) {
-  assert(insertPoint && "null insert point");
-
-  if (mergeLabel) {
-    if (continueLabel) {
-      instBuilder.opLoopMerge(mergeLabel, continueLabel, loopControl).x();
-      insertPoint->appendInstruction(std::move(constructSite));
-    } else {
-      instBuilder.opSelectionMerge(mergeLabel, selectionControl).x();
-      insertPoint->appendInstruction(std::move(constructSite));
-    }
-  }
-
-  instBuilder.opBranchConditional(condition, trueLabel, falseLabel, {}).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-void ModuleBuilder::createReturn() {
-  assert(insertPoint && "null insert point");
-  instBuilder.opReturn().x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-void ModuleBuilder::createReturnValue(uint32_t value) {
-  assert(insertPoint && "null insert point");
-  instBuilder.opReturnValue(value).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-uint32_t ModuleBuilder::createExtInst(uint32_t resultType, uint32_t setId,
-                                      uint32_t instId,
-                                      llvm::ArrayRef<uint32_t> operands) {
-  assert(insertPoint && "null insert point");
-  uint32_t resultId = theContext.takeNextId();
-  instBuilder.opExtInst(resultType, resultId, setId, instId, operands).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return resultId;
-}
-
-void ModuleBuilder::createBarrier(uint32_t execution, uint32_t memory,
-                                  uint32_t semantics) {
-  assert(insertPoint && "null insert point");
-  if (execution)
-    instBuilder.opControlBarrier(execution, memory, semantics).x();
-  else
-    instBuilder.opMemoryBarrier(memory, semantics).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-uint32_t ModuleBuilder::createBitFieldExtract(uint32_t resultType,
-                                              uint32_t base, uint32_t offset,
-                                              uint32_t count, bool isSigned) {
-  assert(insertPoint && "null insert point");
-  uint32_t resultId = theContext.takeNextId();
-  if (isSigned)
-    instBuilder.opBitFieldSExtract(resultType, resultId, base, offset, count);
-  else
-    instBuilder.opBitFieldUExtract(resultType, resultId, base, offset, count);
-  instBuilder.x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return resultId;
-}
-
-uint32_t ModuleBuilder::createBitFieldInsert(uint32_t resultType, uint32_t base,
-                                             uint32_t insert, uint32_t offset,
-                                             uint32_t count) {
-  assert(insertPoint && "null insert point");
-  uint32_t resultId = theContext.takeNextId();
-  instBuilder
-      .opBitFieldInsert(resultType, resultId, base, insert, offset, count)
-      .x();
-  insertPoint->appendInstruction(std::move(constructSite));
-  return resultId;
-}
-
-void ModuleBuilder::createEmitVertex() {
-  assert(insertPoint && "null insert point");
-  instBuilder.opEmitVertex().x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-void ModuleBuilder::createEndPrimitive() {
-  assert(insertPoint && "null insert point");
-  instBuilder.opEndPrimitive().x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-void ModuleBuilder::addExecutionMode(uint32_t entryPointId,
-                                     spv::ExecutionMode em,
-                                     llvm::ArrayRef<uint32_t> params) {
-  instBuilder.opExecutionMode(entryPointId, em);
-  for (const auto &param : params) {
-    instBuilder.literalInteger(param);
-  }
-  instBuilder.x();
-  theModule.addExecutionMode(std::move(constructSite));
-}
-
-void ModuleBuilder::addExtension(Extension ext, llvm::StringRef target,
-                                 SourceLocation srcLoc) {
-  assert(featureManager);
-  featureManager->requestExtension(ext, target, srcLoc);
-  // Do not emit OpExtension if the given extension is natively supported in the
-  // target environment.
-  if (featureManager->isExtensionRequiredForTargetEnv(ext))
-    theModule.addExtension(featureManager->getExtensionName(ext));
-}
-
-uint32_t ModuleBuilder::getGLSLExtInstSet() {
-  if (glslExtSetId == 0) {
-    glslExtSetId = theContext.takeNextId();
-    theModule.addExtInstSet(glslExtSetId, "GLSL.std.450");
-  }
-  return glslExtSetId;
-}
-
-uint32_t ModuleBuilder::addStageIOVar(uint32_t type,
-                                      spv::StorageClass storageClass,
-                                      std::string name) {
-  const uint32_t pointerType = getPointerType(type, storageClass);
-  const uint32_t varId = theContext.takeNextId();
-  instBuilder.opVariable(pointerType, varId, storageClass, llvm::None).x();
-  theModule.addVariable(std::move(constructSite));
-  theModule.addDebugName(varId, name);
-  return varId;
-}
-
-uint32_t ModuleBuilder::addStageBuiltinVar(uint32_t type, spv::StorageClass sc,
-                                           spv::BuiltIn builtin) {
-  auto found =
-      std::find_if(builtinVars.begin(), builtinVars.end(),
-                   [sc, builtin](const BuiltInVarInfo &varInfo) {
-                     return varInfo.sc == sc && varInfo.builtIn == builtin;
-                   });
-  if (found != builtinVars.end()) {
-    return found->variable;
-  }
-
-  const uint32_t pointerType = getPointerType(type, sc);
-  const uint32_t varId = theContext.takeNextId();
-  instBuilder.opVariable(pointerType, varId, sc, llvm::None).x();
-  theModule.addVariable(std::move(constructSite));
-
-  // Decorate with the specified Builtin
-  const Decoration *d = Decoration::getBuiltIn(theContext, builtin);
-  theModule.addDecoration(d, varId);
-
-  builtinVars.emplace_back(sc, builtin, varId);
-
-  return varId;
-}
-
-uint32_t ModuleBuilder::addModuleVar(uint32_t type, spv::StorageClass sc,
-                                     llvm::StringRef name,
-                                     llvm::Optional<uint32_t> init) {
-  assert(sc != spv::StorageClass::Function);
-
-  // TODO: basically duplicated code of addFileVar()
-  const uint32_t pointerType = getPointerType(type, sc);
-  const uint32_t varId = theContext.takeNextId();
-  instBuilder.opVariable(pointerType, varId, sc, init).x();
-  theModule.addVariable(std::move(constructSite));
-  theModule.addDebugName(varId, name);
-  return varId;
-}
-
-void ModuleBuilder::decorateDSetBinding(uint32_t targetId, uint32_t setNumber,
-                                        uint32_t bindingNumber) {
-  const auto *d = Decoration::getDescriptorSet(theContext, setNumber);
-  theModule.addDecoration(d, targetId);
-
-  d = Decoration::getBinding(theContext, bindingNumber);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateInputAttachmentIndex(uint32_t targetId,
-                                                 uint32_t indexNumber) {
-  const auto *d = Decoration::getInputAttachmentIndex(theContext, indexNumber);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateCounterBufferId(uint32_t mainBufferId,
-                                            uint32_t counterBufferId) {
-  if (spirvOptions.enableReflect) {
-    addExtension(Extension::GOOGLE_hlsl_functionality1, "SPIR-V reflection",
-                 {});
-    theModule.addDecoration(
-        Decoration::getHlslCounterBufferGOOGLE(theContext, counterBufferId),
-        mainBufferId);
-  }
-}
-
-void ModuleBuilder::decorateHlslSemantic(uint32_t targetId,
-                                         llvm::StringRef semantic,
-                                         llvm::Optional<uint32_t> memberIdx) {
-  if (spirvOptions.enableReflect) {
-    addExtension(Extension::GOOGLE_hlsl_functionality1, "SPIR-V reflection",
-                 {});
-    theModule.addDecoration(
-        Decoration::getHlslSemanticGOOGLE(theContext, semantic, memberIdx),
-        targetId);
-  }
-}
-
-void ModuleBuilder::decorateLocation(uint32_t targetId, uint32_t location) {
-  const Decoration *d =
-      Decoration::getLocation(theContext, location, llvm::None);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateIndex(uint32_t targetId, uint32_t index) {
-  const Decoration *d = Decoration::getIndex(theContext, index);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateSpecId(uint32_t targetId, uint32_t specId) {
-  const Decoration *d = Decoration::getSpecId(theContext, specId);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateCentroid(uint32_t targetId) {
-  const Decoration *d = Decoration::getCentroid(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateFlat(uint32_t targetId) {
-  const Decoration *d = Decoration::getFlat(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateNoPerspective(uint32_t targetId) {
-  const Decoration *d = Decoration::getNoPerspective(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateSample(uint32_t targetId) {
-  const Decoration *d = Decoration::getSample(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateBlock(uint32_t targetId) {
-  const Decoration *d = Decoration::getBlock(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateRelaxedPrecision(uint32_t targetId) {
-  const Decoration *d = Decoration::getRelaxedPrecision(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decoratePatch(uint32_t targetId) {
-  const Decoration *d = Decoration::getPatch(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateNonUniformEXT(uint32_t targetId) {
-  const Decoration *d = Decoration::getNonUniformEXT(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-void ModuleBuilder::decorateNoContraction(uint32_t targetId) {
-  const Decoration *d = Decoration::getNoContraction(theContext);
-  theModule.addDecoration(d, targetId);
-}
-
-#define IMPL_GET_PRIMITIVE_TYPE(ty)                                            \
-                                                                               \
-  uint32_t ModuleBuilder::get##ty##Type() {                                    \
-    const Type *type = Type::get##ty(theContext);                              \
-    const uint32_t typeId = theContext.getResultIdForType(type);               \
-    theModule.addType(type, typeId);                                           \
-    return typeId;                                                             \
-  }
-
-IMPL_GET_PRIMITIVE_TYPE(Void)
-IMPL_GET_PRIMITIVE_TYPE(Bool)
-IMPL_GET_PRIMITIVE_TYPE(Int32)
-IMPL_GET_PRIMITIVE_TYPE(Uint32)
-IMPL_GET_PRIMITIVE_TYPE(Float32)
-
-#undef IMPL_GET_PRIMITIVE_TYPE
-
-// Note: At the moment, Float16 capability should not be added for Vulkan 1.0.
-// It is not a required capability, and adding the SPV_AMD_gpu_half_float does
-// not enable this capability. Any driver that supports float16 in Vulkan 1.0
-// should accept this extension.
-#define IMPL_GET_PRIMITIVE_TYPE_WITH_CAPABILITY(ty, cap)                       \
-                                                                               \
-  uint32_t ModuleBuilder::get##ty##Type() {                                    \
-    if (spv::Capability::cap == spv::Capability::Float16)                      \
-      addExtension(Extension::AMD_gpu_shader_half_float, "16-bit float", {});  \
-    else                                                                       \
-      requireCapability(spv::Capability::cap);                                 \
-    const Type *type = Type::get##ty(theContext);                              \
-    const uint32_t typeId = theContext.getResultIdForType(type);               \
-    theModule.addType(type, typeId);                                           \
-    return typeId;                                                             \
-  }
-
-IMPL_GET_PRIMITIVE_TYPE_WITH_CAPABILITY(Int64, Int64)
-IMPL_GET_PRIMITIVE_TYPE_WITH_CAPABILITY(Uint64, Int64)
-IMPL_GET_PRIMITIVE_TYPE_WITH_CAPABILITY(Float64, Float64)
-IMPL_GET_PRIMITIVE_TYPE_WITH_CAPABILITY(Int16, Int16)
-IMPL_GET_PRIMITIVE_TYPE_WITH_CAPABILITY(Uint16, Int16)
-IMPL_GET_PRIMITIVE_TYPE_WITH_CAPABILITY(Float16, Float16)
-
-#undef IMPL_GET_PRIMITIVE_TYPE_WITH_CAPABILITY
-
-uint32_t ModuleBuilder::getVecType(uint32_t elemType, uint32_t elemCount) {
-  const Type *type = nullptr;
-  switch (elemCount) {
-  case 2:
-    type = Type::getVec2(theContext, elemType);
-    break;
-  case 3:
-    type = Type::getVec3(theContext, elemType);
-    break;
-  case 4:
-    type = Type::getVec4(theContext, elemType);
-    break;
-  default:
-    assert(false && "unhandled vector size");
-    // Error found. Return 0 as the <result-id> directly.
-    return 0;
-  }
-
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getMatType(QualType elemType, uint32_t colType,
-                                   uint32_t colCount,
-                                   Type::DecorationSet decorations) {
-  // NOTE: According to Item "Data rules" of SPIR-V Spec 2.16.1 "Universal
-  // Validation Rules":
-  //   Matrix types can only be parameterized with floating-point types.
-  //
-  // So we need special handling of non-fp matrices. We emulate non-fp
-  // matrices as an array of vectors.
-  if (!elemType->isFloatingType())
-    return getArrayType(colType, getConstantUint32(colCount), decorations);
-
-  const Type *type = Type::getMatrix(theContext, colType, colCount);
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getPointerType(uint32_t pointeeType,
-                                       spv::StorageClass storageClass) {
-  const Type *type = Type::getPointer(theContext, storageClass, pointeeType);
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-  return typeId;
-}
-
-uint32_t
-ModuleBuilder::getStructType(llvm::ArrayRef<uint32_t> fieldTypes,
-                             llvm::StringRef structName,
-                             llvm::ArrayRef<llvm::StringRef> fieldNames,
-                             Type::DecorationSet decorations) {
-  const Type *type =
-      Type::getStruct(theContext, fieldTypes, structName, decorations);
-  bool isRegistered = false;
-  const uint32_t typeId = theContext.getResultIdForType(type, &isRegistered);
-  theModule.addType(type, typeId);
-  if (!isRegistered) {
-    theModule.addDebugName(typeId, structName);
-    if (!fieldNames.empty()) {
-      assert(fieldNames.size() == fieldTypes.size());
-      for (uint32_t i = 0; i < fieldNames.size(); ++i)
-        theModule.addDebugName(typeId, fieldNames[i],
-                               llvm::Optional<uint32_t>(i));
-    }
-  }
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getSparseResidencyStructType(uint32_t type) {
-  const auto uintType = getUint32Type();
-  return getStructType({uintType, type}, "SparseResidencyStruct",
-                       {"Residency.Code", "Result.Type"});
-}
-
-uint32_t ModuleBuilder::getArrayType(uint32_t elemType, uint32_t count,
-                                     Type::DecorationSet decorations) {
-  const Type *type = Type::getArray(theContext, elemType, count, decorations);
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getRuntimeArrayType(uint32_t elemType,
-                                            Type::DecorationSet decorations) {
-  const Type *type = Type::getRuntimeArray(theContext, elemType, decorations);
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getFunctionType(uint32_t returnType,
-                                        llvm::ArrayRef<uint32_t> paramTypes) {
-  const Type *type = Type::getFunction(theContext, returnType, paramTypes);
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getImageType(uint32_t sampledType, spv::Dim dim,
-                                     uint32_t depth, bool isArray, uint32_t ms,
-                                     uint32_t sampled,
-                                     spv::ImageFormat format) {
-  const Type *type = Type::getImage(theContext, sampledType, dim, depth,
-                                    isArray, ms, sampled, format);
-  bool isRegistered = false;
-  const uint32_t typeId = theContext.getResultIdForType(type, &isRegistered);
-  theModule.addType(type, typeId);
-
-  switch (format) {
-  case spv::ImageFormat::Rg32f:
-  case spv::ImageFormat::Rg16f:
-  case spv::ImageFormat::R11fG11fB10f:
-  case spv::ImageFormat::R16f:
-  case spv::ImageFormat::Rgba16:
-  case spv::ImageFormat::Rgb10A2:
-  case spv::ImageFormat::Rg16:
-  case spv::ImageFormat::Rg8:
-  case spv::ImageFormat::R16:
-  case spv::ImageFormat::R8:
-  case spv::ImageFormat::Rgba16Snorm:
-  case spv::ImageFormat::Rg16Snorm:
-  case spv::ImageFormat::Rg8Snorm:
-  case spv::ImageFormat::R16Snorm:
-  case spv::ImageFormat::R8Snorm:
-  case spv::ImageFormat::Rg32i:
-  case spv::ImageFormat::Rg16i:
-  case spv::ImageFormat::Rg8i:
-  case spv::ImageFormat::R16i:
-  case spv::ImageFormat::R8i:
-  case spv::ImageFormat::Rgb10a2ui:
-  case spv::ImageFormat::Rg32ui:
-  case spv::ImageFormat::Rg16ui:
-  case spv::ImageFormat::Rg8ui:
-  case spv::ImageFormat::R16ui:
-  case spv::ImageFormat::R8ui:
-    requireCapability(spv::Capability::StorageImageExtendedFormats);
-    break;
-  default:
-    // Only image formats requiring extended formats are relevant. The rest just
-    // pass through.
-    break;
-  }
-
-  if (dim == spv::Dim::Dim1D) {
-    if (sampled == 2u) {
-      requireCapability(spv::Capability::Image1D);
-    } else {
-      requireCapability(spv::Capability::Sampled1D);
-    }
-  } else if (dim == spv::Dim::Buffer) {
-    requireCapability(spv::Capability::SampledBuffer);
-  } else if (dim == spv::Dim::SubpassData) {
-    requireCapability(spv::Capability::InputAttachment);
-  }
-
-  if (isArray && ms) {
-    requireCapability(spv::Capability::ImageMSArray);
-  }
-
-  // Skip constructing the debug name if we have already done it before.
-  if (!isRegistered) {
-    const char *dimStr = "";
-    switch (dim) {
-    case spv::Dim::Dim1D:
-      dimStr = "1d.";
-      break;
-    case spv::Dim::Dim2D:
-      dimStr = "2d.";
-      break;
-    case spv::Dim::Dim3D:
-      dimStr = "3d.";
-      break;
-    case spv::Dim::Cube:
-      dimStr = "cube.";
-      break;
-    case spv::Dim::Rect:
-      dimStr = "rect.";
-      break;
-    case spv::Dim::Buffer:
-      dimStr = "buffer.";
-      break;
-    case spv::Dim::SubpassData:
-      dimStr = "subpass.";
-      break;
-    default:
-      break;
-    }
-
-    std::string name =
-        std::string("type.") + dimStr + "image" + (isArray ? ".array" : "");
-    theModule.addDebugName(typeId, name);
-  }
-
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getSamplerType() {
-  const Type *type = Type::getSampler(theContext);
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-  theModule.addDebugName(typeId, "type.sampler");
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getSampledImageType(uint32_t imageType) {
-  const Type *type = Type::getSampledImage(theContext, imageType);
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-  theModule.addDebugName(typeId, "type.sampled.image");
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getByteAddressBufferType(bool isRW) {
-  // Create a uint RuntimeArray with Array Stride of 4.
-  const uint32_t uintType = getUint32Type();
-  const auto *arrStride4 = Decoration::getArrayStride(theContext, 4u);
-  const Type *raType =
-      Type::getRuntimeArray(theContext, uintType, {arrStride4});
-  const uint32_t raTypeId = theContext.getResultIdForType(raType);
-  theModule.addType(raType, raTypeId);
-
-  // Create a struct containing the runtime array as its only member.
-  // The struct must also be decorated as BufferBlock. The offset decoration
-  // should also be applied to the first (only) member. NonWritable decoration
-  // should also be applied to the first member if isRW is true.
-  llvm::SmallVector<const Decoration *, 3> typeDecs;
-  typeDecs.push_back(Decoration::getBufferBlock(theContext));
-  typeDecs.push_back(Decoration::getOffset(theContext, 0, 0));
-  if (!isRW)
-    typeDecs.push_back(Decoration::getNonWritable(theContext, 0));
-
-  const Type *type = Type::getStruct(theContext, {raTypeId}, "", typeDecs);
-  const uint32_t typeId = theContext.getResultIdForType(type);
-  theModule.addType(type, typeId);
-  theModule.addDebugName(typeId, isRW ? "type.RWByteAddressBuffer"
-                                      : "type.ByteAddressBuffer");
-  return typeId;
-}
-
-uint32_t ModuleBuilder::getConstantBool(bool value, bool isSpecConst) {
-  if (isSpecConst) {
-    const uint32_t constId = theContext.takeNextId();
-    if (value) {
-      instBuilder.opSpecConstantTrue(getBoolType(), constId).x();
-    } else {
-      instBuilder.opSpecConstantFalse(getBoolType(), constId).x();
-    }
-
-    theModule.addVariable(std::move(constructSite));
-    return constId;
-  }
-
-  const uint32_t typeId = getBoolType();
-  const Constant *constant = value ? Constant::getTrue(theContext, typeId)
-                                   : Constant::getFalse(theContext, typeId);
-
-  const uint32_t constId = theContext.getResultIdForConstant(constant);
-  theModule.addConstant(constant, constId);
-  return constId;
-}
-
-#define IMPL_GET_PRIMITIVE_CONST(builderTy, cppTy)                             \
-                                                                               \
-  uint32_t ModuleBuilder::getConstant##builderTy(cppTy value) {                \
-    const uint32_t typeId = get##builderTy##Type();                            \
-    const Constant *constant =                                                 \
-        Constant::get##builderTy(theContext, typeId, value);                   \
-    const uint32_t constId = theContext.getResultIdForConstant(constant);      \
-    theModule.addConstant(constant, constId);                                  \
-    return constId;                                                            \
-  }
-
-#define IMPL_GET_PRIMITIVE_CONST_SPEC_CONST(builderTy, cppTy)                  \
-                                                                               \
-  uint32_t ModuleBuilder::getConstant##builderTy(cppTy value,                  \
-                                                 bool isSpecConst) {           \
-    if (isSpecConst) {                                                         \
-      const uint32_t constId = theContext.takeNextId();                        \
-      instBuilder                                                              \
-          .opSpecConstant(get##builderTy##Type(), constId,                     \
-                          cast::BitwiseCast<uint32_t>(value))                  \
-          .x();                                                                \
-      theModule.addVariable(std::move(constructSite));                         \
-      return constId;                                                          \
-    }                                                                          \
-                                                                               \
-    const uint32_t typeId = get##builderTy##Type();                            \
-    const Constant *constant =                                                 \
-        Constant::get##builderTy(theContext, typeId, value);                   \
-    const uint32_t constId = theContext.getResultIdForConstant(constant);      \
-    theModule.addConstant(constant, constId);                                  \
-    return constId;                                                            \
-  }
-
-IMPL_GET_PRIMITIVE_CONST(Int16, int16_t)
-IMPL_GET_PRIMITIVE_CONST_SPEC_CONST(Int32, int32_t)
-IMPL_GET_PRIMITIVE_CONST(Uint16, uint16_t)
-IMPL_GET_PRIMITIVE_CONST_SPEC_CONST(Uint32, uint32_t)
-IMPL_GET_PRIMITIVE_CONST(Float16, int16_t)
-IMPL_GET_PRIMITIVE_CONST_SPEC_CONST(Float32, float)
-IMPL_GET_PRIMITIVE_CONST(Float64, double)
-IMPL_GET_PRIMITIVE_CONST(Int64, int64_t)
-IMPL_GET_PRIMITIVE_CONST(Uint64, uint64_t)
-
-#undef IMPL_GET_PRIMITIVE_CONST
-#undef IMPL_GET_PRIMITIVE_CONST_SPEC_CONST
-
-uint32_t
-ModuleBuilder::getConstantComposite(uint32_t typeId,
-                                    llvm::ArrayRef<uint32_t> constituents) {
-  const Constant *constant =
-      Constant::getComposite(theContext, typeId, constituents);
-  const uint32_t constId = theContext.getResultIdForConstant(constant);
-  theModule.addConstant(constant, constId);
-  return constId;
-}
-
-uint32_t ModuleBuilder::getConstantNull(uint32_t typeId) {
-  const Constant *constant = Constant::getNull(theContext, typeId);
-  const uint32_t constId = theContext.getResultIdForConstant(constant);
-  theModule.addConstant(constant, constId);
-  return constId;
-}
-
-void ModuleBuilder::debugLine(uint32_t file, uint32_t line, uint32_t column) {
-  instBuilder.opLine(file, line, column).x();
-  insertPoint->appendInstruction(std::move(constructSite));
-}
-
-BasicBlock *ModuleBuilder::getBasicBlock(uint32_t labelId) {
-  auto it = basicBlocks.find(labelId);
-  if (it == basicBlocks.end()) {
-    assert(false && "invalid <label-id>");
-    return nullptr;
-  }
-
-  return it->second.get();
-}
-
-} // end namespace spirv
-} // end namespace clang

+ 0 - 1901
tools/clang/lib/SPIRV/TypeTranslator.cpp

@@ -1,1901 +0,0 @@
-//===--- TypeTranslator.cpp - TypeTranslator implementation ------*- C++ -*-==//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TypeTranslator.h"
-
-#include <algorithm>
-#include <tuple>
-
-#include "dxc/DXIL/DxilConstants.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/HlslTypes.h"
-#include "clang/SPIRV/AstTypeProbe.h"
-
-namespace clang {
-namespace spirv {
-
-namespace {
-/// The alignment for 4-component float vectors.
-constexpr uint32_t kStd140Vec4Alignment = 16u;
-
-/// Rounds the given value up to the given power of 2.
-inline uint32_t roundToPow2(uint32_t val, uint32_t pow2) {
-  assert(pow2 != 0);
-  return (val + pow2 - 1) & ~(pow2 - 1);
-}
-
-/// Returns true if the given vector type (of the given size) crosses the
-/// 4-component vector boundary if placed at the given offset.
-bool improperStraddle(QualType type, int size, int offset) {
-  assert(isVectorType(type));
-  return size <= 16 ? offset / 16 != (offset + size - 1) / 16
-                    : offset % 16 != 0;
-}
-
-/// Returns the :packoffset() annotation on the given decl. Returns nullptr if
-/// the decl does not have one.
-const hlsl::ConstantPacking *getPackOffset(const NamedDecl *decl) {
-  for (auto *annotation : decl->getUnusualAnnotations())
-    if (auto *packing = dyn_cast<hlsl::ConstantPacking>(annotation))
-      return packing;
-  return nullptr;
-}
-
-} // anonymous namespace
-
-QualType TypeTranslator::getBoolTypeWithSourceComponents(QualType sourceType) {
-  if (isScalarType(sourceType)) {
-    return astContext.BoolTy;
-  }
-  uint32_t elemCount = 0;
-  if (isVectorType(sourceType, nullptr, &elemCount)) {
-    return astContext.getExtVectorType(astContext.BoolTy, elemCount);
-  }
-
-  llvm_unreachable("only scalar and vector types are supported in "
-                   "getBoolTypeWithSourceComponents");
-}
-QualType TypeTranslator::getUintTypeWithSourceComponents(QualType sourceType) {
-  if (isScalarType(sourceType)) {
-    return astContext.UnsignedIntTy;
-  }
-  uint32_t elemCount = 0;
-  if (isVectorType(sourceType, nullptr, &elemCount)) {
-    return astContext.getExtVectorType(astContext.UnsignedIntTy, elemCount);
-  }
-  llvm_unreachable("only scalar and vector types are supported in "
-                   "getUintTypeWithSourceComponents");
-}
-
-bool TypeTranslator::isRelaxedPrecisionType(QualType type,
-                                            const SpirvCodeGenOptions &opts) {
-  // Primitive types
-  {
-    QualType ty = {};
-    if (isScalarType(type, &ty))
-      if (const auto *builtinType = ty->getAs<BuiltinType>())
-        switch (builtinType->getKind()) {
-        case BuiltinType::Min12Int:
-        case BuiltinType::Min16Int:
-        case BuiltinType::Min16UInt:
-        case BuiltinType::Min16Float:
-        case BuiltinType::Min10Float: {
-          // If '-enable-16bit-types' options is enabled, these types are
-          // translated to real 16-bit type, and therefore are not
-          // RelaxedPrecision.
-          // If the options is not enabled, these types are translated to 32-bit
-          // types with the added RelaxedPrecision decoration.
-          return !opts.enable16BitTypes;
-        default:
-          // Filter switch only interested in relaxed precision eligible types.
-          break;
-        }
-        }
-  }
-
-  // Vector & Matrix types could use relaxed precision based on their element
-  // type.
-  {
-    QualType elemType = {};
-    if (isVectorType(type, &elemType) || isMxNMatrix(type, &elemType))
-      return isRelaxedPrecisionType(elemType, opts);
-  }
-
-  return false;
-}
-
-bool TypeTranslator::isOpaqueType(QualType type) {
-  if (const auto *recordType = type->getAs<RecordType>()) {
-    const auto name = recordType->getDecl()->getName();
-
-    if (name == "Texture1D" || name == "RWTexture1D")
-      return true;
-    if (name == "Texture2D" || name == "RWTexture2D")
-      return true;
-    if (name == "Texture2DMS" || name == "RWTexture2DMS")
-      return true;
-    if (name == "Texture3D" || name == "RWTexture3D")
-      return true;
-    if (name == "TextureCube" || name == "RWTextureCube")
-      return true;
-
-    if (name == "Texture1DArray" || name == "RWTexture1DArray")
-      return true;
-    if (name == "Texture2DArray" || name == "RWTexture2DArray")
-      return true;
-    if (name == "Texture2DMSArray" || name == "RWTexture2DMSArray")
-      return true;
-    if (name == "TextureCubeArray" || name == "RWTextureCubeArray")
-      return true;
-
-    if (name == "Buffer" || name == "RWBuffer")
-      return true;
-
-    if (name == "SamplerState" || name == "SamplerComparisonState")
-      return true;
-  }
-  return false;
-}
-
-bool TypeTranslator::isOpaqueStructType(QualType type) {
-  if (isOpaqueType(type))
-    return false;
-
-  if (const auto *recordType = type->getAs<RecordType>())
-    for (const auto *field : recordType->getDecl()->decls())
-      if (const auto *fieldDecl = dyn_cast<FieldDecl>(field))
-        if (isOpaqueType(fieldDecl->getType()) ||
-            isOpaqueStructType(fieldDecl->getType()))
-          return true;
-
-  return false;
-}
-
-bool TypeTranslator::isOpaqueArrayType(QualType type) {
-  if (const auto *arrayType = type->getAsArrayTypeUnsafe())
-    return isOpaqueType(arrayType->getElementType());
-  return false;
-}
-
-void TypeTranslator::LiteralTypeHint::setHint(QualType ty) {
-  // You can set hint only once for each object.
-  assert(type == QualType());
-  type = ty;
-  translator.pushIntendedLiteralType(type);
-}
-
-TypeTranslator::LiteralTypeHint::LiteralTypeHint(TypeTranslator &t)
-    : type({}), translator(t) {}
-
-TypeTranslator::LiteralTypeHint::LiteralTypeHint(TypeTranslator &t, QualType ty)
-    : type(ty), translator(t) {
-  if (!isLiteralType(type))
-    translator.pushIntendedLiteralType(type);
-}
-
-TypeTranslator::LiteralTypeHint::~LiteralTypeHint() {
-  if (type != QualType() && !isLiteralType(type))
-    translator.popIntendedLiteralType();
-}
-
-bool TypeTranslator::LiteralTypeHint::isLiteralType(QualType type) {
-  if (type->isSpecificBuiltinType(BuiltinType::LitInt) ||
-      type->isSpecificBuiltinType(BuiltinType::LitFloat))
-    return true;
-
-  // For cases such as 'vector<literal int, 2>' or 'vector<literal float, 1>'
-  if (hlsl::IsHLSLVecType(type))
-    return isLiteralType(hlsl::GetHLSLVecElementType(type));
-
-  return false;
-}
-
-void TypeTranslator::pushIntendedLiteralType(QualType type) {
-  QualType elemType = {};
-  if (isVectorType(type, &elemType)) {
-    type = elemType;
-  } else if (isMxNMatrix(type, &elemType)) {
-    type = elemType;
-  }
-  assert(!type->isSpecificBuiltinType(BuiltinType::LitInt) &&
-         !type->isSpecificBuiltinType(BuiltinType::LitFloat));
-  intendedLiteralTypes.push(type);
-}
-
-QualType TypeTranslator::getIntendedLiteralType(QualType type) {
-  if (!intendedLiteralTypes.empty()) {
-    // If the stack is not empty, there is potentially a useful hint about how a
-    // given literal should be translated.
-    //
-    // However, a hint should not be returned blindly. It is possible that casts
-    // are occuring. For Example:
-    //
-    //   TU
-    //    |_ n1: <IntegralToFloating> float
-    //       |_ n2: ConditionalOperator 'literal int'
-    //          |_ n3: cond, bool
-    //          |_ n4: 'literal int' 2
-    //          |_ n5: 'literal int' 3
-    //
-    // When evaluating the return type of ConditionalOperator, we shouldn't
-    // provide 'float' as hint. The cast AST node should take care of that.
-    // In the above example, we have no hints about how '2' or '3' should be
-    // used.
-    QualType potentialHint = intendedLiteralTypes.top();
-    const bool hintIsInteger =
-        potentialHint->isIntegerType() && !potentialHint->isBooleanType();
-    const bool hintIsFloating = potentialHint->isFloatingType();
-    const bool isDifferentBasicType =
-        (type->isSpecificBuiltinType(BuiltinType::LitInt) && !hintIsInteger) ||
-        (type->isSpecificBuiltinType(BuiltinType::LitFloat) && !hintIsFloating);
-
-    if (!isDifferentBasicType)
-      return intendedLiteralTypes.top();
-  }
-
-  // We don't have any useful hints, return the given type itself.
-  return type;
-}
-
-void TypeTranslator::popIntendedLiteralType() {
-  assert(!intendedLiteralTypes.empty());
-  intendedLiteralTypes.pop();
-}
-
-uint32_t TypeTranslator::getLocationCount(QualType type) {
-  // See Vulkan spec 14.1.4. Location Assignment for the complete set of rules.
-
-  const auto canonicalType = type.getCanonicalType();
-  if (canonicalType != type)
-    return getLocationCount(canonicalType);
-
-  // Inputs and outputs of the following types consume a single interface
-  // location:
-  // * 16-bit scalar and vector types, and
-  // * 32-bit scalar and vector types, and
-  // * 64-bit scalar and 2-component vector types.
-
-  // 64-bit three- and four- component vectors consume two consecutive
-  // locations.
-
-  // Primitive types
-  if (isScalarType(type))
-    return 1;
-
-  // Vector types
-  {
-    QualType elemType = {};
-    uint32_t elemCount = {};
-    if (isVectorType(type, &elemType, &elemCount)) {
-      const auto *builtinType = elemType->getAs<BuiltinType>();
-      switch (builtinType->getKind()) {
-      case BuiltinType::Double:
-      case BuiltinType::LongLong:
-      case BuiltinType::ULongLong:
-        if (elemCount >= 3)
-          return 2;
-      default:
-        // Filter switch only interested in types occupying 2 locations.
-        break;
-      }
-      return 1;
-    }
-  }
-
-  // If the declared input or output is an n * m 16- , 32- or 64- bit matrix,
-  // it will be assigned multiple locations starting with the location
-  // specified. The number of locations assigned for each matrix will be the
-  // same as for an n-element array of m-component vectors.
-
-  // Matrix types
-  {
-    QualType elemType = {};
-    uint32_t rowCount = 0, colCount = 0;
-    if (isMxNMatrix(type, &elemType, &rowCount, &colCount))
-      return getLocationCount(astContext.getExtVectorType(elemType, colCount)) *
-             rowCount;
-  }
-
-  // Typedefs
-  if (const auto *typedefType = type->getAs<TypedefType>())
-    return getLocationCount(typedefType->desugar());
-
-  // Reference types
-  if (const auto *refType = type->getAs<ReferenceType>())
-    return getLocationCount(refType->getPointeeType());
-
-  // Pointer types
-  if (const auto *ptrType = type->getAs<PointerType>())
-    return getLocationCount(ptrType->getPointeeType());
-
-  // If a declared input or output is an array of size n and each element takes
-  // m locations, it will be assigned m * n consecutive locations starting with
-  // the location specified.
-
-  // Array types
-  if (const auto *arrayType = astContext.getAsConstantArrayType(type))
-    return getLocationCount(arrayType->getElementType()) *
-           static_cast<uint32_t>(arrayType->getSize().getZExtValue());
-
-  // Struct type
-  if (type->getAs<RecordType>()) {
-    assert(false && "all structs should already be flattened");
-    return 0;
-  }
-
-  emitError(
-      "calculating number of occupied locations for type %0 unimplemented")
-      << type;
-  return 0;
-}
-
-uint32_t TypeTranslator::getTypeWithCustomBitwidth(QualType type,
-                                                   uint32_t bitwidth) {
-  // Cases where the given type is a vector of float/int.
-  {
-    QualType elemType = {};
-    uint32_t elemCount = 0;
-    const bool isVec = isVectorType(type, &elemType, &elemCount);
-    if (isVec) {
-      return theBuilder.getVecType(
-          getTypeWithCustomBitwidth(elemType, bitwidth), elemCount);
-    }
-  }
-
-  // Scalar cases.
-  assert(!type->isBooleanType());
-  assert(type->isIntegerType() || type->isFloatingType());
-  if (type->isFloatingType()) {
-    switch (bitwidth) {
-    case 16:
-      return theBuilder.getFloat16Type();
-    case 32:
-      return theBuilder.getFloat32Type();
-    case 64:
-      return theBuilder.getFloat64Type();
-    }
-  }
-  if (type->isSignedIntegerType()) {
-    switch (bitwidth) {
-    case 16:
-      return theBuilder.getInt16Type();
-    case 32:
-      return theBuilder.getInt32Type();
-    case 64:
-      return theBuilder.getInt64Type();
-    }
-  }
-  if (type->isUnsignedIntegerType()) {
-    switch (bitwidth) {
-    case 16:
-      return theBuilder.getUint16Type();
-    case 32:
-      return theBuilder.getUint32Type();
-    case 64:
-      return theBuilder.getUint64Type();
-    }
-  }
-  llvm_unreachable(
-      "invalid type or bitwidth passed to getTypeWithCustomBitwidth");
-}
-
-uint32_t TypeTranslator::getElementSpirvBitwidth(QualType type) {
-  const auto canonicalType = type.getCanonicalType();
-  if (canonicalType != type)
-    return getElementSpirvBitwidth(canonicalType);
-
-  // Vector types
-  {
-    QualType elemType = {};
-    if (isVectorType(type, &elemType))
-      return getElementSpirvBitwidth(elemType);
-  }
-
-  // Matrix types
-  if (hlsl::IsHLSLMatType(type))
-    return getElementSpirvBitwidth(hlsl::GetHLSLMatElementType(type));
-
-  // Array types
-  if (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
-    return getElementSpirvBitwidth(arrayType->getElementType());
-  }
-
-  // Typedefs
-  if (const auto *typedefType = type->getAs<TypedefType>())
-    return getElementSpirvBitwidth(typedefType->desugar());
-
-  // Reference types
-  if (const auto *refType = type->getAs<ReferenceType>())
-    return getElementSpirvBitwidth(refType->getPointeeType());
-
-  // Pointer types
-  if (const auto *ptrType = type->getAs<PointerType>())
-    return getElementSpirvBitwidth(ptrType->getPointeeType());
-
-  // Scalar types
-  QualType ty = {};
-  const bool isScalar = isScalarType(type, &ty);
-  assert(isScalar);
-  (void)isScalar;
-  if (const auto *builtinType = ty->getAs<BuiltinType>()) {
-    switch (builtinType->getKind()) {
-    case BuiltinType::Bool:
-    case BuiltinType::Int:
-    case BuiltinType::UInt:
-    case BuiltinType::Float:
-      return 32;
-    case BuiltinType::Double:
-    case BuiltinType::LongLong:
-    case BuiltinType::ULongLong:
-      return 64;
-    // Half builtin type is always 16-bit. The HLSL 'half' keyword is translated
-    // to 'Half' enum if -enable-16bit-types is true.
-    // int16_t and uint16_t map to Short and UShort
-    case BuiltinType::Half:
-    case BuiltinType::Short:
-    case BuiltinType::UShort:
-      return 16;
-    // HalfFloat builtin type is just an alias for Float builtin type and is
-    // always 32-bit. The HLSL 'half' keyword is translated to 'HalfFloat' enum
-    // if -enable-16bit-types is false.
-    case BuiltinType::HalfFloat:
-      return 32;
-    // The following types are treated as 16-bit if '-enable-16bit-types' option
-    // is enabled. They are treated as 32-bit otherwise.
-    case BuiltinType::Min12Int:
-    case BuiltinType::Min16Int:
-    case BuiltinType::Min16UInt:
-    case BuiltinType::Min16Float:
-    case BuiltinType::Min10Float: {
-      return spirvOptions.enable16BitTypes ? 16 : 32;
-    }
-    case BuiltinType::LitFloat: {
-      // First try to see if there are any hints about how this literal type
-      // is going to be used. If so, use the hint.
-      if (getIntendedLiteralType(ty) != ty) {
-        return getElementSpirvBitwidth(getIntendedLiteralType(ty));
-      }
-
-      const auto &semantics = astContext.getFloatTypeSemantics(type);
-      const auto bitwidth = llvm::APFloat::getSizeInBits(semantics);
-      return bitwidth <= 32 ? 32 : 64;
-    }
-    case BuiltinType::LitInt: {
-      // First try to see if there are any hints about how this literal type
-      // is going to be used. If so, use the hint.
-      if (getIntendedLiteralType(ty) != ty) {
-        return getElementSpirvBitwidth(getIntendedLiteralType(ty));
-      }
-
-      const auto bitwidth = astContext.getIntWidth(type);
-      // All integer variants with bitwidth larger than 32 are represented
-      // as 64-bit int in SPIR-V.
-      // All integer variants with bitwidth of 32 or less are represented as
-      // 32-bit int in SPIR-V.
-      return bitwidth > 32 ? 64 : 32;
-    }
-    default:
-      // Other builtin types are either not relevant to bitcount or not in HLSL.
-      break;
-    }
-  }
-  llvm_unreachable("invalid type passed to getElementSpirvBitwidth");
-}
-
-uint32_t TypeTranslator::translateType(QualType type, SpirvLayoutRule rule) {
-  const auto desugaredType = desugarType(type);
-  if (desugaredType != type) {
-    const auto id = translateType(desugaredType, rule);
-    // Clear potentially set matrix majorness info
-    typeMatMajorAttr = llvm::None;
-    return id;
-  }
-
-  // Primitive types
-  {
-    QualType ty = {};
-    if (isScalarType(type, &ty)) {
-      if (const auto *builtinType = ty->getAs<BuiltinType>()) {
-        switch (builtinType->getKind()) {
-        case BuiltinType::Void:
-          return theBuilder.getVoidType();
-        case BuiltinType::Bool: {
-          // According to the SPIR-V Spec: There is no physical size or bit
-          // pattern defined for boolean type. Therefore an unsigned integer is
-          // used to represent booleans when layout is required.
-          if (rule == SpirvLayoutRule::Void)
-            return theBuilder.getBoolType();
-          else
-            return theBuilder.getUint32Type();
-        }
-        // All the ints
-        case BuiltinType::Int:
-        case BuiltinType::UInt:
-        case BuiltinType::Short:
-        case BuiltinType::UShort:
-        case BuiltinType::Min12Int:
-        case BuiltinType::Min16Int:
-        case BuiltinType::Min16UInt:
-        case BuiltinType::LongLong:
-        case BuiltinType::ULongLong:
-        // All the floats
-        case BuiltinType::Double:
-        case BuiltinType::Float:
-        case BuiltinType::Half:
-        case BuiltinType::HalfFloat:
-        case BuiltinType::Min16Float:
-        case BuiltinType::Min10Float: {
-          const auto bitwidth = getElementSpirvBitwidth(ty);
-          return getTypeWithCustomBitwidth(ty, bitwidth);
-        }
-        // Literal types. First try to resolve them using hints.
-        case BuiltinType::LitInt:
-        case BuiltinType::LitFloat: {
-          if (getIntendedLiteralType(ty) != ty) {
-            return translateType(getIntendedLiteralType(ty));
-          }
-          const auto bitwidth = getElementSpirvBitwidth(ty);
-          return getTypeWithCustomBitwidth(ty, bitwidth);
-        }
-        default:
-          emitError("primitive type %0 unimplemented")
-              << builtinType->getTypeClassName();
-          return 0;
-        }
-      }
-    }
-  }
-
-  // Reference types
-  if (const auto *refType = type->getAs<ReferenceType>()) {
-    // Note: Pointer/reference types are disallowed in HLSL source code.
-    // Although developers cannot use them directly, they are generated into
-    // the AST by out/inout parameter modifiers in function signatures.
-    // We already pass function arguments via pointers to tempoary local
-    // variables. So it should be fine to drop the pointer type and treat it
-    // as the underlying pointee type here.
-    return translateType(refType->getPointeeType(), rule);
-  }
-
-  // Pointer types
-  if (const auto *ptrType = type->getAs<PointerType>()) {
-    // The this object in a struct member function is of pointer type.
-    return translateType(ptrType->getPointeeType(), rule);
-  }
-
-  // In AST, vector/matrix types are TypedefType of TemplateSpecializationType.
-  // We handle them via HLSL type inspection functions.
-
-  // Vector types
-  {
-    QualType elemType = {};
-    uint32_t elemCount = {};
-    if (isVectorType(type, &elemType, &elemCount))
-      return theBuilder.getVecType(translateType(elemType, rule), elemCount);
-  }
-
-  // Matrix types
-  {
-    QualType elemType = {};
-    uint32_t rowCount = 0, colCount = 0;
-    if (isMxNMatrix(type, &elemType, &rowCount, &colCount)) {
-      // HLSL matrices are row major, while SPIR-V matrices are column major.
-      // We are mapping what HLSL semantically mean a row into a column here.
-      const uint32_t vecType =
-          theBuilder.getVecType(translateType(elemType, rule), colCount);
-
-      // If the matrix element type is not float, it is represented as an array
-      // of vectors, and should therefore have the ArrayStride decoration.
-      llvm::SmallVector<const Decoration *, 4> decorations;
-      if (!elemType->isFloatingType() && rule != SpirvLayoutRule::Void) {
-        uint32_t stride = 0;
-        (void)getAlignmentAndSize(type, rule, &stride);
-        decorations.push_back(
-            Decoration::getArrayStride(*theBuilder.getSPIRVContext(), stride));
-      }
-
-      return theBuilder.getMatType(elemType, vecType, rowCount, decorations);
-    }
-  }
-
-  // Struct type
-  if (const auto *structType = type->getAs<RecordType>()) {
-    const auto *decl = structType->getDecl();
-
-    // HLSL resource types are also represented as RecordType in the AST.
-    // (ClassTemplateSpecializationDecl is a subclass of CXXRecordDecl, which is
-    // then a subclass of RecordDecl.) So we need to check them before checking
-    // the general struct type.
-    if (const auto id = translateResourceType(type, rule))
-      return id;
-
-    // Collect all fields' types and names.
-    llvm::SmallVector<uint32_t, 4> fieldTypes;
-    llvm::SmallVector<llvm::StringRef, 4> fieldNames;
-
-    // If this struct is derived from some other struct, place an implicit field
-    // at the very beginning for the base struct.
-    if (const auto *cxxDecl = dyn_cast<CXXRecordDecl>(decl))
-      for (const auto base : cxxDecl->bases()) {
-        fieldTypes.push_back(translateType(base.getType(), rule));
-        fieldNames.push_back("");
-      }
-
-    // Create fields for all members of this struct
-    for (const auto *field : decl->fields()) {
-      fieldTypes.push_back(translateType(field->getType(), rule));
-      fieldNames.push_back(field->getName());
-    }
-
-    llvm::SmallVector<const Decoration *, 4> decorations;
-    if (rule != SpirvLayoutRule::Void) {
-      decorations = getLayoutDecorations(collectDeclsInDeclContext(decl), rule);
-    }
-
-    return theBuilder.getStructType(fieldTypes, decl->getName(), fieldNames,
-                                    decorations);
-  }
-
-  // Array type
-  if (const auto *arrayType = astContext.getAsArrayType(type)) {
-    const auto elemType = arrayType->getElementType();
-    const uint32_t elemTypeId = translateType(elemType, rule);
-
-    llvm::SmallVector<const Decoration *, 4> decorations;
-    if (rule != SpirvLayoutRule::Void &&
-        // We won't have stride information for structured/byte buffers since
-        // they contain runtime arrays.
-        !isAKindOfStructuredOrByteBuffer(elemType)) {
-      uint32_t stride = 0;
-      (void)getAlignmentAndSize(type, rule, &stride);
-      decorations.push_back(
-          Decoration::getArrayStride(*theBuilder.getSPIRVContext(), stride));
-    }
-
-    if (const auto *caType = astContext.getAsConstantArrayType(type)) {
-      const auto size = static_cast<uint32_t>(caType->getSize().getZExtValue());
-      return theBuilder.getArrayType(
-          elemTypeId, theBuilder.getConstantUint32(size), decorations);
-    } else {
-      assert(type->isIncompleteArrayType());
-      // Runtime arrays of resources needs additional capability.
-      if (hlsl::IsHLSLResourceType(arrayType->getElementType())) {
-        theBuilder.addExtension(Extension::EXT_descriptor_indexing,
-                                "runtime array of resources", {});
-        theBuilder.requireCapability(
-            spv::Capability::RuntimeDescriptorArrayEXT);
-      }
-      return theBuilder.getRuntimeArrayType(elemTypeId, decorations);
-    }
-  }
-
-  emitError("type %0 unimplemented") << type->getTypeClassName();
-  type->dump();
-  return 0;
-}
-
-uint32_t TypeTranslator::getACSBufferCounter() {
-  auto &context = *theBuilder.getSPIRVContext();
-  const uint32_t i32Type = theBuilder.getInt32Type();
-
-  llvm::SmallVector<const Decoration *, 4> decorations;
-  decorations.push_back(Decoration::getOffset(context, 0, 0));
-  decorations.push_back(Decoration::getBufferBlock(context));
-
-  return theBuilder.getStructType(i32Type, "type.ACSBuffer.counter", {},
-                                  decorations);
-}
-
-bool TypeTranslator::isRWByteAddressBuffer(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    return rt->getDecl()->getName() == "RWByteAddressBuffer";
-  }
-  return false;
-}
-
-bool TypeTranslator::isAppendStructuredBuffer(QualType type) {
-  const auto *recordType = type->getAs<RecordType>();
-  if (!recordType)
-    return false;
-  const auto name = recordType->getDecl()->getName();
-  return name == "AppendStructuredBuffer";
-}
-
-bool TypeTranslator::isConsumeStructuredBuffer(QualType type) {
-  const auto *recordType = type->getAs<RecordType>();
-  if (!recordType)
-    return false;
-  const auto name = recordType->getDecl()->getName();
-  return name == "ConsumeStructuredBuffer";
-}
-
-bool TypeTranslator::isRWAppendConsumeSBuffer(QualType type) {
-  if (const RecordType *recordType = type->getAs<RecordType>()) {
-    StringRef name = recordType->getDecl()->getName();
-    return name == "RWStructuredBuffer" || name == "AppendStructuredBuffer" ||
-           name == "ConsumeStructuredBuffer";
-  }
-  return false;
-}
-
-bool TypeTranslator::isAKindOfStructuredOrByteBuffer(QualType type) {
-  // Strip outer arrayness first
-  while (type->isArrayType())
-    type = type->getAsArrayTypeUnsafe()->getElementType();
-
-  if (const RecordType *recordType = type->getAs<RecordType>()) {
-    StringRef name = recordType->getDecl()->getName();
-    return name == "StructuredBuffer" || name == "RWStructuredBuffer" ||
-           name == "ByteAddressBuffer" || name == "RWByteAddressBuffer" ||
-           name == "AppendStructuredBuffer" ||
-           name == "ConsumeStructuredBuffer";
-  }
-  return false;
-}
-
-bool TypeTranslator::isOrContainsAKindOfStructuredOrByteBuffer(QualType type) {
-  if (const RecordType *recordType = type->getAs<RecordType>()) {
-    StringRef name = recordType->getDecl()->getName();
-    if (name == "StructuredBuffer" || name == "RWStructuredBuffer" ||
-        name == "ByteAddressBuffer" || name == "RWByteAddressBuffer" ||
-        name == "AppendStructuredBuffer" || name == "ConsumeStructuredBuffer")
-      return true;
-
-    for (const auto *field : recordType->getDecl()->fields()) {
-      if (isOrContainsAKindOfStructuredOrByteBuffer(field->getType()))
-        return true;
-    }
-  }
-  return false;
-}
-
-bool TypeTranslator::isOrContains16BitType(QualType type) {
-  // Primitive types
-  {
-    QualType ty = {};
-    if (isScalarType(type, &ty)) {
-      if (const auto *builtinType = ty->getAs<BuiltinType>()) {
-        switch (builtinType->getKind()) {
-        case BuiltinType::Min12Int:
-        case BuiltinType::Min16Int:
-        case BuiltinType::Min16UInt:
-        case BuiltinType::Min10Float:
-        case BuiltinType::Min16Float:
-          return spirvOptions.enable16BitTypes;
-        // the 'Half' enum always represents 16-bit and 'HalfFloat' always
-        // represents 32-bit floats.
-        // int16_t and uint16_t map to Short and UShort
-        case BuiltinType::Short:
-        case BuiltinType::UShort:
-        case BuiltinType::Half:
-          return true;
-        default:
-          return false;
-        }
-      }
-    }
-  }
-
-  // Vector types
-  {
-    QualType elemType = {};
-    if (isVectorType(type, &elemType))
-      return isOrContains16BitType(elemType);
-  }
-
-  // Matrix types
-  {
-    QualType elemType = {};
-    if (isMxNMatrix(type, &elemType)) {
-      return isOrContains16BitType(elemType);
-    }
-  }
-
-  // Struct type
-  if (const auto *structType = type->getAs<RecordType>()) {
-    const auto *decl = structType->getDecl();
-
-    for (const auto *field : decl->fields()) {
-      if (isOrContains16BitType(field->getType()))
-        return true;
-    }
-
-    return false;
-  }
-
-  // Array type
-  if (const auto *arrayType = type->getAsArrayTypeUnsafe()) {
-    return isOrContains16BitType(arrayType->getElementType());
-  }
-
-  // Reference types
-  if (const auto *refType = type->getAs<ReferenceType>()) {
-    return isOrContains16BitType(refType->getPointeeType());
-  }
-
-  // Pointer types
-  if (const auto *ptrType = type->getAs<PointerType>()) {
-    return isOrContains16BitType(ptrType->getPointeeType());
-  }
-
-  if (const auto *typedefType = type->getAs<TypedefType>()) {
-    return isOrContains16BitType(typedefType->desugar());
-  }
-
-  emitError("checking 16-bit type for %0 unimplemented")
-      << type->getTypeClassName();
-  type->dump();
-  return 0;
-}
-
-bool TypeTranslator::isStructuredBuffer(QualType type) {
-  const auto *recordType = type->getAs<RecordType>();
-  if (!recordType)
-    return false;
-  const auto name = recordType->getDecl()->getName();
-  return name == "StructuredBuffer" || name == "RWStructuredBuffer";
-}
-
-bool TypeTranslator::isByteAddressBuffer(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    return rt->getDecl()->getName() == "ByteAddressBuffer";
-  }
-  return false;
-}
-
-bool TypeTranslator::isRWBuffer(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    return rt->getDecl()->getName() == "RWBuffer";
-  }
-  return false;
-}
-
-bool TypeTranslator::isBuffer(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    return rt->getDecl()->getName() == "Buffer";
-  }
-  return false;
-}
-
-bool TypeTranslator::isRWTexture(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    const auto name = rt->getDecl()->getName();
-    if (name == "RWTexture1D" || name == "RWTexture1DArray" ||
-        name == "RWTexture2D" || name == "RWTexture2DArray" ||
-        name == "RWTexture3D")
-      return true;
-  }
-  return false;
-}
-
-bool TypeTranslator::isTexture(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    const auto name = rt->getDecl()->getName();
-    if (name == "Texture1D" || name == "Texture1DArray" ||
-        name == "Texture2D" || name == "Texture2DArray" ||
-        name == "Texture2DMS" || name == "Texture2DMSArray" ||
-        name == "TextureCube" || name == "TextureCubeArray" ||
-        name == "Texture3D")
-      return true;
-  }
-  return false;
-}
-
-bool TypeTranslator::isTextureMS(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    const auto name = rt->getDecl()->getName();
-    if (name == "Texture2DMS" || name == "Texture2DMSArray")
-      return true;
-  }
-  return false;
-}
-
-bool TypeTranslator::isSampler(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    const auto name = rt->getDecl()->getName();
-    if (name == "SamplerState" || name == "SamplerComparisonState")
-      return true;
-  }
-  return false;
-}
-
-bool TypeTranslator::isSubpassInput(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>())
-    return rt->getDecl()->getName() == "SubpassInput";
-
-  return false;
-}
-
-bool TypeTranslator::isSubpassInputMS(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>())
-    return rt->getDecl()->getName() == "SubpassInputMS";
-
-  return false;
-}
-
-bool TypeTranslator::isOrContainsNonFpColMajorMatrix(QualType type,
-                                                     const Decl *decl) const {
-  const auto isColMajorDecl = [this](const Decl *decl) {
-    return decl->hasAttr<HLSLColumnMajorAttr>() ||
-           (!decl->hasAttr<HLSLRowMajorAttr>() &&
-            !spirvOptions.defaultRowMajor);
-  };
-
-  QualType elemType = {};
-  if (isMxNMatrix(type, &elemType) && !elemType->isFloatingType()) {
-    return isColMajorDecl(decl);
-  }
-
-  if (const auto *arrayType = astContext.getAsConstantArrayType(type)) {
-    if (isMxNMatrix(arrayType->getElementType(), &elemType) &&
-        !elemType->isFloatingType())
-      return isColMajorDecl(decl);
-  }
-
-  if (const auto *structType = type->getAs<RecordType>()) {
-    const auto *decl = structType->getDecl();
-    for (const auto *field : decl->fields()) {
-      if (isOrContainsNonFpColMajorMatrix(field->getType(), field))
-        return true;
-    }
-  }
-
-  return false;
-}
-
-bool TypeTranslator::isConstantTextureBuffer(const Decl *decl) {
-  if (const auto *bufferDecl = dyn_cast<HLSLBufferDecl>(decl->getDeclContext()))
-    // Make sure we are not returning true for VarDecls inside cbuffer/tbuffer.
-    return bufferDecl->isConstantBufferView();
-
-  return false;
-}
-
-bool TypeTranslator::isResourceType(const ValueDecl *decl) {
-  if (isConstantTextureBuffer(decl))
-    return true;
-
-  QualType declType = decl->getType();
-
-  // Deprive the arrayness to see the element type
-  while (declType->isArrayType()) {
-    declType = declType->getAsArrayTypeUnsafe()->getElementType();
-  }
-
-  if (isSubpassInput(declType) || isSubpassInputMS(declType))
-    return true;
-
-  return hlsl::IsHLSLResourceType(declType);
-}
-
-bool TypeTranslator::isRowMajorMatrix(QualType type) const {
-  // The type passed in may not be desugared. Check attributes on itself first.
-  bool attrRowMajor = false;
-  if (hlsl::HasHLSLMatOrientation(type, &attrRowMajor))
-    return attrRowMajor;
-
-  // Use the majorness info we recorded before.
-  if (typeMatMajorAttr.hasValue()) {
-    switch (typeMatMajorAttr.getValue()) {
-    case AttributedType::attr_hlsl_row_major:
-      return true;
-    case AttributedType::attr_hlsl_column_major:
-      return false;
-    default:
-      // Only oriented matrices are relevant.
-      break;
-    }
-  }
-
-  return spirvOptions.defaultRowMajor;
-}
-
-bool TypeTranslator::canTreatAsSameScalarType(QualType type1, QualType type2) {
-  // Treat const int/float the same as const int/float
-  type1.removeLocalConst();
-  type2.removeLocalConst();
-
-  return (type1.getCanonicalType() == type2.getCanonicalType()) ||
-         // Treat 'literal float' and 'float' as the same
-         (type1->isSpecificBuiltinType(BuiltinType::LitFloat) &&
-          type2->isFloatingType()) ||
-         (type2->isSpecificBuiltinType(BuiltinType::LitFloat) &&
-          type1->isFloatingType()) ||
-         // Treat 'literal int' and 'int'/'uint' as the same
-         (type1->isSpecificBuiltinType(BuiltinType::LitInt) &&
-          type2->isIntegerType() &&
-          // Disallow boolean types
-          !type2->isSpecificBuiltinType(BuiltinType::Bool)) ||
-         (type2->isSpecificBuiltinType(BuiltinType::LitInt) &&
-          type1->isIntegerType() &&
-          // Disallow boolean types
-          !type1->isSpecificBuiltinType(BuiltinType::Bool));
-}
-
-bool TypeTranslator::isSameScalarOrVecType(QualType type1, QualType type2) {
-  { // Scalar types
-    QualType scalarType1 = {}, scalarType2 = {};
-    if (isScalarType(type1, &scalarType1) && isScalarType(type2, &scalarType2))
-      return canTreatAsSameScalarType(scalarType1, scalarType2);
-  }
-
-  { // Vector types
-    QualType elemType1 = {}, elemType2 = {};
-    uint32_t count1 = {}, count2 = {};
-    if (isVectorType(type1, &elemType1, &count1) &&
-        isVectorType(type2, &elemType2, &count2))
-      return count1 == count2 && canTreatAsSameScalarType(elemType1, elemType2);
-  }
-
-  return false;
-}
-
-bool TypeTranslator::isSameType(QualType type1, QualType type2) {
-  if (isSameScalarOrVecType(type1, type2))
-    return true;
-
-  type1.removeLocalConst();
-  type2.removeLocalConst();
-
-  { // Matrix types
-    QualType elemType1 = {}, elemType2 = {};
-    uint32_t row1 = 0, row2 = 0, col1 = 0, col2 = 0;
-    if (isMxNMatrix(type1, &elemType1, &row1, &col1) &&
-        isMxNMatrix(type2, &elemType2, &row2, &col2))
-      return row1 == row2 && col1 == col2 &&
-             canTreatAsSameScalarType(elemType1, elemType2);
-  }
-
-  { // Array types
-    if (const auto *arrType1 = astContext.getAsConstantArrayType(type1))
-      if (const auto *arrType2 = astContext.getAsConstantArrayType(type2))
-        return hlsl::GetArraySize(type1) == hlsl::GetArraySize(type2) &&
-               isSameType(arrType1->getElementType(),
-                          arrType2->getElementType());
-  }
-
-  // TODO: support other types if needed
-
-  return false;
-}
-
-QualType TypeTranslator::getElementType(QualType type) {
-  QualType elemType = {};
-  if (isScalarType(type, &elemType) || isVectorType(type, &elemType) ||
-      isMxNMatrix(type, &elemType) || canFitIntoOneRegister(type, &elemType)) {
-    return elemType;
-  }
-
-  if (const auto *arrType = astContext.getAsConstantArrayType(type)) {
-    return arrType->getElementType();
-  }
-
-  emitError("unsupported resource type parameter %0") << type;
-  // Note: We are returning the original type instead of a null QualType here
-  // to keep the translation going and avoid hitting asserts trying to query
-  // info from null QualType in other places of the compiler. Although we are
-  // likely generating invalid code here, it should be fine since the error
-  // reported will prevent the CodeGen from actually outputing.
-  return type;
-}
-
-QualType TypeTranslator::getComponentVectorType(QualType matrixType) {
-  assert(isMxNMatrix(matrixType));
-
-  const QualType elemType = hlsl::GetHLSLMatElementType(matrixType);
-  uint32_t rowCount = 0, colCount = 0;
-  hlsl::GetHLSLMatRowColCount(matrixType, rowCount, colCount);
-  return astContext.getExtVectorType(elemType, colCount);
-}
-
-uint32_t TypeTranslator::getComponentVectorTypeId(QualType matrixType) {
-  assert(isMxNMatrix(matrixType));
-
-  const uint32_t elemType =
-      translateType(hlsl::GetHLSLMatElementType(matrixType));
-
-  uint32_t rowCount = 0, colCount = 0;
-  hlsl::GetHLSLMatRowColCount(matrixType, rowCount, colCount);
-
-  return theBuilder.getVecType(elemType, colCount);
-}
-
-spv::Capability
-TypeTranslator::getCapabilityForStorageImageReadWrite(QualType type) {
-  if (const auto *rt = type->getAs<RecordType>()) {
-    const auto name = rt->getDecl()->getName();
-    // RWBuffer translates into OpTypeImage Buffer with Sampled = 2
-    if (name == "RWBuffer")
-      return spv::Capability::ImageBuffer;
-    // RWBuffer translates into OpTypeImage 1D with Sampled = 2
-    if (name == "RWTexture1D" || name == "RWTexture1DArray")
-      return spv::Capability::Image1D;
-  }
-  return spv::Capability::Max;
-}
-
-bool TypeTranslator::shouldSkipInStructLayout(const Decl *decl) {
-  // Ignore implicit generated struct declarations/constructors/destructors
-  if (decl->isImplicit())
-    return true;
-  // Ignore embedded type decls
-  if (isa<TypeDecl>(decl))
-    return true;
-  // Ignore embeded function decls
-  if (isa<FunctionDecl>(decl))
-    return true;
-  // Ignore empty decls
-  if (isa<EmptyDecl>(decl))
-    return true;
-
-  // For the $Globals cbuffer, we only care about externally-visiable
-  // non-resource-type variables. The rest should be filtered out.
-
-  const auto *declContext = decl->getDeclContext();
-
-  // Special check for ConstantBuffer/TextureBuffer, whose DeclContext is a
-  // HLSLBufferDecl. So that we need to check the HLSLBufferDecl's parent decl
-  // to check whether this is a ConstantBuffer/TextureBuffer defined in the
-  // global namespace.
-  // Note that we should not be seeing ConstantBuffer/TextureBuffer for normal
-  // cbuffer/tbuffer or push constant blocks. So this case should only happen
-  // for $Globals cbuffer.
-  if (isConstantTextureBuffer(decl) &&
-      declContext->getLexicalParent()->isTranslationUnit())
-    return true;
-
-  // $Globals' "struct" is the TranslationUnit, so we should ignore resources
-  // in the TranslationUnit "struct" and its child namespaces.
-  if (declContext->isTranslationUnit() || declContext->isNamespace()) {
-    // External visibility
-    if (const auto *declDecl = dyn_cast<DeclaratorDecl>(decl))
-      if (!declDecl->hasExternalFormalLinkage())
-        return true;
-
-    // cbuffer/tbuffer
-    if (isa<HLSLBufferDecl>(decl))
-      return true;
-
-    // Other resource types
-    if (const auto *valueDecl = dyn_cast<ValueDecl>(decl))
-      if (isResourceType(valueDecl))
-        return true;
-  }
-
-  return false;
-}
-
-llvm::SmallVector<const Decoration *, 4> TypeTranslator::getLayoutDecorations(
-    const llvm::SmallVector<const Decl *, 4> &decls, SpirvLayoutRule rule) {
-  const auto spirvContext = theBuilder.getSPIRVContext();
-  llvm::SmallVector<const Decoration *, 4> decorations;
-  uint32_t offset = 0, index = 0;
-  for (const auto *decl : decls) {
-    // The field can only be FieldDecl (for normal structs) or VarDecl (for
-    // HLSLBufferDecls).
-    const auto *declDecl = cast<DeclaratorDecl>(decl);
-    auto fieldType = declDecl->getType();
-
-    uint32_t memberAlignment = 0, memberSize = 0, stride = 0;
-    std::tie(memberAlignment, memberSize) =
-        getAlignmentAndSize(fieldType, rule, &stride);
-
-    // The next avaiable location after layouting the previos members
-    const uint32_t nextLoc = offset;
-
-    if (rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
-        rule == SpirvLayoutRule::RelaxedGLSLStd430 ||
-        rule == SpirvLayoutRule::FxcCTBuffer) {
-      alignUsingHLSLRelaxedLayout(fieldType, memberSize, memberAlignment,
-                                  &offset);
-    } else {
-      offset = roundToPow2(offset, memberAlignment);
-    }
-
-
-    // The vk::offset attribute takes precedence over all.
-    if (const auto *offsetAttr = decl->getAttr<VKOffsetAttr>()) {
-      offset = offsetAttr->getOffset();
-    }
-    // The :packoffset() annotation takes precedence over normal layout
-    // calculation.
-    else if (const auto *pack = getPackOffset(declDecl)) {
-      const uint32_t packOffset =
-          pack->Subcomponent * 16 + pack->ComponentOffset * 4;
-      // Do minimal check to make sure the offset specified by packoffset does
-      // not cause overlap.
-      if (packOffset < nextLoc) {
-        emitError("packoffset caused overlap with previous members", pack->Loc);
-      } else {
-        offset = packOffset;
-      }
-    }
-
-    // Each structure-type member must have an Offset Decoration.
-    decorations.push_back(Decoration::getOffset(*spirvContext, offset, index));
-    offset += memberSize;
-
-    // Each structure-type member that is a matrix or array-of-matrices must be
-    // decorated with
-    // * A MatrixStride decoration, and
-    // * one of the RowMajor or ColMajor Decorations.
-    if (const auto *arrayType = astContext.getAsConstantArrayType(fieldType)) {
-      // We have an array of matrices as a field, we need to decorate
-      // MatrixStride on the field. So skip possible arrays here.
-      fieldType = arrayType->getElementType();
-    }
-
-    // Non-floating point matrices are represented as arrays of vectors, and
-    // therefore ColMajor and RowMajor decorations should not be applied to
-    // them.
-    QualType elemType = {};
-    if (isMxNMatrix(fieldType, &elemType) && elemType->isFloatingType()) {
-      memberAlignment = memberSize = stride = 0;
-      std::tie(memberAlignment, memberSize) =
-          getAlignmentAndSize(fieldType, rule, &stride);
-
-      decorations.push_back(
-          Decoration::getMatrixStride(*spirvContext, stride, index));
-
-      // We need to swap the RowMajor and ColMajor decorations since HLSL
-      // matrices are conceptually row-major while SPIR-V are conceptually
-      // column-major.
-      if (isRowMajorMatrix(fieldType)) {
-        decorations.push_back(Decoration::getColMajor(*spirvContext, index));
-      } else {
-        // If the source code has neither row_major nor column_major annotated,
-        // it should be treated as column_major since that's the default.
-        decorations.push_back(Decoration::getRowMajor(*spirvContext, index));
-      }
-    }
-
-    ++index;
-  }
-
-  return decorations;
-}
-
-void TypeTranslator::collectDeclsInNamespace(
-    const NamespaceDecl *nsDecl, llvm::SmallVector<const Decl *, 4> *decls) {
-  for (const auto *decl : nsDecl->decls()) {
-    collectDeclsInField(decl, decls);
-  }
-}
-
-void TypeTranslator::collectDeclsInField(
-    const Decl *field, llvm::SmallVector<const Decl *, 4> *decls) {
-
-  // Case of nested namespaces.
-  if (const auto *nsDecl = dyn_cast<NamespaceDecl>(field)) {
-    collectDeclsInNamespace(nsDecl, decls);
-  }
-
-  if (shouldSkipInStructLayout(field))
-    return;
-
-  if (!isa<DeclaratorDecl>(field)) {
-    return;
-  }
-
-  decls->push_back(field);
-}
-
-llvm::SmallVector<const Decl *, 4>
-TypeTranslator::collectDeclsInDeclContext(const DeclContext *declContext) {
-  llvm::SmallVector<const Decl *, 4> decls;
-  for (const auto *field : declContext->decls()) {
-    collectDeclsInField(field, &decls);
-  }
-  return decls;
-}
-
-uint32_t TypeTranslator::translateResourceType(QualType type,
-                                               SpirvLayoutRule rule) {
-  // Resource types are either represented like C struct or C++ class in the
-  // AST. Samplers are represented like C struct, so isStructureType() will
-  // return true for it; textures are represented like C++ class, so
-  // isClassType() will return true for it.
-
-  assert(type->isStructureOrClassType());
-
-  const auto *recordType = type->getAs<RecordType>();
-  assert(recordType);
-  const llvm::StringRef name = recordType->getDecl()->getName();
-
-  // TODO: avoid string comparison once hlsl::IsHLSLResouceType() does that.
-
-  { // Texture types
-    spv::Dim dim = {};
-    bool isArray = {};
-    if ((dim = spv::Dim::Dim1D, isArray = false, name == "Texture1D") ||
-        (dim = spv::Dim::Dim2D, isArray = false, name == "Texture2D") ||
-        (dim = spv::Dim::Dim3D, isArray = false, name == "Texture3D") ||
-        (dim = spv::Dim::Cube, isArray = false, name == "TextureCube") ||
-        (dim = spv::Dim::Dim1D, isArray = true, name == "Texture1DArray") ||
-        (dim = spv::Dim::Dim2D, isArray = true, name == "Texture2DArray") ||
-        (dim = spv::Dim::Dim2D, isArray = false, name == "Texture2DMS") ||
-        (dim = spv::Dim::Dim2D, isArray = true, name == "Texture2DMSArray") ||
-        // There is no Texture3DArray
-        (dim = spv::Dim::Cube, isArray = true, name == "TextureCubeArray")) {
-      const auto isMS = (name == "Texture2DMS" || name == "Texture2DMSArray");
-      const auto sampledType = hlsl::GetHLSLResourceResultType(type);
-      return theBuilder.getImageType(translateType(getElementType(sampledType)),
-                                     dim, /*depth*/ 2, isArray, isMS);
-    }
-
-    // There is no RWTexture3DArray
-    if ((dim = spv::Dim::Dim1D, isArray = false, name == "RWTexture1D") ||
-        (dim = spv::Dim::Dim2D, isArray = false, name == "RWTexture2D") ||
-        (dim = spv::Dim::Dim3D, isArray = false, name == "RWTexture3D") ||
-        (dim = spv::Dim::Dim1D, isArray = true, name == "RWTexture1DArray") ||
-        (dim = spv::Dim::Dim2D, isArray = true, name == "RWTexture2DArray")) {
-      const auto sampledType = hlsl::GetHLSLResourceResultType(type);
-      const auto format = translateSampledTypeToImageFormat(sampledType);
-      return theBuilder.getImageType(translateType(getElementType(sampledType)),
-                                     dim, /*depth*/ 2, isArray, /*MS*/ 0,
-                                     /*Sampled*/ 2u, format);
-    }
-  }
-
-  // Sampler types
-  if (name == "SamplerState" || name == "SamplerComparisonState") {
-    return theBuilder.getSamplerType();
-  }
-
-  if (name == "StructuredBuffer" || name == "RWStructuredBuffer" ||
-      name == "AppendStructuredBuffer" || name == "ConsumeStructuredBuffer") {
-    // StructureBuffer<S> will be translated into an OpTypeStruct with one
-    // field, which is an OpTypeRuntimeArray of OpTypeStruct (S).
-
-    // If layout rule is void, it means these resource types are used for
-    // declaring local resources, which should be created as alias variables.
-    // The aliased-to variable should surely be in the Uniform storage class,
-    // which has layout decorations.
-    bool asAlias = false;
-    if (rule == SpirvLayoutRule::Void) {
-      asAlias = true;
-      rule = spirvOptions.sBufferLayoutRule;
-    }
-
-    auto &context = *theBuilder.getSPIRVContext();
-    const auto s = hlsl::GetHLSLResourceResultType(type);
-    const uint32_t structType = translateType(s, rule);
-    std::string structName;
-    const auto innerType = hlsl::GetHLSLResourceResultType(type);
-    if (innerType->isStructureType())
-      structName = innerType->getAs<RecordType>()->getDecl()->getName();
-    else
-      structName = getAstTypeName(innerType);
-
-    const bool isRowMajor = isRowMajorMatrix(s);
-    llvm::SmallVector<const Decoration *, 4> decorations;
-
-    // The stride for the runtime array is the size of S.
-    uint32_t size = 0, stride = 0;
-    std::tie(std::ignore, size) = getAlignmentAndSize(s, rule, &stride);
-    decorations.push_back(Decoration::getArrayStride(context, size));
-    const uint32_t raType =
-        theBuilder.getRuntimeArrayType(structType, decorations);
-
-    decorations.clear();
-
-    // Attach majorness decoration if this is a *StructuredBuffer<matrix>.
-    if (isMxNMatrix(s))
-      decorations.push_back(isRowMajor ? Decoration::getColMajor(context, 0)
-                                       : Decoration::getRowMajor(context, 0));
-
-    decorations.push_back(Decoration::getOffset(context, 0, 0));
-    if (name == "StructuredBuffer")
-      decorations.push_back(Decoration::getNonWritable(context, 0));
-    decorations.push_back(Decoration::getBufferBlock(context));
-    const std::string typeName = "type." + name.str() + "." + structName;
-    const auto valType =
-        theBuilder.getStructType(raType, typeName, {}, decorations);
-
-    if (asAlias) {
-      // All structured buffers are in the Uniform storage class.
-      return theBuilder.getPointerType(valType, spv::StorageClass::Uniform);
-    } else {
-      return valType;
-    }
-  }
-
-  // ByteAddressBuffer types.
-  if (name == "ByteAddressBuffer") {
-    const auto bufferType = theBuilder.getByteAddressBufferType(/*isRW*/ false);
-    if (rule == SpirvLayoutRule::Void) {
-      // All byte address buffers are in the Uniform storage class.
-      return theBuilder.getPointerType(bufferType, spv::StorageClass::Uniform);
-    } else {
-      return bufferType;
-    }
-  }
-  // RWByteAddressBuffer types.
-  if (name == "RWByteAddressBuffer") {
-    const auto bufferType = theBuilder.getByteAddressBufferType(/*isRW*/ true);
-    if (rule == SpirvLayoutRule::Void) {
-      // All byte address buffers are in the Uniform storage class.
-      return theBuilder.getPointerType(bufferType, spv::StorageClass::Uniform);
-    } else {
-      return bufferType;
-    }
-  }
-
-  // Buffer and RWBuffer types
-  if (name == "Buffer" || name == "RWBuffer") {
-    theBuilder.requireCapability(spv::Capability::SampledBuffer);
-    const auto sampledType = hlsl::GetHLSLResourceResultType(type);
-    if (sampledType->isStructureType() && name.startswith("RW")) {
-      // Note: actually fxc supports RWBuffer over struct types. However, the
-      // struct member must fit into a 4-component vector and writing to a
-      // RWBuffer element must write all components. This is a feature that are
-      // rarely used by developers. We just emit an error saying not supported
-      // for now.
-      emitError("cannot instantiate RWBuffer with struct type %0")
-          << sampledType;
-      return 0;
-    }
-    const auto format = translateSampledTypeToImageFormat(sampledType);
-    return theBuilder.getImageType(
-        translateType(getElementType(sampledType)), spv::Dim::Buffer,
-        /*depth*/ 2, /*isArray*/ 0, /*ms*/ 0,
-        /*sampled*/ name == "Buffer" ? 1 : 2, format);
-  }
-
-  // InputPatch
-  if (name == "InputPatch") {
-    const auto elemType = hlsl::GetHLSLInputPatchElementType(type);
-    const auto elemCount = hlsl::GetHLSLInputPatchCount(type);
-    const uint32_t elemTypeId = translateType(elemType);
-    const uint32_t elemCountId = theBuilder.getConstantUint32(elemCount);
-    return theBuilder.getArrayType(elemTypeId, elemCountId);
-  }
-  // OutputPatch
-  if (name == "OutputPatch") {
-    const auto elemType = hlsl::GetHLSLOutputPatchElementType(type);
-    const auto elemCount = hlsl::GetHLSLOutputPatchCount(type);
-    const uint32_t elemTypeId = translateType(elemType);
-    const uint32_t elemCountId = theBuilder.getConstantUint32(elemCount);
-    return theBuilder.getArrayType(elemTypeId, elemCountId);
-  }
-  // Output stream objects (TriangleStream, LineStream, and PointStream)
-  if (name == "TriangleStream" || name == "LineStream" ||
-      name == "PointStream") {
-    return translateType(hlsl::GetHLSLResourceResultType(type), rule);
-  }
-
-  if (name == "SubpassInput" || name == "SubpassInputMS") {
-    const auto sampledType = hlsl::GetHLSLResourceResultType(type);
-    return theBuilder.getImageType(
-        translateType(getElementType(sampledType)), spv::Dim::SubpassData,
-        /*depth*/ 2, /*isArray*/ false, /*ms*/ name == "SubpassInputMS",
-        /*sampled*/ 2);
-  }
-
-  return 0;
-}
-
-spv::ImageFormat
-TypeTranslator::translateSampledTypeToImageFormat(QualType sampledType) {
-  uint32_t elemCount = 1;
-  QualType ty = {};
-  if (isScalarType(sampledType, &ty) ||
-      isVectorType(sampledType, &ty, &elemCount) ||
-      canFitIntoOneRegister(sampledType, &ty, &elemCount)) {
-    if (const auto *builtinType = ty->getAs<BuiltinType>()) {
-      switch (builtinType->getKind()) {
-      case BuiltinType::Int:
-        return elemCount == 1 ? spv::ImageFormat::R32i
-                              : elemCount == 2 ? spv::ImageFormat::Rg32i
-                                               : spv::ImageFormat::Rgba32i;
-      case BuiltinType::UInt:
-        return elemCount == 1 ? spv::ImageFormat::R32ui
-                              : elemCount == 2 ? spv::ImageFormat::Rg32ui
-                                               : spv::ImageFormat::Rgba32ui;
-      case BuiltinType::Float:
-      case BuiltinType::HalfFloat:
-        return elemCount == 1 ? spv::ImageFormat::R32f
-                              : elemCount == 2 ? spv::ImageFormat::Rg32f
-                                               : spv::ImageFormat::Rgba32f;
-      default:
-        // Other sampled types unimplemented or irrelevant.
-        break;
-      }
-    }
-  }
-  emitError(
-      "cannot translate resource type parameter %0 to proper image format")
-      << sampledType;
-  return spv::ImageFormat::Unknown;
-}
-
-bool TypeTranslator::canFitIntoOneRegister(QualType structType,
-                                           QualType *elemType,
-                                           uint32_t *elemCount) {
-  if (structType->getAsStructureType() == nullptr)
-    return false;
-
-  const auto *structDecl = structType->getAsStructureType()->getDecl();
-  QualType firstElemType;
-  uint32_t totalCount = 0;
-
-  for (const auto *field : structDecl->fields()) {
-    QualType type;
-    uint32_t count = 1;
-
-    if (isScalarType(field->getType(), &type) ||
-        isVectorType(field->getType(), &type, &count)) {
-      if (firstElemType.isNull()) {
-        firstElemType = type;
-      } else {
-        if (!canTreatAsSameScalarType(firstElemType, type)) {
-          emitError("all struct members should have the same element type for "
-                    "resource template instantiation",
-                    structDecl->getLocation());
-          return false;
-        }
-      }
-      totalCount += count;
-    } else {
-      emitError("unsupported struct element type for resource template "
-                "instantiation",
-                structDecl->getLocation());
-      return false;
-    }
-  }
-
-  if (totalCount > 4) {
-    emitError(
-        "resource template element type %0 cannot fit into four 32-bit scalars",
-        structDecl->getLocation())
-        << structType;
-    return false;
-  }
-
-  if (elemType)
-    *elemType = firstElemType;
-  if (elemCount)
-    *elemCount = totalCount;
-  return true;
-}
-
-void TypeTranslator::alignUsingHLSLRelaxedLayout(QualType fieldType,
-                                                 uint32_t fieldSize,
-                                                 uint32_t fieldAlignment,
-                                                 uint32_t *currentOffset) {
-  QualType vecElemType = {};
-  const bool fieldIsVecType = isVectorType(fieldType, &vecElemType);
-
-  // Adjust according to HLSL relaxed layout rules.
-  // Aligning vectors as their element types so that we can pack a float
-  // and a float3 tightly together.
-  if (fieldIsVecType) {
-    uint32_t scalarAlignment = 0;
-    std::tie(scalarAlignment, std::ignore) =
-        getAlignmentAndSize(vecElemType, SpirvLayoutRule::Void, nullptr);
-    if (scalarAlignment <= 4)
-      fieldAlignment = scalarAlignment;
-  }
-
-  *currentOffset = roundToPow2(*currentOffset, fieldAlignment);
-
-  // Adjust according to HLSL relaxed layout rules.
-  // Bump to 4-component vector alignment if there is a bad straddle
-  if (fieldIsVecType &&
-      improperStraddle(fieldType, fieldSize, *currentOffset)) {
-    fieldAlignment = kStd140Vec4Alignment;
-    *currentOffset = roundToPow2(*currentOffset, fieldAlignment);
-  }
-}
-
-std::pair<uint32_t, uint32_t>
-TypeTranslator::getAlignmentAndSize(QualType type, SpirvLayoutRule rule,
-                                    uint32_t *stride) {
-  // std140 layout rules:
-
-  // 1. If the member is a scalar consuming N basic machine units, the base
-  //    alignment is N.
-  //
-  // 2. If the member is a two- or four-component vector with components
-  //    consuming N basic machine units, the base alignment is 2N or 4N,
-  //    respectively.
-  //
-  // 3. If the member is a three-component vector with components consuming N
-  //    basic machine units, the base alignment is 4N.
-  //
-  // 4. If the member is an array of scalars or vectors, the base alignment and
-  //    array stride are set to match the base alignment of a single array
-  //    element, according to rules (1), (2), and (3), and rounded up to the
-  //    base alignment of a vec4. The array may have padding at the end; the
-  //    base offset of the member following the array is rounded up to the next
-  //    multiple of the base alignment.
-  //
-  // 5. If the member is a column-major matrix with C columns and R rows, the
-  //    matrix is stored identically to an array of C column vectors with R
-  //    components each, according to rule (4).
-  //
-  // 6. If the member is an array of S column-major matrices with C columns and
-  //    R rows, the matrix is stored identically to a row of S X C column
-  //    vectors with R components each, according to rule (4).
-  //
-  // 7. If the member is a row-major matrix with C columns and R rows, the
-  //    matrix is stored identically to an array of R row vectors with C
-  //    components each, according to rule (4).
-  //
-  // 8. If the member is an array of S row-major matrices with C columns and R
-  //    rows, the matrix is stored identically to a row of S X R row vectors
-  //    with C components each, according to rule (4).
-  //
-  // 9. If the member is a structure, the base alignment of the structure is N,
-  //    where N is the largest base alignment value of any of its members, and
-  //    rounded up to the base alignment of a vec4. The individual members of
-  //    this substructure are then assigned offsets by applying this set of
-  //    rules recursively, where the base offset of the first member of the
-  //    sub-structure is equal to the aligned offset of the structure. The
-  //    structure may have padding at the end; the base offset of the member
-  //    following the sub-structure is rounded up to the next multiple of the
-  //    base alignment of the structure.
-  //
-  // 10. If the member is an array of S structures, the S elements of the array
-  //     are laid out in order, according to rule (9).
-  //
-  // This method supports multiple layout rules, all of them modifying the
-  // std140 rules listed above:
-  //
-  // std430:
-  // - Array base alignment and stride does not need to be rounded up to a
-  //   multiple of 16.
-  // - Struct base alignment does not need to be rounded up to a multiple of 16.
-  //
-  // Relaxed std140/std430:
-  // - Vector base alignment is set as its element type's base alignment.
-  //
-  // FxcCTBuffer:
-  // - Vector base alignment is set as its element type's base alignment.
-  // - Arrays/structs do not need to have padding at the end; arrays/structs do
-  //   not affect the base offset of the member following them.
-  //
-  // FxcSBuffer:
-  // - Vector/matrix/array base alignment is set as its element type's base
-  //   alignment.
-  // - Arrays/structs do not need to have padding at the end; arrays/structs do
-  //   not affect the base offset of the member following them.
-  // - Struct base alignment does not need to be rounded up to a multiple of 16.
-
-  const auto desugaredType = desugarType(type);
-  if (desugaredType != type) {
-    const auto id = getAlignmentAndSize(desugaredType, rule, stride);
-    // Clear potentially set matrix majorness info
-    typeMatMajorAttr = llvm::None;
-    return id;
-  }
-
-  { // Rule 1
-    QualType ty = {};
-    if (isScalarType(type, &ty))
-      if (const auto *builtinType = ty->getAs<BuiltinType>())
-        switch (builtinType->getKind()) {
-        case BuiltinType::Bool:
-        case BuiltinType::Int:
-        case BuiltinType::UInt:
-        case BuiltinType::Float:
-          return {4, 4};
-        case BuiltinType::Double:
-        case BuiltinType::LongLong:
-        case BuiltinType::ULongLong:
-          return {8, 8};
-        case BuiltinType::Min12Int:
-        case BuiltinType::Min16Int:
-        case BuiltinType::Min16UInt:
-        case BuiltinType::Min16Float:
-        case BuiltinType::Min10Float: {
-          if (spirvOptions.enable16BitTypes)
-            return {2, 2};
-          else
-            return {4, 4};
-        }
-        // the 'Half' enum always represents 16-bit floats.
-        // int16_t and uint16_t map to Short and UShort.
-        case BuiltinType::Short:
-        case BuiltinType::UShort:
-        case BuiltinType::Half:
-          return {2, 2};
-        // 'HalfFloat' always represents 32-bit floats.
-        case BuiltinType::HalfFloat:
-          return {4, 4};
-        default:
-          emitError("alignment and size calculation for type %0 unimplemented")
-              << type;
-          return {0, 0};
-        }
-  }
-
-  { // Rule 2 and 3
-    QualType elemType = {};
-    uint32_t elemCount = {};
-    if (isVectorType(type, &elemType, &elemCount)) {
-      uint32_t alignment = 0, size = 0;
-      std::tie(alignment, size) = getAlignmentAndSize(elemType, rule, stride);
-      // Use element alignment for fxc rules and VK_EXT_scalar_block_layout
-      if (rule != SpirvLayoutRule::FxcCTBuffer &&
-          rule != SpirvLayoutRule::FxcSBuffer &&
-          rule != SpirvLayoutRule::Scalar)
-        alignment = (elemCount == 3 ? 4 : elemCount) * size;
-
-      return {alignment, elemCount * size};
-    }
-  }
-
-  { // Rule 5 and 7
-    QualType elemType = {};
-    uint32_t rowCount = 0, colCount = 0;
-    if (isMxNMatrix(type, &elemType, &rowCount, &colCount)) {
-      uint32_t alignment = 0, size = 0;
-      std::tie(alignment, size) = getAlignmentAndSize(elemType, rule, stride);
-
-      // Matrices are treated as arrays of vectors:
-      // The base alignment and array stride are set to match the base alignment
-      // of a single array element, according to rules 1, 2, and 3, and rounded
-      // up to the base alignment of a vec4.
-      bool isRowMajor = isRowMajorMatrix(type);
-
-      const uint32_t vecStorageSize = isRowMajor ? colCount : rowCount;
-
-      if (rule == SpirvLayoutRule::FxcSBuffer ||
-          rule == SpirvLayoutRule::Scalar) {
-        *stride = vecStorageSize * size;
-        // Use element alignment for fxc structured buffers and
-        // VK_EXT_scalar_block_layout
-        return {alignment, rowCount * colCount * size};
-      }
-
-      alignment *= (vecStorageSize == 3 ? 4 : vecStorageSize);
-      if (rule == SpirvLayoutRule::GLSLStd140 ||
-          rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
-          rule == SpirvLayoutRule::FxcCTBuffer) {
-        alignment = roundToPow2(alignment, kStd140Vec4Alignment);
-      }
-      *stride = alignment;
-      size = (isRowMajor ? rowCount : colCount) * alignment;
-
-      return {alignment, size};
-    }
-  }
-
-  // Rule 9
-  if (const auto *structType = type->getAs<RecordType>()) {
-    // Special case for handling empty structs, whose size is 0 and has no
-    // requirement over alignment (thus 1).
-    if (structType->getDecl()->field_empty())
-      return {1, 0};
-
-    uint32_t maxAlignment = 0;
-    uint32_t structSize = 0;
-
-    for (const auto *field : structType->getDecl()->fields()) {
-      uint32_t memberAlignment = 0, memberSize = 0;
-      std::tie(memberAlignment, memberSize) =
-          getAlignmentAndSize(field->getType(), rule, stride);
-
-      if (rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
-          rule == SpirvLayoutRule::RelaxedGLSLStd430 ||
-          rule == SpirvLayoutRule::FxcCTBuffer) {
-        alignUsingHLSLRelaxedLayout(field->getType(), memberSize,
-                                    memberAlignment, &structSize);
-      } else {
-        structSize = roundToPow2(structSize, memberAlignment);
-      }
-
-      // Reset the current offset to the one specified in the source code
-      // if exists. It's debatable whether we should do sanity check here.
-      // If the developers want manually control the layout, we leave
-      // everything to them.
-      if (const auto *offsetAttr = field->getAttr<VKOffsetAttr>()) {
-        structSize = offsetAttr->getOffset();
-      }
-
-      // The base alignment of the structure is N, where N is the largest
-      // base alignment value of any of its members...
-      maxAlignment = std::max(maxAlignment, memberAlignment);
-      structSize += memberSize;
-    }
-
-    if (rule == SpirvLayoutRule::Scalar) {
-      // A structure has a scalar alignment equal to the largest scalar
-      // alignment of any of its members in VK_EXT_scalar_block_layout.
-      return {maxAlignment, structSize};
-    }
-
-    if (rule == SpirvLayoutRule::GLSLStd140 ||
-        rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
-        rule == SpirvLayoutRule::FxcCTBuffer) {
-      // ... and rounded up to the base alignment of a vec4.
-      maxAlignment = roundToPow2(maxAlignment, kStd140Vec4Alignment);
-    }
-
-    if (rule != SpirvLayoutRule::FxcCTBuffer &&
-        rule != SpirvLayoutRule::FxcSBuffer) {
-      // The base offset of the member following the sub-structure is rounded up
-      // to the next multiple of the base alignment of the structure.
-      structSize = roundToPow2(structSize, maxAlignment);
-    }
-    return {maxAlignment, structSize};
-  }
-
-  // Rule 4, 6, 8, and 10
-  if (const auto *arrayType = astContext.getAsConstantArrayType(type)) {
-    const auto elemCount = arrayType->getSize().getZExtValue();
-    uint32_t alignment = 0, size = 0;
-    std::tie(alignment, size) =
-        getAlignmentAndSize(arrayType->getElementType(), rule, stride);
-
-    if (rule == SpirvLayoutRule::FxcSBuffer ||
-        rule == SpirvLayoutRule::Scalar) {
-      *stride = size;
-      // Use element alignment for fxc structured buffers and
-      // VK_EXT_scalar_block_layout
-      return {alignment, size * elemCount};
-    }
-
-    if (rule == SpirvLayoutRule::GLSLStd140 ||
-        rule == SpirvLayoutRule::RelaxedGLSLStd140 ||
-        rule == SpirvLayoutRule::FxcCTBuffer) {
-      // The base alignment and array stride are set to match the base alignment
-      // of a single array element, according to rules 1, 2, and 3, and rounded
-      // up to the base alignment of a vec4.
-      alignment = roundToPow2(alignment, kStd140Vec4Alignment);
-    }
-    if (rule == SpirvLayoutRule::FxcCTBuffer) {
-      // In fxc cbuffer/tbuffer packing rules, arrays does not affect the data
-      // packing after it. But we still need to make sure paddings are inserted
-      // internally if necessary.
-      *stride = roundToPow2(size, alignment);
-      size += *stride * (elemCount - 1);
-    } else {
-      // Need to round size up considering stride for scalar types
-      size = roundToPow2(size, alignment);
-      *stride = size; // Use size instead of alignment here for Rule 10
-      size *= elemCount;
-      // The base offset of the member following the array is rounded up to the
-      // next multiple of the base alignment.
-      size = roundToPow2(size, alignment);
-    }
-
-    return {alignment, size};
-  }
-
-  emitError("alignment and size calculation for type %0 unimplemented") << type;
-  return {0, 0};
-}
-
-QualType TypeTranslator::desugarType(QualType type) {
-  if (const auto *attrType = type->getAs<AttributedType>()) {
-    switch (auto kind = attrType->getAttrKind()) {
-    case AttributedType::attr_hlsl_row_major:
-    case AttributedType::attr_hlsl_column_major:
-      typeMatMajorAttr = kind;
-      break;
-    default:
-      // Only matrices should apply to typeMatMajorAttr.
-      break;
-    }
-    return desugarType(
-        attrType->getLocallyUnqualifiedSingleStepDesugaredType());
-  }
-
-  if (const auto *typedefType = type->getAs<TypedefType>()) {
-    return desugarType(typedefType->desugar());
-  }
-
-  return type;
-}
-
-} // end namespace spirv
-} // end namespace clang

+ 0 - 1
tools/clang/unittests/SPIRV/CMakeLists.txt

@@ -10,7 +10,6 @@ add_clang_unittest(clang-spirv-tests
   CodeGenSPIRVTest.cpp
   FileTestFixture.cpp
   FileTestUtils.cpp
-  InstBuilderTest.cpp
   SPIRVContextTest.cpp
   SPIRVTestOptions.cpp
   TestMain.cpp

+ 0 - 189
tools/clang/unittests/SPIRV/InstBuilderTest.cpp

@@ -1,189 +0,0 @@
-//===- unittests/SPIRV/InstBuilderTest.cpp ------ InstBuilder tests -------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/SPIRV/InstBuilder.h"
-
-#include "SPIRVTestUtils.h"
-
-namespace {
-
-using namespace clang::spirv;
-
-using ::testing::ContainerEq;
-
-TEST(InstBuilder, InstWoParams) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  expectBuildSuccess(ib.opFunctionEnd().x());
-  // opFunctionEnd takes no parameters.
-  auto expected = constructInst(spv::Op::OpFunctionEnd, {});
-  EXPECT_THAT(result, ContainerEq(expected));
-}
-
-TEST(InstBuilder, InstWFixedNumberOfParams) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // OpMemoryModel takes a fixed number of parameters.
-  expectBuildSuccess(
-      ib.opMemoryModel(spv::AddressingModel::Logical, spv::MemoryModel::GLSL450)
-          .x());
-  auto expected =
-      constructInst(spv::Op::OpMemoryModel,
-                    {static_cast<uint32_t>(spv::AddressingModel::Logical),
-                     static_cast<uint32_t>(spv::MemoryModel::GLSL450)});
-  EXPECT_THAT(result, ContainerEq(expected));
-}
-
-TEST(InstBuilder, InstWAdditionalParams) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // OpDecorate <target-id> ArrayStride needs an additional literal number.
-  expectBuildSuccess(
-      ib.opDecorate(1, spv::Decoration::ArrayStride).literalInteger(42).x());
-  auto expected = constructInst(
-      spv::Op::OpDecorate,
-      {1, static_cast<uint32_t>(spv::Decoration::ArrayStride), 42});
-  EXPECT_THAT(result, ContainerEq(expected));
-}
-
-TEST(InstBuilder, InstWBitEnumParams) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  auto control =
-      spv::LoopControlMask::Unroll | spv::LoopControlMask::DontUnroll;
-  // OpLoopMerge takes an BitEnum parameter.
-  expectBuildSuccess(ib.opLoopMerge(1, 2, control).x());
-  auto expected = constructInst(spv::Op::OpLoopMerge,
-                                {1, 2, static_cast<uint32_t>(control)});
-  EXPECT_THAT(result, ContainerEq(expected));
-}
-
-TEST(InstBuilder, InstWBitEnumParamsNeedAdditionalParams) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Aligned requires an additional literal integer.
-  auto access =
-      spv::MemoryAccessMask::Nontemporal | spv::MemoryAccessMask::Aligned;
-  expectBuildSuccess(
-      ib.opStore(1, 2, llvm::Optional<spv::MemoryAccessMask>(access))
-          .literalInteger(16)
-          .x());
-  auto expected = constructInst(spv::Op::OpStore,
-                                {1, 2, static_cast<uint32_t>(access), 16});
-  EXPECT_THAT(result, ContainerEq(expected));
-}
-
-TEST(InstBuilder, InstMissingAdditionalBuiltin) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Missing the builtIn parameter required by Builtin decoration causes an
-  // error.
-  EXPECT_EQ(InstBuilder::Status::ExpectBuiltIn,
-            ib.opDecorate(1, spv::Decoration::BuiltIn).x());
-}
-
-TEST(InstBuilder, InstMissingAdditionalFPFastMathMode) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Missing the FPFastMathMode parameter required by FPFastMathMode decoration
-  // causes an error.
-  EXPECT_EQ(InstBuilder::Status::ExpectFPFastMathMode,
-            ib.opDecorate(1, spv::Decoration::FPFastMathMode).x());
-}
-
-TEST(InstBuilder, InstMissingAdditionalFPRoundingMode) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Missing the FPRoundingMode parameter required by RoundingMode decoration
-  // causes an error.
-  EXPECT_EQ(InstBuilder::Status::ExpectFPRoundingMode,
-            ib.opDecorate(1, spv::Decoration::FPRoundingMode).x());
-}
-
-TEST(InstBuilder, InstMissingAdditionalFuncParamAttr) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Missing the FunctionParameterAttribute parameter required by
-  // FuncParamAttr decoration causes an error.
-  EXPECT_EQ(InstBuilder::Status::ExpectFunctionParameterAttribute,
-            ib.opDecorate(1, spv::Decoration::FuncParamAttr).x());
-}
-
-TEST(InstBuilder, InstMissingAdditionalIdRef) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Missing the IdRef parameter required by ImageOperands causes an error.
-  EXPECT_EQ(
-      InstBuilder::Status::ExpectIdRef,
-      ib.opImageSampleImplicitLod(1, 2, 3, 4, spv::ImageOperandsMask::Bias)
-          .x());
-}
-
-TEST(InstBuilder, InstMissingAdditionalLinkageType) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Missing the LinkageType parameter required by the LinkageAttributes
-  // decoration causes an error.
-  EXPECT_EQ(InstBuilder::Status::ExpectLinkageType,
-            ib.opDecorate(1, spv::Decoration::LinkageAttributes)
-                .literalString("name")
-                .x());
-}
-
-TEST(InstBuilder, InstMissingAdditionalLiteralInteger) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Missing the literal integer required by ArrayStride causes an error.
-  EXPECT_EQ(InstBuilder::Status::ExpectLiteralInteger,
-            ib.opDecorate(1, spv::Decoration::ArrayStride).x());
-}
-
-TEST(InstBuilder, InstMissingAdditionalLiteralString) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-  // Missing the LiteralString parameter required by the LinkageAttributes
-  // decoration causes an error.
-  EXPECT_EQ(InstBuilder::Status::ExpectLiteralString,
-            ib.opDecorate(1, spv::Decoration::LinkageAttributes).x());
-}
-
-TEST(InstBuilder, NullConsumerResultsInError) {
-  auto ib = InstBuilder(nullptr);
-  EXPECT_EQ(InstBuilder::Status::NullConsumer, ib.opLine(1, 2, 3).x());
-}
-
-TEST(InstBuilder, InstWStringParams) {
-  std::vector<uint32_t> result;
-  auto ib = constructInstBuilder(result);
-
-  expectBuildSuccess(ib.opString(1, "").x());
-  expectBuildSuccess(ib.opString(2, "m").x());
-  expectBuildSuccess(ib.opString(3, "ma").x());
-  expectBuildSuccess(ib.opString(4, "mai").x());
-  expectBuildSuccess(ib.opString(5, "main").x());
-  expectBuildSuccess(ib.opString(6, "mainf").x());
-
-  SimpleInstBuilder sib;
-  uint32_t strWord = 0;
-  sib.inst(spv::Op::OpString, {1, strWord});
-  strWord = 'm';
-  sib.inst(spv::Op::OpString, {2, strWord});
-  strWord |= 'a' << 8;
-  sib.inst(spv::Op::OpString, {3, strWord});
-  strWord |= 'i' << 16;
-  sib.inst(spv::Op::OpString, {4, strWord});
-  strWord |= 'n' << 24;
-  sib.inst(spv::Op::OpString, {5, strWord, 0});
-  sib.inst(spv::Op::OpString, {6, strWord, 'f'});
-
-  EXPECT_THAT(result, ContainerEq(sib.get()));
-}
-// TOOD: Add tests for providing more parameters than needed
-
-} // anonymous namespace