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