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

namespace sh
{

namespace
{

class ValidateGlobalInitializerTraverser : public TIntermTraverser
{
  public:
    ValidateGlobalInitializerTraverser(const TParseContext *context);

    void visitSymbol(TIntermSymbol *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; }
    bool issueWarning() const { return mIssueWarning; }

  private:
    const TParseContext *mContext;
    bool mIsValid;
    bool mIssueWarning;
};

void ValidateGlobalInitializerTraverser::visitSymbol(TIntermSymbol *node)
{
    const TSymbol *sym =
        mContext->symbolTable.find(node->getSymbol(), mContext->getShaderVersion());
    if (sym->isVariable())
    {
        // ESSL 1.00 section 4.3 (or ESSL 3.00 section 4.3):
        // Global initializers must be constant expressions.
        const TVariable *var = static_cast<const TVariable *>(sym);
        switch (var->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 (mContext->getShaderVersion() >= 300)
                {
                    mIsValid = false;
                }
                else
                {
                    mIssueWarning = true;
                }
                break;
            default:
                mIsValid = false;
        }
    }
}

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(const TParseContext *context)
    : TIntermTraverser(true, false, false), mContext(context), mIsValid(true), mIssueWarning(false)
{
}

}  // namespace

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

}  // namespace sh
