// Copyright (c) 2018 LunarG Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Validates correctness of the intra-block preconditions of SPIR-V
// instructions.

#include "source/val/validate.h"

#include <string>

#include "source/diagnostic.h"
#include "source/opcode.h"
#include "source/val/instruction.h"
#include "source/val/validation_state.h"

namespace spvtools {
namespace val {

enum {
  // Status right after meeting OpFunction.
  IN_NEW_FUNCTION,
  // Status right after meeting the entry block.
  IN_ENTRY_BLOCK,
  // Status right after meeting non-entry blocks.
  PHI_VALID,
  // Status right after meeting non-OpVariable instructions in the entry block
  // or non-OpPhi instructions in non-entry blocks, except OpLine.
  PHI_AND_VAR_INVALID,
};

spv_result_t ValidateAdjacency(ValidationState_t& _) {
  const auto& instructions = _.ordered_instructions();
  int adjacency_status = PHI_AND_VAR_INVALID;

  for (size_t i = 0; i < instructions.size(); ++i) {
    const auto& inst = instructions[i];
    switch (inst.opcode()) {
      case SpvOpFunction:
      case SpvOpFunctionParameter:
        adjacency_status = IN_NEW_FUNCTION;
        break;
      case SpvOpLabel:
        adjacency_status =
            adjacency_status == IN_NEW_FUNCTION ? IN_ENTRY_BLOCK : PHI_VALID;
        break;
      case SpvOpPhi:
        if (adjacency_status != PHI_VALID) {
          return _.diag(SPV_ERROR_INVALID_DATA, &inst)
                 << "OpPhi must appear within a non-entry block before all "
                 << "non-OpPhi instructions "
                 << "(except for OpLine, which can be mixed with OpPhi).";
        }
        break;
      case SpvOpLine:
      case SpvOpNoLine:
        break;
      case SpvOpLoopMerge:
        adjacency_status = PHI_AND_VAR_INVALID;
        if (i != (instructions.size() - 1)) {
          switch (instructions[i + 1].opcode()) {
            case SpvOpBranch:
            case SpvOpBranchConditional:
              break;
            default:
              return _.diag(SPV_ERROR_INVALID_DATA, &inst)
                     << "OpLoopMerge must immediately precede either an "
                     << "OpBranch or OpBranchConditional instruction. "
                     << "OpLoopMerge must be the second-to-last instruction in "
                     << "its block.";
          }
        }
        break;
      case SpvOpSelectionMerge:
        adjacency_status = PHI_AND_VAR_INVALID;
        if (i != (instructions.size() - 1)) {
          switch (instructions[i + 1].opcode()) {
            case SpvOpBranchConditional:
            case SpvOpSwitch:
              break;
            default:
              return _.diag(SPV_ERROR_INVALID_DATA, &inst)
                     << "OpSelectionMerge must immediately precede either an "
                     << "OpBranchConditional or OpSwitch instruction. "
                     << "OpSelectionMerge must be the second-to-last "
                     << "instruction in its block.";
          }
        }
        break;
      case SpvOpVariable:
        if (inst.GetOperandAs<SpvStorageClass>(2) == SpvStorageClassFunction &&
            adjacency_status != IN_ENTRY_BLOCK) {
          return _.diag(SPV_ERROR_INVALID_DATA, &inst)
                 << "All OpVariable instructions in a function must be the "
                    "first instructions in the first block.";
        }
        break;
      default:
        adjacency_status = PHI_AND_VAR_INVALID;
        break;
    }
  }

  return SPV_SUCCESS;
}

}  // namespace val
}  // namespace spvtools
