1 //
2 // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "compiler/translator/DirectiveHandler.h"
8
9 #include <sstream>
10
11 #include "compiler/translator/compilerdebug.h"
12 #include "compiler/translator/Diagnostics.h"
13
getBehavior(const std::string & str)14 static TBehavior getBehavior(const std::string& str)
15 {
16 static const std::string kRequire("require");
17 static const std::string kEnable("enable");
18 static const std::string kDisable("disable");
19 static const std::string kWarn("warn");
20
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
TDirectiveHandler(TExtensionBehavior & extBehavior,TDiagnostics & diagnostics,int & shaderVersion)28 TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
29 TDiagnostics& diagnostics,
30 int& shaderVersion)
31 : mExtensionBehavior(extBehavior),
32 mDiagnostics(diagnostics),
33 mShaderVersion(shaderVersion)
34 {
35 }
36
~TDirectiveHandler()37 TDirectiveHandler::~TDirectiveHandler()
38 {
39 }
40
handleError(const pp::SourceLocation & loc,const std::string & msg)41 void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
42 const std::string& msg)
43 {
44 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
45 }
46
handlePragma(const pp::SourceLocation & loc,const std::string & name,const std::string & value)47 void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
48 const std::string& name,
49 const std::string& value)
50 {
51 static const std::string kSTDGL("STDGL");
52 static const std::string kOptimize("optimize");
53 static const std::string kDebug("debug");
54 static const std::string kOn("on");
55 static const std::string kOff("off");
56
57 bool invalidValue = false;
58 if (name == kSTDGL)
59 {
60 // The STDGL pragma is used to reserve pragmas for use by future
61 // revisions of GLSL. Ignore it.
62 return;
63 }
64 else if (name == kOptimize)
65 {
66 if (value == kOn) mPragma.optimize = true;
67 else if (value == kOff) mPragma.optimize = false;
68 else invalidValue = true;
69 }
70 else if (name == kDebug)
71 {
72 if (value == kOn) mPragma.debug = true;
73 else if (value == kOff) mPragma.debug = false;
74 else invalidValue = true;
75 }
76 else
77 {
78 mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
79 return;
80 }
81
82 if (invalidValue)
83 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
84 "invalid pragma value", value,
85 "'on' or 'off' expected");
86 }
87
handleExtension(const pp::SourceLocation & loc,const std::string & name,const std::string & behavior)88 void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
89 const std::string& name,
90 const std::string& behavior)
91 {
92 static const std::string kExtAll("all");
93
94 TBehavior behaviorVal = getBehavior(behavior);
95 if (behaviorVal == EBhUndefined)
96 {
97 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
98 "behavior", name, "invalid");
99 return;
100 }
101
102 if (name == kExtAll)
103 {
104 if (behaviorVal == EBhRequire)
105 {
106 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
107 "extension", name,
108 "cannot have 'require' behavior");
109 }
110 else if (behaviorVal == EBhEnable)
111 {
112 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
113 "extension", name,
114 "cannot have 'enable' behavior");
115 }
116 else
117 {
118 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
119 iter != mExtensionBehavior.end(); ++iter)
120 iter->second = behaviorVal;
121 }
122 return;
123 }
124
125 TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
126 if (iter != mExtensionBehavior.end())
127 {
128 iter->second = behaviorVal;
129 return;
130 }
131
132 pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
133 switch (behaviorVal) {
134 case EBhRequire:
135 severity = pp::Diagnostics::PP_ERROR;
136 break;
137 case EBhEnable:
138 case EBhWarn:
139 case EBhDisable:
140 severity = pp::Diagnostics::PP_WARNING;
141 break;
142 default:
143 UNREACHABLE();
144 break;
145 }
146 mDiagnostics.writeInfo(severity, loc,
147 "extension", name, "is not supported");
148 }
149
handleVersion(const pp::SourceLocation & loc,int version)150 void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
151 int version)
152 {
153 if (version == 100 ||
154 version == 300)
155 {
156 mShaderVersion = version;
157 }
158 else
159 {
160 std::stringstream stream;
161 stream << version;
162 std::string str = stream.str();
163 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
164 "version number", str, "not supported");
165 }
166 }
167