Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / compiler / translator / DirectiveHandler.cpp
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
14 static TBehavior getBehavior(const std::string& str)
15 {
16     const char kRequire[] = "require";
17     const char kEnable[] = "enable";
18     const char kDisable[] = "disable";
19     const char 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                                      int& shaderVersion)
31     : mExtensionBehavior(extBehavior),
32       mDiagnostics(diagnostics),
33       mShaderVersion(shaderVersion)
34 {
35 }
36
37 TDirectiveHandler::~TDirectiveHandler()
38 {
39 }
40
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
47 void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
48                                      const std::string& name,
49                                      const std::string& value,
50                                      bool stdgl)
51 {
52     if (stdgl)
53     {
54         const char kInvariant[] = "invariant";
55         const char kAll[] = "all";
56
57         if (name == kInvariant && value == kAll)
58             mPragma.stdgl.invariantAll = true;
59         // The STDGL pragma is used to reserve pragmas for use by future
60         // revisions of GLSL.  Do not generate an error on unexpected
61         // name and value.
62         return;
63     }
64     else
65     {
66         const char kOptimize[] = "optimize";
67         const char kDebug[] = "debug";
68         const char kOn[] = "on";
69         const char kOff[] = "off";
70
71         bool invalidValue = false;
72         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::PP_UNRECOGNIZED_PRAGMA, loc, name);
87             return;
88         }
89
90         if (invalidValue)
91         {
92             mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
93                                    "invalid pragma value", value,
94                                    "'on' or 'off' expected");
95         }
96     }
97 }
98
99 void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
100                                         const std::string& name,
101                                         const std::string& behavior)
102 {
103     const char kExtAll[] = "all";
104
105     TBehavior behaviorVal = getBehavior(behavior);
106     if (behaviorVal == EBhUndefined)
107     {
108         mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
109                                "behavior", name, "invalid");
110         return;
111     }
112
113     if (name == kExtAll)
114     {
115         if (behaviorVal == EBhRequire)
116         {
117             mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
118                                    "extension", name,
119                                    "cannot have 'require' behavior");
120         }
121         else if (behaviorVal == EBhEnable)
122         {
123             mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
124                                    "extension", name,
125                                    "cannot have 'enable' behavior");
126         }
127         else
128         {
129             for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
130                  iter != mExtensionBehavior.end(); ++iter)
131                 iter->second = behaviorVal;
132         }
133         return;
134     }
135
136     TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
137     if (iter != mExtensionBehavior.end())
138     {
139         iter->second = behaviorVal;
140         return;
141     }
142
143     pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
144     switch (behaviorVal) {
145       case EBhRequire:
146         severity = pp::Diagnostics::PP_ERROR;
147         break;
148       case EBhEnable:
149       case EBhWarn:
150       case EBhDisable:
151         severity = pp::Diagnostics::PP_WARNING;
152         break;
153       default:
154         UNREACHABLE();
155         break;
156     }
157     mDiagnostics.writeInfo(severity, loc,
158                            "extension", name, "is not supported");
159 }
160
161 void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
162                                       int version)
163 {
164     if (version == 100 ||
165         version == 300)
166     {
167         mShaderVersion = version;
168     }
169     else
170     {
171         std::stringstream stream;
172         stream << version;
173         std::string str = stream.str();
174         mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
175                                "version number", str, "not supported");
176     }
177 }