blob: 1c76ceded87a3b04b30408425d7d4468c00a44ca [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001//
2// Copyright (c) 2012 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
Nicolas Capenscc863da2015-01-21 15:50:55 -05007#include "DirectiveHandler.h"
John Bauman66b8ab22014-05-06 15:57:45 -04008
9#include <sstream>
10
Nicolas Capenscc863da2015-01-21 15:50:55 -050011#include "debug.h"
12#include "Diagnostics.h"
John Bauman66b8ab22014-05-06 15:57:45 -040013
14static 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
28TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior,
29 TDiagnostics& diagnostics)
30 : mExtensionBehavior(extBehavior),
31 mDiagnostics(diagnostics)
32{
33}
34
35TDirectiveHandler::~TDirectiveHandler()
36{
37}
38
39void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
40 const std::string& msg)
41{
42 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
43}
44
45void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
46 const std::string& name,
47 const std::string& value)
48{
49 static const std::string kSTDGL("STDGL");
50 static const std::string kOptimize("optimize");
51 static const std::string kDebug("debug");
52 static const std::string kOn("on");
53 static const std::string kOff("off");
54
55 bool invalidValue = false;
56 if (name == kSTDGL)
57 {
58 // The STDGL pragma is used to reserve pragmas for use by future
59 // revisions of GLSL. Ignore it.
60 return;
61 }
62 else if (name == kOptimize)
63 {
64 if (value == kOn) mPragma.optimize = true;
65 else if (value == kOff) mPragma.optimize = false;
66 else invalidValue = true;
67 }
68 else if (name == kDebug)
69 {
70 if (value == kOn) mPragma.debug = true;
71 else if (value == kOff) mPragma.debug = false;
72 else invalidValue = true;
73 }
74 else
75 {
76 mDiagnostics.report(pp::Diagnostics::UNRECOGNIZED_PRAGMA, loc, name);
77 return;
78 }
79
80 if (invalidValue)
81 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
82 "invalid pragma value", value,
83 "'on' or 'off' expected");
84}
85
86void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
87 const std::string& name,
88 const std::string& behavior)
89{
90 static const std::string kExtAll("all");
91
92 TBehavior behaviorVal = getBehavior(behavior);
93 if (behaviorVal == EBhUndefined)
94 {
95 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
96 "behavior", name, "invalid");
97 return;
98 }
99
100 if (name == kExtAll)
101 {
102 if (behaviorVal == EBhRequire)
103 {
104 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
105 "extension", name,
106 "cannot have 'require' behavior");
107 }
108 else if (behaviorVal == EBhEnable)
109 {
110 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
111 "extension", name,
112 "cannot have 'enable' behavior");
113 }
114 else
115 {
116 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
117 iter != mExtensionBehavior.end(); ++iter)
118 iter->second = behaviorVal;
119 }
120 return;
121 }
122
123 TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
124 if (iter != mExtensionBehavior.end())
125 {
126 iter->second = behaviorVal;
127 return;
128 }
129
130 pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
131 switch (behaviorVal) {
132 case EBhRequire:
133 severity = pp::Diagnostics::PP_ERROR;
134 break;
135 case EBhEnable:
136 case EBhWarn:
137 case EBhDisable:
138 severity = pp::Diagnostics::PP_WARNING;
139 break;
140 default:
141 UNREACHABLE();
142 break;
143 }
144 mDiagnostics.writeInfo(severity, loc,
145 "extension", name, "is not supported");
146}
147
148void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
149 int version)
150{
151 static const int kVersion = 100;
152
153 if (version != kVersion)
154 {
155 std::stringstream stream;
156 stream << version;
157 std::string str = stream.str();
158 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
159 "version number", str, "not supported");
160 }
161}