// 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 "validate.h"

#include <string>

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

namespace spvtools {

spv_result_t ValidateAdjacency(ValidationState_t& _) {
  const auto& instructions = _.ordered_instructions();
  for (auto i = instructions.cbegin(); i != instructions.cend(); ++i) {
    switch (i->opcode()) {
      case SpvOpPhi:
        if (i != instructions.cbegin()) {
          switch (prev(i)->opcode()) {
            case SpvOpLabel:
            case SpvOpPhi:
            case SpvOpLine:
              break;
            default:
              return _.diag(SPV_ERROR_INVALID_DATA)
                     << "OpPhi must appear before all non-OpPhi instructions "
                     << "(except for OpLine, which can be mixed with OpPhi).";
          }
        }
        break;
      case SpvOpLoopMerge:
        if (next(i) != instructions.cend()) {
          switch (next(i)->opcode()) {
            case SpvOpBranch:
            case SpvOpBranchConditional:
              break;
            default:
              return _.diag(SPV_ERROR_INVALID_DATA)
                     << "OpLoopMerge must immediately precede either an "
                     << "OpBranch or OpBranchConditional instruction. "
                     << "OpLoopMerge must be the second-to-last instruction in "
                     << "its block.";
          }
        }
        break;
      case SpvOpSelectionMerge:
        if (next(i) != instructions.cend()) {
          switch (next(i)->opcode()) {
            case SpvOpBranchConditional:
            case SpvOpSwitch:
              break;
            default:
              return _.diag(SPV_ERROR_INVALID_DATA)
                     << "OpSelectionMerge must immediately precede either an "
                     << "OpBranchConditional or OpSwitch instruction. "
                     << "OpSelectionMerge must be the second-to-last "
                     << "instruction in its block.";
          }
        }
      default:
        break;
    }
  }

  return SPV_SUCCESS;
}

}  // namespace spvtools
