Edit

kc3-lang/angle/src/compiler/translator/ValidateGlobalInitializer.cpp

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2021-06-13 01:09:27
    Hash : 8b869a95
    Message : Translator: Generate Ops for all built-in functions EOpCallBuiltInFunction is removed in this change, as well as the "op": "auto" property in builtin_function_declarations.txt. Instead, gen_builtin_symbols.py automatically generates Ops for every built-in function and generates the TOperator enum accordingly. This simplifies SPIR-V code generation by allowing switches to be used on operators instead of string comparisons. Bug: angleproject:4589 Bug: angleproject:4889 Change-Id: Ia351524400b0e12a10a5572e27e9b88c6ec2e61c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2958869 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Tim Van Patten <timvp@google.com>

  • src/compiler/translator/ValidateGlobalInitializer.cpp
  • //
    // Copyright 2002 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,
                                           bool isWebGL,
                                           bool hasExtNonConstGlobalInitializers);
    
        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:
        ANGLE_INLINE void onNonConstInitializerVisit(bool accept)
        {
            if (accept)
            {
                if (!mExtNonConstGlobalInitializers)
                {
                    mIssueWarning = true;
                }
            }
            else
            {
                mIsValid = false;
            }
        }
    
        int mShaderVersion;
        bool mIsWebGL;
        bool mExtNonConstGlobalInitializers;
        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.
                onNonConstInitializerVisit(mExtNonConstGlobalInitializers ||
                                           ((mShaderVersion < 300) && mIsWebGL));
                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:
                onNonConstInitializerVisit(mExtNonConstGlobalInitializers ||
                                           ((mShaderVersion < 300) && mIsWebGL));
                break;
            default:
                UNREACHABLE();
        }
    }
    
    bool ValidateGlobalInitializerTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
    {
        // Disallow calls to user-defined functions and texture lookup functions in global variable
        // initializers.  For simplicity, all non-math built-in calls are disallowed.
        if (node->isFunctionCall() ||
            (BuiltInGroup::IsBuiltIn(node->getOp()) && !BuiltInGroup::IsMath(node->getOp())))
        {
            onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
        }
        return true;
    }
    
    bool ValidateGlobalInitializerTraverser::visitBinary(Visit visit, TIntermBinary *node)
    {
        if (node->isAssignment())
        {
            onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
        }
        return true;
    }
    
    bool ValidateGlobalInitializerTraverser::visitUnary(Visit visit, TIntermUnary *node)
    {
        if (node->isAssignment())
        {
            onNonConstInitializerVisit(mExtNonConstGlobalInitializers);
        }
        return true;
    }
    
    ValidateGlobalInitializerTraverser::ValidateGlobalInitializerTraverser(
        int shaderVersion,
        bool isWebGL,
        bool hasExtNonConstGlobalInitializers)
        : TIntermTraverser(true, false, false, nullptr),
          mShaderVersion(shaderVersion),
          mIsWebGL(isWebGL),
          mExtNonConstGlobalInitializers(hasExtNonConstGlobalInitializers),
          mIsValid(true),
          mIssueWarning(false)
    {
        setMaxAllowedDepth(kMaxAllowedTraversalDepth);
    }
    
    }  // namespace
    
    bool ValidateGlobalInitializer(TIntermTyped *initializer,
                                   int shaderVersion,
                                   bool isWebGL,
                                   bool hasExtNonConstGlobalInitializers,
                                   bool *warning)
    {
        ValidateGlobalInitializerTraverser validate(shaderVersion, isWebGL,
                                                    hasExtNonConstGlobalInitializers);
        initializer->traverse(&validate);
        ASSERT(warning != nullptr);
        *warning = validate.issueWarning();
        return validate.isValid();
    }
    
    }  // namespace sh