//
// Copyright (c) 2002-2015 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.
//

#include "compiler/translator/ValidateGlobalInitializer.h"

#include "compiler/translator/tree_util/IntermTraverse.h"

namespace sh
{

namespace
{

const int kMaxAllowedTraversalDepth = 256;

class ValidateGlobalInitializerTraverser : public TIntermTraverser
{
  public:
    ValidateGlobalInitializerTraverser(int shaderVersion);

    void visitSymbol(TIntermSymbol *node) override;
    void visitConstantUnion(TIntermConstantUnion *node) override;
    bool visitAggregate(Visit visit, TIntermAggregate *node) override;
    bool visitBinary(Visit visit, TIntermBinary *node) override;
    bool visitUnary(Visit visit, TIntermUnary *node) override;

    bool isValid() const { return mIsValid && mMaxDepth < mMaxAllowedDepth; }
    bool issueWarning() const { return mIssueWarning; }

  private:
    int mShaderVersion;
    bool mIsValid;
    bool mIssueWarning;
};

void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node)
{
    // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):
    // Global initializers must be constant expressions.
    switch (node->getType().getQualifier())
    {
        case EvqConst:
            break;
        case EvqGlobal:
        case EvqTemporary:
        case EvqUniform:
            // We allow these cases to be compatible with legacy ESSL 1.00 content.
            // Implement stricter rules for ESSL 3.00 since there's no legacy content to deal
            // with.
            if (mShaderVersion >= 300)
            {
                mIsValid = false;
            }
            else
            {
                mIssueWarning = true;
            }
            break;
        default:
            mIsValid = false;
    }
}

void ValidateGlobalInitializerTraverser::visitConstantUnion(TIntermConstantUnion *node)
{
    // Constant unions that are not constant expressions may result from folding a ternary
    // expression.
    switch (node->getType().getQualifier())
    {
        case EvqConst:
            break;
        case EvqTemporary:
            if (mShaderVersion >= 300)
            {
                mIsValid = false;
            }
            else
            {
                mIssueWarning = true;
            }
            break;
        default:
            UNREACHABLE();
    }
}

bool ValidateGlobalInitializerTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
{
    // Disallow calls to user-defined functions and texture lookup functions in global variable
    // initializers.
    // This is done simply by disabling all function calls - built-in math functions don't use
    // the function call ops.
    if (node->isFunctionCall())
    {
        mIsValid = false;
    }
    return true;
}

bool ValidateGlobalInitializerTraverser::visitBinary(Visit visit, TIntermBinary *node)
{
    if (node->isAssignment())
    {
        mIsValid = false;
    }
    return true;
}

bool ValidateGlobalInitializerTraverser::visitUnary(Visit visit, TIntermUnary *node)
{
    if (node->isAssignment())
    {
        mIsValid = false;
    }
    return true;
}

ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(int shaderVersion)
    : TIntermTraverser(true, false, false, nullptr),
      mShaderVersion(shaderVersion),
      mIsValid(true),
      mIssueWarning(false)
{
    setMaxAllowedDepth(kMaxAllowedTraversalDepth);
}

}  // namespace

bool ValidateGlobalInitializer(TIntermTyped *initializer, int shaderVersion, bool *warning)
{
    ValidateGlobalInitializerTraverser validate(shaderVersion);
    initializer->traverse(&validate);
    ASSERT(warning != nullptr);
    *warning = validate.issueWarning();
    return validate.isValid();
}

}  // namespace sh
