Edit

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

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2016-12-16 12:01:18
    Hash : 77ba408a
    Message : Unify Diagnostics interface Use the same kind of interface for reporting preprocessor errors as for reporting regular compiler errors, and make global errors like having too many uniforms also go through Diagnostics. Also don't create std::string objects unnecessarily. Includes cleanups of some dead code related to reporting errors. BUG=angleproject:1670 TEST=angle_unittests Change-Id: I3ee794d32ddeec1826bdf1b76b558f35259f82c0 Reviewed-on: https://chromium-review.googlesource.com/421527 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>

  • src/compiler/translator/DirectiveHandler.cpp
  • //
    // Copyright (c) 2012-2013 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/DirectiveHandler.h"
    
    #include <sstream>
    
    #include "angle_gl.h"
    #include "common/debug.h"
    #include "compiler/translator/Diagnostics.h"
    
    namespace sh
    {
    
    static TBehavior getBehavior(const std::string &str)
    {
        const char kRequire[] = "require";
        const char kEnable[]  = "enable";
        const char kDisable[] = "disable";
        const char kWarn[]    = "warn";
    
        if (str == kRequire)
            return EBhRequire;
        else if (str == kEnable)
            return EBhEnable;
        else if (str == kDisable)
            return EBhDisable;
        else if (str == kWarn)
            return EBhWarn;
        return EBhUndefined;
    }
    
    TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
                                         TDiagnostics &diagnostics,
                                         int &shaderVersion,
                                         sh::GLenum shaderType,
                                         bool debugShaderPrecisionSupported)
        : mExtensionBehavior(extBehavior),
          mDiagnostics(diagnostics),
          mShaderVersion(shaderVersion),
          mShaderType(shaderType),
          mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
    {
    }
    
    TDirectiveHandler::~TDirectiveHandler()
    {
    }
    
    void TDirectiveHandler::handleError(const pp::SourceLocation &loc, const std::string &msg)
    {
        mDiagnostics.error(loc, msg.c_str(), "");
    }
    
    void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc,
                                         const std::string &name,
                                         const std::string &value,
                                         bool stdgl)
    {
        if (stdgl)
        {
            const char kInvariant[] = "invariant";
            const char kAll[]       = "all";
    
            if (name == kInvariant && value == kAll)
            {
                if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
                {
                    // ESSL 3.00.4 section 4.6.1
                    mDiagnostics.error(
                        loc, "#pragma STDGL invariant(all) can not be used in fragment shader",
                        name.c_str());
                }
                mPragma.stdgl.invariantAll = true;
            }
            // The STDGL pragma is used to reserve pragmas for use by future
            // revisions of GLSL.  Do not generate an error on unexpected
            // name and value.
            return;
        }
        else
        {
            const char kOptimize[]             = "optimize";
            const char kDebug[]                = "debug";
            const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
            const char kOn[]                   = "on";
            const char kOff[]                  = "off";
    
            bool invalidValue = false;
            if (name == kOptimize)
            {
                if (value == kOn)
                    mPragma.optimize = true;
                else if (value == kOff)
                    mPragma.optimize = false;
                else
                    invalidValue = true;
            }
            else if (name == kDebug)
            {
                if (value == kOn)
                    mPragma.debug = true;
                else if (value == kOff)
                    mPragma.debug = false;
                else
                    invalidValue = true;
            }
            else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
            {
                if (value == kOn)
                    mPragma.debugShaderPrecision = true;
                else if (value == kOff)
                    mPragma.debugShaderPrecision = false;
                else
                    invalidValue = true;
            }
            else
            {
                mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
                return;
            }
    
            if (invalidValue)
            {
                mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());
            }
        }
    }
    
    void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc,
                                            const std::string &name,
                                            const std::string &behavior)
    {
        const char kExtAll[] = "all";
    
        TBehavior behaviorVal = getBehavior(behavior);
        if (behaviorVal == EBhUndefined)
        {
            mDiagnostics.error(loc, "behavior invalid", name.c_str());
            return;
        }
    
        if (name == kExtAll)
        {
            if (behaviorVal == EBhRequire)
            {
                mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());
            }
            else if (behaviorVal == EBhEnable)
            {
                mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());
            }
            else
            {
                for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
                     iter != mExtensionBehavior.end(); ++iter)
                    iter->second = behaviorVal;
            }
            return;
        }
    
        TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
        if (iter != mExtensionBehavior.end())
        {
            iter->second = behaviorVal;
            return;
        }
    
        switch (behaviorVal)
        {
            case EBhRequire:
                mDiagnostics.error(loc, "extension is not supported", name.c_str());
                break;
            case EBhEnable:
            case EBhWarn:
            case EBhDisable:
                mDiagnostics.warning(loc, "extension is not supported", name.c_str());
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void TDirectiveHandler::handleVersion(const pp::SourceLocation &loc, int version)
    {
        if (version == 100 || version == 300 || version == 310)
        {
            mShaderVersion = version;
        }
        else
        {
            std::stringstream stream;
            stream << version;
            std::string str = stream.str();
            mDiagnostics.error(loc, "version number not supported", str.c_str());
        }
    }
    
    }  // namespace sh