//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ReplaceShadowingVariables.cpp: Replace all references to any variable in the AST that is
// a redefinition of a variable in a nested scope. This is a useful for ESSL 1.00 shaders
// where the spec section "4.2.3. Redeclaring Variables" states "However, a nested scope can
// override an outer scope's declaration of a particular variable name." This is changed in
// later spec versions, such as ESSL 3.20 spec which states "If [a variable] is declared as
// a parameter in a function definition, it is scoped until the end of that function
// definition. A function's parameter declarations and body together form a single scope."
//
// So this class is useful when translating from ESSL 1.00 shaders, where function body var
// redefinition is allowed, to later shader versions where it's not allowed.
//

#include "compiler/translator/tree_util/ReplaceShadowingVariables.h"
#include "compiler/translator/tree_util/ReplaceVariable.h"

#include "compiler/translator/Compiler.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/Symbol.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/IntermTraverse.h"

#include <unordered_set>

namespace sh
{

namespace
{

// Custom struct to queue up any replacements until after AST traversal
struct DeferredReplacementBlock
{
    const TVariable *originalVariable;  // variable to be replaced
    TVariable *replacementVariable;     // variable to replace originalVar with
    TIntermBlock *functionBody;         // function body where replacement occurs
};

class ReplaceShadowingVariablesTraverser : public TIntermTraverser
{
  public:
    ReplaceShadowingVariablesTraverser(TSymbolTable *symbolTable)
        : TIntermTraverser(true, true, true, symbolTable), mParameterNames{}, mFunctionBody(nullptr)
    {}

    bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override
    {
        // In pre-visit of function, record params
        if (visit == PreVisit)
        {
            ASSERT(mParameterNames.size() == 0);
            const TFunction *func = node->getFunctionPrototype()->getFunction();
            // Grab all of the parameter names from the function prototype
            size_t paramCount = func->getParamCount();
            for (size_t i = 0; i < paramCount; ++i)
            {
                mParameterNames.emplace(std::string(func->getParam(i)->name().data()));
            }
            if (mParameterNames.size() > 0)
                mFunctionBody = node->getBody();
        }
        else if (visit == PostVisit)
        {
            // Clear data saved from function definition
            mParameterNames.clear();
            mFunctionBody = nullptr;
        }
        return true;
    }
    bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
    {
        if (visit == PreVisit && mParameterNames.size() != 0)
        {
            TIntermSequence *decls = node->getSequence();
            for (auto &declVector : *decls)
            {
                // no init case
                TIntermSymbol *symNode = declVector->getAsSymbolNode();
                if (symNode == nullptr)
                {
                    // init case
                    TIntermBinary *binaryNode = declVector->getAsBinaryNode();
                    ASSERT(binaryNode->getOp() == EOpInitialize);
                    symNode = binaryNode->getLeft()->getAsSymbolNode();
                }
                ASSERT(symNode != nullptr);
                std::string varName = std::string(symNode->variable().name().data());
                if (mParameterNames.count(varName) > 0)
                {
                    // We found a redefined var so queue replacement
                    mReplacements.emplace_back(DeferredReplacementBlock{
                        &symNode->variable(),
                        CreateTempVariable(mSymbolTable, &symNode->variable().getType()),
                        mFunctionBody});
                }
            }
        }
        return true;
    }
    // Perform replacement of vars for any deferred replacements that were identified
    ANGLE_NO_DISCARD bool executeReplacements(TCompiler *compiler)
    {
        for (DeferredReplacementBlock &replace : mReplacements)
        {
            if (!ReplaceVariable(compiler, replace.functionBody, replace.originalVariable,
                                 replace.replacementVariable))
            {
                return false;
            }
        }
        mReplacements.clear();
        return true;
    }

  private:
    std::unordered_set<std::string> mParameterNames;
    TIntermBlock *mFunctionBody;
    std::vector<DeferredReplacementBlock> mReplacements;
};

}  // anonymous namespace

// Replaces every occurrence of a variable with another variable.
ANGLE_NO_DISCARD bool ReplaceShadowingVariables(TCompiler *compiler,
                                                TIntermBlock *root,
                                                TSymbolTable *symbolTable)
{
    ReplaceShadowingVariablesTraverser traverser(symbolTable);
    root->traverse(&traverser);
    if (!traverser.executeReplacements(compiler))
    {
        return false;
    }
    return traverser.updateTree(compiler, root);
}

}  // namespace sh
