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 {
     59 	static const std::string kSTDGL("STDGL");
     60 	static const std::string kOptimize("optimize");
     61 	static const std::string kDebug("debug");
     62 	static const std::string kOn("on");
     63 	static const std::string kOff("off");
     64 
     65 	bool invalidValue = false;
     66 	if (name == kSTDGL)
     67 	{
     68 		// The STDGL pragma is used to reserve pragmas for use by future
     69 		// revisions of GLSL. Ignore it.
     70 		return;
     71 	}
     72 	else if (name == kOptimize)
     73 	{
     74 		if (value == kOn) mPragma.optimize = true;
     75 		else if (value == kOff) mPragma.optimize = false;
     76 		else invalidValue = true;
     77 	}
     78 	else if (name == kDebug)
     79 	{
     80 		if (value == kOn) mPragma.debug = true;
     81 		else if (value == kOff) mPragma.debug = false;
     82 		else invalidValue = true;
     83 	}
     84 	else
     85 	{
     86 		mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name);
     87 		return;
     88 	}
     89 
     90 	if (invalidValue)
     91 		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
     92 		                       "invalid pragma value", value,
     93 		                       "'on' or 'off' expected");
     94 }
     95 
     96 void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
     97                                         const std::string& name,
     98                                         const std::string& behavior)
     99 {
    100 	static const std::string kExtAll("all");
    101 
    102 	TBehavior behaviorVal = getBehavior(behavior);
    103 	if (behaviorVal == EBhUndefined)
    104 	{
    105 		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
    106 		                       "behavior", name, "invalid");
    107 		return;
    108 	}
    109 
    110 	if (name == kExtAll)
    111 	{
    112 		if (behaviorVal == EBhRequire)
    113 		{
    114 			mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
    115 			                       "extension", name,
    116 			                       "cannot have 'require' behavior");
    117 		}
    118 		else if (behaviorVal == EBhEnable)
    119 		{
    120 			mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
    121 			                       "extension", name,
    122 			                       "cannot have 'enable' behavior");
    123 		}
    124 		else
    125 		{
    126 			for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
    127 				 iter != mExtensionBehavior.end(); ++iter)
    128 				iter->second = behaviorVal;
    129 		}
    130 		return;
    131 	}
    132 
    133 	TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
    134 	if (iter != mExtensionBehavior.end())
    135 	{
    136 		iter->second = behaviorVal;
    137 		return;
    138 	}
    139 
    140 	pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
    141 	switch (behaviorVal) {
    142 	case EBhRequire:
    143 		severity = pp::Diagnostics::PP_ERROR;
    144 		break;
    145 	case EBhEnable:
    146 	case EBhWarn:
    147 	case EBhDisable:
    148 		severity = pp::Diagnostics::PP_WARNING;
    149 		break;
    150 	default:
    151 		UNREACHABLE(behaviorVal);
    152 		break;
    153 	}
    154 	mDiagnostics.writeInfo(severity, loc,
    155 	                       "extension", name, "is not supported");
    156 }
    157 
    158 void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
    159                                       int version)
    160 {
    161 	if (version == 100 ||
    162 	    version == 300)
    163 	{
    164 		mShaderVersion = version;
    165 	}
    166 	else
    167 	{
    168 		std::stringstream stream;
    169 		stream << version;
    170 		std::string str = stream.str();
    171 		mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
    172 		                       "version number", str, "not supported");
    173 	}
    174 }
    175