|
1 // |
|
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 |
|
7 #include "compiler/DirectiveHandler.h" |
|
8 |
|
9 #include <sstream> |
|
10 |
|
11 #include "compiler/compiler_debug.h" |
|
12 #include "compiler/Diagnostics.h" |
|
13 |
|
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 |
|
28 TDirectiveHandler::TDirectiveHandler(TExtensionBehavior& extBehavior, |
|
29 TDiagnostics& diagnostics) |
|
30 : mExtensionBehavior(extBehavior), |
|
31 mDiagnostics(diagnostics) |
|
32 { |
|
33 } |
|
34 |
|
35 TDirectiveHandler::~TDirectiveHandler() |
|
36 { |
|
37 } |
|
38 |
|
39 void TDirectiveHandler::handleError(const pp::SourceLocation& loc, |
|
40 const std::string& msg) |
|
41 { |
|
42 mDiagnostics.writeInfo(pp::Diagnostics::ERROR, loc, msg, "", ""); |
|
43 } |
|
44 |
|
45 void 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::ERROR, loc, |
|
82 "invalid pragma value", value, |
|
83 "'on' or 'off' expected"); |
|
84 } |
|
85 |
|
86 void 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::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::ERROR, loc, |
|
105 "extension", name, |
|
106 "cannot have 'require' behavior"); |
|
107 } |
|
108 else if (behaviorVal == EBhEnable) |
|
109 { |
|
110 mDiagnostics.writeInfo(pp::Diagnostics::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::ERROR; |
|
131 switch (behaviorVal) { |
|
132 case EBhRequire: |
|
133 severity = pp::Diagnostics::ERROR; |
|
134 break; |
|
135 case EBhEnable: |
|
136 case EBhWarn: |
|
137 case EBhDisable: |
|
138 severity = pp::Diagnostics::WARNING; |
|
139 break; |
|
140 default: |
|
141 UNREACHABLE(); |
|
142 break; |
|
143 } |
|
144 mDiagnostics.writeInfo(severity, loc, |
|
145 "extension", name, "is not supported"); |
|
146 } |
|
147 |
|
148 void 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::ERROR, loc, |
|
159 "version number", str, "not supported"); |
|
160 } |
|
161 } |