blob: 2391d35aa6f43c74532d4b5748666923a0159ce4 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman66b8ab22014-05-06 15:57:45 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// 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
John Bauman66b8ab22014-05-06 15:57:45 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// 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.
John Bauman66b8ab22014-05-06 15:57:45 -040014
Nicolas Capenscc863da2015-01-21 15:50:55 -050015#include "DirectiveHandler.h"
John Bauman66b8ab22014-05-06 15:57:45 -040016
17#include <sstream>
18
Nicolas Capenscc863da2015-01-21 15:50:55 -050019#include "debug.h"
20#include "Diagnostics.h"
John Bauman66b8ab22014-05-06 15:57:45 -040021
22static TBehavior getBehavior(const std::string& str)
23{
Nicolas Capens0bac2852016-05-07 06:09:58 -040024 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");
John Bauman66b8ab22014-05-06 15:57:45 -040028
Nicolas Capens0bac2852016-05-07 06:09:58 -040029 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;
John Bauman66b8ab22014-05-06 15:57:45 -040034}
35
36TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
Nicolas Capensc6841852015-02-15 14:25:37 -050037 TDiagnostics& diagnostics,
38 int& shaderVersion)
Nicolas Capens0bac2852016-05-07 06:09:58 -040039 : mExtensionBehavior(extBehavior),
40 mDiagnostics(diagnostics),
41 mShaderVersion(shaderVersion)
John Bauman66b8ab22014-05-06 15:57:45 -040042{
43}
44
45TDirectiveHandler::~TDirectiveHandler()
46{
47}
48
49void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
50 const std::string& msg)
51{
Nicolas Capens0bac2852016-05-07 06:09:58 -040052 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
John Bauman66b8ab22014-05-06 15:57:45 -040053}
54
55void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
56 const std::string& name,
57 const std::string& value)
58{
Nicolas Capens0bac2852016-05-07 06:09:58 -040059 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");
John Bauman66b8ab22014-05-06 15:57:45 -040064
Nicolas Capens0bac2852016-05-07 06:09:58 -040065 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 }
John Bauman66b8ab22014-05-06 15:57:45 -040089
Nicolas Capens0bac2852016-05-07 06:09:58 -040090 if (invalidValue)
91 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
92 "invalid pragma value", value,
93 "'on' or 'off' expected");
John Bauman66b8ab22014-05-06 15:57:45 -040094}
95
96void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
97 const std::string& name,
98 const std::string& behavior)
99{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400100 static const std::string kExtAll("all");
John Bauman66b8ab22014-05-06 15:57:45 -0400101
Nicolas Capens0bac2852016-05-07 06:09:58 -0400102 TBehavior behaviorVal = getBehavior(behavior);
103 if (behaviorVal == EBhUndefined)
104 {
105 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
106 "behavior", name, "invalid");
107 return;
108 }
John Bauman66b8ab22014-05-06 15:57:45 -0400109
Nicolas Capens0bac2852016-05-07 06:09:58 -0400110 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 }
John Bauman66b8ab22014-05-06 15:57:45 -0400132
Nicolas Capens0bac2852016-05-07 06:09:58 -0400133 TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
134 if (iter != mExtensionBehavior.end())
135 {
136 iter->second = behaviorVal;
137 return;
138 }
John Bauman66b8ab22014-05-06 15:57:45 -0400139
Nicolas Capens0bac2852016-05-07 06:09:58 -0400140 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");
John Bauman66b8ab22014-05-06 15:57:45 -0400156}
157
158void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
159 int version)
160{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400161 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 }
John Bauman66b8ab22014-05-06 15:57:45 -0400174}