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 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 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 { 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 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 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