Home | History | Annotate | Download | only in translator
      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