michael@0: // michael@0: // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: #include "compiler/DirectiveHandler.h" michael@0: michael@0: #include michael@0: michael@0: #include "compiler/compiler_debug.h" michael@0: #include "compiler/Diagnostics.h" michael@0: michael@0: static TBehavior getBehavior(const std::string& str) michael@0: { michael@0: static const std::string kRequire("require"); michael@0: static const std::string kEnable("enable"); michael@0: static const std::string kDisable("disable"); michael@0: static const std::string kWarn("warn"); michael@0: michael@0: if (str == kRequire) return EBhRequire; michael@0: else if (str == kEnable) return EBhEnable; michael@0: else if (str == kDisable) return EBhDisable; michael@0: else if (str == kWarn) return EBhWarn; michael@0: return EBhUndefined; michael@0: } michael@0: michael@0: TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior, michael@0: TDiagnostics& diagnostics) michael@0: : mExtensionBehavior(extBehavior), michael@0: mDiagnostics(diagnostics) michael@0: { michael@0: } michael@0: michael@0: TDirectiveHandler::~TDirectiveHandler() michael@0: { michael@0: } michael@0: michael@0: void TDirectiveHandler::handleError(const pp::SourceLocation& loc, michael@0: const std::string& msg) michael@0: { michael@0: mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, msg, "", ""); michael@0: } michael@0: michael@0: void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, michael@0: const std::string& name, michael@0: const std::string& value) michael@0: { michael@0: static const std::string kSTDGL("STDGL"); michael@0: static const std::string kOptimize("optimize"); michael@0: static const std::string kDebug("debug"); michael@0: static const std::string kOn("on"); michael@0: static const std::string kOff("off"); michael@0: michael@0: bool invalidValue = false; michael@0: if (name == kSTDGL) michael@0: { michael@0: // The STDGL pragma is used to reserve pragmas for use by future michael@0: // revisions of GLSL. Ignore it. michael@0: return; michael@0: } michael@0: else if (name == kOptimize) michael@0: { michael@0: if (value == kOn) mPragma.optimize = true; michael@0: else if (value == kOff) mPragma.optimize = false; michael@0: else invalidValue = true; michael@0: } michael@0: else if (name == kDebug) michael@0: { michael@0: if (value == kOn) mPragma.debug = true; michael@0: else if (value == kOff) mPragma.debug = false; michael@0: else invalidValue = true; michael@0: } michael@0: else michael@0: { michael@0: mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name); michael@0: return; michael@0: } michael@0: michael@0: if (invalidValue) michael@0: mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, michael@0: "invalid pragma value", value, michael@0: "'on' or 'off' expected"); michael@0: } michael@0: michael@0: void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, michael@0: const std::string& name, michael@0: const std::string& behavior) michael@0: { michael@0: static const std::string kExtAll("all"); michael@0: michael@0: TBehavior behaviorVal = getBehavior(behavior); michael@0: if (behaviorVal == EBhUndefined) michael@0: { michael@0: mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, michael@0: "behavior", name, "invalid"); michael@0: return; michael@0: } michael@0: michael@0: if (name == kExtAll) michael@0: { michael@0: if (behaviorVal == EBhRequire) michael@0: { michael@0: mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, michael@0: "extension", name, michael@0: "cannot have 'require' behavior"); michael@0: } michael@0: else if (behaviorVal == EBhEnable) michael@0: { michael@0: mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, michael@0: "extension", name, michael@0: "cannot have 'enable' behavior"); michael@0: } michael@0: else michael@0: { michael@0: for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin(); michael@0: iter != mExtensionBehavior.end(); ++iter) michael@0: iter->second = behaviorVal; michael@0: } michael@0: return; michael@0: } michael@0: michael@0: TExtensionBehavior::iterator iter = mExtensionBehavior.find(name); michael@0: if (iter != mExtensionBehavior.end()) michael@0: { michael@0: iter->second = behaviorVal; michael@0: return; michael@0: } michael@0: michael@0: pp::Diagnostics::Severity severity = pp::Diagnostics::ERROR; michael@0: switch (behaviorVal) { michael@0: case EBhRequire: michael@0: severity = pp::Diagnostics::ERROR; michael@0: break; michael@0: case EBhEnable: michael@0: case EBhWarn: michael@0: case EBhDisable: michael@0: severity = pp::Diagnostics::WARNING; michael@0: break; michael@0: default: michael@0: UNREACHABLE(); michael@0: break; michael@0: } michael@0: mDiagnostics.writeInfo(severity, loc, michael@0: "extension", name, "is not supported"); michael@0: } michael@0: michael@0: void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc, michael@0: int version) michael@0: { michael@0: static const int kVersion = 100; michael@0: michael@0: if (version != kVersion) michael@0: { michael@0: std::stringstream stream; michael@0: stream << version; michael@0: std::string str = stream.str(); michael@0: mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, michael@0: "version number", str, "not supported"); michael@0: } michael@0: }