18b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org//
20bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
38b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org// Use of this source code is governed by a BSD-style license that can be
48b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org// found in the LICENSE file.
58b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org//
68b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
717732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/DirectiveHandler.h"
88b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
98b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org#include <sstream>
108b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
1117732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/compilerdebug.h"
1217732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/Diagnostics.h"
138b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
148b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.orgstatic TBehavior getBehavior(const std::string& str)
158b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org{
168b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kRequire("require");
178b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kEnable("enable");
188b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kDisable("disable");
198b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kWarn("warn");
208b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
218b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    if (str == kRequire) return EBhRequire;
228b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    else if (str == kEnable) return EBhEnable;
238b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    else if (str == kDisable) return EBhDisable;
248b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    else if (str == kWarn) return EBhWarn;
258b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    return EBhUndefined;
268b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org}
278b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
288b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.orgTDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
295524db0c05c8df6002489a077b18dd6fd5746448shannon.woods%transgaming.com@gtempaccount.com                                     TDiagnostics& diagnostics,
305524db0c05c8df6002489a077b18dd6fd5746448shannon.woods%transgaming.com@gtempaccount.com                                     int& shaderVersion)
3173bc298e3f0688d40c07c13d94197c4146ae1b49alokp@chromium.org    : mExtensionBehavior(extBehavior),
325524db0c05c8df6002489a077b18dd6fd5746448shannon.woods%transgaming.com@gtempaccount.com      mDiagnostics(diagnostics),
335524db0c05c8df6002489a077b18dd6fd5746448shannon.woods%transgaming.com@gtempaccount.com      mShaderVersion(shaderVersion)
348b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org{
358b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org}
368b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
378b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.orgTDirectiveHandler::~TDirectiveHandler()
388b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org{
398b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org}
408b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
418b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.orgvoid TDirectiveHandler::handleError(const pp::SourceLocation& loc,
428b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                    const std::string& msg)
438b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org{
447f2d7945ee702241829727751bd4c7424662b225Shannon Woods    mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
458b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org}
468b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
478b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.orgvoid TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
488b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                     const std::string& name,
498b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                     const std::string& value)
508b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org{
518b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kSTDGL("STDGL");
528b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kOptimize("optimize");
538b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kDebug("debug");
548b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kOn("on");
558b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kOff("off");
568b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
578b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    bool invalidValue = false;
588b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    if (name == kSTDGL)
598b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    {
608b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        // The STDGL pragma is used to reserve pragmas for use by future
618b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        // revisions of GLSL. Ignore it.
628b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        return;
638b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
648b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    else if (name == kOptimize)
658b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    {
668b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        if (value == kOn) mPragma.optimize = true;
678b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        else if (value == kOff) mPragma.optimize = false;
688b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        else invalidValue = true;
698b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
708b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    else if (name == kDebug)
718b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    {
728b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        if (value == kOn) mPragma.debug = true;
738b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        else if (value == kOff) mPragma.debug = false;
748b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        else invalidValue = true;
758b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
768b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    else
778b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    {
787f2d7945ee702241829727751bd4c7424662b225Shannon Woods        mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
798b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        return;
808b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
818b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
828b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    if (invalidValue)
837f2d7945ee702241829727751bd4c7424662b225Shannon Woods      mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
848b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                             "invalid pragma value", value,
858b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                             "'on' or 'off' expected");
868b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org}
878b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
888b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.orgvoid TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
898b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                        const std::string& name,
908b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                        const std::string& behavior)
918b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org{
928b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    static const std::string kExtAll("all");
938b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
948b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    TBehavior behaviorVal = getBehavior(behavior);
958b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    if (behaviorVal == EBhUndefined)
968b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    {
977f2d7945ee702241829727751bd4c7424662b225Shannon Woods        mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
988b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                               "behavior", name, "invalid");
998b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        return;
1008b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
1018b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
1028b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    if (name == kExtAll)
1038b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    {
1048b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        if (behaviorVal == EBhRequire)
1058b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        {
1067f2d7945ee702241829727751bd4c7424662b225Shannon Woods            mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
1078b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                   "extension", name,
1088b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                   "cannot have 'require' behavior");
1098b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        }
1108b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        else if (behaviorVal == EBhEnable)
1118b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        {
1127f2d7945ee702241829727751bd4c7424662b225Shannon Woods            mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
1138b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                   "extension", name,
1148b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                   "cannot have 'enable' behavior");
1158b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        }
1168b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        else
1178b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        {
11873bc298e3f0688d40c07c13d94197c4146ae1b49alokp@chromium.org            for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
11973bc298e3f0688d40c07c13d94197c4146ae1b49alokp@chromium.org                 iter != mExtensionBehavior.end(); ++iter)
1208b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                iter->second = behaviorVal;
1218b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        }
1228b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        return;
1238b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
1248b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
12573bc298e3f0688d40c07c13d94197c4146ae1b49alokp@chromium.org    TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
12673bc298e3f0688d40c07c13d94197c4146ae1b49alokp@chromium.org    if (iter != mExtensionBehavior.end())
1278b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    {
1288b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        iter->second = behaviorVal;
1298b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        return;
1308b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
1318b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
1327f2d7945ee702241829727751bd4c7424662b225Shannon Woods    pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
1338b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    switch (behaviorVal) {
1348b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org      case EBhRequire:
1357f2d7945ee702241829727751bd4c7424662b225Shannon Woods        severity = pp::Diagnostics::PP_ERROR;
1368b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        break;
1378b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org      case EBhEnable:
1388b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org      case EBhWarn:
1398b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org      case EBhDisable:
1407f2d7945ee702241829727751bd4c7424662b225Shannon Woods        severity = pp::Diagnostics::PP_WARNING;
1418b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        break;
1428b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org      default:
1438b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        UNREACHABLE();
1448b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        break;
1458b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
1468b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    mDiagnostics.writeInfo(severity, loc,
1478b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                           "extension", name, "is not supported");
1488b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org}
1498b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org
1508b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.orgvoid TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
1518b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                                      int version)
1528b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org{
1530bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com    if (version == 100 ||
1540bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com        version == 300)
1550bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com    {
1565524db0c05c8df6002489a077b18dd6fd5746448shannon.woods%transgaming.com@gtempaccount.com        mShaderVersion = version;
1570bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com    }
1580bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com    else
1598b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    {
1608b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        std::stringstream stream;
1618b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        stream << version;
1628b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org        std::string str = stream.str();
1637f2d7945ee702241829727751bd4c7424662b225Shannon Woods        mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
1648b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org                               "version number", str, "not supported");
1658b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org    }
1668b851c6db4ba79cbd5b658e799076b8e7a908f6dalokp@chromium.org}
167