// Copyright (c) 2015 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
// "Materials"), to deal in the Materials without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Materials, and to
// permit persons to whom the Materials are furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Materials.
//
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
//    https://www.khronos.org/registry/
//
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

#include "opcode.h"

#include <assert.h>
#include <string.h>

#include "endian.h"
#include "instruction.h"
#include "libspirv/libspirv.h"
#include "spirv_constant.h"

namespace {

// Descriptions of each opcode.  Each entry describes the format of the
// instruction that follows a particular opcode.
//
// Most fields are initialized statically by including an automatically
// generated file.
// The operandTypes fields are initialized during spvOpcodeInitialize().
//
// TODO(dneto): Some of the macros are quite unreadable.  We could make
// good use of constexpr functions, but some compilers don't support that yet.
spv_opcode_desc_t opcodeTableEntries[] = {
#define EmptyList \
  {}
#define List(...) \
  { __VA_ARGS__ }
#define Capability(X) SPV_CAPABILITY_AS_MASK(SpvCapability##X)
#define Capability2(X, Y) Capability(X) | Capability(Y)
#define SpvCapabilityNone \
  0  // Needed so Capability(None) still expands to valid syntax.
#define Instruction(Name, HasResult, HasType, NumLogicalOperands,        \
                    NumCapabilities, CapabilityRequired, IsVariable,     \
                    LogicalArgsList)                                     \
  {#Name,     SpvOp##Name, (NumCapabilities) ? (CapabilityRequired) : 0, \
   0,         {}, /* Filled in later. Operand list, including            \
                     result id and type id, if needed */                 \
   HasResult, HasType,     LogicalArgsList},
#include "opcode.inc"
#undef EmptyList
#undef List
#undef Capability
#undef Capability2
#undef CapabilityNone
#undef Instruction
};

// Has the opcodeTableEntries table been fully elaborated?
// That is, are the operandTypes fields initialized?
bool opcodeTableInitialized = false;

// Opcode API

// Converts the given operand class enum (from the SPIR-V document generation
// logic) to the operand type required by the parser.  The SPV_OPERAND_TYPE_NONE
// value indicates there is no current operand and no further operands.
// This only applies to logical operands.
spv_operand_type_t convertOperandClassToType(SpvOp opcode,
                                             OperandClass operandClass) {
  // The spec document generator uses OptionalOperandLiteral for several kinds
  // of repeating values.  Our parser needs more specific information about
  // what is being repeated.
  if (operandClass == OperandOptionalLiteral) {
    switch (opcode) {
      case SpvOpLoad:
      case SpvOpStore:
      case SpvOpCopyMemory:
      case SpvOpCopyMemorySized:
        // Expect an optional mask.  When the Aligned bit is set in the mask,
        // we will later add the expectation of a literal number operand.
        return SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS;
      case SpvOpExecutionMode:
        return SPV_OPERAND_TYPE_VARIABLE_EXECUTION_MODE;
      default:
        break;
    }
  } else if (operandClass == OperandVariableLiterals) {
    if (opcode == SpvOpConstant || opcode == SpvOpSpecConstant) {
      // The number type is determined by the type Id operand.
      return SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER;
    }
  }

  switch (operandClass) {
    case OperandNone:
      return SPV_OPERAND_TYPE_NONE;
    case OperandId:
      return SPV_OPERAND_TYPE_ID;
    case OperandOptionalId:
      return SPV_OPERAND_TYPE_OPTIONAL_ID;
    case OperandOptionalImage:
      return SPV_OPERAND_TYPE_OPTIONAL_IMAGE;
    case OperandVariableIds:
      if (opcode == SpvOpSpecConstantOp) {
        // These are the operands to the specialization constant opcode.
        // The assembler and binary parser set up the extra Id and literal
        // arguments when processing the opcode operand.  So don't add
        // an operand type for them here.
        return SPV_OPERAND_TYPE_NONE;
      }
      return SPV_OPERAND_TYPE_VARIABLE_ID;
    // The spec only uses OptionalLiteral for an optional literal number.
    case OperandOptionalLiteral:
      return SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER;
    case OperandOptionalLiteralString:
      return SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING;
    // This is only used for sequences of literal numbers.
    case OperandVariableLiterals:
      return SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER;
    case OperandLiteralNumber:
      if (opcode == SpvOpExtInst) {
        // We use a special operand type for the extension instruction number.
        // For now, we assume there is only one LiteraNumber argument to
        // OpExtInst, and it is the extension instruction argument.
        // See the ExtInst entry in opcode.inc
        // TODO(dneto): Use a function to confirm the assumption, and to verify
        // that the index into the operandClass is 1, as expected.
        return SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER;
      } else if (opcode == SpvOpSpecConstantOp) {
        // Use a special operand type for the opcode operand, so we can
        // use mnemonic names instead of the numbers.  For example, the
        // assembler should accept "IAdd" instead of the numeric value of
        // SpvOpIAdd.
        return SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER;
      }
      return SPV_OPERAND_TYPE_LITERAL_INTEGER;
    case OperandLiteralString:
      return SPV_OPERAND_TYPE_LITERAL_STRING;
    case OperandSource:
      return SPV_OPERAND_TYPE_SOURCE_LANGUAGE;
    case OperandExecutionModel:
      return SPV_OPERAND_TYPE_EXECUTION_MODEL;
    case OperandAddressing:
      return SPV_OPERAND_TYPE_ADDRESSING_MODEL;
    case OperandMemory:
      return SPV_OPERAND_TYPE_MEMORY_MODEL;
    case OperandExecutionMode:
      return SPV_OPERAND_TYPE_EXECUTION_MODE;
    case OperandStorage:
      return SPV_OPERAND_TYPE_STORAGE_CLASS;
    case OperandDimensionality:
      return SPV_OPERAND_TYPE_DIMENSIONALITY;
    case OperandSamplerAddressingMode:
      return SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE;
    case OperandSamplerFilterMode:
      return SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE;
    case OperandSamplerImageFormat:
      return SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT;
    case OperandImageChannelOrder:
      // This is only used to describe the value generated by OpImageQueryOrder.
      // It is not used as an operand.
      break;
    case OperandImageChannelDataType:
      // This is only used to describe the value generated by
      // OpImageQueryFormat. It is not used as an operand.
      break;
    case OperandImageOperands:
      // This is not used in opcode.inc. It only exists to generate the
      // corresponding spec section. In parsing, image operands meld into the
      // OperandOptionalImage case.
      break;
    case OperandFPFastMath:
      return SPV_OPERAND_TYPE_FP_FAST_MATH_MODE;
    case OperandFPRoundingMode:
      return SPV_OPERAND_TYPE_FP_ROUNDING_MODE;
    case OperandLinkageType:
      return SPV_OPERAND_TYPE_LINKAGE_TYPE;
    case OperandAccessQualifier:
      return SPV_OPERAND_TYPE_ACCESS_QUALIFIER;
    case OperandFuncParamAttr:
      return SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE;
    case OperandDecoration:
      return SPV_OPERAND_TYPE_DECORATION;
    case OperandBuiltIn:
      return SPV_OPERAND_TYPE_BUILT_IN;
    case OperandSelect:
      return SPV_OPERAND_TYPE_SELECTION_CONTROL;
    case OperandLoop:
      return SPV_OPERAND_TYPE_LOOP_CONTROL;
    case OperandFunction:
      return SPV_OPERAND_TYPE_FUNCTION_CONTROL;
    case OperandMemorySemantics:
      return SPV_OPERAND_TYPE_MEMORY_SEMANTICS;
    case OperandMemoryAccess:
      // This case does not occur in the table for SPIR-V 0.99 Rev 32.
      // We expect that it will become SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS,
      // and we can remove the special casing above for memory operation
      // instructions.
      break;
    case OperandScope:
      return SPV_OPERAND_TYPE_EXECUTION_SCOPE;
    case OperandGroupOperation:
      return SPV_OPERAND_TYPE_GROUP_OPERATION;
    case OperandKernelEnqueueFlags:
      return SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS;
    case OperandKernelProfilingInfo:
      return SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO;
    case OperandCapability:
      return SPV_OPERAND_TYPE_CAPABILITY;

    // Used by GroupMemberDecorate
    case OperandVariableIdLiteral:
      return SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER;

    // Used by Switch
    case OperandVariableLiteralId:
      return SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID;

    // These exceptional cases shouldn't occur.
    case OperandCount:
    default:
      break;
  }
  assert(0 && "Unexpected operand class");
  return SPV_OPERAND_TYPE_NONE;
}

}  // anonymous namespace

// Finish populating the opcodeTableEntries array.
void spvOpcodeTableInitialize() {
  // Compute the operandTypes field for each entry.
  for (auto& opcode : opcodeTableEntries) {
    opcode.numTypes = 0;
    // Type ID always comes first, if present.
    if (opcode.hasType)
      opcode.operandTypes[opcode.numTypes++] = SPV_OPERAND_TYPE_TYPE_ID;
    // Result ID always comes next, if present
    if (opcode.hasResult)
      opcode.operandTypes[opcode.numTypes++] = SPV_OPERAND_TYPE_RESULT_ID;
    const uint16_t maxNumOperands =
        sizeof(opcode.operandTypes) / sizeof(opcode.operandTypes[0]);
    const uint16_t maxNumClasses =
        sizeof(opcode.operandClass) / sizeof(opcode.operandClass[0]);
    for (uint16_t classIndex = 0;
         opcode.numTypes < maxNumOperands && classIndex < maxNumClasses;
         classIndex++) {
      const OperandClass operandClass = opcode.operandClass[classIndex];
      const auto operandType =
          convertOperandClassToType(opcode.opcode, operandClass);
      opcode.operandTypes[opcode.numTypes++] = operandType;
      // The OperandNone value is not explicitly represented in the .inc file.
      // However, it is the zero value, and is created via implicit value
      // initialization.  It converts to SPV_OPERAND_TYPE_NONE.
      // The SPV_OPERAND_TYPE_NONE operand type indicates no current or futher
      // operands.
      if (operandType == SPV_OPERAND_TYPE_NONE) {
        opcode.numTypes--;
        break;
      }
    }

    // We should have written the terminating SPV_OPERAND_TYPE_NONE entry, but
    // also without overflowing.
    assert((opcode.numTypes < maxNumOperands) &&
           "Operand class list is too long.  Expand "
           "spv_opcode_desc_t.operandClass");
  }
  opcodeTableInitialized = true;
}

const char* spvGeneratorStr(uint32_t generator) {
  switch (generator) {
    case SPV_GENERATOR_KHRONOS:
      return "Khronos";
    case SPV_GENERATOR_LUNARG:
      return "LunarG";
    case SPV_GENERATOR_VALVE:
      return "Valve";
    case SPV_GENERATOR_CODEPLAY:
      return "Codeplay Software Ltd.";
    case SPV_GENERATOR_NVIDIA:
      return "NVIDIA";
    case SPV_GENERATOR_ARM:
      return "ARM";
    default:
      return "Unknown";
  }
}

uint32_t spvOpcodeMake(uint16_t wordCount, SpvOp opcode) {
  return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16);
}

void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount, SpvOp* pOpcode) {
  if (pWordCount) {
    *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
  }
  if (pOpcode) {
    *pOpcode = (SpvOp)(0x0000ffff & word);
  }
}

spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable) {
  if (!pInstTable) return SPV_ERROR_INVALID_POINTER;

  static spv_opcode_table_t table = {
      sizeof(opcodeTableEntries) / sizeof(spv_opcode_desc_t),
      opcodeTableEntries};

  // TODO(dneto): Consider thread safety of initialization.
  // That is, ordering effects of the flag vs. the table updates.
  if (!opcodeTableInitialized) spvOpcodeTableInitialize();

  *pInstTable = &table;

  return SPV_SUCCESS;
}

spv_result_t spvOpcodeTableNameLookup(const spv_opcode_table table,
                                      const char* name,
                                      spv_opcode_desc* pEntry) {
  if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
  if (!table) return SPV_ERROR_INVALID_TABLE;

  // TODO: This lookup of the Opcode table is suboptimal! Binary sort would be
  // preferable but the table requires sorting on the Opcode name, but it's
  // static
  // const initialized and matches the order of the spec.
  const size_t nameLength = strlen(name);
  for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
    if (nameLength == strlen(table->entries[opcodeIndex].name) &&
        !strncmp(name, table->entries[opcodeIndex].name, nameLength)) {
      // NOTE: Found out Opcode!
      *pEntry = &table->entries[opcodeIndex];
      return SPV_SUCCESS;
    }
  }

  return SPV_ERROR_INVALID_LOOKUP;
}

spv_result_t spvOpcodeTableValueLookup(const spv_opcode_table table,
                                       const SpvOp opcode,
                                       spv_opcode_desc* pEntry) {
  if (!table) return SPV_ERROR_INVALID_TABLE;
  if (!pEntry) return SPV_ERROR_INVALID_POINTER;

  // TODO: As above this lookup is not optimal.
  for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
    if (opcode == table->entries[opcodeIndex].opcode) {
      // NOTE: Found the Opcode!
      *pEntry = &table->entries[opcodeIndex];
      return SPV_SUCCESS;
    }
  }

  return SPV_ERROR_INVALID_LOOKUP;
}

int32_t spvOpcodeRequiresCapabilities(spv_opcode_desc entry) {
  return entry->capabilities != 0;
}

void spvInstructionCopy(const uint32_t* words, const SpvOp opcode,
                        const uint16_t wordCount, const spv_endianness_t endian,
                        spv_instruction_t* pInst) {
  pInst->opcode = opcode;
  pInst->words.resize(wordCount);
  for (uint16_t wordIndex = 0; wordIndex < wordCount; ++wordIndex) {
    pInst->words[wordIndex] = spvFixWord(words[wordIndex], endian);
    if (!wordIndex) {
      uint16_t thisWordCount;
      SpvOp thisOpcode;
      spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode);
      assert(opcode == thisOpcode && wordCount == thisWordCount &&
             "Endianness failed!");
    }
  }
}

const char* spvOpcodeString(const SpvOp opcode) {
// Use the syntax table so it's sure to be complete.
#define Instruction(Name, ...) \
  case SpvOp##Name:            \
    return #Name;
  switch (opcode) {
#include "opcode.inc"
    default:
      assert(0 && "Unreachable!");
  }
  return "unknown";
#undef Instruction
}

int32_t spvOpcodeIsScalarType(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpTypeInt:
    case SpvOpTypeFloat:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeIsConstant(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpConstantTrue:
    case SpvOpConstantFalse:
    case SpvOpConstant:
    case SpvOpConstantComposite:
    case SpvOpConstantSampler:
    // case SpvOpConstantNull:
    case SpvOpConstantNull:
    case SpvOpSpecConstantTrue:
    case SpvOpSpecConstantFalse:
    case SpvOpSpecConstant:
    case SpvOpSpecConstantComposite:
      // case SpvOpSpecConstantOp:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeIsComposite(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpTypeVector:
    case SpvOpTypeMatrix:
    case SpvOpTypeArray:
    case SpvOpTypeStruct:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeAreTypesEqual(const spv_instruction_t* pTypeInst0,
                               const spv_instruction_t* pTypeInst1) {
  if (pTypeInst0->opcode != pTypeInst1->opcode) return false;
  if (pTypeInst0->words[1] != pTypeInst1->words[1]) return false;
  return true;
}

int32_t spvOpcodeIsPointer(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpVariable:
    case SpvOpAccessChain:
    case SpvOpInBoundsAccessChain:
    case SpvOpFunctionParameter:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeIsObject(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpConstantTrue:
    case SpvOpConstantFalse:
    case SpvOpConstant:
    case SpvOpConstantComposite:
    // TODO: case SpvOpConstantSampler:
    case SpvOpConstantNull:
    case SpvOpSpecConstantTrue:
    case SpvOpSpecConstantFalse:
    case SpvOpSpecConstant:
    case SpvOpSpecConstantComposite:
    // TODO: case SpvOpSpecConstantOp:
    case SpvOpVariable:
    case SpvOpAccessChain:
    case SpvOpInBoundsAccessChain:
    case SpvOpConvertFToU:
    case SpvOpConvertFToS:
    case SpvOpConvertSToF:
    case SpvOpConvertUToF:
    case SpvOpUConvert:
    case SpvOpSConvert:
    case SpvOpFConvert:
    case SpvOpConvertPtrToU:
    // TODO: case SpvOpConvertUToPtr:
    case SpvOpPtrCastToGeneric:
    // TODO: case SpvOpGenericCastToPtr:
    case SpvOpBitcast:
    // TODO: case SpvOpGenericCastToPtrExplicit:
    case SpvOpSatConvertSToU:
    case SpvOpSatConvertUToS:
    case SpvOpVectorExtractDynamic:
    case SpvOpCompositeConstruct:
    case SpvOpCompositeExtract:
    case SpvOpCopyObject:
    case SpvOpTranspose:
    case SpvOpSNegate:
    case SpvOpFNegate:
    case SpvOpNot:
    case SpvOpIAdd:
    case SpvOpFAdd:
    case SpvOpISub:
    case SpvOpFSub:
    case SpvOpIMul:
    case SpvOpFMul:
    case SpvOpUDiv:
    case SpvOpSDiv:
    case SpvOpFDiv:
    case SpvOpUMod:
    case SpvOpSRem:
    case SpvOpSMod:
    case SpvOpVectorTimesScalar:
    case SpvOpMatrixTimesScalar:
    case SpvOpVectorTimesMatrix:
    case SpvOpMatrixTimesVector:
    case SpvOpMatrixTimesMatrix:
    case SpvOpOuterProduct:
    case SpvOpDot:
    case SpvOpShiftRightLogical:
    case SpvOpShiftRightArithmetic:
    case SpvOpShiftLeftLogical:
    case SpvOpBitwiseOr:
    case SpvOpBitwiseXor:
    case SpvOpBitwiseAnd:
    case SpvOpAny:
    case SpvOpAll:
    case SpvOpIsNan:
    case SpvOpIsInf:
    case SpvOpIsFinite:
    case SpvOpIsNormal:
    case SpvOpSignBitSet:
    case SpvOpLessOrGreater:
    case SpvOpOrdered:
    case SpvOpUnordered:
    case SpvOpLogicalOr:
    case SpvOpLogicalAnd:
    case SpvOpSelect:
    case SpvOpIEqual:
    case SpvOpFOrdEqual:
    case SpvOpFUnordEqual:
    case SpvOpINotEqual:
    case SpvOpFOrdNotEqual:
    case SpvOpFUnordNotEqual:
    case SpvOpULessThan:
    case SpvOpSLessThan:
    case SpvOpFOrdLessThan:
    case SpvOpFUnordLessThan:
    case SpvOpUGreaterThan:
    case SpvOpSGreaterThan:
    case SpvOpFOrdGreaterThan:
    case SpvOpFUnordGreaterThan:
    case SpvOpULessThanEqual:
    case SpvOpSLessThanEqual:
    case SpvOpFOrdLessThanEqual:
    case SpvOpFUnordLessThanEqual:
    case SpvOpUGreaterThanEqual:
    case SpvOpSGreaterThanEqual:
    case SpvOpFOrdGreaterThanEqual:
    case SpvOpFUnordGreaterThanEqual:
    case SpvOpDPdx:
    case SpvOpDPdy:
    case SpvOpFwidth:
    case SpvOpDPdxFine:
    case SpvOpDPdyFine:
    case SpvOpFwidthFine:
    case SpvOpDPdxCoarse:
    case SpvOpDPdyCoarse:
    case SpvOpFwidthCoarse:
    case SpvOpReturnValue:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeIsBasicTypeNullable(SpvOp opcode) {
  switch (opcode) {
    case SpvOpTypeBool:
    case SpvOpTypeInt:
    case SpvOpTypeFloat:
    case SpvOpTypePointer:
    case SpvOpTypeEvent:
    case SpvOpTypeDeviceEvent:
    case SpvOpTypeReserveId:
    case SpvOpTypeQueue:
      return true;
    default:
      return false;
  }
}

int32_t spvInstructionIsInBasicBlock(const spv_instruction_t* pFirstInst,
                                     const spv_instruction_t* pInst) {
  while (pFirstInst != pInst) {
    if (SpvOpFunction == pInst->opcode) break;
    pInst--;
  }
  if (SpvOpFunction != pInst->opcode) return false;
  return true;
}

int32_t spvOpcodeIsValue(SpvOp opcode) {
  if (spvOpcodeIsPointer(opcode)) return true;
  if (spvOpcodeIsConstant(opcode)) return true;
  switch (opcode) {
    case SpvOpLoad:
      // TODO: Other Opcode's resulting in a value
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeGeneratesType(SpvOp op) {
  switch (op) {
    case SpvOpTypeVoid:
    case SpvOpTypeBool:
    case SpvOpTypeInt:
    case SpvOpTypeFloat:
    case SpvOpTypeVector:
    case SpvOpTypeMatrix:
    case SpvOpTypeImage:
    case SpvOpTypeSampler:
    case SpvOpTypeSampledImage:
    case SpvOpTypeArray:
    case SpvOpTypeRuntimeArray:
    case SpvOpTypeStruct:
    case SpvOpTypeOpaque:
    case SpvOpTypePointer:
    case SpvOpTypeFunction:
    case SpvOpTypeEvent:
    case SpvOpTypeDeviceEvent:
    case SpvOpTypeReserveId:
    case SpvOpTypeQueue:
    case SpvOpTypePipe:
      return true;
    default:
      // In particular, OpTypeForwardPointer does not generate a type,
      // but declares a storage class for a pointer type generated
      // by a different instruction.
      break;
  }
  return 0;
}
