blob: 936c00a56c24d3f6fb5aa232dace51c3bde7075d [file] [log] [blame]
alokp@chromium.org8b851c62012-06-15 16:25:11 +00001//
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +00002// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
alokp@chromium.org8b851c62012-06-15 16:25:11 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/DirectiveHandler.h"
alokp@chromium.org8b851c62012-06-15 16:25:11 +00008
9#include <sstream>
10
Jamie Madilla6564902015-04-27 14:30:32 +000011#include "compiler/translator/compilerdebug.h"
Geoff Lang17732822013-08-29 13:46:49 -040012#include "compiler/translator/Diagnostics.h"
alokp@chromium.org8b851c62012-06-15 16:25:11 +000013
14static TBehavior getBehavior(const std::string& str)
15{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070016 const char kRequire[] = "require";
17 const char kEnable[] = "enable";
18 const char kDisable[] = "disable";
19 const char kWarn[] = "warn";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000020
21 if (str == kRequire) return EBhRequire;
22 else if (str == kEnable) return EBhEnable;
23 else if (str == kDisable) return EBhDisable;
24 else if (str == kWarn) return EBhWarn;
25 return EBhUndefined;
26}
27
28TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +000029 TDiagnostics& diagnostics,
Olli Etuaho853dc1a2014-11-06 17:25:48 +020030 int& shaderVersion,
31 bool debugShaderPrecisionSupported)
alokp@chromium.org73bc2982012-06-19 18:48:05 +000032 : mExtensionBehavior(extBehavior),
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +000033 mDiagnostics(diagnostics),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020034 mShaderVersion(shaderVersion),
35 mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000036{
37}
38
39TDirectiveHandler::~TDirectiveHandler()
40{
41}
42
43void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
44 const std::string& msg)
45{
Shannon Woods7f2d7942013-11-19 15:07:58 -050046 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
alokp@chromium.org8b851c62012-06-15 16:25:11 +000047}
48
49void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
50 const std::string& name,
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070051 const std::string& value,
52 bool stdgl)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000053{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070054 if (stdgl)
55 {
56 const char kInvariant[] = "invariant";
57 const char kAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000058
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070059 if (name == kInvariant && value == kAll)
60 mPragma.stdgl.invariantAll = true;
alokp@chromium.org8b851c62012-06-15 16:25:11 +000061 // The STDGL pragma is used to reserve pragmas for use by future
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070062 // revisions of GLSL. Do not generate an error on unexpected
63 // name and value.
alokp@chromium.org8b851c62012-06-15 16:25:11 +000064 return;
65 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000066 else
67 {
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070068 const char kOptimize[] = "optimize";
69 const char kDebug[] = "debug";
Olli Etuaho853dc1a2014-11-06 17:25:48 +020070 const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070071 const char kOn[] = "on";
72 const char kOff[] = "off";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000073
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070074 bool invalidValue = false;
75 if (name == kOptimize)
76 {
77 if (value == kOn) mPragma.optimize = true;
78 else if (value == kOff) mPragma.optimize = false;
79 else invalidValue = true;
80 }
81 else if (name == kDebug)
82 {
83 if (value == kOn) mPragma.debug = true;
84 else if (value == kOff) mPragma.debug = false;
85 else invalidValue = true;
86 }
Olli Etuaho853dc1a2014-11-06 17:25:48 +020087 else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
88 {
89 if (value == kOn) mPragma.debugShaderPrecision = true;
90 else if (value == kOff) mPragma.debugShaderPrecision = false;
91 else invalidValue = true;
92 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070093 else
94 {
95 mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
96 return;
97 }
98
99 if (invalidValue)
100 {
101 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
102 "invalid pragma value", value,
103 "'on' or 'off' expected");
104 }
105 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000106}
107
108void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
109 const std::string& name,
110 const std::string& behavior)
111{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700112 const char kExtAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000113
114 TBehavior behaviorVal = getBehavior(behavior);
115 if (behaviorVal == EBhUndefined)
116 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500117 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000118 "behavior", name, "invalid");
119 return;
120 }
121
122 if (name == kExtAll)
123 {
124 if (behaviorVal == EBhRequire)
125 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500126 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000127 "extension", name,
128 "cannot have 'require' behavior");
129 }
130 else if (behaviorVal == EBhEnable)
131 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500132 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000133 "extension", name,
134 "cannot have 'enable' behavior");
135 }
136 else
137 {
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000138 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
139 iter != mExtensionBehavior.end(); ++iter)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000140 iter->second = behaviorVal;
141 }
142 return;
143 }
144
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000145 TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
146 if (iter != mExtensionBehavior.end())
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000147 {
148 iter->second = behaviorVal;
149 return;
150 }
151
Shannon Woods7f2d7942013-11-19 15:07:58 -0500152 pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000153 switch (behaviorVal) {
154 case EBhRequire:
Shannon Woods7f2d7942013-11-19 15:07:58 -0500155 severity = pp::Diagnostics::PP_ERROR;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000156 break;
157 case EBhEnable:
158 case EBhWarn:
159 case EBhDisable:
Shannon Woods7f2d7942013-11-19 15:07:58 -0500160 severity = pp::Diagnostics::PP_WARNING;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000161 break;
162 default:
163 UNREACHABLE();
164 break;
165 }
166 mDiagnostics.writeInfo(severity, loc,
167 "extension", name, "is not supported");
168}
169
170void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
171 int version)
172{
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000173 if (version == 100 ||
174 version == 300)
175 {
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000176 mShaderVersion = version;
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000177 }
178 else
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000179 {
180 std::stringstream stream;
181 stream << version;
182 std::string str = stream.str();
Shannon Woods7f2d7942013-11-19 15:07:58 -0500183 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000184 "version number", str, "not supported");
185 }
186}