• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getBehavior(const std::string & str)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 
TDirectiveHandler(TExtensionBehavior & extBehavior,TDiagnostics & diagnostics,int & shaderVersion)36 TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
37                                      TDiagnostics& diagnostics,
38                                      int& shaderVersion)
39 	: mExtensionBehavior(extBehavior),
40 	  mDiagnostics(diagnostics),
41 	  mShaderVersion(shaderVersion)
42 {
43 }
44 
~TDirectiveHandler()45 TDirectiveHandler::~TDirectiveHandler()
46 {
47 }
48 
handleError(const pp::SourceLocation & loc,const std::string & msg)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 
handlePragma(const pp::SourceLocation & loc,const std::string & name,const std::string & value)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 
handleExtension(const pp::SourceLocation & loc,const std::string & name,const std::string & behavior)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 
handleVersion(const pp::SourceLocation & loc,int version)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