// Copyright 2020 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/tint/lang/spirv/reader/ast_parser/ast_parser.h"

#include <algorithm>
#include <limits>
#include <locale>
#include <utility>

#include "source/opt/build_module.h"
#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/core/type/depth_texture.h"
#include "src/tint/lang/core/type/multisampled_texture.h"
#include "src/tint/lang/core/type/sampled_texture.h"
#include "src/tint/lang/core/type/texture_dimension.h"
#include "src/tint/lang/spirv/reader/ast_parser/function.h"
#include "src/tint/lang/wgsl/ast/disable_validation_attribute.h"
#include "src/tint/lang/wgsl/ast/id_attribute.h"
#include "src/tint/lang/wgsl/ast/interpolate_attribute.h"
#include "src/tint/lang/wgsl/ast/unary_op_expression.h"
#include "src/tint/lang/wgsl/resolver/resolve.h"
#include "src/tint/utils/containers/unique_vector.h"
#include "src/tint/utils/rtti/switch.h"

using namespace tint::core::fluent_types;  // NOLINT

namespace tint::spirv::reader::ast_parser {
namespace {

// Input SPIR-V needs only to conform to Vulkan 1.1 requirements.
// The combination of the SPIR-V reader and the semantics of WGSL
// tighten up the code so that the output of the SPIR-V *writer*
// will satisfy SPV_ENV_WEBGPU_0 validation.
const spv_target_env kInputEnv = SPV_ENV_VULKAN_1_1;

/// @param inst a SPIR-V instruction
/// @returns Returns the opcode for an instruciton
inline spv::Op opcode(const spvtools::opt::Instruction& inst) {
    return inst.opcode();
}
/// @param inst a SPIR-V instruction pointer
/// @returns Returns the opcode for an instruciton
inline spv::Op opcode(const spvtools::opt::Instruction* inst) {
    return inst->opcode();
}

// A FunctionTraverser is used to compute an ordering of functions in the
// module such that callees precede callers.
class FunctionTraverser {
  public:
    explicit FunctionTraverser(const spvtools::opt::Module& module) : module_(module) {}

    // @returns the functions in the modules such that callees precede callers.
    std::vector<const spvtools::opt::Function*> TopologicallyOrderedFunctions() {
        visited_.clear();
        ordered_.clear();
        id_to_func_.clear();
        for (const auto& f : module_) {
            id_to_func_[f.result_id()] = &f;
        }
        for (const auto& f : module_) {
            Visit(f);
        }
        return ordered_;
    }

  private:
    void Visit(const spvtools::opt::Function& f) {
        if (visited_.count(&f)) {
            return;
        }
        visited_.insert(&f);
        for (const auto& bb : f) {
            for (const auto& inst : bb) {
                if (opcode(inst) != spv::Op::OpFunctionCall) {
                    continue;
                }
                const auto* callee = id_to_func_[inst.GetSingleWordInOperand(0)];
                if (callee) {
                    Visit(*callee);
                }
            }
        }
        ordered_.push_back(&f);
    }

    const spvtools::opt::Module& module_;
    std::unordered_set<const spvtools::opt::Function*> visited_;
    std::unordered_map<uint32_t, const spvtools::opt::Function*> id_to_func_;
    std::vector<const spvtools::opt::Function*> ordered_;
};

// Returns true if the opcode operates as if its operands are signed integral.
bool AssumesSignedOperands(spv::Op opcode) {
    switch (opcode) {
        case spv::Op::OpSNegate:
        case spv::Op::OpSDiv:
        case spv::Op::OpSRem:
        case spv::Op::OpSMod:
        case spv::Op::OpSLessThan:
        case spv::Op::OpSLessThanEqual:
        case spv::Op::OpSGreaterThan:
        case spv::Op::OpSGreaterThanEqual:
        case spv::Op::OpConvertSToF:
            return true;
        default:
            break;
    }
    return false;
}

// Returns true if the GLSL extended instruction expects operands to be signed.
// @param extended_opcode GLSL.std.450 opcode
// @returns true if all operands must be signed integral type
bool AssumesSignedOperands(GLSLstd450 extended_opcode) {
    switch (extended_opcode) {
        case GLSLstd450SAbs:
        case GLSLstd450SSign:
        case GLSLstd450SMin:
        case GLSLstd450SMax:
        case GLSLstd450SClamp:
        case GLSLstd450FindSMsb:
            return true;
        default:
            break;
    }
    return false;
}

// Returns true if the opcode operates as if its operands are unsigned integral.
bool AssumesUnsignedOperands(spv::Op opcode) {
    switch (opcode) {
        case spv::Op::OpUDiv:
        case spv::Op::OpUMod:
        case spv::Op::OpULessThan:
        case spv::Op::OpULessThanEqual:
        case spv::Op::OpUGreaterThan:
        case spv::Op::OpUGreaterThanEqual:
        case spv::Op::OpConvertUToF:
            return true;
        default:
            break;
    }
    return false;
}

// Returns true if the GLSL extended instruction expects operands to be
// unsigned.
// @param extended_opcode GLSL.std.450 opcode
// @returns true if all operands must be unsigned integral type
bool AssumesUnsignedOperands(GLSLstd450 extended_opcode) {
    switch (extended_opcode) {
        case GLSLstd450UMin:
        case GLSLstd450UMax:
        case GLSLstd450UClamp:
        case GLSLstd450FindUMsb:
            return true;
        default:
            break;
    }
    return false;
}

// Returns true if the corresponding WGSL operation requires
// the signedness of the second operand to match the signedness of the
// first operand, and it's not one of the OpU* or OpS* instructions.
// (Those are handled via MakeOperand.)
bool AssumesSecondOperandSignednessMatchesFirstOperand(spv::Op opcode) {
    switch (opcode) {
        // All the OpI* integer binary operations.
        case spv::Op::OpIAdd:
        case spv::Op::OpISub:
        case spv::Op::OpIMul:
        case spv::Op::OpIEqual:
        case spv::Op::OpINotEqual:
        // All the bitwise integer binary operations.
        case spv::Op::OpBitwiseAnd:
        case spv::Op::OpBitwiseOr:
        case spv::Op::OpBitwiseXor:
            return true;
        default:
            break;
    }
    return false;
}

// Returns true if the corresponding WGSL operation requires
// the signedness of the result to match the signedness of the first operand.
bool AssumesResultSignednessMatchesFirstOperand(spv::Op opcode) {
    switch (opcode) {
        case spv::Op::OpNot:
        case spv::Op::OpSNegate:
        case spv::Op::OpBitCount:
        case spv::Op::OpBitReverse:
        case spv::Op::OpSDiv:
        case spv::Op::OpSMod:
        case spv::Op::OpSRem:
        case spv::Op::OpIAdd:
        case spv::Op::OpISub:
        case spv::Op::OpIMul:
        case spv::Op::OpBitwiseAnd:
        case spv::Op::OpBitwiseOr:
        case spv::Op::OpBitwiseXor:
        case spv::Op::OpShiftLeftLogical:
        case spv::Op::OpShiftRightLogical:
        case spv::Op::OpShiftRightArithmetic:
            return true;
        default:
            break;
    }
    return false;
}

// Returns true if the extended instruction requires the signedness of the
// result to match the signedness of the first operand to the operation.
// @param extended_opcode GLSL.std.450 opcode
// @returns true if the result type must match the first operand type.
bool AssumesResultSignednessMatchesFirstOperand(GLSLstd450 extended_opcode) {
    switch (extended_opcode) {
        case GLSLstd450SAbs:
        case GLSLstd450SSign:
        case GLSLstd450SMin:
        case GLSLstd450SMax:
        case GLSLstd450SClamp:
        case GLSLstd450UMin:
        case GLSLstd450UMax:
        case GLSLstd450UClamp:
        case GLSLstd450FindILsb:
        case GLSLstd450FindSMsb:
        case GLSLstd450FindUMsb:
            return true;
        default:
            break;
    }
    return false;
}

// @param a SPIR-V decoration
// @return true when the given decoration is a pipeline decoration other than a
// bulitin variable.
bool IsPipelineDecoration(const Decoration& deco) {
    if (deco.size() < 1) {
        return false;
    }
    switch (static_cast<spv::Decoration>(deco[0])) {
        case spv::Decoration::Location:
        case spv::Decoration::Flat:
        case spv::Decoration::NoPerspective:
        case spv::Decoration::Centroid:
        case spv::Decoration::Sample:
            return true;
        default:
            break;
    }
    return false;
}

}  // namespace

TypedExpression::TypedExpression() = default;

TypedExpression::TypedExpression(const TypedExpression&) = default;

TypedExpression& TypedExpression::operator=(const TypedExpression&) = default;

TypedExpression::TypedExpression(const Type* type_in, const ast::Expression* expr_in)
    : type(type_in), expr(expr_in) {}

ASTParser::ASTParser(const std::vector<uint32_t>& spv_binary)
    : spv_binary_(spv_binary),
      fail_stream_(&success_, &errors_),
      namer_(fail_stream_),
      enum_converter_(fail_stream_),
      tools_context_(kInputEnv) {
    // Create a message consumer to propagate error messages from SPIRV-Tools
    // out as our own failures.
    message_consumer_ = [this](spv_message_level_t level, const char* /*source*/,
                               const spv_position_t& position, const char* message) {
        switch (level) {
            // Ignore info and warning message.
            case SPV_MSG_WARNING:
            case SPV_MSG_INFO:
                break;
            // Otherwise, propagate the error.
            default:
                // For binary validation errors, we only have the instruction
                // number.  It's not text, so there is no column number.
                this->Fail() << "line:" << position.index << ": " << message;
        }
    };
}

ASTParser::~ASTParser() = default;

bool ASTParser::Parse() {
    // Set up use of SPIRV-Tools utilities.
    spvtools::SpirvTools spv_tools(kInputEnv);

    // Error messages from SPIRV-Tools are forwarded as failures, including
    // setting |success_| to false.
    spv_tools.SetMessageConsumer(message_consumer_);

    if (!success_) {
        return false;
    }

    // Only consider modules valid for Vulkan 1.0.  On failure, the message
    // consumer will set the error status.
    if (!spv_tools.Validate(spv_binary_)) {
        success_ = false;
        return false;
    }
    if (!BuildInternalModule()) {
        return false;
    }
    if (!ParseInternalModule()) {
        return false;
    }

    return success_;
}

Program ASTParser::Program(bool resolve) {
    // TODO(dneto): Should we clear out spv_binary_ here, to reduce
    // memory usage?
    if (resolve) {
        return tint::resolver::Resolve(builder_);
    } else {
        return tint::Program(std::move(builder_));
    }
}

const Type* ASTParser::ConvertType(uint32_t type_id, PtrAs ptr_as) {
    if (!success_) {
        return nullptr;
    }

    if (type_mgr_ == nullptr) {
        Fail() << "ConvertType called when the internal module has not been built";
        return nullptr;
    }

    auto* spirv_type = type_mgr_->GetType(type_id);
    if (spirv_type == nullptr) {
        Fail() << "ID is not a SPIR-V type: " << type_id;
        return nullptr;
    }

    switch (spirv_type->kind()) {
        case spvtools::opt::analysis::Type::kVoid:
            return ty_.Void();
        case spvtools::opt::analysis::Type::kBool:
            return ty_.Bool();
        case spvtools::opt::analysis::Type::kInteger:
            return ConvertType(spirv_type->AsInteger());
        case spvtools::opt::analysis::Type::kFloat:
            return ConvertType(spirv_type->AsFloat());
        case spvtools::opt::analysis::Type::kVector:
            return ConvertType(spirv_type->AsVector());
        case spvtools::opt::analysis::Type::kMatrix:
            return ConvertType(spirv_type->AsMatrix());
        case spvtools::opt::analysis::Type::kRuntimeArray:
            return ConvertType(type_id, spirv_type->AsRuntimeArray());
        case spvtools::opt::analysis::Type::kArray:
            return ConvertType(type_id, spirv_type->AsArray());
        case spvtools::opt::analysis::Type::kStruct:
            return ConvertStructType(type_id);
        case spvtools::opt::analysis::Type::kPointer:
            return ConvertType(type_id, ptr_as, spirv_type->AsPointer());
        case spvtools::opt::analysis::Type::kFunction:
            // Tint doesn't have a Function type.
            // We need to convert the result type and parameter types.
            // But the SPIR-V defines those before defining the function
            // type.  No further work is required here.
            return nullptr;
        case spvtools::opt::analysis::Type::kSampler:
        case spvtools::opt::analysis::Type::kSampledImage:
        case spvtools::opt::analysis::Type::kImage:
            // Fake it for sampler and texture types.  These are handled in an
            // entirely different way.
            return ty_.Void();
        default:
            break;
    }

    Fail() << "unknown SPIR-V type with ID " << type_id << ": "
           << def_use_mgr_->GetDef(type_id)->PrettyPrint();
    return nullptr;
}

DecorationList ASTParser::GetDecorationsFor(uint32_t id) const {
    DecorationList result;
    const auto& decorations = deco_mgr_->GetDecorationsFor(id, true);
    std::unordered_set<uint32_t> visited;
    for (const auto* inst : decorations) {
        if (opcode(inst) != spv::Op::OpDecorate) {
            continue;
        }
        // Example: OpDecorate %struct_id Block
        // Example: OpDecorate %array_ty ArrayStride 16
        auto decoration_kind = inst->GetSingleWordInOperand(1);
        switch (static_cast<spv::Decoration>(decoration_kind)) {
            // Restrict and RestrictPointer have no effect in graphics APIs.
            case spv::Decoration::Restrict:
            case spv::Decoration::RestrictPointer:
                break;
            default:
                if (visited.emplace(decoration_kind).second) {
                    std::vector<uint32_t> inst_as_words;
                    inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
                    Decoration d(inst_as_words.begin() + 2, inst_as_words.end());
                    result.push_back(d);
                }
                break;
        }
    }
    return result;
}

DecorationList ASTParser::GetDecorationsForMember(uint32_t id, uint32_t member_index) const {
    DecorationList result;
    const auto& decorations = deco_mgr_->GetDecorationsFor(id, true);
    std::unordered_set<uint32_t> visited;
    for (const auto* inst : decorations) {
        // Example: OpMemberDecorate %struct_id 1 Offset 16
        if ((opcode(inst) != spv::Op::OpMemberDecorate) ||
            (inst->GetSingleWordInOperand(1) != member_index)) {
            continue;
        }
        auto decoration_kind = inst->GetSingleWordInOperand(2);
        switch (static_cast<spv::Decoration>(decoration_kind)) {
            // Restrict and RestrictPointer have no effect in graphics APIs.
            case spv::Decoration::Restrict:
            case spv::Decoration::RestrictPointer:
                break;
            default:
                if (visited.emplace(decoration_kind).second) {
                    std::vector<uint32_t> inst_as_words;
                    inst->ToBinaryWithoutAttachedDebugInsts(&inst_as_words);
                    Decoration d(inst_as_words.begin() + 3, inst_as_words.end());
                    result.push_back(d);
                }
        }
    }
    return result;
}

std::string ASTParser::ShowType(uint32_t type_id) {
    if (def_use_mgr_) {
        const auto* type_inst = def_use_mgr_->GetDef(type_id);
        if (type_inst) {
            return type_inst->PrettyPrint();
        }
    }
    return "SPIR-V type " + std::to_string(type_id);
}

Attributes ASTParser::ConvertMemberDecoration(uint32_t struct_type_id,
                                              uint32_t member_index,
                                              const Type* member_ty,
                                              const Decoration& decoration) {
    if (decoration.empty()) {
        Fail() << "malformed SPIR-V decoration: it's empty";
        return {};
    }
    Attributes out;
    switch (static_cast<spv::Decoration>(decoration[0])) {
        case spv::Decoration::Offset: {
            if (decoration.size() != 2) {
                Fail() << "malformed Offset decoration: expected 1 literal operand, has "
                       << decoration.size() - 1 << ": member " << member_index << " of "
                       << ShowType(struct_type_id);
                return {};
            }
            out.Add(builder_.MemberOffset(Source{}, AInt(decoration[1])));
            break;
        }
        case spv::Decoration::NonReadable:       // WGSL doesn't have a member decoration for this.
        case spv::Decoration::NonWritable:       // WGSL doesn't have a member decoration for this.
        case spv::Decoration::ColMajor:          // WGSL only supports column major matrices.
        case spv::Decoration::RelaxedPrecision:  // WGSL doesn't support relaxed precision.
            break;
        case spv::Decoration::RowMajor:
            Fail() << "WGSL does not support row-major matrices: can't "
                      "translate member "
                   << member_index << " of " << ShowType(struct_type_id);
            break;
        case spv::Decoration::MatrixStride: {
            if (decoration.size() != 2) {
                Fail() << "malformed MatrixStride decoration: expected 1 literal operand, has "
                       << decoration.size() - 1 << ": member " << member_index << " of "
                       << ShowType(struct_type_id);
                break;
            }
            uint32_t stride = decoration[1];
            auto* ty = member_ty->UnwrapAlias();
            while (auto* arr = ty->As<Array>()) {
                ty = arr->type->UnwrapAlias();
            }
            auto* mat = ty->As<Matrix>();
            if (!mat) {
                Fail() << "MatrixStride cannot be applied to type " << ty->String();
                break;
            }
            uint32_t natural_stride = (mat->rows == 2) ? 8 : 16;
            if (stride == natural_stride) {
                break;  // Decoration matches the natural stride for the matrix
            }
            if (!member_ty->Is<Matrix>()) {
                Fail() << "custom matrix strides not currently supported on array of matrices";
                break;
            }
            out.Add(create<ast::StrideAttribute>(Source{}, decoration[1]));
            out.Add(builder_.ASTNodes().Create<ast::DisableValidationAttribute>(
                builder_.ID(), builder_.AllocateNodeID(),
                ast::DisabledValidation::kIgnoreStrideAttribute));
            break;
        }
        default: {
            // TODO(dneto): Support the remaining member decorations.
            Fail() << "unhandled member decoration: " << decoration[0] << " on member "
                   << member_index << " of " << ShowType(struct_type_id);
            break;
        }
    }
    return out;
}

bool ASTParser::BuildInternalModule() {
    if (!success_) {
        return false;
    }

    const spv_context& context = tools_context_.CContext();
    ir_context_ = spvtools::BuildModule(context->target_env, context->consumer, spv_binary_.data(),
                                        spv_binary_.size());
    if (!ir_context_) {
        return Fail() << "internal error: couldn't build the internal "
                         "representation of the module";
    }
    module_ = ir_context_->module();
    def_use_mgr_ = ir_context_->get_def_use_mgr();
    constant_mgr_ = ir_context_->get_constant_mgr();
    type_mgr_ = ir_context_->get_type_mgr();
    deco_mgr_ = ir_context_->get_decoration_mgr();

    topologically_ordered_functions_ = FunctionTraverser(*module_).TopologicallyOrderedFunctions();

    return success_;
}

void ASTParser::ResetInternalModule() {
    ir_context_.reset(nullptr);
    module_ = nullptr;
    def_use_mgr_ = nullptr;
    constant_mgr_ = nullptr;
    type_mgr_ = nullptr;
    deco_mgr_ = nullptr;

    glsl_std_450_imports_.clear();
}

bool ASTParser::ParseInternalModule() {
    if (!success_) {
        return false;
    }
    RegisterLineNumbers();
    if (!ParseInternalModuleExceptFunctions()) {
        return false;
    }
    if (!EmitFunctions()) {
        return false;
    }
    return success_;
}

void ASTParser::RegisterLineNumbers() {
    Source::Location instruction_number{};

    // Has there been an OpLine since the last OpNoLine or start of the module?
    bool in_op_line_scope = false;
    // The source location provided by the most recent OpLine instruction.
    Source::Location op_line_source{};
    const bool run_on_debug_insts = true;
    module_->ForEachInst(
        [this, &in_op_line_scope, &op_line_source,
         &instruction_number](const spvtools::opt::Instruction* inst) {
            ++instruction_number.line;
            switch (opcode(inst)) {
                case spv::Op::OpLine:
                    in_op_line_scope = true;
                    // TODO(dneto): This ignores the File ID (operand 0), since the Tint
                    // Source concept doesn't represent that.
                    op_line_source.line = inst->GetSingleWordInOperand(1);
                    op_line_source.column = inst->GetSingleWordInOperand(2);
                    break;
                case spv::Op::OpNoLine:
                    in_op_line_scope = false;
                    break;
                default:
                    break;
            }
            this->inst_source_[inst] = in_op_line_scope ? op_line_source : instruction_number;
        },
        run_on_debug_insts);
}

Source ASTParser::GetSourceForResultIdForTest(uint32_t id) const {
    return GetSourceForInst(def_use_mgr_->GetDef(id));
}

Source ASTParser::GetSourceForInst(const spvtools::opt::Instruction* inst) const {
    auto where = inst_source_.find(inst);
    if (where == inst_source_.end()) {
        return {};
    }
    return Source{where->second};
}

bool ASTParser::ParseInternalModuleExceptFunctions() {
    if (!success_) {
        return false;
    }
    if (!RegisterExtendedInstructionImports()) {
        return false;
    }
    if (!RegisterUserAndStructMemberNames()) {
        return false;
    }
    if (!RegisterWorkgroupSizeBuiltin()) {
        return false;
    }
    if (!RegisterEntryPoints()) {
        return false;
    }
    if (!RegisterHandleUsage()) {
        return false;
    }
    if (!RegisterTypes()) {
        return false;
    }
    if (!RejectInvalidPointerRoots()) {
        return false;
    }
    if (!EmitScalarSpecConstants()) {
        return false;
    }
    if (!EmitModuleScopeVariables()) {
        return false;
    }
    return success_;
}

bool ASTParser::RegisterExtendedInstructionImports() {
    for (const spvtools::opt::Instruction& import : module_->ext_inst_imports()) {
        std::string name(reinterpret_cast<const char*>(import.GetInOperand(0).words.data()));
        // TODO(dneto): Handle other extended instruction sets when needed.
        if (name == "GLSL.std.450") {
            glsl_std_450_imports_.insert(import.result_id());
        } else if (name.find("NonSemantic.") == 0) {
            ignored_imports_.insert(import.result_id());
        } else {
            return Fail() << "Unrecognized extended instruction set: " << name;
        }
    }
    return true;
}

bool ASTParser::IsGlslExtendedInstruction(const spvtools::opt::Instruction& inst) const {
    return (opcode(inst) == spv::Op::OpExtInst) &&
           (glsl_std_450_imports_.count(inst.GetSingleWordInOperand(0)) > 0);
}

bool ASTParser::IsIgnoredExtendedInstruction(const spvtools::opt::Instruction& inst) const {
    return (opcode(inst) == spv::Op::OpExtInst) &&
           (ignored_imports_.count(inst.GetSingleWordInOperand(0)) > 0);
}

bool ASTParser::RegisterUserAndStructMemberNames() {
    if (!success_) {
        return false;
    }
    // Register entry point names. An entry point name is the point of contact
    // between the API and the shader. It has the highest priority for
    // preservation, so register it first.
    for (const spvtools::opt::Instruction& entry_point : module_->entry_points()) {
        const uint32_t function_id = entry_point.GetSingleWordInOperand(1);
        const std::string name = entry_point.GetInOperand(2).AsString();

        // This translator requires the entry point to be a valid WGSL identifier.
        // Allowing otherwise leads to difficulties in that the programmer needs
        // to get a mapping from their original entry point name to the WGSL name,
        // and we don't have a good mechanism for that.
        if (!IsValidIdentifier(name)) {
            return Fail() << "entry point name is not a valid WGSL identifier: " << name;
        }

        // SPIR-V allows a single function to be the implementation for more
        // than one entry point.  In the common case, it's one-to-one, and we should
        // try to name the function after the entry point.  Otherwise, give the
        // function a name automatically derived from the entry point name.
        namer_.SuggestSanitizedName(function_id, name);

        // There is another many-to-one relationship to take care of:  In SPIR-V
        // the same name can be used for multiple entry points, provided they are
        // for different shader stages. Take action now to ensure we can use the
        // entry point name later on, and not have it taken for another identifier
        // by an accidental collision with a derived name made for a different ID.
        if (!namer_.IsRegistered(name)) {
            // The entry point name is "unoccupied" becase an earlier entry point
            // grabbed the slot for the function that implements both entry points.
            // Register this new entry point's name, to avoid accidental collisions
            // with a future generated ID.
            if (!namer_.RegisterWithoutId(name)) {
                return false;
            }
        }
    }

    // Register names from OpName and OpMemberName
    for (const auto& inst : module_->debugs2()) {
        switch (opcode(inst)) {
            case spv::Op::OpName: {
                const auto name = inst.GetInOperand(1).AsString();
                if (!name.empty()) {
                    namer_.SuggestSanitizedName(inst.GetSingleWordInOperand(0), name);
                }
                break;
            }
            case spv::Op::OpMemberName: {
                const auto name = inst.GetInOperand(2).AsString();
                if (!name.empty()) {
                    namer_.SuggestSanitizedMemberName(inst.GetSingleWordInOperand(0),
                                                      inst.GetSingleWordInOperand(1), name);
                }
                break;
            }
            default:
                break;
        }
    }

    // Fill in struct member names, and disambiguate them.
    for (const auto* type_inst : module_->GetTypes()) {
        if (opcode(type_inst) == spv::Op::OpTypeStruct) {
            namer_.ResolveMemberNamesForStruct(type_inst->result_id(), type_inst->NumInOperands());
        }
    }

    return true;
}

bool ASTParser::IsValidIdentifier(const std::string& str) {
    if (str.empty()) {
        return false;
    }
    std::locale c_locale("C");
    if (str[0] == '_') {
        if (str.length() == 1u || str[1] == '_') {
            // https://www.w3.org/TR/WGSL/#identifiers
            // must not be '_' (a single underscore)
            // must not start with two underscores
            return false;
        }
    } else if (!std::isalpha(str[0], c_locale)) {
        return false;
    }
    for (const char& ch : str) {
        if ((ch != '_') && !std::isalnum(ch, c_locale)) {
            return false;
        }
    }
    return true;
}

bool ASTParser::RegisterWorkgroupSizeBuiltin() {
    WorkgroupSizeInfo& info = workgroup_size_builtin_;
    for (const spvtools::opt::Instruction& inst : module_->annotations()) {
        if (opcode(inst) != spv::Op::OpDecorate) {
            continue;
        }
        if (inst.GetSingleWordInOperand(1) != uint32_t(spv::Decoration::BuiltIn)) {
            continue;
        }
        if (inst.GetSingleWordInOperand(2) != uint32_t(spv::BuiltIn::WorkgroupSize)) {
            continue;
        }
        info.id = inst.GetSingleWordInOperand(0);
    }
    if (info.id == 0) {
        return true;
    }
    // Gather the values.
    const spvtools::opt::Instruction* composite_def = def_use_mgr_->GetDef(info.id);
    if (!composite_def) {
        return Fail() << "Invalid WorkgroupSize builtin value";
    }
    // SPIR-V validation checks that the result is a 3-element vector of 32-bit
    // integer scalars (signed or unsigned).  Rely on validation to check the
    // type.  In theory the instruction could be OpConstantNull and still
    // pass validation, but that would be non-sensical.  Be a little more
    // stringent here and check for specific opcodes.  WGSL does not support
    // const-expr yet, so avoid supporting OpSpecConstantOp here.
    // TODO(dneto): See https://github.com/gpuweb/gpuweb/issues/1272 for WGSL
    // const_expr proposals.
    if ((opcode(composite_def) != spv::Op::OpSpecConstantComposite &&
         opcode(composite_def) != spv::Op::OpConstantComposite)) {
        return Fail() << "Invalid WorkgroupSize builtin.  Expected 3-element "
                         "OpSpecConstantComposite or OpConstantComposite:  "
                      << composite_def->PrettyPrint();
    }
    info.type_id = composite_def->type_id();
    // Extract the component type from the vector type.
    info.component_type_id = def_use_mgr_->GetDef(info.type_id)->GetSingleWordInOperand(0);

    /// Sets the ID and value of the index'th member of the composite constant.
    /// Returns false and emits a diagnostic on error.
    auto set_param = [this, composite_def](uint32_t* id_ptr, uint32_t* value_ptr,
                                           int index) -> bool {
        const auto id = composite_def->GetSingleWordInOperand(static_cast<uint32_t>(index));
        const auto* def = def_use_mgr_->GetDef(id);
        if (!def ||
            (opcode(def) != spv::Op::OpSpecConstant && opcode(def) != spv::Op::OpConstant) ||
            (def->NumInOperands() != 1)) {
            return Fail() << "invalid component " << index << " of workgroupsize "
                          << (def ? def->PrettyPrint() : std::string("no definition"));
        }
        *id_ptr = id;
        // Use the default value of a spec constant.
        *value_ptr = def->GetSingleWordInOperand(0);
        return true;
    };

    return set_param(&info.x_id, &info.x_value, 0) && set_param(&info.y_id, &info.y_value, 1) &&
           set_param(&info.z_id, &info.z_value, 2);
}

bool ASTParser::RegisterEntryPoints() {
    // Mapping from entry point ID to GridSize computed from LocalSize
    // decorations.
    std::unordered_map<uint32_t, GridSize> local_size;
    for (const spvtools::opt::Instruction& inst : module_->execution_modes()) {
        auto mode = static_cast<spv::ExecutionMode>(inst.GetSingleWordInOperand(1));
        if (mode == spv::ExecutionMode::LocalSize) {
            if (inst.NumInOperands() != 5) {
                // This won't even get past SPIR-V binary parsing.
                return Fail() << "invalid LocalSize execution mode: " << inst.PrettyPrint();
            }
            uint32_t function_id = inst.GetSingleWordInOperand(0);
            local_size[function_id] =
                GridSize{inst.GetSingleWordInOperand(2), inst.GetSingleWordInOperand(3),
                         inst.GetSingleWordInOperand(4)};
        }
    }

    for (const spvtools::opt::Instruction& entry_point : module_->entry_points()) {
        const auto stage = spv::ExecutionModel(entry_point.GetSingleWordInOperand(0));
        const uint32_t function_id = entry_point.GetSingleWordInOperand(1);

        const std::string ep_name = entry_point.GetOperand(2).AsString();
        if (!IsValidIdentifier(ep_name)) {
            return Fail() << "entry point name is not a valid WGSL identifier: " << ep_name;
        }

        bool owns_inner_implementation = false;
        std::string inner_implementation_name;

        auto where = function_to_ep_info_.find(function_id);
        if (where == function_to_ep_info_.end()) {
            // If this is the first entry point to have function_id as its
            // implementation, then this entry point is responsible for generating
            // the inner implementation.
            owns_inner_implementation = true;
            inner_implementation_name = namer_.MakeDerivedName(ep_name);
        } else {
            // Reuse the inner implementation owned by the first entry point.
            inner_implementation_name = where->second[0].inner_name;
        }
        TINT_ASSERT(!inner_implementation_name.empty());
        TINT_ASSERT(ep_name != inner_implementation_name);

        UniqueVector<uint32_t, 8> inputs;
        UniqueVector<uint32_t, 8> outputs;
        for (unsigned iarg = 3; iarg < entry_point.NumInOperands(); iarg++) {
            const uint32_t var_id = entry_point.GetSingleWordInOperand(iarg);
            if (const auto* var_inst = def_use_mgr_->GetDef(var_id)) {
                switch (spv::StorageClass(var_inst->GetSingleWordInOperand(0))) {
                    case spv::StorageClass::Input:
                        inputs.Add(var_id);
                        break;
                    case spv::StorageClass::Output:
                        outputs.Add(var_id);
                        break;
                    default:
                        break;
                }
            }
        }
        // Save the lists, in ID-sorted order.
        tint::Vector<uint32_t, 8> sorted_inputs(inputs);
        std::sort(sorted_inputs.begin(), sorted_inputs.end());
        tint::Vector<uint32_t, 8> sorted_outputs(outputs);
        std::sort(sorted_outputs.begin(), sorted_outputs.end());

        const auto ast_stage = enum_converter_.ToPipelineStage(stage);
        GridSize wgsize;
        if (ast_stage == ast::PipelineStage::kCompute) {
            if (workgroup_size_builtin_.id) {
                // Store the default values.
                // WGSL allows specializing these, but this code doesn't support that
                // yet. https://github.com/gpuweb/gpuweb/issues/1442
                wgsize = GridSize{workgroup_size_builtin_.x_value, workgroup_size_builtin_.y_value,
                                  workgroup_size_builtin_.z_value};
            } else {
                // Use the LocalSize execution mode.  This is the second choice.
                auto where_local_size = local_size.find(function_id);
                if (where_local_size != local_size.end()) {
                    wgsize = where_local_size->second;
                }
            }
        }
        function_to_ep_info_[function_id].emplace_back(
            ep_name, ast_stage, owns_inner_implementation, inner_implementation_name,
            std::move(sorted_inputs), std::move(sorted_outputs), wgsize);
    }

    // The enum conversion could have failed, so return the existing status value.
    return success_;
}

const Type* ASTParser::ConvertType(const spvtools::opt::analysis::Integer* int_ty) {
    if (int_ty->width() == 32) {
        return int_ty->IsSigned() ? static_cast<const Type*>(ty_.I32())
                                  : static_cast<const Type*>(ty_.U32());
    }
    Fail() << "unhandled integer width: " << int_ty->width();
    return nullptr;
}

const Type* ASTParser::ConvertType(const spvtools::opt::analysis::Float* float_ty) {
    if (float_ty->width() == 32) {
        return ty_.F32();
    }
    Fail() << "unhandled float width: " << float_ty->width();
    return nullptr;
}

const Type* ASTParser::ConvertType(const spvtools::opt::analysis::Vector* vec_ty) {
    const auto num_elem = vec_ty->element_count();
    auto* ast_elem_ty = ConvertType(type_mgr_->GetId(vec_ty->element_type()));
    if (ast_elem_ty == nullptr) {
        return ast_elem_ty;
    }
    return ty_.Vector(ast_elem_ty, num_elem);
}

const Type* ASTParser::ConvertType(const spvtools::opt::analysis::Matrix* mat_ty) {
    const auto* vec_ty = mat_ty->element_type()->AsVector();
    const auto* scalar_ty = vec_ty->element_type();
    const auto num_rows = vec_ty->element_count();
    const auto num_columns = mat_ty->element_count();
    auto* ast_scalar_ty = ConvertType(type_mgr_->GetId(scalar_ty));
    if (ast_scalar_ty == nullptr) {
        return nullptr;
    }
    return ty_.Matrix(ast_scalar_ty, num_columns, num_rows);
}

const Type* ASTParser::ConvertType(uint32_t type_id,
                                   const spvtools::opt::analysis::RuntimeArray* rtarr_ty) {
    auto* ast_elem_ty = ConvertType(type_mgr_->GetId(rtarr_ty->element_type()));
    if (ast_elem_ty == nullptr) {
        return nullptr;
    }
    uint32_t array_stride = 0;
    if (!ParseArrayDecorations(rtarr_ty, &array_stride)) {
        return nullptr;
    }
    const Type* result = ty_.Array(ast_elem_ty, 0, array_stride);
    return MaybeGenerateAlias(type_id, rtarr_ty, result);
}

const Type* ASTParser::ConvertType(uint32_t type_id, const spvtools::opt::analysis::Array* arr_ty) {
    // Get the element type. The SPIR-V optimizer's types representation
    // deduplicates array types that have the same parameterization.
    // We don't want that deduplication, so get the element type from
    // the SPIR-V type directly.
    const auto* inst = def_use_mgr_->GetDef(type_id);
    const auto elem_type_id = inst->GetSingleWordInOperand(0);
    auto* ast_elem_ty = ConvertType(elem_type_id);
    if (ast_elem_ty == nullptr) {
        return nullptr;
    }
    // Get the length.
    const auto& length_info = arr_ty->length_info();
    if (length_info.words.empty()) {
        // The internal representation is invalid. The discriminant vector
        // is mal-formed.
        Fail() << "internal error: Array length info is invalid";
        return nullptr;
    }
    if (length_info.words[0] != spvtools::opt::analysis::Array::LengthInfo::kConstant) {
        Fail() << "Array type " << type_mgr_->GetId(arr_ty)
               << " length is a specialization constant";
        return nullptr;
    }
    const auto* constant = constant_mgr_->FindDeclaredConstant(length_info.id);
    if (constant == nullptr) {
        Fail() << "Array type " << type_mgr_->GetId(arr_ty) << " length ID " << length_info.id
               << " does not name an OpConstant";
        return nullptr;
    }
    const uint64_t num_elem = constant->GetZeroExtendedValue();
    // For now, limit to only 32bits.
    if (num_elem > std::numeric_limits<uint32_t>::max()) {
        Fail() << "Array type " << type_mgr_->GetId(arr_ty)
               << " has too many elements (more than can fit in 32 bits): " << num_elem;
        return nullptr;
    }
    uint32_t array_stride = 0;
    if (!ParseArrayDecorations(arr_ty, &array_stride)) {
        return nullptr;
    }
    if (remap_buffer_block_type_.count(elem_type_id)) {
        remap_buffer_block_type_.insert(type_mgr_->GetId(arr_ty));
    }
    const Type* result = ty_.Array(ast_elem_ty, static_cast<uint32_t>(num_elem), array_stride);
    return MaybeGenerateAlias(type_id, arr_ty, result);
}

bool ASTParser::ParseArrayDecorations(const spvtools::opt::analysis::Type* spv_type,
                                      uint32_t* array_stride) {
    *array_stride = 0;  // Implicit stride case.
    const auto type_id = type_mgr_->GetId(spv_type);
    for (auto& decoration : this->GetDecorationsFor(type_id)) {
        if (decoration.size() == 2 && decoration[0] == uint32_t(spv::Decoration::ArrayStride)) {
            const auto stride = decoration[1];
            if (stride == 0) {
                return Fail() << "invalid array type ID " << type_id << ": ArrayStride can't be 0";
            }
            *array_stride = stride;
        } else {
            return Fail() << "invalid array type ID " << type_id << ": unknown decoration "
                          << (decoration.empty() ? "(empty)" : std::to_string(decoration[0]))
                          << " with " << decoration.size() << " total words";
        }
    }
    return true;
}

const Type* ASTParser::ConvertStructType(uint32_t type_id) {
    // Compute the struct decoration.
    auto struct_decorations = this->GetDecorationsFor(type_id);
    if (struct_decorations.size() == 1) {
        const auto decoration = struct_decorations[0][0];
        if (decoration == uint32_t(spv::Decoration::BufferBlock)) {
            remap_buffer_block_type_.insert(type_id);
        } else if (decoration != uint32_t(spv::Decoration::Block)) {
            Fail() << "struct with ID " << type_id
                   << " has unrecognized decoration: " << int(decoration);
        }
    } else if (struct_decorations.size() > 1) {
        Fail() << "can't handle a struct with more than one decoration: struct " << type_id
               << " has " << struct_decorations.size();
        return nullptr;
    }

    // The SPIR-V optimizer's types representation deduplicates types. We don't want that
    // deduplication, so get the member types from the SPIR-V instruction directly.
    const auto* inst = def_use_mgr_->GetDef(type_id);
    auto num_members = inst->NumOperands() - 1;
    if (num_members == 0) {
        Fail() << "WGSL does not support empty structures. can't convert type: "
               << def_use_mgr_->GetDef(type_id)->PrettyPrint();
        return nullptr;
    }

    // Compute members
    tint::Vector<const ast::StructMember*, 8> ast_members;
    TypeList ast_member_types;
    unsigned num_non_writable_members = 0;
    for (uint32_t member_index = 0; member_index < num_members; ++member_index) {
        const auto member_type_id = inst->GetOperand(member_index + 1).AsId();
        auto* ast_member_ty = ConvertType(member_type_id);
        if (ast_member_ty == nullptr) {
            // Already emitted diagnostics.
            return nullptr;
        }

        ast_member_types.emplace_back(ast_member_ty);

        // Scan member for built-in decorations. Some vertex built-ins are handled
        // specially, and should not generate a structure member.
        bool create_ast_member = true;
        for (auto& decoration : GetDecorationsForMember(type_id, member_index)) {
            if (decoration.empty()) {
                Fail() << "malformed SPIR-V decoration: it's empty";
                return nullptr;
            }
            if ((decoration[0] == uint32_t(spv::Decoration::BuiltIn)) && (decoration.size() > 1)) {
                switch (static_cast<spv::BuiltIn>(decoration[1])) {
                    case spv::BuiltIn::Position:
                        // Record this built-in variable specially.
                        builtin_position_.struct_type_id = type_id;
                        builtin_position_.position_member_index = member_index;
                        builtin_position_.position_member_type_id = member_type_id;
                        create_ast_member = false;  // Not part of the WGSL structure.
                        break;
                    case spv::BuiltIn::PointSize:  // not supported in WGSL, but ignore
                        builtin_position_.pointsize_member_index = member_index;
                        create_ast_member = false;  // Not part of the WGSL structure.
                        break;
                    case spv::BuiltIn::ClipDistance:  // not supported in WGSL
                    case spv::BuiltIn::CullDistance:  // not supported in WGSL
                        create_ast_member = false;    // Not part of the WGSL structure.
                        break;
                    default:
                        Fail() << "unrecognized builtin " << decoration[1];
                        return nullptr;
                }
            }
        }
        if (!create_ast_member) {
            // This member is decorated as a built-in, and is handled specially.
            continue;
        }

        bool is_non_writable = false;
        Attributes ast_member_decorations;
        for (auto& decoration : GetDecorationsForMember(type_id, member_index)) {
            if (IsPipelineDecoration(decoration)) {
                // IO decorations are handled when emitting the entry point.
                continue;
            } else if (decoration[0] == uint32_t(spv::Decoration::NonWritable)) {
                // WGSL doesn't represent individual members as non-writable. Instead,
                // apply the ReadOnly access control to the containing struct if all
                // the members are non-writable.
                is_non_writable = true;
            } else {
                auto attrs =
                    ConvertMemberDecoration(type_id, member_index, ast_member_ty, decoration);
                ast_member_decorations.Add(attrs);
                if (!success_) {
                    return nullptr;
                }
            }
        }

        if (is_non_writable) {
            // Count a member as non-writable only once, no matter how many
            // NonWritable decorations are applied to it.
            ++num_non_writable_members;
        }
        const auto member_name = namer_.GetMemberName(type_id, member_index);
        auto* ast_struct_member =
            builder_.Member(Source{}, member_name, ast_member_ty->Build(builder_),
                            std::move(ast_member_decorations.list));
        ast_members.Push(ast_struct_member);
    }

    if (ast_members.IsEmpty()) {
        // All members were likely built-ins. Don't generate an empty AST structure.
        return nullptr;
    }

    namer_.SuggestSanitizedName(type_id, "S");

    auto name = namer_.GetName(type_id);

    // Now make the struct.
    auto sym = builder_.Symbols().Register(name);
    auto* ast_struct =
        create<ast::Struct>(Source{}, builder_.Ident(sym), std::move(ast_members), tint::Empty);
    if (num_non_writable_members == num_members) {
        read_only_struct_types_.insert(ast_struct->name->symbol);
    }
    AddTypeDecl(sym, ast_struct);
    const auto* result = ty_.Struct(sym, std::move(ast_member_types));
    struct_id_for_symbol_[sym] = type_id;
    return result;
}

void ASTParser::AddTypeDecl(Symbol name, const ast::TypeDecl* decl) {
    auto iter = declared_types_.insert(name);
    if (iter.second) {
        builder_.AST().AddTypeDecl(decl);
    }
}

const Type* ASTParser::ConvertType(uint32_t type_id,
                                   PtrAs ptr_as,
                                   const spvtools::opt::analysis::Pointer*) {
    const auto* inst = def_use_mgr_->GetDef(type_id);
    const auto pointee_type_id = inst->GetSingleWordInOperand(1);
    const auto storage_class = spv::StorageClass(inst->GetSingleWordInOperand(0));

    if (pointee_type_id == builtin_position_.struct_type_id) {
        builtin_position_.pointer_type_id = type_id;
        // Pipeline IO builtins map to private variables.
        builtin_position_.storage_class = spv::StorageClass::Private;
        return nullptr;
    }
    auto* ast_elem_ty = ConvertType(pointee_type_id, PtrAs::Ptr);
    if (ast_elem_ty == nullptr) {
        Fail() << "SPIR-V pointer type with ID " << type_id << " has invalid pointee type "
               << pointee_type_id;
        return nullptr;
    }

    auto ast_address_space = enum_converter_.ToAddressSpace(storage_class);
    if (ast_address_space == core::AddressSpace::kUniform &&
        remap_buffer_block_type_.count(pointee_type_id)) {
        ast_address_space = core::AddressSpace::kStorage;
        remap_buffer_block_type_.insert(type_id);
    }

    // Pipeline input and output variables map to private variables.
    if (ast_address_space == core::AddressSpace::kIn ||
        ast_address_space == core::AddressSpace::kOut) {
        ast_address_space = core::AddressSpace::kPrivate;
    }
    switch (ptr_as) {
        case PtrAs::Ref:
            return ty_.Reference(ast_address_space, ast_elem_ty);
        case PtrAs::Ptr:
            return ty_.Pointer(ast_address_space, ast_elem_ty);
    }
    Fail() << "invalid value for ptr_as: " << static_cast<int>(ptr_as);
    return nullptr;
}

bool ASTParser::RegisterTypes() {
    if (!success_) {
        return false;
    }

    // First record the structure types that should have a `block` decoration
    // in WGSL. In particular, exclude user-defined pipeline IO in a
    // block-decorated struct.
    for (const auto& type_or_value : module_->types_values()) {
        if (opcode(type_or_value) != spv::Op::OpVariable) {
            continue;
        }
        const auto& var = type_or_value;
        const auto spirv_storage_class = spv::StorageClass(var.GetSingleWordInOperand(0));
        if ((spirv_storage_class != spv::StorageClass::StorageBuffer) &&
            (spirv_storage_class != spv::StorageClass::Uniform)) {
            continue;
        }
        const auto* ptr_type = def_use_mgr_->GetDef(var.type_id());
        if (opcode(ptr_type) != spv::Op::OpTypePointer) {
            return Fail() << "OpVariable type expected to be a pointer: " << var.PrettyPrint();
        }
        const auto* store_type = def_use_mgr_->GetDef(ptr_type->GetSingleWordInOperand(1));
        if (opcode(store_type) == spv::Op::OpTypeStruct) {
            struct_types_for_buffers_.insert(store_type->result_id());
        } else {
            Fail() << "WGSL does not support arrays of buffers: " << var.PrettyPrint();
        }
    }

    // Now convert each type.
    for (auto& type_or_const : module_->types_values()) {
        const auto* type = type_mgr_->GetType(type_or_const.result_id());
        if (type == nullptr) {
            continue;
        }
        ConvertType(type_or_const.result_id());
    }
    // Manufacture a type for the gl_Position variable if we have to.
    if ((builtin_position_.struct_type_id != 0) &&
        (builtin_position_.position_member_pointer_type_id == 0)) {
        builtin_position_.position_member_pointer_type_id = type_mgr_->FindPointerToType(
            builtin_position_.position_member_type_id, builtin_position_.storage_class);
        ConvertType(builtin_position_.position_member_pointer_type_id);
    }
    return success_;
}

bool ASTParser::RejectInvalidPointerRoots() {
    if (!success_) {
        return false;
    }
    for (auto& inst : module_->types_values()) {
        if (const auto* result_type = type_mgr_->GetType(inst.type_id())) {
            if (result_type->AsPointer()) {
                switch (opcode(inst)) {
                    case spv::Op::OpVariable:
                        // This is the only valid case.
                        break;
                    case spv::Op::OpUndef:
                        return Fail() << "undef pointer is not valid: " << inst.PrettyPrint();
                    case spv::Op::OpConstantNull:
                        return Fail() << "null pointer is not valid: " << inst.PrettyPrint();
                    default:
                        return Fail()
                               << "module-scope pointer is not valid: " << inst.PrettyPrint();
                }
            }
        }
    }
    return success();
}

bool ASTParser::EmitScalarSpecConstants() {
    if (!success_) {
        return false;
    }
    // Generate a module-scope const declaration for each instruction
    // that is OpSpecConstantTrue, OpSpecConstantFalse, or OpSpecConstant.
    for (auto& inst : module_->types_values()) {
        // These will be populated for a valid scalar spec constant.
        const Type* ast_type = nullptr;
        ast::LiteralExpression* ast_expr = nullptr;

        switch (opcode(inst)) {
            case spv::Op::OpSpecConstantTrue:
            case spv::Op::OpSpecConstantFalse: {
                ast_type = ConvertType(inst.type_id());
                ast_expr = create<ast::BoolLiteralExpression>(
                    Source{}, opcode(inst) == spv::Op::OpSpecConstantTrue);
                break;
            }
            case spv::Op::OpSpecConstant: {
                ast_type = ConvertType(inst.type_id());
                const uint32_t literal_value = inst.GetSingleWordInOperand(0);
                ast_expr = Switch(
                    ast_type,  //
                    [&](const I32*) {
                        return create<ast::IntLiteralExpression>(
                            Source{}, static_cast<int64_t>(literal_value),
                            ast::IntLiteralExpression::Suffix::kI);
                    },
                    [&](const U32*) {
                        return create<ast::IntLiteralExpression>(
                            Source{}, static_cast<int64_t>(literal_value),
                            ast::IntLiteralExpression::Suffix::kU);
                    },
                    [&](const F32*) {
                        float float_value;
                        // Copy the bits so we can read them as a float.
                        std::memcpy(&float_value, &literal_value, sizeof(float_value));
                        return create<ast::FloatLiteralExpression>(
                            Source{}, static_cast<double>(float_value),
                            ast::FloatLiteralExpression::Suffix::kF);
                    });
                if (ast_expr == nullptr) {
                    return Fail() << " invalid result type for OpSpecConstant "
                                  << inst.PrettyPrint();
                }
                break;
            }
            default:
                break;
        }
        if (ast_type && ast_expr) {
            Attributes spec_id_attrs;
            for (const auto& deco : GetDecorationsFor(inst.result_id())) {
                if ((deco.size() == 2) && (deco[0] == uint32_t(spv::Decoration::SpecId))) {
                    const uint32_t id = deco[1];
                    if (id > 65535) {
                        return Fail() << "SpecId too large. WGSL override IDs must be "
                                         "between 0 and 65535: ID %"
                                      << inst.result_id() << " has SpecId " << id;
                    }
                    auto* cid = builder_.Id(Source{}, AInt(id));
                    spec_id_attrs.Add(cid);
                    break;
                }
            }
            auto* ast_var =
                MakeOverride(inst.result_id(), ast_type, ast_expr, std::move(spec_id_attrs));
            if (ast_var) {
                scalar_spec_constants_.insert(inst.result_id());
            }
        }
    }
    return success_;
}

const Type* ASTParser::MaybeGenerateAlias(uint32_t type_id,
                                          const spvtools::opt::analysis::Type* type,
                                          const Type* ast_type) {
    if (!success_) {
        return nullptr;
    }

    // We only care about arrays, and runtime arrays.
    switch (type->kind()) {
        case spvtools::opt::analysis::Type::kRuntimeArray:
            // Runtime arrays are always decorated with ArrayStride so always get a
            // type alias.
            namer_.SuggestSanitizedName(type_id, "RTArr");
            break;
        case spvtools::opt::analysis::Type::kArray:
            // Only make a type aliase for arrays with decorations.
            if (GetDecorationsFor(type_id).empty()) {
                return ast_type;
            }
            namer_.SuggestSanitizedName(type_id, "Arr");
            break;
        default:
            // Ignore constants, and any other types.
            return ast_type;
    }
    auto* ast_underlying_type = ast_type;
    if (ast_underlying_type == nullptr) {
        Fail() << "internal error: no type registered for SPIR-V ID: " << type_id;
        return nullptr;
    }
    const auto name = namer_.GetName(type_id);
    const auto sym = builder_.Symbols().Register(name);
    auto* ast_alias_type = builder_.ty.alias(sym, ast_underlying_type->Build(builder_));

    // Record this new alias as the AST type for this SPIR-V ID.
    AddTypeDecl(sym, ast_alias_type);

    return ty_.Alias(sym, ast_underlying_type);
}

bool ASTParser::EmitModuleScopeVariables() {
    if (!success_) {
        return false;
    }
    for (const auto& type_or_value : module_->types_values()) {
        if (opcode(type_or_value) != spv::Op::OpVariable) {
            continue;
        }
        const auto& var = type_or_value;
        const auto spirv_storage_class = spv::StorageClass(var.GetSingleWordInOperand(0));

        uint32_t type_id = var.type_id();
        if ((type_id == builtin_position_.pointer_type_id) &&
            ((spirv_storage_class == spv::StorageClass::Input) ||
             (spirv_storage_class == spv::StorageClass::Output))) {
            // TODO(crbug.com/tint/103): Support modules that contain multiple Position built-ins.
            if (builtin_position_.per_vertex_var_id != 0) {
                return Fail()
                       << "unsupported: multiple Position built-in variables in the same module";
            }

            // Skip emitting gl_PerVertex.
            builtin_position_.per_vertex_var_id = var.result_id();
            builtin_position_.per_vertex_var_init_id =
                var.NumInOperands() > 1 ? var.GetSingleWordInOperand(1) : 0u;
            continue;
        }
        switch (enum_converter_.ToAddressSpace(spirv_storage_class)) {
            case core::AddressSpace::kUndefined:
            case core::AddressSpace::kIn:
            case core::AddressSpace::kOut:
            case core::AddressSpace::kUniform:
            case core::AddressSpace::kHandle:
            case core::AddressSpace::kStorage:
            case core::AddressSpace::kWorkgroup:
            case core::AddressSpace::kPrivate:
                break;
            default:
                return Fail() << "invalid SPIR-V storage class " << int(spirv_storage_class)
                              << " for module scope variable: " << var.PrettyPrint();
        }
        if (!success_) {
            return false;
        }
        const Type* ast_store_type = nullptr;
        core::AddressSpace ast_address_space = core::AddressSpace::kUndefined;
        if (spirv_storage_class == spv::StorageClass::UniformConstant) {
            // These are opaque handles: samplers or textures
            ast_store_type = GetHandleTypeForSpirvHandle(var);
            if (!ast_store_type) {
                return false;
            }
            // ast_storage_class should remain kNone because handle variables
            // are never declared with an explicit address space.
        } else {
            const Type* ast_type = ConvertType(type_id);
            if (ast_type == nullptr) {
                return Fail() << "internal error: failed to register Tint AST type for "
                                 "SPIR-V type with ID: "
                              << var.type_id();
            }
            if (auto* ast_ptr_type = ast_type->As<Pointer>()) {
                ast_store_type = ast_ptr_type->type;
                ast_address_space = ast_ptr_type->address_space;
            } else {
                return Fail() << "variable with ID " << var.result_id() << " has non-pointer type "
                              << var.type_id();
            }
        }
        TINT_ASSERT(ast_store_type != nullptr);

        const ast::Expression* ast_initializer = nullptr;
        if (var.NumInOperands() > 1) {
            // SPIR-V initializers are always constants.
            // (OpenCL also allows the ID of an OpVariable, but we don't handle that
            // here.)
            ast_initializer = MakeConstantExpression(var.GetSingleWordInOperand(1)).expr;
        }
        auto ast_access = VarAccess(ast_store_type, ast_address_space);
        auto* ast_var = MakeVar(var.result_id(), ast_address_space, ast_access, ast_store_type,
                                ast_initializer, Attributes{});
        // TODO(dneto): initializers (a.k.a. initializer expression)
        if (ast_var) {
            builder_.AST().AddGlobalVariable(ast_var);
            module_variable_.GetOrAdd(var.result_id(), [&] {
                return ModuleVariable{ast_var, ast_address_space, ast_access};
            });
        }
    }

    // Emit gl_Position instead of gl_PerVertex
    if (builtin_position_.per_vertex_var_id) {
        // Make sure the variable has a name.
        namer_.SuggestSanitizedName(builtin_position_.per_vertex_var_id, "gl_Position");
        const ast::Expression* ast_initializer = nullptr;
        if (builtin_position_.per_vertex_var_init_id) {
            // The initializer is complex.
            const auto* init = def_use_mgr_->GetDef(builtin_position_.per_vertex_var_init_id);
            switch (opcode(init)) {
                case spv::Op::OpConstantComposite:
                case spv::Op::OpSpecConstantComposite:
                    ast_initializer =
                        MakeConstantExpression(
                            init->GetSingleWordInOperand(builtin_position_.position_member_index))
                            .expr;
                    break;
                default:
                    return Fail() << "gl_PerVertex initializer too complex. only "
                                     "OpCompositeConstruct and OpSpecConstantComposite "
                                     "are supported: "
                                  << init->PrettyPrint();
            }
        }
        auto storage_type = ConvertType(builtin_position_.position_member_type_id);
        auto ast_address_space = enum_converter_.ToAddressSpace(builtin_position_.storage_class);
        auto ast_access = VarAccess(storage_type, ast_address_space);
        auto* ast_var = MakeVar(builtin_position_.per_vertex_var_id, ast_address_space, ast_access,
                                storage_type, ast_initializer, {});

        builder_.AST().AddGlobalVariable(ast_var);
        module_variable_.GetOrAdd(builtin_position_.per_vertex_var_id, [&] {
            return ModuleVariable{ast_var, ast_address_space};
        });
    }
    return success_;
}

// @param var_id SPIR-V id of an OpVariable, assumed to be pointer
// to an array
// @returns the IntConstant for the size of the array, or nullptr
const spvtools::opt::analysis::IntConstant* ASTParser::GetArraySize(uint32_t var_id) {
    auto* var = def_use_mgr_->GetDef(var_id);
    if (!var || opcode(var) != spv::Op::OpVariable) {
        return nullptr;
    }
    auto* ptr_type = def_use_mgr_->GetDef(var->type_id());
    if (!ptr_type || opcode(ptr_type) != spv::Op::OpTypePointer) {
        return nullptr;
    }
    auto* array_type = def_use_mgr_->GetDef(ptr_type->GetSingleWordInOperand(1));
    if (!array_type || opcode(array_type) != spv::Op::OpTypeArray) {
        return nullptr;
    }
    auto* size = constant_mgr_->FindDeclaredConstant(array_type->GetSingleWordInOperand(1));
    if (!size) {
        return nullptr;
    }
    return size->AsIntConstant();
}

core::Access ASTParser::VarAccess(const Type* storage_type, core::AddressSpace address_space) {
    if (address_space != core::AddressSpace::kStorage) {
        return core::Access::kUndefined;
    }

    bool read_only = false;
    if (auto* tn = storage_type->As<Named>()) {
        read_only = read_only_struct_types_.count(tn->name) > 0;
    }

    // Apply the access(read) or access(read_write) modifier.
    return read_only ? core::Access::kRead : core::Access::kReadWrite;
}

const ast::Var* ASTParser::MakeVar(uint32_t id,
                                   core::AddressSpace address_space,
                                   core::Access access,
                                   const Type* storage_type,
                                   const ast::Expression* initializer,
                                   Attributes attrs) {
    if (storage_type == nullptr) {
        Fail() << "internal error: can't make ast::Variable for null type";
        return nullptr;
    }

    // Handle variables (textures and samplers) are always in the handle
    // address space, so we don't mention the address space.
    if (address_space == core::AddressSpace::kHandle) {
        address_space = core::AddressSpace::kUndefined;
    }

    if (!ConvertDecorationsForVariable(id, &storage_type, attrs,
                                       address_space != core::AddressSpace::kPrivate)) {
        return nullptr;
    }

    // Use type inference if there is an initializer.
    auto sym = builder_.Symbols().Register(namer_.Name(id));
    return builder_.Var(Source{}, sym, initializer ? ast::Type{} : storage_type->Build(builder_),
                        address_space, access, initializer, std::move(attrs.list));
}

const ast::Let* ASTParser::MakeLet(uint32_t id, const ast::Expression* initializer) {
    auto sym = builder_.Symbols().Register(namer_.Name(id));
    return builder_.Let(Source{}, sym, initializer, tint::Empty);
}

const ast::Override* ASTParser::MakeOverride(uint32_t id,
                                             const Type* type,
                                             const ast::Expression* initializer,
                                             Attributes attrs) {
    if (!ConvertDecorationsForVariable(id, &type, attrs, false)) {
        return nullptr;
    }
    auto sym = builder_.Symbols().Register(namer_.Name(id));
    return builder_.Override(Source{}, sym, type->Build(builder_), initializer,
                             std::move(attrs.list));
}

const ast::Parameter* ASTParser::MakeParameter(uint32_t id, const Type* type, Attributes attrs) {
    if (!ConvertDecorationsForVariable(id, &type, attrs, false)) {
        return nullptr;
    }

    auto sym = builder_.Symbols().Register(namer_.Name(id));
    return builder_.Param(Source{}, sym, type->Build(builder_), attrs.list);
}

bool ASTParser::ConvertDecorationsForVariable(uint32_t id,
                                              const Type** store_type,
                                              Attributes& attrs,
                                              bool transfer_pipeline_io) {
    DecorationList non_builtin_pipeline_decorations;
    for (auto& deco : GetDecorationsFor(id)) {
        if (deco.empty()) {
            return Fail() << "malformed decoration on ID " << id << ": it is empty";
        }
        if (deco[0] == uint32_t(spv::Decoration::BuiltIn)) {
            if (deco.size() == 1) {
                return Fail() << "malformed BuiltIn decoration on ID " << id << ": has no operand";
            }
            const auto spv_builtin = static_cast<spv::BuiltIn>(deco[1]);
            switch (spv_builtin) {
                case spv::BuiltIn::PointSize:
                    special_builtins_[id] = spv_builtin;
                    return false;  // This is not an error
                case spv::BuiltIn::SampleId:
                case spv::BuiltIn::VertexIndex:
                case spv::BuiltIn::InstanceIndex:
                case spv::BuiltIn::LocalInvocationId:
                case spv::BuiltIn::LocalInvocationIndex:
                case spv::BuiltIn::GlobalInvocationId:
                case spv::BuiltIn::WorkgroupId:
                case spv::BuiltIn::NumWorkgroups:
                    // The SPIR-V variable may signed (because GLSL requires signed for
                    // some of these), but WGSL requires unsigned.  Handle specially
                    // so we always perform the conversion at load and store.
                    special_builtins_[id] = spv_builtin;
                    if (auto* forced_type = UnsignedTypeFor(*store_type)) {
                        // Requires conversion and special handling in code generation.
                        if (transfer_pipeline_io) {
                            *store_type = forced_type;
                        }
                    }
                    break;
                case spv::BuiltIn::SampleMask: {
                    // In SPIR-V this is used for both input and output variable.
                    // The SPIR-V variable has store type of array of integer scalar,
                    // either signed or unsigned.
                    // WGSL requires the store type to be u32.
                    auto* size = GetArraySize(id);
                    if (!size || size->GetZeroExtendedValue() != 1) {
                        Fail() << "WGSL supports a sample mask of at most 32 bits. "
                                  "SampleMask must be an array of 1 element.";
                    }
                    special_builtins_[id] = spv_builtin;
                    if (transfer_pipeline_io) {
                        *store_type = ty_.U32();
                    }
                    break;
                }
                default:
                    break;
            }
            auto ast_builtin = enum_converter_.ToBuiltin(spv_builtin);
            if (ast_builtin == core::BuiltinValue::kUndefined) {
                // A diagnostic has already been emitted.
                return false;
            }
            if (transfer_pipeline_io) {
                attrs.Add(builder_, Source{}, ast_builtin);
            }
        }
        if (transfer_pipeline_io && IsPipelineDecoration(deco)) {
            non_builtin_pipeline_decorations.push_back(deco);
        }
        if (deco[0] == uint32_t(spv::Decoration::DescriptorSet)) {
            if (deco.size() == 1) {
                return Fail() << "malformed DescriptorSet decoration on ID " << id
                              << ": has no operand";
            }
            attrs.Add(builder_.Group(Source{}, AInt(deco[1])));
        }
        if (deco[0] == uint32_t(spv::Decoration::Binding)) {
            if (deco.size() == 1) {
                return Fail() << "malformed Binding decoration on ID " << id << ": has no operand";
            }
            attrs.Add(builder_.Binding(Source{}, AInt(deco[1])));
        }
    }

    if (transfer_pipeline_io) {
        if (!ConvertPipelineDecorations(*store_type, non_builtin_pipeline_decorations, attrs)) {
            return false;
        }
    }

    return success();
}

DecorationList ASTParser::GetMemberPipelineDecorations(const Struct& struct_type,
                                                       int member_index) {
    // Yes, I could have used std::copy_if or std::copy_if.
    DecorationList result;
    for (const auto& deco : GetDecorationsForMember(struct_id_for_symbol_[struct_type.name],
                                                    static_cast<uint32_t>(member_index))) {
        if (IsPipelineDecoration(deco)) {
            result.emplace_back(deco);
        }
    }
    return result;
}

void ASTParser::SetLocation(Attributes& attributes, const ast::Attribute* replacement) {
    if (!replacement) {
        return;
    }
    for (auto*& attribute : attributes.list) {
        if (attribute->Is<ast::LocationAttribute>()) {
            // Replace this location attribute with the replacement.
            // The old one doesn't leak because it's kept in the builder's AST node
            // list.
            attribute = replacement;
            return;  // Assume there is only one such decoration.
        }
    }
    // The list didn't have a location. Add it.
    attributes.Add(replacement);
    return;
}

bool ASTParser::ConvertPipelineDecorations(const Type* store_type,
                                           const DecorationList& decorations,
                                           Attributes& attributes) {
    // Vulkan defaults to perspective-correct interpolation.
    core::InterpolationType type = core::InterpolationType::kPerspective;
    core::InterpolationSampling sampling = core::InterpolationSampling::kUndefined;

    for (const auto& deco : decorations) {
        TINT_ASSERT(deco.size() > 0);
        switch (static_cast<spv::Decoration>(deco[0])) {
            case spv::Decoration::Location:
                if (deco.size() != 2) {
                    return Fail()
                           << "malformed Location decoration on ID requires one literal operand";
                }
                SetLocation(attributes, builder_.Location(AInt(deco[1])));
                if (store_type->IsIntegerScalarOrVector()) {
                    // Default to flat interpolation for integral user-defined IO types.
                    type = core::InterpolationType::kFlat;
                }
                break;
            case spv::Decoration::Flat:
                type = core::InterpolationType::kFlat;
                break;
            case spv::Decoration::NoPerspective:
                if (store_type->IsIntegerScalarOrVector()) {
                    // This doesn't capture the array or struct case.
                    return Fail() << "NoPerspective is invalid on integral IO";
                }
                type = core::InterpolationType::kLinear;
                break;
            case spv::Decoration::Centroid:
                if (store_type->IsIntegerScalarOrVector()) {
                    // This doesn't capture the array or struct case.
                    return Fail() << "Centroid interpolation sampling is invalid on integral IO";
                }
                sampling = core::InterpolationSampling::kCentroid;
                break;
            case spv::Decoration::Sample:
                if (store_type->IsIntegerScalarOrVector()) {
                    // This doesn't capture the array or struct case.
                    return Fail() << "Sample interpolation sampling is invalid on integral IO";
                }
                sampling = core::InterpolationSampling::kSample;
                break;
            default:
                break;
        }
    }

    if (type == core::InterpolationType::kFlat && !attributes.Has<ast::LocationAttribute>()) {
        // WGSL requires that '@interpolate(flat)' needs to be paired with '@location', however
        // SPIR-V requires all fragment shader integer Inputs are 'flat'. If the decorations do not
        // contain a spv::Decoration::Location, then make this perspective.
        type = core::InterpolationType::kPerspective;
    }

    // Apply interpolation.
    if (type == core::InterpolationType::kPerspective &&
        sampling == core::InterpolationSampling::kUndefined) {
        // This is the default. Don't add a decoration.
    } else {
        attributes.Add(builder_.Interpolate(type, sampling));
    }

    return success();
}

bool ASTParser::CanMakeConstantExpression(uint32_t id) {
    if ((id == workgroup_size_builtin_.id) || (id == workgroup_size_builtin_.x_id) ||
        (id == workgroup_size_builtin_.y_id) || (id == workgroup_size_builtin_.z_id)) {
        return true;
    }
    const auto* inst = def_use_mgr_->GetDef(id);
    if (!inst) {
        return false;
    }
    if (opcode(inst) == spv::Op::OpUndef) {
        return true;
    }
    return nullptr != constant_mgr_->FindDeclaredConstant(id);
}

TypedExpression ASTParser::MakeConstantExpression(uint32_t id) {
    if (!success_) {
        return {};
    }

    // Handle the special cases for workgroup sizing.
    if (id == workgroup_size_builtin_.id) {
        auto x = MakeConstantExpression(workgroup_size_builtin_.x_id);
        auto y = MakeConstantExpression(workgroup_size_builtin_.y_id);
        auto z = MakeConstantExpression(workgroup_size_builtin_.z_id);
        auto* ast_type = ty_.Vector(x.type, 3);
        return {ast_type, builder_.Call(Source{}, ast_type->Build(builder_),
                                        tint::Vector{x.expr, y.expr, z.expr})};
    } else if (id == workgroup_size_builtin_.x_id) {
        return MakeConstantExpressionForScalarSpirvConstant(
            Source{}, ConvertType(workgroup_size_builtin_.component_type_id),
            constant_mgr_->GetConstant(
                type_mgr_->GetType(workgroup_size_builtin_.component_type_id),
                {workgroup_size_builtin_.x_value}));
    } else if (id == workgroup_size_builtin_.y_id) {
        return MakeConstantExpressionForScalarSpirvConstant(
            Source{}, ConvertType(workgroup_size_builtin_.component_type_id),
            constant_mgr_->GetConstant(
                type_mgr_->GetType(workgroup_size_builtin_.component_type_id),
                {workgroup_size_builtin_.y_value}));
    } else if (id == workgroup_size_builtin_.z_id) {
        return MakeConstantExpressionForScalarSpirvConstant(
            Source{}, ConvertType(workgroup_size_builtin_.component_type_id),
            constant_mgr_->GetConstant(
                type_mgr_->GetType(workgroup_size_builtin_.component_type_id),
                {workgroup_size_builtin_.z_value}));
    }

    // Handle the general case where a constant is already registered
    // with the SPIR-V optimizer's analysis framework.
    const auto* inst = def_use_mgr_->GetDef(id);
    if (inst == nullptr) {
        Fail() << "ID " << id << " is not a registered instruction";
        return {};
    }
    auto source = GetSourceForInst(inst);

    auto* original_ast_type = ConvertType(inst->type_id());
    if (original_ast_type == nullptr) {
        return {};
    }

    switch (opcode(inst)) {
        case spv::Op::OpUndef:  // Remap undef to null.
        case spv::Op::OpConstantNull:
            return {original_ast_type, MakeNullValue(original_ast_type)};
        case spv::Op::OpConstantTrue:
        case spv::Op::OpConstantFalse:
        case spv::Op::OpConstant: {
            const auto* spirv_const = constant_mgr_->FindDeclaredConstant(id);
            if (spirv_const == nullptr) {
                Fail() << "ID " << id << " is not a constant";
                return {};
            }
            return MakeConstantExpressionForScalarSpirvConstant(source, original_ast_type,
                                                                spirv_const);
        }
        case spv::Op::OpConstantComposite: {
            // Handle vector, matrix, array, and struct

            auto itr = declared_constant_composites_.find(id);
            if (itr != declared_constant_composites_.end()) {
                // We've already declared this constant value as a module-scope const, so just
                // reference that identifier.
                return {original_ast_type, builder_.Expr(itr->second)};
            }

            const auto* spirv_const = constant_mgr_->FindDeclaredConstant(id);
            if (spirv_const->IsZero()) {
                // All zeros, so just use a zero value constructor and always inline it.
                return {original_ast_type,
                        builder_.Call(source, original_ast_type->Build(builder_))};
            }

            // Generate a composite from explicit components.
            bool all_same = true;
            uint32_t first_id = 0u;
            ExpressionList ast_components;
            if (!inst->WhileEachInId([&](const uint32_t* id_ref) -> bool {
                    auto component = MakeConstantExpression(*id_ref);
                    if (!component) {
                        this->Fail() << "invalid constant with ID " << *id_ref;
                        return false;
                    }
                    ast_components.Push(component.expr);

                    // Check if this argument is different from the others.
                    if (first_id != 0u) {
                        if (*id_ref != first_id) {
                            all_same = false;
                        }
                    } else {
                        first_id = *id_ref;
                    }

                    return true;
                })) {
                // We've already emitted a diagnostic.
                return {};
            }

            const ast::Expression* expr = nullptr;
            if (all_same && original_ast_type->Is<Vector>()) {
                // We're constructing a vector and all the operands were the same, so use a splat.
                expr = builder_.Call(source, original_ast_type->Build(builder_), ast_components[0]);
            } else {
                expr = builder_.Call(source, original_ast_type->Build(builder_),
                                     std::move(ast_components));
            }

            if (def_use_mgr_->NumUses(id) == 1) {
                // The constant is only used once, so just inline its use.
                return {original_ast_type, expr};
            }

            // Create a module-scope const declaration for the constant.
            auto name = namer_.Name(id);
            auto* decl = builder_.GlobalConst(name, expr);
            declared_constant_composites_.insert({id, decl->name->symbol});
            return {original_ast_type, builder_.Expr(name)};
        }
        case spv::Op::OpSpecConstantComposite:
        case spv::Op::OpSpecConstantOp: {
            // TODO(crbug.com/tint/111): Handle OpSpecConstantOp and OpSpecConstantComposite here.
            Fail() << "unimplemented: OpSpecConstantOp and OpSpecConstantComposite";
            return {};
        }
        default:
            break;
    }
    Fail() << "unhandled constant instruction " << inst->PrettyPrint();
    return {};
}

TypedExpression ASTParser::MakeConstantExpressionForScalarSpirvConstant(
    Source source,
    const Type* original_ast_type,
    const spvtools::opt::analysis::Constant* spirv_const) {
    auto* ast_type = original_ast_type->UnwrapAlias();

    // TODO(dneto): Note: NullConstant for int, uint, float map to a regular 0.
    // So canonicalization should map that way too.
    // Currently "null<type>" is missing from the WGSL parser.
    // See https://bugs.chromium.org/p/tint/issues/detail?id=34
    return Switch(
        ast_type,
        [&](const I32*) -> TypedExpression {
            const auto value = spirv_const->GetS32();
            if (value == std::numeric_limits<int32_t>::min()) {
                // Avoid overflowing i-suffixed literal.
                return {ty_.I32(), builder_.Call(source, builder_.ty.i32(),
                                                 create<ast::IntLiteralExpression>(
                                                     source, value,
                                                     ast::IntLiteralExpression::Suffix::kNone))};
            } else {
                return {ty_.I32(),
                        create<ast::IntLiteralExpression>(source, static_cast<int64_t>(value),
                                                          ast::IntLiteralExpression::Suffix::kI)};
            }
        },
        [&](const U32*) {
            return TypedExpression{ty_.U32(),
                                   create<ast::IntLiteralExpression>(
                                       source, static_cast<int64_t>(spirv_const->GetU32()),
                                       ast::IntLiteralExpression::Suffix::kU)};
        },
        [&](const F32*) {
            if (auto f = core::CheckedConvert<f32>(AFloat(spirv_const->GetFloat())); f == Success) {
                return TypedExpression{ty_.F32(),
                                       create<ast::FloatLiteralExpression>(
                                           source, static_cast<double>(spirv_const->GetFloat()),
                                           ast::FloatLiteralExpression::Suffix::kF)};
            } else {
                Fail() << "value cannot be represented as 'f32': " << spirv_const->GetFloat();
                return TypedExpression{};
            }
        },
        [&](const Bool*) {
            const bool value =
                spirv_const->AsNullConstant() ? false : spirv_const->AsBoolConstant()->value();
            return TypedExpression{ty_.Bool(), create<ast::BoolLiteralExpression>(source, value)};
        },  //
        TINT_ICE_ON_NO_MATCH);
}

const ast::Expression* ASTParser::MakeNullValue(const Type* type) {
    // TODO(dneto): Use the no-operands initializer syntax when it becomes
    // available in Tint.
    // https://github.com/gpuweb/gpuweb/issues/685
    // https://bugs.chromium.org/p/tint/issues/detail?id=34

    if (!type) {
        Fail() << "trying to create null value for a null type";
        return nullptr;
    }

    auto* original_type = type;
    type = type->UnwrapAlias();

    return Switch(
        type,  //
        [&](const I32*) {
            return create<ast::IntLiteralExpression>(Source{}, 0,
                                                     ast::IntLiteralExpression::Suffix::kI);
        },
        [&](const U32*) {
            return create<ast::IntLiteralExpression>(Source{}, 0,
                                                     ast::IntLiteralExpression::Suffix::kU);
        },
        [&](const F32*) {
            return create<ast::FloatLiteralExpression>(Source{}, 0,
                                                       ast::FloatLiteralExpression::Suffix::kF);
        },
        [&](const Vector*) { return builder_.Call(Source{}, type->Build(builder_)); },
        [&](const Matrix*) { return builder_.Call(Source{}, type->Build(builder_)); },
        [&](const Array*) { return builder_.Call(Source{}, type->Build(builder_)); },
        [&](const Bool*) { return create<ast::BoolLiteralExpression>(Source{}, false); },
        [&](const Struct* struct_ty) {
            ExpressionList ast_components;
            for (auto* member : struct_ty->members) {
                ast_components.Push(MakeNullValue(member));
            }
            return builder_.Call(Source{}, original_type->Build(builder_),
                                 std::move(ast_components));
        },  //
        TINT_ICE_ON_NO_MATCH);
}

TypedExpression ASTParser::MakeNullExpression(const Type* type) {
    return {type, MakeNullValue(type)};
}

const Type* ASTParser::UnsignedTypeFor(const Type* type) {
    if (type->Is<I32>()) {
        return ty_.U32();
    }
    if (auto* v = type->As<Vector>()) {
        if (v->type->Is<I32>()) {
            return ty_.Vector(ty_.U32(), v->size);
        }
    }
    return {};
}

const Type* ASTParser::SignedTypeFor(const Type* type) {
    if (type->Is<U32>()) {
        return ty_.I32();
    }
    if (auto* v = type->As<Vector>()) {
        if (v->type->Is<U32>()) {
            return ty_.Vector(ty_.I32(), v->size);
        }
    }
    return {};
}

TypedExpression ASTParser::RectifyOperandSignedness(const spvtools::opt::Instruction& inst,
                                                    TypedExpression&& expr) {
    bool requires_signed = false;
    bool requires_unsigned = false;
    if (IsGlslExtendedInstruction(inst)) {
        const auto extended_opcode = static_cast<GLSLstd450>(inst.GetSingleWordInOperand(1));
        requires_signed = AssumesSignedOperands(extended_opcode);
        requires_unsigned = AssumesUnsignedOperands(extended_opcode);
    } else {
        const auto op = opcode(inst);
        requires_signed = AssumesSignedOperands(op);
        requires_unsigned = AssumesUnsignedOperands(op);
    }
    if (!requires_signed && !requires_unsigned) {
        // No conversion is required, assuming our tables are complete.
        return std::move(expr);
    }
    if (!expr) {
        Fail() << "internal error: RectifyOperandSignedness given a null expr\n";
        return {};
    }
    // TODO(crbug.com/tint/1669) should this unpack aliases too?
    auto* type = expr.type->UnwrapRef();
    if (!type) {
        Fail() << "internal error: unmapped type for: " << expr.expr->TypeInfo().name << "\n";
        return {};
    }
    if (requires_unsigned) {
        if (auto* unsigned_ty = UnsignedTypeFor(type)) {
            // Conversion is required.
            return {unsigned_ty,
                    builder_.Bitcast(Source{}, unsigned_ty->Build(builder_), expr.expr)};
        }
    } else if (requires_signed) {
        if (auto* signed_ty = SignedTypeFor(type)) {
            // Conversion is required.
            return {signed_ty, builder_.Bitcast(Source{}, signed_ty->Build(builder_), expr.expr)};
        }
    }
    // We should not reach here.
    return std::move(expr);
}

TypedExpression ASTParser::RectifySecondOperandSignedness(const spvtools::opt::Instruction& inst,
                                                          const Type* first_operand_type,
                                                          TypedExpression&& second_operand_expr) {
    const Type* target_type = first_operand_type->UnwrapRef();
    if ((target_type != second_operand_expr.type->UnwrapRef()) &&
        AssumesSecondOperandSignednessMatchesFirstOperand(opcode(inst))) {
        // Conversion is required.
        return {target_type,
                builder_.Bitcast(Source{}, target_type->Build(builder_), second_operand_expr.expr)};
    }
    // No conversion necessary.
    return std::move(second_operand_expr);
}

const Type* ASTParser::ForcedResultType(const spvtools::opt::Instruction& inst,
                                        const Type* first_operand_type) {
    first_operand_type = first_operand_type->UnwrapRef();
    const auto op = opcode(inst);
    if (AssumesResultSignednessMatchesFirstOperand(op)) {
        return first_operand_type;
    }
    if (IsGlslExtendedInstruction(inst)) {
        const auto extended_opcode = static_cast<GLSLstd450>(inst.GetSingleWordInOperand(1));
        if (AssumesResultSignednessMatchesFirstOperand(extended_opcode)) {
            return first_operand_type;
        }
    }
    return nullptr;
}

const Type* ASTParser::GetSignedIntMatchingShape(const Type* other) {
    if (other == nullptr) {
        Fail() << "no type provided";
    }
    if (other->Is<F32>() || other->Is<U32>() || other->Is<I32>()) {
        return ty_.I32();
    }
    if (auto* vec_ty = other->As<Vector>()) {
        return ty_.Vector(ty_.I32(), vec_ty->size);
    }
    Fail() << "required numeric scalar or vector, but got " << other->TypeInfo().name;
    return nullptr;
}

const Type* ASTParser::GetUnsignedIntMatchingShape(const Type* other) {
    if (other == nullptr) {
        Fail() << "no type provided";
        return nullptr;
    }
    if (other->Is<F32>() || other->Is<U32>() || other->Is<I32>()) {
        return ty_.U32();
    }
    if (auto* vec_ty = other->As<Vector>()) {
        return ty_.Vector(ty_.U32(), vec_ty->size);
    }
    Fail() << "required numeric scalar or vector, but got " << other->TypeInfo().name;
    return nullptr;
}

TypedExpression ASTParser::RectifyForcedResultType(TypedExpression expr,
                                                   const spvtools::opt::Instruction& inst,
                                                   const Type* first_operand_type) {
    auto* forced_result_ty = ForcedResultType(inst, first_operand_type);
    if ((!forced_result_ty) || (forced_result_ty == expr.type)) {
        return expr;
    }
    return {expr.type, builder_.Bitcast(Source{}, expr.type->Build(builder_), expr.expr)};
}

TypedExpression ASTParser::AsUnsigned(TypedExpression expr) {
    if (expr.type && expr.type->IsSignedScalarOrVector()) {
        auto* new_type = GetUnsignedIntMatchingShape(expr.type);
        return {new_type, builder_.Bitcast(Source{}, new_type->Build(builder_), expr.expr)};
    }
    return expr;
}

TypedExpression ASTParser::AsSigned(TypedExpression expr) {
    if (expr.type && expr.type->IsUnsignedScalarOrVector()) {
        auto* new_type = GetSignedIntMatchingShape(expr.type);
        return {new_type, builder_.Bitcast(Source{}, new_type->Build(builder_), expr.expr)};
    }
    return expr;
}

bool ASTParser::EmitFunctions() {
    if (!success_) {
        return false;
    }
    for (const auto* f : topologically_ordered_functions_) {
        if (!success_) {
            return false;
        }

        auto id = f->result_id();
        auto it = function_to_ep_info_.find(id);
        if (it == function_to_ep_info_.end()) {
            FunctionEmitter emitter(this, *f, nullptr);
            success_ = emitter.Emit();
        } else {
            for (const auto& ep : it->second) {
                FunctionEmitter emitter(this, *f, &ep);
                success_ = emitter.Emit();
                if (!success_) {
                    return false;
                }
            }
        }
    }
    return success_;
}

const spvtools::opt::Instruction* ASTParser::GetMemoryObjectDeclarationForHandle(
    uint32_t id,
    bool follow_image) {
    auto saved_id = id;
    auto local_fail = [this, saved_id, id, follow_image]() -> const spvtools::opt::Instruction* {
        const auto* inst = def_use_mgr_->GetDef(id);
        Fail() << "Could not find memory object declaration for the "
               << (follow_image ? "image" : "sampler") << " underlying id " << id
               << " (from original id " << saved_id << ") "
               << (inst ? inst->PrettyPrint() : std::string());
        return nullptr;
    };

    auto& memo_table = (follow_image ? mem_obj_decl_image_ : mem_obj_decl_sampler_);

    // Use a visited set to defend against bad input which might have long
    // chains or even loops.
    std::unordered_set<uint32_t> visited;

    // Trace backward in the SSA data flow until we hit a memory object
    // declaration.
    while (true) {
        auto where = memo_table.find(id);
        if (where != memo_table.end()) {
            return where->second;
        }
        // Protect against loops.
        auto visited_iter = visited.find(id);
        if (visited_iter != visited.end()) {
            // We've hit a loop. Mark all the visited nodes
            // as dead ends.
            for (auto iter : visited) {
                memo_table[iter] = nullptr;
            }
            return nullptr;
        }
        visited.insert(id);

        const auto* inst = def_use_mgr_->GetDef(id);
        if (inst == nullptr) {
            return local_fail();
        }
        switch (opcode(inst)) {
            case spv::Op::OpFunctionParameter:
            case spv::Op::OpVariable:
                // We found the memory object declaration.
                // Remember it as the answer for the whole path.
                for (auto iter : visited) {
                    memo_table[iter] = inst;
                }
                return inst;
            case spv::Op::OpLoad:
                // Follow the pointer being loaded
                id = inst->GetSingleWordInOperand(0);
                break;
            case spv::Op::OpCopyObject:
                // Follow the object being copied.
                id = inst->GetSingleWordInOperand(0);
                break;
            case spv::Op::OpAccessChain:
            case spv::Op::OpInBoundsAccessChain:
            case spv::Op::OpPtrAccessChain:
            case spv::Op::OpInBoundsPtrAccessChain:
                // Follow the base pointer.
                id = inst->GetSingleWordInOperand(0);
                break;
            case spv::Op::OpSampledImage:
                // Follow the image or the sampler, depending on the follow_image
                // parameter.
                id = inst->GetSingleWordInOperand(follow_image ? 0 : 1);
                break;
            case spv::Op::OpImage:
                // Follow the sampled image
                id = inst->GetSingleWordInOperand(0);
                break;
            default:
                // Can't trace further.
                // Remember it as the answer for the whole path.
                for (auto iter : visited) {
                    memo_table[iter] = nullptr;
                }
                return nullptr;
        }
    }
}

const spvtools::opt::Instruction* ASTParser::GetSpirvTypeForHandleOrHandleMemoryObjectDeclaration(
    const spvtools::opt::Instruction& obj) {
    if (!success()) {
        return nullptr;
    }
    // The WGSL handle type is determined by looking at information from
    // several sources:
    //    - the usage of the handle by image access instructions
    //    - the SPIR-V type declaration
    // Each source does not have enough information to completely determine
    // the result.

    // Messages are phrased in terms of images and samplers because those
    // are the only SPIR-V handles supported by WGSL.

    // Get the SPIR-V handle type.
    const auto* type = def_use_mgr_->GetDef(obj.type_id());
    if (!type) {
        Fail() << "Invalid type for image, sampler, variable or function parameter to image or "
                  "sampler "
               << obj.PrettyPrint();
        return nullptr;
    }
    switch (opcode(type)) {
        case spv::Op::OpTypeSampler:
        case spv::Op::OpTypeImage:
            return type;
        case spv::Op::OpTypePointer:
            // The remaining cases.
            break;
        default:
            Fail() << "Invalid type for image, sampler, variable or function parameter to image or "
                      "sampler "
                   << obj.PrettyPrint();
            return nullptr;
    }

    // Look at the pointee type instead.
    const auto* raw_handle_type = def_use_mgr_->GetDef(type->GetSingleWordInOperand(1));
    if (!raw_handle_type) {
        Fail() << "Invalid pointer type for variable or function parameter " << obj.PrettyPrint();
        return nullptr;
    }
    switch (opcode(raw_handle_type)) {
        case spv::Op::OpTypeSampler:
        case spv::Op::OpTypeImage:
            // The expected cases.
            break;
        case spv::Op::OpTypeArray:
        case spv::Op::OpTypeRuntimeArray:
            Fail() << "arrays of textures or samplers are not supported in WGSL; can't "
                      "translate variable or function parameter: "
                   << obj.PrettyPrint();
            return nullptr;
        case spv::Op::OpTypeSampledImage:
            Fail() << "WGSL does not support combined image-samplers: " << obj.PrettyPrint();
            return nullptr;
        default:
            Fail() << "invalid type for image or sampler variable or function "
                      "parameter: "
                   << obj.PrettyPrint();
            return nullptr;
    }
    return raw_handle_type;
}

const Type* ASTParser::GetHandleTypeForSpirvHandle(const spvtools::opt::Instruction& obj) {
    auto where = handle_type_.find(&obj);
    if (where != handle_type_.end()) {
        return where->second;
    }

    const spvtools::opt::Instruction* raw_handle_type =
        GetSpirvTypeForHandleOrHandleMemoryObjectDeclaration(obj);
    if (!raw_handle_type) {
        return nullptr;
    }

    // The memory object declaration could be a sampler or image.
    // Where possible, determine which one it is from the usage inferred
    // for the variable.
    Usage usage = handle_usage_[&obj];
    if (!usage.IsValid()) {
        Fail() << "Invalid sampler or texture usage for variable or function parameter "
               << obj.PrettyPrint() << "\n"
               << usage;
        return nullptr;
    }
    // Infer a handle type, if usage didn't already tell us.
    if (!usage.IsComplete()) {
        // In SPIR-V you could statically reference a texture or sampler without
        // using it in a way that gives us a clue on how to declare it.  Look inside
        // the store type to infer a usage.
        if (opcode(raw_handle_type) == spv::Op::OpTypeSampler) {
            usage.AddSampler();
        } else {
            // It's a texture.
            if (raw_handle_type->NumInOperands() != 7) {
                Fail() << "invalid SPIR-V image type: expected 7 operands: "
                       << raw_handle_type->PrettyPrint();
                return nullptr;
            }
            const auto sampled_param = raw_handle_type->GetSingleWordInOperand(5);
            const auto format_param = raw_handle_type->GetSingleWordInOperand(6);
            // Only storage images have a format.
            if ((format_param != uint32_t(spv::ImageFormat::Unknown)) ||
                sampled_param == 2 /* without sampler */) {
                // Get NonWritable and NonReadable attributes of the variable.
                bool is_nonwritable = false;
                bool is_nonreadable = false;
                for (const auto& deco : GetDecorationsFor(obj.result_id())) {
                    if (deco.size() != 1) {
                        continue;
                    }
                    if (deco[0] == uint32_t(spv::Decoration::NonWritable)) {
                        is_nonwritable = true;
                    }
                    if (deco[0] == uint32_t(spv::Decoration::NonReadable)) {
                        is_nonreadable = true;
                    }
                }
                if (is_nonwritable && is_nonreadable) {
                    Fail() << "storage image variable is both NonWritable and NonReadable"
                           << obj.PrettyPrint();
                }
                if (!is_nonwritable && !is_nonreadable) {
                    Fail() << "storage image variable is neither NonWritable nor NonReadable"
                           << obj.PrettyPrint();
                }
                // Let's make it one of the storage textures.
                if (is_nonwritable) {
                    usage.AddStorageReadTexture();
                } else {
                    usage.AddStorageWriteTexture();
                }
            } else {
                usage.AddSampledTexture();
            }
        }
        if (!usage.IsComplete()) {
            Fail() << "internal error: should have inferred a complete handle type. got "
                   << usage.to_str();
            return nullptr;
        }
    }

    // Construct the Tint handle type.
    const Type* ast_handle_type = nullptr;
    if (usage.IsSampler()) {
        ast_handle_type =
            ty_.Sampler(usage.IsComparisonSampler() ? core::type::SamplerKind::kComparisonSampler
                                                    : core::type::SamplerKind::kSampler);
    } else if (usage.IsTexture()) {
        const spvtools::opt::analysis::Image* image_type =
            type_mgr_->GetType(raw_handle_type->result_id())->AsImage();
        if (!image_type) {
            Fail() << "internal error: Couldn't look up image type"
                   << raw_handle_type->PrettyPrint();
            return nullptr;
        }

        if (image_type->is_arrayed()) {
            // Give a nicer error message here, where we have the offending variable
            // in hand, rather than inside the enum converter.
            switch (static_cast<spv::Dim>(image_type->dim())) {
                case spv::Dim::Dim2D:
                case spv::Dim::Cube:
                    break;
                default:
                    Fail() << "WGSL arrayed textures must be 2d_array or cube_array: "
                              "invalid multisampled texture variable or function parameter "
                           << namer_.Name(obj.result_id()) << ": " << obj.PrettyPrint();
                    return nullptr;
            }
        }

        const core::type::TextureDimension dim =
            enum_converter_.ToDim(image_type->dim(), image_type->is_arrayed());
        if (dim == core::type::TextureDimension::kNone) {
            return nullptr;
        }

        // WGSL storage textures are always formatted.  Unformatted textures are always sampled.
        if (usage.IsSampledTexture() || usage.IsStorageReadOnlyTexture() ||
            (uint32_t(image_type->format()) == uint32_t(spv::ImageFormat::Unknown))) {
            // Make a sampled texture type.
            auto* ast_sampled_component_type =
                ConvertType(raw_handle_type->GetSingleWordInOperand(0));

            // Vulkan ignores the depth parameter on OpImage, so pay attention to the
            // usage as well.  That is, it's valid for a Vulkan shader to use an
            // OpImage variable with an OpImage*Dref* instruction.  In WGSL we must
            // treat that as a depth texture.
            if (image_type->depth() == 1 || usage.IsDepthTexture()) {
                if (image_type->is_multisampled()) {
                    ast_handle_type = ty_.DepthMultisampledTexture(dim);
                } else {
                    ast_handle_type = ty_.DepthTexture(dim);
                }
            } else if (image_type->is_multisampled()) {
                if (dim != core::type::TextureDimension::k2d) {
                    Fail() << "WGSL multisampled textures must be 2d and non-arrayed: "
                              "invalid multisampled texture variable or function parameter "
                           << namer_.Name(obj.result_id()) << ": " << obj.PrettyPrint();
                }
                // Multisampled textures are never depth textures.
                ast_handle_type = ty_.MultisampledTexture(dim, ast_sampled_component_type);
            } else {
                ast_handle_type = ty_.SampledTexture(dim, ast_sampled_component_type);
            }
        } else {
            const auto access =
                usage.IsStorageReadWriteTexture() ? core::Access::kReadWrite : core::Access::kWrite;
            if (access == core::Access::kReadWrite) {
                Require(wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures);
            }
            const auto format = enum_converter_.ToTexelFormat(image_type->format());
            if (format == core::TexelFormat::kUndefined) {
                return nullptr;
            }
            ast_handle_type = ty_.StorageTexture(dim, format, access);
        }
    } else {
        Fail() << "unsupported: UniformConstant variable or function parameter is not a recognized "
                  "sampler or texture "
               << obj.PrettyPrint();
        return nullptr;
    }

    // Remember it for later.
    handle_type_[&obj] = ast_handle_type;
    return ast_handle_type;
}

const Type* ASTParser::GetComponentTypeForFormat(core::TexelFormat format) {
    switch (format) {
        case core::TexelFormat::kR32Uint:
        case core::TexelFormat::kRgba8Uint:
        case core::TexelFormat::kRg32Uint:
        case core::TexelFormat::kRgba16Uint:
        case core::TexelFormat::kRgba32Uint:
            return ty_.U32();

        case core::TexelFormat::kR32Sint:
        case core::TexelFormat::kRgba8Sint:
        case core::TexelFormat::kRg32Sint:
        case core::TexelFormat::kRgba16Sint:
        case core::TexelFormat::kRgba32Sint:
            return ty_.I32();

        case core::TexelFormat::kRgba8Unorm:
        case core::TexelFormat::kRgba8Snorm:
        case core::TexelFormat::kR32Float:
        case core::TexelFormat::kRg32Float:
        case core::TexelFormat::kRgba16Float:
        case core::TexelFormat::kRgba32Float:
            return ty_.F32();
        default:
            break;
    }
    Fail() << "unknown format " << int(format);
    return nullptr;
}

unsigned ASTParser::GetChannelCountForFormat(core::TexelFormat format) {
    switch (format) {
        case core::TexelFormat::kR32Float:
        case core::TexelFormat::kR32Sint:
        case core::TexelFormat::kR32Uint:
            // One channel
            return 1;

        case core::TexelFormat::kRg32Float:
        case core::TexelFormat::kRg32Sint:
        case core::TexelFormat::kRg32Uint:
            // Two channels
            return 2;

        case core::TexelFormat::kRgba16Float:
        case core::TexelFormat::kRgba16Sint:
        case core::TexelFormat::kRgba16Uint:
        case core::TexelFormat::kRgba32Float:
        case core::TexelFormat::kRgba32Sint:
        case core::TexelFormat::kRgba32Uint:
        case core::TexelFormat::kRgba8Sint:
        case core::TexelFormat::kRgba8Snorm:
        case core::TexelFormat::kRgba8Uint:
        case core::TexelFormat::kRgba8Unorm:
            // Four channels
            return 4;

        default:
            break;
    }
    Fail() << "unknown format " << int(format);
    return 0;
}

const Type* ASTParser::GetTexelTypeForFormat(core::TexelFormat format) {
    const auto* component_type = GetComponentTypeForFormat(format);
    if (!component_type) {
        return nullptr;
    }
    return ty_.Vector(component_type, 4);
}

bool ASTParser::RegisterHandleUsage() {
    if (!success_) {
        return false;
    }

    // Map a function ID to the list of its function parameter instructions, in
    // order.
    std::unordered_map<uint32_t, std::vector<const spvtools::opt::Instruction*>> function_params;
    for (const auto* f : topologically_ordered_functions_) {
        // Record the instructions defining this function's parameters.
        auto& params = function_params[f->result_id()];
        f->ForEachParam(
            [&params](const spvtools::opt::Instruction* param) { params.push_back(param); });
    }

    // Returns the memory object declaration for an image underlying the first
    // operand of the given image instruction.
    auto get_image = [this](const spvtools::opt::Instruction& image_inst) {
        return this->GetMemoryObjectDeclarationForHandle(image_inst.GetSingleWordInOperand(0),
                                                         true);
    };
    // Returns the memory object declaration for a sampler underlying the first
    // operand of the given image instruction.
    auto get_sampler = [this](const spvtools::opt::Instruction& image_inst) {
        return this->GetMemoryObjectDeclarationForHandle(image_inst.GetSingleWordInOperand(0),
                                                         false);
    };

    // Scan the bodies of functions for image operations, recording their implied
    // usage properties on the memory object declarations (i.e. variables or
    // function parameters).  We scan the functions in an order so that callees
    // precede callers. That way the usage on a function parameter is already
    // computed before we see the call to that function.  So when we reach
    // a function call, we can add the usage from the callee formal parameters.
    for (const auto* f : topologically_ordered_functions_) {
        for (const auto& bb : *f) {
            for (const auto& inst : bb) {
                switch (opcode(inst)) {
                        // Single texel reads and writes

                    case spv::Op::OpImageRead:
                        handle_usage_[get_image(inst)].AddStorageReadTexture();
                        break;
                    case spv::Op::OpImageWrite:
                        handle_usage_[get_image(inst)].AddStorageWriteTexture();
                        break;
                    case spv::Op::OpImageFetch:
                        handle_usage_[get_image(inst)].AddSampledTexture();
                        break;

                        // Sampling and gathering from a sampled image.

                    case spv::Op::OpImageSampleImplicitLod:
                    case spv::Op::OpImageSampleExplicitLod:
                    case spv::Op::OpImageSampleProjImplicitLod:
                    case spv::Op::OpImageSampleProjExplicitLod:
                    case spv::Op::OpImageGather:
                        handle_usage_[get_image(inst)].AddSampledTexture();
                        handle_usage_[get_sampler(inst)].AddSampler();
                        break;
                    case spv::Op::OpImageSampleDrefImplicitLod:
                    case spv::Op::OpImageSampleDrefExplicitLod:
                    case spv::Op::OpImageSampleProjDrefImplicitLod:
                    case spv::Op::OpImageSampleProjDrefExplicitLod:
                    case spv::Op::OpImageDrefGather:
                        // Depth reference access implies usage as a depth texture, which
                        // in turn is a sampled texture.
                        handle_usage_[get_image(inst)].AddDepthTexture();
                        handle_usage_[get_sampler(inst)].AddComparisonSampler();
                        break;

                        // Image queries

                    case spv::Op::OpImageQuerySizeLod:
                        // Vulkan requires Sampled=1 for this. SPIR-V already requires MS=0.
                        handle_usage_[get_image(inst)].AddSampledTexture();
                        break;
                    case spv::Op::OpImageQuerySize:
                        // Applies to either MS=1 or Sampled=0 or 2.
                        // So we can't force it to be multisampled, or storage image.
                        break;
                    case spv::Op::OpImageQueryLod:
                        handle_usage_[get_image(inst)].AddSampledTexture();
                        handle_usage_[get_sampler(inst)].AddSampler();
                        break;
                    case spv::Op::OpImageQueryLevels:
                        // We can't tell anything more than that it's an image.
                        handle_usage_[get_image(inst)].AddTexture();
                        break;
                    case spv::Op::OpImageQuerySamples:
                        handle_usage_[get_image(inst)].AddMultisampledTexture();
                        break;

                        // Function calls

                    case spv::Op::OpFunctionCall: {
                        // Propagate handle usages from callee function formal parameters to
                        // the matching caller parameters.  This is where we rely on the
                        // fact that callees have been processed earlier in the flow.
                        const auto num_in_operands = inst.NumInOperands();
                        // The first operand of the call is the function ID.
                        // The remaining operands are the operands to the function.
                        if (num_in_operands < 1) {
                            return Fail() << "Call instruction must have at least one operand"
                                          << inst.PrettyPrint();
                        }
                        const auto function_id = inst.GetSingleWordInOperand(0);
                        const auto& formal_params = function_params[function_id];
                        if (formal_params.size() != (num_in_operands - 1)) {
                            return Fail()
                                   << "Called function has " << formal_params.size()
                                   << " parameters, but function call has " << (num_in_operands - 1)
                                   << " parameters" << inst.PrettyPrint();
                        }
                        for (uint32_t i = 1; i < num_in_operands; ++i) {
                            auto where = handle_usage_.find(formal_params[i - 1]);
                            if (where == handle_usage_.end()) {
                                // We haven't recorded any handle usage on the formal parameter.
                                continue;
                            }
                            const Usage& formal_param_usage = where->second;
                            const auto operand_id = inst.GetSingleWordInOperand(i);
                            const auto* operand_as_sampler =
                                GetMemoryObjectDeclarationForHandle(operand_id, false);
                            const auto* operand_as_image =
                                GetMemoryObjectDeclarationForHandle(operand_id, true);
                            if (operand_as_sampler) {
                                handle_usage_[operand_as_sampler].Add(formal_param_usage);
                            }
                            if (operand_as_image && (operand_as_image != operand_as_sampler)) {
                                handle_usage_[operand_as_image].Add(formal_param_usage);
                            }
                        }
                        break;
                    }

                    default:
                        break;
                }
            }
        }
    }
    return success_;
}

Usage ASTParser::GetHandleUsage(uint32_t id) const {
    const auto where = handle_usage_.find(def_use_mgr_->GetDef(id));
    if (where != handle_usage_.end()) {
        return where->second;
    }
    return Usage();
}

const spvtools::opt::Instruction* ASTParser::GetInstructionForTest(uint32_t id) const {
    return def_use_mgr_ ? def_use_mgr_->GetDef(id) : nullptr;
}

std::string ASTParser::GetMemberName(const Struct& struct_type, int member_index) {
    auto where = struct_id_for_symbol_.find(struct_type.name);
    if (where == struct_id_for_symbol_.end()) {
        Fail() << "no structure type registered for symbol";
        return "";
    }
    return namer_.GetMemberName(where->second, static_cast<uint32_t>(member_index));
}

WorkgroupSizeInfo::WorkgroupSizeInfo() = default;

WorkgroupSizeInfo::~WorkgroupSizeInfo() = default;

}  // namespace tint::spirv::reader::ast_parser
