Edit

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

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2016-12-12 14:42:19
    Hash : d7b1ab58
    Message : Fix up translator style. Using git cl format. BUG=angleproject:650 Change-Id: I7d3f98d2b0dcfb0a8de6c35327db74e55c28d761 Reviewed-on: https://chromium-review.googlesource.com/419059 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/compiler/translator/ValidateGlobalInitializer.cpp
  • //
    // 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
        // EOpFunctionCall.
        if (node->getOp() == EOpFunctionCall)
        {
            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