Home | History | Annotate | Download | only in compiler
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "DirectiveHandler.h"
     16 
     17 #include <sstream>
     18 
     19 #include "debug.h"
     20 #include "Diagnostics.h"
     21 
     22 static TBehavior getBehavior(const std::string& str)
     23 {
     24 	static const std::string kRequire("require");
     25 	static const std::string kEnable("enable");
     26 	static const std::string kDisable("disable");
     27 	static const std::string kWarn("warn");
     28 
     29 	if (str == kRequire) return EBhRequire;
     30 	else if (str == kEnable) return EBhEnable;
     31 	else if (str == kDisable) return EBhDisable;
     32 	else if (str == kWarn) return EBhWarn;
     33 	return EBhUndefined;
     34 }
     35 
     36 TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
     37                                      TDiagnostics& diagnostics,
     38                                      int& shaderVersion)
     39 	: mExtensionBehavior(extBehavior),
     40 	  mDiagnostics(diagnostics),
     41 	  mShaderVersion(shaderVersion)
     42 {
     43 }
     44 
     45 TDirectiveHandler::~TDirectiveHandler()
     46 {
     47 }
     48 
     49 void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
     50                                     const std::string& msg)
     51 {
     52 	mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
     53 }
     54 
     55 void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
     56                                      const std::string& name,
     57                                      const std::string& value,
     58                                      bool stdgl)
     59 {
     60 	static const std::string kSTDGL("STDGL");
     61 	static const std::string kOptimize("optimize");
     62 	static const std::string kDebug("debug");
     63 	static const std::string kOn("on");
     64 	static const std::string kOff("off");
     65 
     66 	bool invalidValue = false;
     67 	if (stdgl || (name == kSTDGL))
     68 	{
     69 		// The STDGL pragma is used to reserve pragmas for use by future
     70 		// revisions of GLSL. Ignore it.
     71 		return;
     72 	}
     73 	else if (name == kOptimize)
     74 	{
     75 		if (value == kOn) mPragma.optimize = true;
     76 		else if (value == kOff) mPragma.optimize = false;
     77 		else invalidValue = true;
     78 	}
     79 	else if (name == kDebug)
     80 	{
     81 		if (value == kOn) mPragma.debug = true;
     82 		else if (value == kOff) mPragma.debug = false;
     83 		else invalidValue = true;
     84 	}
     85 	else
     86 	{
     87 		mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
     88 		return;
     89 	}
     90 
     91 	if (invalidValue)
     92 		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
     93 		                       "invalid pragma value", value,
     94 		                       "'on' or 'off' expected");
     95 }
     96 
     97 void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
     98                                         const std::string& name,
     99                                         const std::string& behavior)
    100 {
    101 	static const std::string kExtAll("all");
    102 
    103 	TBehavior behaviorVal = getBehavior(behavior);
    104 	if (behaviorVal == EBhUndefined)
    105 	{
    106 		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
    107 		                       "behavior", name, "invalid");
    108 		return;
    109 	}
    110 
    111 	if (name == kExtAll)
    112 	{
    113 		if (behaviorVal == EBhRequire)
    114 		{
    115 			mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
    116 			                       "extension", name,
    117 			                       "cannot have 'require' behavior");
    118 		}
    119 		else if (behaviorVal == EBhEnable)
    120 		{
    121 			mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
    122 			                       "extension", name,
    123 			                       "cannot have 'enable' behavior");
    124 		}
    125 		else
    126 		{
    127 			for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
    128 				 iter != mExtensionBehavior.end(); ++iter)
    129 				iter->second = behaviorVal;
    130 		}
    131 		return;
    132 	}
    133 
    134 	TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
    135 	if (iter != mExtensionBehavior.end())
    136 	{
    137 		iter->second = behaviorVal;
    138 		return;
    139 	}
    140 
    141 	pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
    142 	switch (behaviorVal) {
    143 	case EBhRequire:
    144 		severity = pp::Diagnostics::PP_ERROR;
    145 		break;
    146 	case EBhEnable:
    147 	case EBhWarn:
    148 	case EBhDisable:
    149 		severity = pp::Diagnostics::PP_WARNING;
    150 		break;
    151 	default:
    152 		UNREACHABLE(behaviorVal);
    153 		break;
    154 	}
    155 	mDiagnostics.writeInfo(severity, loc,
    156 	                       "extension", name, "is not supported");
    157 }
    158 
    159 void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
    160                                       int version)
    161 {
    162 	if (version == 100 ||
    163 	    version == 300)
    164 	{
    165 		mShaderVersion = version;
    166 	}
    167 	else
    168 	{
    169 		std::stringstream stream;
    170 		stream << version;
    171 		std::string str = stream.str();
    172 		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
    173 		                       "version number", str, "not supported");
    174 	}
    175 }
    176