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/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::PP_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::PP_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 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::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 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::PP_ERROR, loc, 159 "version number", str, "not supported"); 160 } 161 } 162