// 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/tint/lang/wgsl/sem/variable.h"

#include <utility>

#include "src/tint/lang/core/type/pointer.h"
#include "src/tint/lang/wgsl/ast/identifier_expression.h"
#include "src/tint/lang/wgsl/ast/parameter.h"
#include "src/tint/lang/wgsl/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::sem {
Variable::Variable(const ast::Variable* declaration) : declaration_(declaration) {}

Variable::~Variable() = default;

LocalVariable::LocalVariable(const ast::Variable* declaration, const sem::Statement* statement)
    : Base(declaration), statement_(statement) {}

LocalVariable::~LocalVariable() = default;

GlobalVariable::GlobalVariable(const ast::Variable* declaration) : Base(declaration) {}

GlobalVariable::~GlobalVariable() = default;

void GlobalVariable::AddTransitivelyReferencedOverride(const GlobalVariable* var) {
    if (transitively_referenced_overrides_.Add(var)) {
        for (auto* ref : var->TransitivelyReferencedOverrides()) {
            AddTransitivelyReferencedOverride(ref);
        }
    }
}

Parameter::Parameter(const ast::Parameter* declaration,
                     uint32_t index /* = 0 */,
                     const core::type::Type* type /* = nullptr */,
                     core::ParameterUsage usage /* = core::ParameterUsage::kNone */)
    : Base(declaration), index_(index), usage_(usage) {
    SetType(type);
}

Parameter::~Parameter() = default;

VariableUser::VariableUser(const ast::IdentifierExpression* declaration,
                           core::EvaluationStage stage,
                           Statement* statement,
                           const core::constant::Value* constant,
                           sem::Variable* variable)
    : Base(declaration,
           variable->Type(),
           stage,
           statement,
           constant,
           /* has_side_effects */ false),
      variable_(variable) {
    auto* type = variable->Type();
    if (type->Is<core::type::Pointer>() && variable->Initializer()) {
        root_identifier_ = variable->Initializer()->RootIdentifier();
    } else {
        root_identifier_ = variable;
    }
}

VariableUser::~VariableUser() = default;

}  // namespace tint::sem
