| // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "DirectiveHandler.h" |
| |
| #include <sstream> |
| |
| #include "debug.h" |
| #include "Diagnostics.h" |
| |
| static TBehavior getBehavior(const std::string& str) |
| { |
| static const char kRequire[] = "require"; |
| static const char kEnable[] = "enable"; |
| static const char kDisable[] = "disable"; |
| static 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) |
| : mExtensionBehavior(extBehavior), |
| mDiagnostics(diagnostics), |
| mShaderVersion(shaderVersion) |
| { |
| } |
| |
| TDirectiveHandler::~TDirectiveHandler() |
| { |
| } |
| |
| void TDirectiveHandler::handleError(const pp::SourceLocation& loc, |
| const std::string& msg) |
| { |
| mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", ""); |
| } |
| |
| void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc, |
| const std::string& name, |
| const std::string& value, |
| bool stdgl) |
| { |
| static const char kSTDGL[] = "STDGL"; |
| static const char kOptimize[] = "optimize"; |
| static const char kDebug[] = "debug"; |
| static const char kOn[] = "on"; |
| static const char kOff[] = "off"; |
| |
| bool invalidValue = false; |
| if (stdgl || (name == kSTDGL)) |
| { |
| // The STDGL pragma is used to reserve pragmas for use by future |
| // revisions of GLSL. Ignore it. |
| return; |
| } |
| else 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 |
| { |
| mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name); |
| return; |
| } |
| |
| if (invalidValue) |
| mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, |
| "invalid pragma value", value, |
| "'on' or 'off' expected"); |
| } |
| |
| void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc, |
| const std::string& name, |
| const std::string& behavior) |
| { |
| static const char kExtAll[] = "all"; |
| |
| TBehavior behaviorVal = getBehavior(behavior); |
| if (behaviorVal == EBhUndefined) |
| { |
| mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, |
| "behavior", name, "invalid"); |
| return; |
| } |
| |
| if (name == kExtAll) |
| { |
| if (behaviorVal == EBhRequire) |
| { |
| mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, |
| "extension", name, |
| "cannot have 'require' behavior"); |
| } |
| else if (behaviorVal == EBhEnable) |
| { |
| mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, |
| "extension", name, |
| "cannot have 'enable' behavior"); |
| } |
| 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; |
| } |
| |
| pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR; |
| switch (behaviorVal) { |
| case EBhRequire: |
| severity = pp::Diagnostics::PP_ERROR; |
| break; |
| case EBhEnable: |
| case EBhWarn: |
| case EBhDisable: |
| severity = pp::Diagnostics::PP_WARNING; |
| break; |
| default: |
| UNREACHABLE(behaviorVal); |
| break; |
| } |
| mDiagnostics.writeInfo(severity, loc, |
| "extension", name, "is not supported"); |
| } |
| |
| void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc, |
| int version) |
| { |
| if (version == 100 || |
| version == 300) |
| { |
| mShaderVersion = version; |
| } |
| else |
| { |
| std::stringstream stream; |
| stream << version; |
| std::string str = stream.str(); |
| mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, |
| "version number", str, "not supported"); |
| } |
| } |