// Copyright 2021 The Tint Authors.
//
// 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.

#include "src/sem/variable.h"

#include <utility>

#include "src/ast/identifier_expression.h"
#include "src/ast/variable.h"

TINT_INSTANTIATE_TYPEINFO(tint::sem::Variable);
TINT_INSTANTIATE_TYPEINFO(tint::sem::GlobalVariable);
TINT_INSTANTIATE_TYPEINFO(tint::sem::LocalVariable);
TINT_INSTANTIATE_TYPEINFO(tint::sem::Parameter);
TINT_INSTANTIATE_TYPEINFO(tint::sem::VariableUser);

namespace tint {
namespace sem {

Variable::Variable(const ast::Variable* declaration,
                   const sem::Type* type,
                   ast::StorageClass storage_class,
                   ast::Access access)
    : declaration_(declaration),
      type_(type),
      storage_class_(storage_class),
      access_(access) {}

Variable::~Variable() = default;

LocalVariable::LocalVariable(const ast::Variable* declaration,
                             const sem::Type* type,
                             ast::StorageClass storage_class,
                             ast::Access access)
    : Base(declaration, type, storage_class, access) {}

LocalVariable::~LocalVariable() = default;

GlobalVariable::GlobalVariable(const ast::Variable* declaration,
                               const sem::Type* type,
                               ast::StorageClass storage_class,
                               ast::Access access,
                               sem::BindingPoint binding_point)
    : Base(declaration, type, storage_class, access),
      binding_point_(binding_point),
      is_pipeline_constant_(false) {}

GlobalVariable::GlobalVariable(const ast::Variable* declaration,
                               const sem::Type* type,
                               uint16_t constant_id)
    : Base(declaration,
           type,
           ast::StorageClass::kNone,
           ast::Access::kReadWrite),
      is_pipeline_constant_(true),
      constant_id_(constant_id) {}

GlobalVariable::~GlobalVariable() = default;

Parameter::Parameter(const ast::Variable* declaration,
                     const sem::Type* type,
                     ast::StorageClass storage_class,
                     ast::Access access,
                     const ParameterUsage usage /* = ParameterUsage::kNone */)
    : Base(declaration, type, storage_class, access), usage_(usage) {}

Parameter::~Parameter() = default;

VariableUser::VariableUser(ast::IdentifierExpression* declaration,
                           const sem::Type* type,
                           Statement* statement,
                           sem::Variable* variable,
                           Constant constant_value)
    : Base(declaration, type, statement, std::move(constant_value)),
      variable_(variable) {}

}  // namespace sem
}  // namespace tint
