Revert of Turned on SkSL->GLSL compiler (patchset #41 id:880001 of https://codereview.chromium.org/2288033003/ )

Reason for revert:
1) Chromium roll failures: https://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_rel_ng/builds/307297/steps/screenshot_sync_tests%20on%20NVIDIA%20GPU%20on%20Linux%20%28with%20patch%29%20on%20Linux/logs/stdio

2) G3 roll failures

3) iOS failures: https://uberchromegw.corp.google.com/i/client.skia/builders/Perf-iOS-Clang-iPad4-GPU-SGX554-Arm7-Release/builds/7177/steps/perf_skia%20on%20iOS-9.2/logs/stdio

Original issue's description:
> Turned on SkSL->GLSL compiler
> GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2288033003
>
> Committed: https://skia.googlesource.com/skia/+/9b0fe3d125f237d9884732a48414fa85fc71b4e3
> Committed: https://skia.googlesource.com/skia/+/b12b3c6908c62c908b3680be01e3b5bfd30de310
> Committed: https://skia.googlesource.com/skia/+/f008b0a59f45c0d4bea3e66faf3b01805009ec89

TBR=benjaminwagner@google.com,bsalomon@google.com,egdaniel@google.com,ethannicholas@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Review-Url: https://codereview.chromium.org/2387643003
diff --git a/gyp/sksl.gyp b/gyp/sksl.gyp
index f45b702..609ace9 100644
--- a/gyp/sksl.gyp
+++ b/gyp/sksl.gyp
@@ -18,7 +18,7 @@
       ],
       'all_dependent_settings': {
         'include_dirs': [
-          '<(skia_src_path)/sksl',
+          '../src/sksl',
         ],
       },
     },
diff --git a/src/gpu/gl/GrGLContext.cpp b/src/gpu/gl/GrGLContext.cpp
index 2126314..9e70b47 100644
--- a/src/gpu/gl/GrGLContext.cpp
+++ b/src/gpu/gl/GrGLContext.cpp
@@ -7,7 +7,6 @@
 
 #include "GrGLContext.h"
 #include "GrGLGLSL.h"
-#include "SkSLCompiler.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -64,17 +63,6 @@
     return new GrGLContext(args);
 }
 
-GrGLContext::~GrGLContext() {
-    delete fCompiler;
-}
-
-SkSL::Compiler* GrGLContext::compiler() const {
-    if (!fCompiler) {
-        fCompiler = new SkSL::Compiler();
-    }
-    return fCompiler;
-}
-
 GrGLContextInfo::GrGLContextInfo(const ConstructorArgs& args) {
     fInterface.reset(SkRef(args.fInterface));
     fGLVersion = args.fGLVersion;
diff --git a/src/gpu/gl/GrGLContext.h b/src/gpu/gl/GrGLContext.h
index 8207ac8..6016f68 100644
--- a/src/gpu/gl/GrGLContext.h
+++ b/src/gpu/gl/GrGLContext.h
@@ -15,9 +15,6 @@
 #include "GrGLUtil.h"
 
 struct GrContextOptions;
-namespace SkSL {
-    class Compiler;
-}
 
 /**
  * Encapsulates information about an OpenGL context including the OpenGL
@@ -42,8 +39,6 @@
 
     const GrGLExtensions& extensions() const { return fInterface->fExtensions; }
 
-    virtual ~GrGLContextInfo() {}
-
 protected:
     struct ConstructorArgs {
         const GrGLInterface*                fInterface;
@@ -69,7 +64,7 @@
 };
 
 /**
- * Extension of GrGLContextInfo that also provides access to GrGLInterface and SkSL::Compiler.
+ * Extension of GrGLContextInfo that also provides access to GrGLInterface.
  */
 class GrGLContext : public GrGLContextInfo {
 public:
@@ -81,16 +76,8 @@
 
     const GrGLInterface* interface() const { return fInterface; }
 
-    SkSL::Compiler* compiler() const;
-
-    ~GrGLContext() override;
-
 private:
-    GrGLContext(const ConstructorArgs& args) 
-    : INHERITED(args)
-    , fCompiler(nullptr) {}
-
-    mutable SkSL::Compiler* fCompiler;
+    GrGLContext(const ConstructorArgs& args) : INHERITED(args) {}
 
     typedef GrGLContextInfo INHERITED;
 };
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 341216a..fcd3270 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3790,11 +3790,20 @@
     fshaderTxt.append(";");
     uTexture.appendDecl(glslCaps, &fshaderTxt);
     fshaderTxt.append(";");
+    const char* fsOutName;
+    if (glslCaps->mustDeclareFragmentShaderOutput()) {
+        oFragColor.appendDecl(glslCaps, &fshaderTxt);
+        fshaderTxt.append(";");
+        fsOutName = oFragColor.c_str();
+    } else {
+        fsOutName = "gl_FragColor";
+    }
     fshaderTxt.appendf(
         "// Copy Program FS\n"
         "void main() {"
-        "  sk_FragColor = %s(u_texture, v_texCoord);"
+        "  %s = %s(u_texture, v_texCoord);"
         "}",
+        fsOutName,
         GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[progIdx], this->glslGeneration())
     );
 
@@ -3927,6 +3936,14 @@
     }
     uTexture.appendDecl(glslCaps, &fshaderTxt);
     fshaderTxt.append(";");
+    const char* fsOutName;
+    if (glslCaps->mustDeclareFragmentShaderOutput()) {
+        oFragColor.appendDecl(glslCaps, &fshaderTxt);
+        fshaderTxt.append(";");
+        fsOutName = oFragColor.c_str();
+    } else {
+        fsOutName = "gl_FragColor";
+    }
     const char* sampleFunction = GrGLSLTexture2DFunctionName(kVec2f_GrSLType,
                                                              kTexture2DSampler_GrSLType,
                                                              this->glslGeneration());
@@ -3937,19 +3954,19 @@
 
     if (oddWidth && oddHeight) {
         fshaderTxt.appendf(
-            "  sk_FragColor = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1) + "
-            "                  %s(u_texture, v_texCoord2) + %s(u_texture, v_texCoord3)) * 0.25;",
-            sampleFunction, sampleFunction, sampleFunction, sampleFunction
+            "  %s = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1) + "
+            "        %s(u_texture, v_texCoord2) + %s(u_texture, v_texCoord3)) * 0.25;",
+            fsOutName, sampleFunction, sampleFunction, sampleFunction, sampleFunction
         );
     } else if (oddWidth || oddHeight) {
         fshaderTxt.appendf(
-            "  sk_FragColor = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1)) * 0.5;",
-            sampleFunction, sampleFunction
+            "  %s = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1)) * 0.5;",
+            fsOutName, sampleFunction, sampleFunction
         );
     } else {
         fshaderTxt.appendf(
-            "  sk_FragColor = %s(u_texture, v_texCoord0);",
-            sampleFunction
+            "  %s = %s(u_texture, v_texCoord0);",
+            fsOutName, sampleFunction
         );
     }
 
@@ -4036,11 +4053,20 @@
                                                  &fshaderTxt);
     uColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
     fshaderTxt.append(";");
+    const char* fsOutName;
+    if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) {
+        oFragColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
+        fshaderTxt.append(";");
+        fsOutName = oFragColor.c_str();
+    } else {
+        fsOutName = "gl_FragColor";
+    }
     fshaderTxt.appendf(
         "// Write Rect Program FS\n"
         "void main() {"
-        "  sk_FragColor = %s;"
+        "  %s = %s;"
         "}",
+        fsOutName,
         uColor.c_str()
     );
 
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
index 04d90ee..d2e49a5 100644
--- a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
@@ -9,8 +9,6 @@
 #include "gl/GrGLGpu.h"
 #include "gl/GrGLSLPrettyPrint.h"
 #include "SkTraceEvent.h"
-#include "SkSLCompiler.h"
-#include "ir/SkSLProgram.h"
 
 #define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
@@ -20,90 +18,6 @@
 
 static void print_shader_source(const char** strings, int* lengths, int count);
 
-static SkSL::GLCaps skslcaps_for_context(const GrGLContext& context) {
-    GrGLStandard standard = context.standard();
-    const GrGLCaps* caps = context.caps();
-    const GrGLSLCaps* glslCaps = caps->glslCaps();
-    SkSL::GLCaps result;
-    switch (standard) {
-        case kGL_GrGLStandard:
-            result.fStandard = SkSL::GLCaps::kGL_Standard;
-            break;
-        case kGLES_GrGLStandard:
-            result.fStandard = SkSL::GLCaps::kGLES_Standard;
-            break;
-        default:
-            SkASSERT(false);
-            result.fStandard = SkSL::GLCaps::kGL_Standard;
-    }
-
-    switch (glslCaps->generation()) {
-        case k110_GrGLSLGeneration:
-            if (kGLES_GrGLStandard == standard) {
-                // ES2's shader language is based on GLSL 1.20 but is version 1.00 of the ES 
-                // language
-                result.fVersion = 100;
-            } else {
-                SkASSERT(kGL_GrGLStandard == standard);
-                result.fVersion = 110;
-            }
-            break;
-        case k130_GrGLSLGeneration:
-            SkASSERT(kGL_GrGLStandard == standard);
-            result.fVersion = 130;
-            break;
-        case k140_GrGLSLGeneration:
-            SkASSERT(kGL_GrGLStandard == standard);
-            result.fVersion = 140;
-            break;
-        case k150_GrGLSLGeneration:
-            SkASSERT(kGL_GrGLStandard == standard);
-            result.fVersion = 150;
-            break;
-        case k330_GrGLSLGeneration:
-            if (kGLES_GrGLStandard == standard) {
-                result.fVersion = 300;
-            } else {
-                SkASSERT(kGL_GrGLStandard == standard);
-                result.fVersion = 330;
-            }
-            break;
-        case k400_GrGLSLGeneration:
-            SkASSERT(kGL_GrGLStandard == standard);
-            result.fVersion = 400;
-            break;
-        case k310es_GrGLSLGeneration:
-            SkASSERT(kGLES_GrGLStandard == standard);
-            result.fVersion = 310;
-            break;
-        case k320es_GrGLSLGeneration:
-            SkASSERT(kGLES_GrGLStandard == standard);
-            result.fVersion = 320;
-            break;
-    }
-    result.fIsCoreProfile = caps->isCoreProfile();
-    result.fUsesPrecisionModifiers = glslCaps->usesPrecisionModifiers();
-    result.fMustDeclareFragmentShaderOutput = glslCaps->mustDeclareFragmentShaderOutput();
-    result.fCanUseMinAndAbsTogether = glslCaps->canUseMinAndAbsTogether();
-    return result;
-}
-
-static void dump_string(std::string s) {
-    // on Android, SkDebugf only displays the first 1K characters of output, which results in
-    // incomplete shader source code. Print each line individually to avoid this problem.
-    size_t index = 0;
-    for (;;) {
-        size_t next = s.find("\n", index);
-        if (next == std::string::npos) {
-            SkDebugf("%s", s.substr(index).c_str());
-            break;
-        } else {
-            SkDebugf("%s", s.substr(index, next - index + 1).c_str());
-            index = next + 1;
-        }
-    }
-}
-
 GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
                                     GrGLuint programId,
                                     GrGLenum type,
@@ -119,39 +33,15 @@
         return 0;
     }
 
-    std::string sksl;
 #ifdef SK_DEBUG
     SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false);
-    sksl = std::string(prettySource.c_str());
+    const GrGLchar* sourceStr = prettySource.c_str();
+    GrGLint sourceLength = static_cast<GrGLint>(prettySource.size());
+    GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
 #else
-    for (int i = 0; i < count; i++) {
-        sksl.append(strings[i], lengths[i]);
-    }
+    GR_GL_CALL(gli, ShaderSource(shaderId, count, strings, lengths));
 #endif
 
-    std::string glsl;
-    SkSL::Compiler& compiler = *glCtx.compiler();
-    SkSL::GLCaps caps = skslcaps_for_context(glCtx);
-    SkASSERT(type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER);
-    SkDEBUGCODE(bool result = )compiler.toGLSL(type == GR_GL_VERTEX_SHADER 
-                                                                    ? SkSL::Program::kVertex_Kind
-                                                                    : SkSL::Program::kFragment_Kind,
-                                               std::string(sksl.c_str()),
-                                               caps,
-                                               &glsl);
-#ifdef SK_DEBUG
-    if (!result) {
-        SkDebugf("SKSL compilation error\n----------------------\n");
-        SkDebugf("SKSL:\n");
-        dump_string(sksl);
-        SkDebugf("\nErrors:\n%s\n", compiler.errorText().c_str());
-        SkDEBUGFAIL("SKSL compilation failed!\n");
-    }
-#endif
-    const char* glslChars = glsl.c_str();
-    GrGLint glslLength = (GrGLint) glsl.length();
-    GR_GL_CALL(gli, ShaderSource(shaderId, 1, &glslChars, &glslLength));
-
     // If tracing is enabled in chrome then we pretty print
     bool traceShader;
     TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), &traceShader);
@@ -182,14 +72,10 @@
                 // buffer param validation.
                 GrGLsizei length = GR_GL_INIT_ZERO;
                 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (char*)log.get()));
-                SkDebugf("GLSL compilation error\n----------------------\n");
-                SkDebugf("SKSL:\n");
-                dump_string(sksl);
-                SkDebugf("GLSL:\n");
-                dump_string(glsl);
-                SkDebugf("Errors:\n%s\n", (const char*) log.get());
+                print_shader_source(strings, lengths, count);
+                SkDebugf("\n%s", (const char*)log.get());
             }
-            SkDEBUGFAIL("GLSL compilation failed!");
+            SkDEBUGFAIL("Shader compilation failed!");
             GR_GL_CALL(gli, DeleteShader(shaderId));
             return 0;
         }
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index eb744a9..d35730f 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -291,10 +291,10 @@
     if (!fHasCustomColorOutput) {
         fHasCustomColorOutput = true;
         fCustomColorOutputIndex = fOutputs.count();
-        fOutputs.push_back().set(kVec4f_GrSLType,  
-                                 GrGLSLShaderVar::kOut_TypeModifier,   
-                                 DeclaredColorOutputName());   
-        fProgramBuilder->finalizeFragmentOutputColor(fOutputs.back()); 
+        fOutputs.push_back().set(kVec4f_GrSLType,
+                                 GrGLSLShaderVar::kOut_TypeModifier,
+                                 DeclaredColorOutputName());
+        fProgramBuilder->finalizeFragmentOutputColor(fOutputs.back());
     }
 }
 
@@ -318,7 +318,7 @@
 }
 
 const char* GrGLSLFragmentShaderBuilder::getPrimaryColorOutputName() const {
-    return fHasCustomColorOutput ? DeclaredColorOutputName() : "sk_FragColor";
+    return fHasCustomColorOutput ? DeclaredColorOutputName() : "gl_FragColor";
 }
 
 void GrGLSLFragmentBuilder::declAppendf(const char* fmt, ...) {
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
index 6a4a184..ecb6d45 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
@@ -203,7 +203,7 @@
     }
 #endif
 
-    static const char* DeclaredColorOutputName() { return "sk_FragColor"; }
+    static const char* DeclaredColorOutputName() { return "fsColorOut"; }
     static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
 
     GrSurfaceOrigin getSurfaceOrigin() const;
diff --git a/src/gpu/glsl/GrGLSLShaderBuilder.h b/src/gpu/glsl/GrGLSLShaderBuilder.h
index f59edb4..a6ff96d 100644
--- a/src/gpu/glsl/GrGLSLShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLShaderBuilder.h
@@ -72,27 +72,23 @@
     void appendTexelFetch(SamplerHandle, const char* coordExpr);
 
     /**
-    * Adds a constant declaration to the top of the shader.
+    * Adds a #define directive to the top of the shader.
     */
-    void defineConstant(const char* type, const char* name, const char* value) {
-        this->definitions().appendf("const %s %s = %s;\n", type, name, value);
+    void define(const char* macro, const char* replacement) {
+        this->definitions().appendf("#define %s %s\n", macro, replacement);
     }
 
-    void defineConstant(const char* name, int value) {
-        this->definitions().appendf("const int %s = %i;\n", name, value);
+    void define(const char* macro, int replacement) {
+        this->definitions().appendf("#define %s %i\n", macro, replacement);
     }
 
-    void defineConstant(const char* name, float value) {
-        this->definitions().appendf("const float %s = %f;\n", name, value);
-    }
-
-    void defineConstantf(const char* type, const char* name, const char* fmt, ...) {
-       this->definitions().appendf("const %s %s = ", type, name);
+    void definef(const char* macro, const char* replacement, ...) {
+       this->definitions().appendf("#define %s ", macro);
        va_list args;
-       va_start(args, fmt);
-       this->definitions().appendVAList(fmt, args);
+       va_start(args, replacement);
+       this->definitions().appendVAList(replacement, args);
        va_end(args);
-       this->definitions().append(";\n");
+       this->definitions().append("\n");
     }
 
     /**
diff --git a/src/gpu/glsl/GrGLSLShaderVar.h b/src/gpu/glsl/GrGLSLShaderVar.h
index 35ac4bc..9d162ec 100644
--- a/src/gpu/glsl/GrGLSLShaderVar.h
+++ b/src/gpu/glsl/GrGLSLShaderVar.h
@@ -213,20 +213,24 @@
 
 private:
     static const char* TypeModifierString(const GrGLSLCaps* glslCaps, TypeModifier t) {
+        GrGLSLGeneration gen = glslCaps->generation();
         switch (t) {
             case kNone_TypeModifier:
                 return "";
-            case kAttribute_TypeModifier: // fall through
-            case kVaryingIn_TypeModifier: // fall through
             case kIn_TypeModifier:
                 return "in";
             case kInOut_TypeModifier:
                 return "inout";
-            case kVaryingOut_TypeModifier: // fall through
             case kOut_TypeModifier:
                 return "out";
             case kUniform_TypeModifier:
                 return "uniform";
+            case kAttribute_TypeModifier:
+                return k110_GrGLSLGeneration == gen ? "attribute" : "in";
+            case kVaryingIn_TypeModifier:
+                return k110_GrGLSLGeneration == gen ? "varying" : "in";
+            case kVaryingOut_TypeModifier:
+                return k110_GrGLSLGeneration == gen ? "varying" : "out";
             default:
                 SkFAIL("Unknown shader variable type modifier.");
                 return ""; // suppress warning
diff --git a/src/gpu/instanced/InstanceProcessor.cpp b/src/gpu/instanced/InstanceProcessor.cpp
index 82116c4..480155b 100644
--- a/src/gpu/instanced/InstanceProcessor.cpp
+++ b/src/gpu/instanced/InstanceProcessor.cpp
@@ -107,10 +107,10 @@
 
     void initParams(const SamplerHandle paramsBuffer) {
         fParamsBuffer = paramsBuffer;
+        fVertexBuilder->definef("PARAMS_IDX_MASK", "0x%xu", kParamsIdx_InfoMask);
         fVertexBuilder->appendPrecisionModifier(kHigh_GrSLPrecision);
-        fVertexBuilder->codeAppendf("int paramsIdx = int(%s & 0x%x);",
-                                    this->attr(Attrib::kInstanceInfo),
-                                    kParamsIdx_InfoMask);
+        fVertexBuilder->codeAppendf("int paramsIdx = int(%s & PARAMS_IDX_MASK);",
+                                    this->attr(Attrib::kInstanceInfo));
     }
 
     const char* attr(Attrib attr) const { return fInstProc.getAttrib((int)attr).fName; }
@@ -224,10 +224,10 @@
         v->codeAppendf("mat2x3 shapeMatrix = mat2x3(%s, %s);",
                        inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
     } else {
-        v->defineConstantf("int", "PERSPECTIVE_FLAG", "0x%x", kPerspective_InfoFlag);
+        v->definef("PERSPECTIVE_FLAG", "0x%xu", kPerspective_InfoFlag);
         v->codeAppendf("mat3 shapeMatrix = mat3(%s, %s, vec3(0, 0, 1));",
                        inputs.attr(Attrib::kShapeMatrixX), inputs.attr(Attrib::kShapeMatrixY));
-        v->codeAppendf("if (0 != (%s & PERSPECTIVE_FLAG)) {",
+        v->codeAppendf("if (0u != (%s & PERSPECTIVE_FLAG)) {",
                        inputs.attr(Attrib::kInstanceInfo));
         v->codeAppend (    "shapeMatrix[2] = ");
         inputs.fetchNextParam(kVec3f_GrSLType);
@@ -237,7 +237,7 @@
 
     bool hasSingleShapeType = SkIsPow2(ip.batchInfo().fShapeTypes);
     if (!hasSingleShapeType) {
-        v->defineConstant("SHAPE_TYPE_BIT", kShapeType_InfoBit);
+        v->define("SHAPE_TYPE_BIT", kShapeType_InfoBit);
         v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;",
                        inputs.attr(Attrib::kInstanceInfo));
     }
@@ -285,8 +285,8 @@
     if (ip.batchInfo().fInnerShapeTypes) {
         bool hasSingleInnerShapeType = SkIsPow2(ip.batchInfo().fInnerShapeTypes);
         if (!hasSingleInnerShapeType) {
-            v->defineConstantf("int", "INNER_SHAPE_TYPE_MASK", "0x%x", kInnerShapeType_InfoMask);
-            v->defineConstant("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit);
+            v->definef("INNER_SHAPE_TYPE_MASK", "0x%xu", kInnerShapeType_InfoMask);
+            v->define("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit);
             v->codeAppendf("uint innerShapeType = ((%s & INNER_SHAPE_TYPE_MASK) >> "
                                                   "INNER_SHAPE_TYPE_BIT);",
                            inputs.attr(Attrib::kInstanceInfo));
@@ -346,13 +346,13 @@
     }
 
     if (usedShapeDefinitions & kOval_ShapeFlag) {
-        v->defineConstant("OVAL_SHAPE_TYPE", (int)ShapeType::kOval);
+        v->definef("OVAL_SHAPE_TYPE", "%du", (int)ShapeType::kOval);
     }
     if (usedShapeDefinitions & kSimpleRRect_ShapeFlag) {
-        v->defineConstant("SIMPLE_R_RECT_SHAPE_TYPE", (int)ShapeType::kSimpleRRect);
+        v->definef("SIMPLE_R_RECT_SHAPE_TYPE", "%du", (int)ShapeType::kSimpleRRect);
     }
     if (usedShapeDefinitions & kNinePatch_ShapeFlag) {
-        v->defineConstant("NINE_PATCH_SHAPE_TYPE", (int)ShapeType::kNinePatch);
+        v->definef("NINE_PATCH_SHAPE_TYPE", "%du", (int)ShapeType::kNinePatch);
     }
     SkASSERT(!(usedShapeDefinitions & (kRect_ShapeFlag | kComplexRRect_ShapeFlag)));
 
@@ -367,8 +367,8 @@
                        inputs.attr(Attrib::kLocalRect), inputs.attr(Attrib::kLocalRect));
     }
     if (ip.batchInfo().fHasLocalMatrix && ip.batchInfo().fHasParams) {
-        v->defineConstantf("int", "LOCAL_MATRIX_FLAG", "0x%x", kLocalMatrix_InfoFlag);
-        v->codeAppendf("if (0 != (%s & LOCAL_MATRIX_FLAG)) {",
+        v->definef("LOCAL_MATRIX_FLAG", "0x%xu", kLocalMatrix_InfoFlag);
+        v->codeAppendf("if (0u != (%s & LOCAL_MATRIX_FLAG)) {",
                        inputs.attr(Attrib::kInstanceInfo));
         if (!ip.batchInfo().fUsesLocalCoords) {
             inputs.skipParams(2);
@@ -1179,7 +1179,7 @@
             }
         }
         if (kRect_ShapeFlag != fBatchInfo.fShapeTypes) {
-           v->defineConstantf("int", "SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
+           v->definef("SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
            varyingHandler->addFlatVarying("earlyAccept", &fEarlyAccept, kHigh_GrSLPrecision);
         }
     }
@@ -1360,10 +1360,10 @@
 void GLSLInstanceProcessor::BackendMultisample::onEmitCode(GrGLSLVertexBuilder*,
                                                            GrGLSLPPFragmentBuilder* f,
                                                            const char*, const char*) {
-    f->defineConstant("SAMPLE_COUNT", fEffectiveSampleCnt);
+    f->define("SAMPLE_COUNT", fEffectiveSampleCnt);
     if (this->isMixedSampled()) {
-        f->defineConstantf("int", "SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
-        f->defineConstantf("int", "SAMPLE_MASK_MSB", "0x%x", 1 << (fEffectiveSampleCnt - 1));
+        f->definef("SAMPLE_MASK_ALL", "0x%x", (1 << fEffectiveSampleCnt) - 1);
+        f->definef("SAMPLE_MASK_MSB", "0x%x", 1 << (fEffectiveSampleCnt - 1));
     }
 
     if (kRect_ShapeFlag != (fBatchInfo.fShapeTypes | fBatchInfo.fInnerShapeTypes)) {
diff --git a/src/sksl/README b/src/sksl/README
deleted file mode 100644
index 1427c21..0000000
--- a/src/sksl/README
+++ /dev/null
@@ -1,35 +0,0 @@
-Overview
-========
-
-SkSL ("Skia Shading Language") is a variant of GLSL which is used as Skia's 
-internal shading language. SkSL is, at its heart, a single standardized version
-of GLSL which avoids all of the various version and dialect differences found
-in GLSL "in the wild", but it does bring a few of its own changes to the table.
-
-Skia uses the SkSL compiler to convert SkSL code to GLSL, GLSL ES, or SPIR-V
-before handing it over to the graphics driver.
-
-Differences from GLSL
-=====================
-
-SkSL is based on GLSL 4.5. For the most part, write SkSL exactly as you would
-desktop GLSL, and the SkSL compiler will take care of version and dialect
-differences (for instance, you always use "in" and "out", and skslc will handle
-translating them to "varying" and "attribute" as appropriate). Be aware of the 
-following differences between SkSL and GLSL:
-
-* no #version or "precision" statement is required, and they will be ignored if
-  present
-* the output color is sk_FragColor (do not declare it)
-* lowp, mediump, and highp are always permitted (but will only be respected if 
-  you run on a GLES device)
-* you do not need to include ".0" to make a number a float (meaning that
-  "vec2(x, y) * 4" is perfectly legal in SkSL, unlike GLSL where it would often
-  have to be expressed "vec2(x, y) * 4.0". There is no performance penalty for 
-  this, as the number is converted to a float at compile time)
-* type suffixes on numbers (1.0f, 0xFFu) are both unnecessary and unsupported
-* some built-in functions and one or two rarely-used language features are not
-  yet supported (sorry!)
-
-SkSL is still under development, and is expected to diverge further from GLSL
-over time.
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 8cc30c4..d2ad812 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -10,13 +10,11 @@
 #include <fstream>
 #include <streambuf>
 
-#include "ast/SkSLASTPrecision.h"
 #include "SkSLIRGenerator.h"
 #include "SkSLParser.h"
 #include "SkSLSPIRVCodeGenerator.h"
 #include "ir/SkSLExpression.h"
 #include "ir/SkSLIntLiteral.h"
-#include "ir/SkSLModifiersDeclaration.h"
 #include "ir/SkSLSymbolTable.h"
 #include "ir/SkSLVarDeclaration.h"
 #include "SkMutex.h"
@@ -99,7 +97,6 @@
     ADD_TYPE(Sampler1D);
     ADD_TYPE(Sampler2D);
     ADD_TYPE(Sampler3D);
-    ADD_TYPE(SamplerExternalOES);
     ADD_TYPE(SamplerCube);
     ADD_TYPE(Sampler2DRect);
     ADD_TYPE(Sampler1DArray);
@@ -131,10 +128,8 @@
     ADD_TYPE(GSampler2DArrayShadow);
     ADD_TYPE(GSamplerCubeArrayShadow);
 
-    Modifiers::Flag ignored1;
-    std::vector<std::unique_ptr<ProgramElement>> ignored2;
-    this->internalConvertProgram(SKSL_INCLUDE, &ignored1, &ignored2);
-    printf("%s", errorText().c_str());
+    std::vector<std::unique_ptr<ProgramElement>> ignored;
+    this->internalConvertProgram(SKSL_INCLUDE, &ignored);
     ASSERT(!fErrorCount);
 }
 
@@ -143,14 +138,12 @@
 }
 
 void Compiler::internalConvertProgram(std::string text,
-                                      Modifiers::Flag* defaultPrecision,
                                       std::vector<std::unique_ptr<ProgramElement>>* result) {
     Parser parser(text, *fTypes, *this);
     std::vector<std::unique_ptr<ASTDeclaration>> parsed = parser.file();
     if (fErrorCount) {
         return;
     }
-    *defaultPrecision = Modifiers::kHighp_Flag;
     for (size_t i = 0; i < parsed.size(); i++) {
         ASTDeclaration& decl = *parsed[i];
         switch (decl.fKind) {
@@ -171,14 +164,6 @@
                 }
                 break;
             }
-            case ASTDeclaration::kModifiers_Kind: {
-                std::unique_ptr<ModifiersDeclaration> f = fIRGenerator->convertModifiersDeclaration(
-                                                                   (ASTModifiersDeclaration&) decl);
-                if (f) {
-                    result->push_back(std::move(f));
-                }
-                break;
-            }
             case ASTDeclaration::kInterfaceBlock_Kind: {
                 std::unique_ptr<InterfaceBlock> i = fIRGenerator->convertInterfaceBlock(
                                                                          (ASTInterfaceBlock&) decl);
@@ -194,10 +179,6 @@
                 }
                 break;
             }
-            case ASTDeclaration::kPrecision_Kind: {
-                *defaultPrecision = ((ASTPrecision&) decl).fPrecision;
-                break;
-            }
             default:
                 ABORT("unsupported declaration: %s\n", decl.description().c_str());
         }
@@ -209,18 +190,16 @@
     fErrorCount = 0;
     fIRGenerator->pushSymbolTable();
     std::vector<std::unique_ptr<ProgramElement>> elements;
-    Modifiers::Flag ignored;
     switch (kind) {
         case Program::kVertex_Kind:
-            this->internalConvertProgram(SKSL_VERT_INCLUDE, &ignored, &elements);
+            this->internalConvertProgram(SKSL_VERT_INCLUDE, &elements);
             break;
         case Program::kFragment_Kind:
-            this->internalConvertProgram(SKSL_FRAG_INCLUDE, &ignored, &elements);
+            this->internalConvertProgram(SKSL_FRAG_INCLUDE, &elements);
             break;
     }
-    Modifiers::Flag defaultPrecision;
-    this->internalConvertProgram(text, &defaultPrecision, &elements);
-    auto result = std::unique_ptr<Program>(new Program(kind, defaultPrecision, std::move(elements), 
+    this->internalConvertProgram(text, &elements);
+    auto result = std::unique_ptr<Program>(new Program(kind, std::move(elements), 
                                                        fIRGenerator->fSymbolTable));;
     fIRGenerator->popSymbolTable();
     this->writeErrorCount();
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index 96ae7d0..9cd1eac 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -15,8 +15,6 @@
 #include "SkSLErrorReporter.h"
 #include "SkSLGLSLCodeGenerator.h"
 
-#define SK_FRAGCOLOR_BUILTIN 10001
-
 namespace SkSL {
 
 class IRGenerator;
@@ -26,8 +24,6 @@
  * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to 
  * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
  * compiled output.
- *
- * See the README for information about SkSL.
  */
 class Compiler : public ErrorReporter {
 public:
@@ -54,7 +50,6 @@
 private:
 
     void internalConvertProgram(std::string text,
-                                Modifiers::Flag* defaultPrecision,
                                 std::vector<std::unique_ptr<ProgramElement>>* result);
 
     std::shared_ptr<SymbolTable> fTypes;
diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h
index 82c265b..1f124d0 100644
--- a/src/sksl/SkSLContext.h
+++ b/src/sksl/SkSLContext.h
@@ -60,7 +60,6 @@
     , fSampler1D_Type(new Type("sampler1D", SpvDim1D, false, false, false, true))
     , fSampler2D_Type(new Type("sampler2D", SpvDim2D, false, false, false, true))
     , fSampler3D_Type(new Type("sampler3D", SpvDim3D, false, false, false, true))
-    , fSamplerExternalOES_Type(new Type("samplerExternalOES", SpvDim2D, false, false, false, true))
     , fSamplerCube_Type(new Type("samplerCube"))
     , fSampler2DRect_Type(new Type("sampler2DRect"))
     , fSampler1DArray_Type(new Type("sampler1DArray"))
@@ -170,7 +169,6 @@
     const std::unique_ptr<Type> fSampler1D_Type;
     const std::unique_ptr<Type> fSampler2D_Type;
     const std::unique_ptr<Type> fSampler3D_Type;
-    const std::unique_ptr<Type> fSamplerExternalOES_Type;
     const std::unique_ptr<Type> fSamplerCube_Type;
     const std::unique_ptr<Type> fSampler2DRect_Type;
     const std::unique_ptr<Type> fSampler1DArray_Type;
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 96b997f..da0bcb9 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -14,11 +14,8 @@
 #include "ir/SkSLExpressionStatement.h"
 #include "ir/SkSLExtension.h"
 #include "ir/SkSLIndexExpression.h"
-#include "ir/SkSLModifiersDeclaration.h"
 #include "ir/SkSLVariableReference.h"
 
-#define SK_FRAGCOLOR_BUILTIN 10001
-
 namespace SkSL {
 
 void GLSLCodeGenerator::write(const char* s) {
@@ -69,7 +66,7 @@
         this->writeLine("struct " + type.name() + " {");
         fIndentation++;
         for (const auto& f : type.fields()) {
-            this->writeModifiers(f.fModifiers, false);
+            this->writeModifiers(f.fModifiers);
             // sizes (which must be static in structs) are part of the type name here
             this->writeType(*f.fType);
             this->writeLine(" " + f.fName + ";");
@@ -127,40 +124,7 @@
     }
 }
 
-static bool is_abs(Expression& expr) {
-    if (expr.fKind != Expression::kFunctionCall_Kind) {
-        return false;
-    }
-    return ((FunctionCall&) expr).fFunction.fName == "abs";
-}
-
-// turns min(abs(x), y) into (abs(x) > (tmpVar = y) ? tmpVar : abs(x)) to avoid a Tegra3 compiler 
-// bug.
-void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherExpr) {
-    ASSERT(!fCaps.fCanUseMinAndAbsTogether);
-    std::string varName = "minAbsHackVar" + to_string(fVarCount++);
-    this->fFunctionHeader += "    " + otherExpr.fType.name() + " " + varName + ";\n";
-    this->write("(");
-    this->writeExpression(absExpr, kTopLevel_Precedence);
-    this->write(" > (" + varName + " = ");
-    this->writeExpression(otherExpr, kRelational_Precedence);
-    this->write(") ? " + varName + " : ");
-    this->writeExpression(absExpr, kTernary_Precedence);
-    this->write(")");
-}
-
 void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
-    if (!fCaps.fCanUseMinAndAbsTogether && c.fFunction.fName == "min") {
-        ASSERT(c.fArguments.size() == 2);
-        if (is_abs(*c.fArguments[0])) {
-            this->writeMinAbsHack(*c.fArguments[0], *c.fArguments[1]);
-            return;
-        }
-        if (is_abs(*c.fArguments[1])) {
-            this->writeMinAbsHack(*c.fArguments[1], *c.fArguments[0]);
-            return;
-        }
-    }
     this->write(c.fFunction.fName + "(");
     const char* separator = "";
     for (const auto& arg : c.fArguments) {
@@ -183,15 +147,7 @@
 }
 
 void GLSLCodeGenerator::writeVariableReference(const VariableReference& ref) {
-    if (ref.fVariable.fModifiers.fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN) {
-        if (fCaps.fMustDeclareFragmentShaderOutput) {
-            this->write("sk_FragColor");
-        } else {
-            this->write("gl_FragColor");
-        }
-    } else {
-        this->write(ref.fVariable.fName);
-    }
+    this->write(ref.fVariable.fName);
 }
 
 void GLSLCodeGenerator::writeIndexExpression(const IndexExpression& expr) {
@@ -314,11 +270,7 @@
 }
 
 void GLSLCodeGenerator::writeIntLiteral(const IntLiteral& i) {
-    if (i.fType == *fContext.fUInt_Type) {
-        this->write(to_string(i.fValue & 0xffffffff) + "u");
-    } else {
-        this->write(to_string(i.fValue));
-    }
+    this->write(to_string(i.fValue));
 }
 
 void GLSLCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
@@ -332,99 +284,28 @@
     for (const auto& param : f.fDeclaration.fParameters) {
         this->write(separator);
         separator = ", ";
-        this->writeModifiers(param->fModifiers, false);
-        std::vector<int> sizes;
-        const Type* type = &param->fType;
-        while (type->kind() == Type::kArray_Kind) {
-            sizes.push_back(type->columns());
-            type = &type->componentType();
-        }
-        this->writeType(*type);
+        this->writeModifiers(param->fModifiers);
+        this->writeType(param->fType);
         this->write(" " + param->fName);
-        for (int s : sizes) {
-            if (s <= 0) {
-                this->write("[]");
-            } else {
-                this->write("[" + to_string(s) + "]");
-            }
-        }
     }
-    this->writeLine(") {");
-
-    fFunctionHeader = "";
-    std::ostream* oldOut = fOut;
-    std::stringstream buffer;
-    fOut = &buffer;
-    fIndentation++;
-    for (const auto& s : f.fBody->fStatements) {
-        this->writeStatement(*s);
-        this->writeLine();
-    }
-    fIndentation--;
-    this->writeLine("}");
-
-    fOut = oldOut;
-    this->write(fFunctionHeader);
-    this->write(buffer.str());
+    this->write(") ");
+    this->writeBlock(*f.fBody);
+    this->writeLine();
 }
 
-void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers, 
-                                       bool globalContext) {
-    if (modifiers.fFlags & Modifiers::kNoPerspective_Flag) {
-        this->write("noperspective ");
-    }
-    if (modifiers.fFlags & Modifiers::kFlat_Flag) {
-        this->write("flat ");
-    }
-    std::string layout = modifiers.fLayout.description();
-    if (layout.length()) {
-        this->write(layout + " ");
-    }
-    if ((modifiers.fFlags & Modifiers::kIn_Flag) && 
-        (modifiers.fFlags & Modifiers::kOut_Flag)) {
-        this->write("inout ");
-    } else if (modifiers.fFlags & Modifiers::kIn_Flag) {
-        if (globalContext && fCaps.fVersion < 130) {
-            this->write(fProgramKind == Program::kVertex_Kind ? "attribute "
-                                                              : "varying ");
-        } else {
-            this->write("in ");
-        }
-    } else if (modifiers.fFlags & Modifiers::kOut_Flag) {
-        if (globalContext && fCaps.fVersion < 130) {
-            this->write("varying ");
-        } else {
-            this->write("out ");
-        }
-    }
-    if (modifiers.fFlags & Modifiers::kUniform_Flag) {
-        this->write("uniform ");
-    }
-    if (modifiers.fFlags & Modifiers::kConst_Flag) {
-        this->write("const ");
-    }
-    if (fCaps.fUsesPrecisionModifiers) {
-        if (modifiers.fFlags & Modifiers::kLowp_Flag) {
-            this->write("lowp ");
-        }
-        if (modifiers.fFlags & Modifiers::kMediump_Flag) {
-            this->write("mediump ");
-        }
-        if (modifiers.fFlags & Modifiers::kHighp_Flag) {
-            this->write("highp ");
-        }
-    }
+void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers) {
+    this->write(modifiers.description());
 }
 
 void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
     if (intf.fVariable.fName == "gl_PerVertex") {
         return;
     }
-    this->writeModifiers(intf.fVariable.fModifiers, true);
+    this->writeModifiers(intf.fVariable.fModifiers);
     this->writeLine(intf.fVariable.fType.name() + " {");
     fIndentation++;
     for (const auto& f : intf.fVariable.fType.fields()) {
-        this->writeModifiers(f.fModifiers, false);
+        this->writeModifiers(f.fModifiers);
         this->writeType(*f.fType);
         this->writeLine(" " + f.fName + ";");
     }
@@ -432,9 +313,9 @@
     this->writeLine("};");
 }
 
-void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool global) {
+void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl) {
     ASSERT(decl.fVars.size() > 0);
-    this->writeModifiers(decl.fVars[0].fVar->fModifiers, global);
+    this->writeModifiers(decl.fVars[0].fVar->fModifiers);
     this->writeType(decl.fBaseType);
     std::string separator = " ";
     for (const auto& var : decl.fVars) {
@@ -444,9 +325,7 @@
         this->write(var.fVar->fName);
         for (const auto& size : var.fSizes) {
             this->write("[");
-            if (size) {
-                this->writeExpression(*size, kTopLevel_Precedence);
-            }
+            this->writeExpression(*size, kTopLevel_Precedence);
             this->write("]");
         }
         if (var.fValue) {
@@ -470,7 +349,7 @@
             this->writeReturnStatement((ReturnStatement&) s);
             break;
         case Statement::kVarDeclarations_Kind:
-            this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration, false);
+            this->writeVarDeclarations(*((VarDeclarationsStatement&) s).fDeclaration);
             break;
         case Statement::kIf_Kind:
             this->writeIfStatement((IfStatement&) s);
@@ -565,57 +444,22 @@
 void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) {
     ASSERT(fOut == nullptr);
     fOut = &out;
-    fProgramKind = program.fKind;
     this->write("#version " + to_string(fCaps.fVersion));
-    if (fCaps.fStandard == GLCaps::kGLES_Standard && fCaps.fVersion >= 300) {
+    if (fCaps.fStandard == GLCaps::kGLES_Standard) {
         this->write(" es");
-    } else if (fCaps.fIsCoreProfile) {
-        this->write(" core");
     }
     this->writeLine();
     for (const auto& e : program.fElements) {
-        if (e->fKind == ProgramElement::kExtension_Kind) {
-            this->writeExtension((Extension&) *e);
-        }
-    }
-    if (fCaps.fStandard == GLCaps::kGLES_Standard) {
-        this->write("precision ");
-        switch (program.fDefaultPrecision) {
-            case Modifiers::kLowp_Flag:
-                this->write("lowp");
-                break;
-            case Modifiers::kMediump_Flag:
-                this->write("mediump");
-                break;
-            case Modifiers::kHighp_Flag:
-                this->write("highp");
-                break;
-            default:
-                ASSERT(false);
-                this->write("<error>");
-        }
-        this->writeLine(" float;");
-    }
-    for (const auto& e : program.fElements) {
         switch (e->fKind) {
             case ProgramElement::kExtension_Kind:
+                this->writeExtension((Extension&) *e);
                 break;
             case ProgramElement::kVar_Kind: {
                 VarDeclarations& decl = (VarDeclarations&) *e;
-                if (decl.fVars.size() > 0) {
-                    int builtin = decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin;
-                    if (builtin == -1) {
-                        // normal var
-                        this->writeVarDeclarations(decl, true);
-                        this->writeLine();
-                    } else if (builtin == SK_FRAGCOLOR_BUILTIN &&
-                               fCaps.fMustDeclareFragmentShaderOutput) {
-                        this->write("out ");
-                        if (fCaps.fUsesPrecisionModifiers) {
-                            this->write("mediump ");
-                        }
-                        this->writeLine("vec4 sk_FragColor;");
-                    }
+                if (decl.fVars.size() > 0 && 
+                    decl.fVars[0].fVar->fModifiers.fLayout.fBuiltin == -1) {
+                    this->writeVarDeclarations(decl);
+                    this->writeLine();
                 }
                 break;
             }
@@ -625,10 +469,6 @@
             case ProgramElement::kFunction_Kind:
                 this->writeFunction((FunctionDefinition&) *e);
                 break;
-            case ProgramElement::kModifiers_Kind:
-                this->writeModifiers(((ModifiersDeclaration&) *e).fModifiers, true);
-                this->writeLine(";");
-                break;
             default:
                 printf("%s\n", e->description().c_str());
                 ABORT("unsupported program element");
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index 9851123..3534aff 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -50,11 +50,6 @@
         kGL_Standard,
         kGLES_Standard
     } fStandard;
-    bool fIsCoreProfile;
-    bool fUsesPrecisionModifiers;
-    bool fMustDeclareFragmentShaderOutput;
-    // The Tegra3 compiler will sometimes never return if we have min(abs(x), y)
-    bool fCanUseMinAndAbsTogether;
 };
 
 /**
@@ -86,8 +81,6 @@
     GLSLCodeGenerator(const Context* context, GLCaps caps)
     : fContext(*context)
     , fCaps(caps)
-    , fOut(nullptr)
-    , fVarCount(0)
     , fIndentation(0)
     , fAtLineStart(true) {}
 
@@ -118,11 +111,11 @@
 
     void writeLayout(const Layout& layout);
 
-    void writeModifiers(const Modifiers& modifiers, bool globalContext);
+    void writeModifiers(const Modifiers& modifiers);
     
     void writeGlobalVars(const VarDeclaration& vs);
 
-    void writeVarDeclarations(const VarDeclarations& decl, bool global);
+    void writeVarDeclarations(const VarDeclarations& decl);
 
     void writeVariableReference(const VariableReference& ref);
 
@@ -130,8 +123,6 @@
     
     void writeIntrinsicCall(const FunctionCall& c);
 
-    void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
-
     void writeFunctionCall(const FunctionCall& c);
 
     void writeConstructor(const Constructor& c);
@@ -173,9 +164,6 @@
     const Context& fContext;
     const GLCaps fCaps;
     std::ostream* fOut;
-    std::string fFunctionHeader;
-    Program::Kind fProgramKind;
-    int fVarCount;
     int fIndentation;
     bool fAtLineStart;
     // Keeps track of which struct types we have written. Given that we are unlikely to ever write 
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index d64684e..c30cac1 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -189,11 +189,7 @@
             }
             value = this->coerce(std::move(value), *type);
         }
-        if ("sk_FragColor" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) {
-            // already defined, ignore
-        } else if ((*fSymbolTable)[varDecl.fName] && 
-                   (*fSymbolTable)[varDecl.fName]->fKind == Symbol::kVariable_Kind && 
-                   ((Variable*) (*fSymbolTable)[varDecl.fName])->fModifiers.fLayout.fBuiltin >= 0) {
+        if ("gl_FragCoord" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) {
             // already defined, just update the modifiers
             Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName];
             old->fModifiers = var->fModifiers;
@@ -207,12 +203,6 @@
                                                                 std::move(variables)));
 }
 
-std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration(
-                                                                 const ASTModifiersDeclaration& m) {
-    Modifiers modifiers = this->convertModifiers(m.fModifiers);
-    return std::unique_ptr<ModifiersDeclaration>(new ModifiersDeclaration(modifiers));
-}
-
 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) {
     std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.fTest), 
                                                     *fContext.fBool_Type);
@@ -429,9 +419,8 @@
                     for (size_t i = 0; i < parameters.size(); i++) {
                         if (parameters[i]->fModifiers != other->fParameters[i]->fModifiers) {
                             fErrors.error(f.fPosition, "modifiers on parameter " + 
-                                                       to_string((uint64_t) i + 1) + 
-                                                       " differ between declaration and "
-                                                       "definition");
+                                                       to_string(i + 1) + " differ between " +
+                                                       "declaration and definition");
                             return nullptr;
                         }
                     }
@@ -627,9 +616,8 @@
         ASSERT(ctor);
         return this->call(Position(), std::move(ctor), std::move(args));
     }
-    std::vector<std::unique_ptr<Expression>> args;
-    args.push_back(std::move(expr));
-    return std::unique_ptr<Expression>(new Constructor(Position(), type, std::move(args)));
+    ABORT("cannot coerce %s to %s", expr->fType.description().c_str(), 
+          type.description().c_str());
 }
 
 static bool is_matrix_multiply(const Type& left, const Type& right) {
@@ -844,12 +832,12 @@
                                               std::vector<std::unique_ptr<Expression>> arguments) {
     if (function.fParameters.size() != arguments.size()) {
         std::string msg = "call to '" + function.fName + "' expected " + 
-                                 to_string((uint64_t) function.fParameters.size()) + 
+                                 to_string(function.fParameters.size()) + 
                                  " argument";
         if (function.fParameters.size() != 1) {
             msg += "s";
         }
-        msg += ", but found " + to_string((uint64_t) arguments.size());
+        msg += ", but found " + to_string(arguments.size());
         fErrors.error(position, msg);
         return nullptr;
     }
@@ -933,8 +921,7 @@
                                                     std::vector<std::unique_ptr<Expression>> args) {
     // FIXME: add support for structs and arrays
     Type::Kind kind = type.kind();
-    if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_Kind && 
-        kind != Type::kArray_Kind) {
+    if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_Kind) {
         fErrors.error(position, "cannot construct '" + type.description() + "'");
         return nullptr;
     }
@@ -951,7 +938,7 @@
         if (args.size() != 1) {
             fErrors.error(position, "invalid arguments to '" + type.description() + 
                                     "' constructor, (expected exactly 1 argument, but found " +
-                                    to_string((uint64_t) args.size()) + ")");
+                                    to_string(args.size()) + ")");
         }
         if (args[0]->fType == *fContext.fBool_Type) {
             std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position, 0));
@@ -966,18 +953,6 @@
                                     "' constructor (expected a number or bool, but found '" +
                                     args[0]->fType.description() + "')");
         }
-        if (args[0]->fKind == Expression::kIntLiteral_Kind && (type == *fContext.fInt_Type || 
-            type == *fContext.fUInt_Type)) {
-            return std::unique_ptr<Expression>(new IntLiteral(fContext, 
-                                                              position, 
-                                                              ((IntLiteral&) *args[0]).fValue,
-                                                              &type));
-        }
-    } else if (kind == Type::kArray_Kind) {
-        const Type& base = type.componentType();
-        for (size_t i = 0; i < args.size(); i++) {
-            args[i] = this->coerce(std::move(args[i]), base);
-        }
     } else {
         ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind);
         int actual = 0;
@@ -1062,7 +1037,7 @@
             }
             this->markWrittenTo(*base);
             break;
-        case Token::LOGICALNOT:
+        case Token::NOT:
             if (base->fType != *fContext.fBool_Type) {
                 fErrors.error(expression.fPosition, 
                               "'" + Token::OperatorName(expression.fOperator) + 
@@ -1070,14 +1045,6 @@
                 return nullptr;
             }
             break;
-        case Token::BITWISENOT:
-            if (base->fType != *fContext.fInt_Type) {
-                fErrors.error(expression.fPosition, 
-                              "'" + Token::OperatorName(expression.fOperator) + 
-                              "' cannot operate on '" + base->fType.description() + "'");
-                return nullptr;
-            }
-            break;
         default: 
             ABORT("unsupported prefix operator\n");
     }
@@ -1087,8 +1054,7 @@
 
 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression> base,
                                                       const ASTExpression& index) {
-    if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::kMatrix_Kind &&
-            base->fType.kind() != Type::kVector_Kind) {
+    if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::kMatrix_Kind) {
         fErrors.error(base->fPosition, "expected array, but found '" + base->fType.description() + 
                                        "'");
         return nullptr;
@@ -1097,11 +1063,9 @@
     if (!converted) {
         return nullptr;
     }
-    if (converted->fType != *fContext.fUInt_Type) {
-        converted = this->coerce(std::move(converted), *fContext.fInt_Type);
-        if (!converted) {
-            return nullptr;
-        }
+    converted = this->coerce(std::move(converted), *fContext.fInt_Type);
+    if (!converted) {
+        return nullptr;
     }
     return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(base), 
                                                            std::move(converted)));
@@ -1179,21 +1143,9 @@
         return nullptr;
     }
     switch (expression.fSuffix->fKind) {
-        case ASTSuffix::kIndex_Kind: {
-            const ASTExpression* expr = ((ASTIndexSuffix&) *expression.fSuffix).fExpression.get();
-            if (expr) {
-                return this->convertIndex(std::move(base), *expr);
-            } else if (base->fKind == Expression::kTypeReference_Kind) {
-                const Type& oldType = ((TypeReference&) *base).fValue;
-                Type* newType = new Type(oldType.name() + "[]", Type::kArray_Kind, oldType, 
-                                         -1);
-                fSymbolTable->takeOwnership(newType);
-                return std::unique_ptr<Expression>(new TypeReference(fContext, base->fPosition, 
-                                                                     *newType));
-            } else {
-                fErrors.error(expression.fPosition, "'[]' must follow a type name");
-            }
-        }
+        case ASTSuffix::kIndex_Kind:
+            return this->convertIndex(std::move(base), 
+                                      *((ASTIndexSuffix&) *expression.fSuffix).fExpression);
         case ASTSuffix::kCall_Kind: {
             auto rawArguments = &((ASTCallSuffix&) *expression.fSuffix).fArguments;
             std::vector<std::unique_ptr<Expression>> arguments;
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index 834ed8d..a3ff210 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -25,7 +25,6 @@
 #include "ast/SkSLASTIfStatement.h"
 #include "ast/SkSLASTInterfaceBlock.h"
 #include "ast/SkSLASTModifiers.h"
-#include "ast/SkSLASTModifiersDeclaration.h"
 #include "ast/SkSLASTPrefixExpression.h"
 #include "ast/SkSLASTReturnStatement.h"
 #include "ast/SkSLASTStatement.h"
@@ -40,7 +39,6 @@
 #include "ir/SkSLFunctionDefinition.h"
 #include "ir/SkSLInterfaceBlock.h"
 #include "ir/SkSLModifiers.h"
-#include "ir/SkSLModifiersDeclaration.h"
 #include "ir/SkSLSymbolTable.h"
 #include "ir/SkSLStatement.h"
 #include "ir/SkSLType.h"
@@ -63,8 +61,6 @@
     std::unique_ptr<FunctionDefinition> convertFunction(const ASTFunction& f);
     std::unique_ptr<Statement> convertStatement(const ASTStatement& statement);
     std::unique_ptr<Expression> convertExpression(const ASTExpression& expression);
-    std::unique_ptr<ModifiersDeclaration> convertModifiersDeclaration(
-                                                                  const ASTModifiersDeclaration& m);
 
 private:
     void pushSymbolTable();
diff --git a/src/sksl/SkSLMain.cpp b/src/sksl/SkSLMain.cpp
index de1b981..24fbb6c 100644
--- a/src/sksl/SkSLMain.cpp
+++ b/src/sksl/SkSLMain.cpp
@@ -9,24 +9,6 @@
 #include <fstream>
 #include "SkSLCompiler.h"
 
-bool endsWith(const std::string& s, const std::string& ending) {
-    if (s.length() >= ending.length()) {
-        return (0 == s.compare(s.length() - ending.length(), ending.length(), ending));
-    }
-    return false;
-}
-
-static SkSL::GLCaps default_caps() {
-    return { 
-             400, 
-             SkSL::GLCaps::kGL_Standard,
-             false, // isCoreProfile
-             false, // usesPrecisionModifiers;
-             false, // mustDeclareFragmentShaderOutput
-             true   // canUseMinAndAbsTogether
-           };
-}
-
 /**
  * Very simple standalone executable to facilitate testing.
  */
@@ -53,30 +35,14 @@
         printf("error reading '%s'\n", argv[1]);
         exit(2);
     }
-    std::string name(argv[2]);
-    if (endsWith(name, ".spirv")) {
-        std::ofstream out(argv[2], std::ofstream::binary);
-        SkSL::Compiler compiler;
-        if (!compiler.toSPIRV(kind, text, out)) {
-            printf("%s", compiler.errorText().c_str());
-            exit(3);
-        }
-        if (out.rdstate()) {
-            printf("error writing '%s'\n", argv[2]);
-            exit(4);
-        }
-    } else if (endsWith(name, ".glsl")) {
-        std::ofstream out(argv[2], std::ofstream::binary);
-        SkSL::Compiler compiler;
-        if (!compiler.toGLSL(kind, text, default_caps(), out)) {
-            printf("%s", compiler.errorText().c_str());
-            exit(3);
-        }
-        if (out.rdstate()) {
-            printf("error writing '%s'\n", argv[2]);
-            exit(4);
-        }
-    } else {
-        printf("expected output filename to end with '.spirv' or '.glsl'");
+    std::ofstream out(argv[2], std::ofstream::binary);
+    SkSL::Compiler compiler;
+    if (!compiler.toSPIRV(kind, text, out)) {
+        printf("%s", compiler.errorText().c_str());
+        exit(3);
+    }
+    if (out.rdstate()) {
+        printf("error writing '%s'\n", argv[2]);
+        exit(4);
     }
 }
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 29f1dbd..b240e45 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -56,9 +56,7 @@
 #include "ast/SkSLASTIndexSuffix.h"
 #include "ast/SkSLASTInterfaceBlock.h"
 #include "ast/SkSLASTIntLiteral.h"
-#include "ast/SkSLASTModifiersDeclaration.h"
 #include "ast/SkSLASTParameter.h"
-#include "ast/SkSLASTPrecision.h"
 #include "ast/SkSLASTPrefixExpression.h"
 #include "ast/SkSLASTReturnStatement.h"
 #include "ast/SkSLASTStatement.h"
@@ -99,13 +97,9 @@
         switch (this->peek().fKind) {
             case Token::END_OF_FILE:
                 return result;
-            case Token::PRECISION: {
-                std::unique_ptr<ASTDeclaration> precision = this->precision();
-                if (precision) {
-                    result.push_back(std::move(precision));
-                }
+            case Token::PRECISION:
+                this->precision();
                 break;
-            }
             case Token::DIRECTIVE: {
                 std::unique_ptr<ASTDeclaration> decl = this->directive();
                 if (decl) {
@@ -169,37 +163,29 @@
 }
 
 /* PRECISION (LOWP | MEDIUMP | HIGHP) type SEMICOLON */
-std::unique_ptr<ASTDeclaration> Parser::precision() {
+void Parser::precision() {
     if (!this->expect(Token::PRECISION, "'precision'")) {
-        return nullptr;
+        return;
     }
-    Modifiers::Flag result;
     Token p = this->nextToken();
     switch (p.fKind) {
-        case Token::LOWP:
-            result = Modifiers::kLowp_Flag;
-            break;
-        case Token::MEDIUMP:
-            result = Modifiers::kMediump_Flag;
-            break;
+        case Token::LOWP: // fall through
+        case Token::MEDIUMP: // fall through
         case Token::HIGHP:
-            result = Modifiers::kHighp_Flag;
+            // ignored for now
             break;
         default:
             this->error(p.fPosition, "expected 'lowp', 'mediump', or 'highp', but found '" + 
                                      p.fText + "'");
-            return nullptr;
+            return;
     }
-    // FIXME handle the type
     if (!this->type()) {
-        return nullptr;
+        return;
     }
     this->expect(Token::SEMICOLON, "';'");
-    return std::unique_ptr<ASTDeclaration>(new ASTPrecision(p.fPosition, result));
 }
 
-/* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? | 
-   DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */
+/* DIRECTIVE(#version) INT_LITERAL | DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */
 std::unique_ptr<ASTDeclaration> Parser::directive() {
     Token start;
     if (!this->expect(Token::DIRECTIVE, "a directive", &start)) {
@@ -207,12 +193,7 @@
     }
     if (start.fText == "#version") {
         this->expect(Token::INT_LITERAL, "a version number");
-        Token next = this->peek();
-        if (next.fText == "es" || next.fText == "compatibility") {
-            this->nextToken();
-        }
-        // version is ignored for now; it will eventually become an error when we stop pretending
-        // to be GLSL
+        // ignored for now
         return nullptr;
     } else if (start.fText == "#extension") {
         Token name;
@@ -246,10 +227,6 @@
     if (lookahead.fKind == Token::STRUCT) {
         return this->structVarDeclaration(modifiers);
     }
-    if (lookahead.fKind == Token::SEMICOLON) {
-        this->nextToken();
-        return std::unique_ptr<ASTDeclaration>(new ASTModifiersDeclaration(modifiers));
-    }
     std::unique_ptr<ASTType> type(this->type());
     if (!type) {
         return nullptr;
@@ -500,13 +477,10 @@
     int set = -1;
     int builtin = -1;
     bool originUpperLeft = false;
-    bool overrideCoverage = false;
-    bool blendSupportAllEquations = false;
     if (this->peek().fKind == Token::LAYOUT) {
         this->nextToken();
         if (!this->expect(Token::LPAREN, "'('")) {
-            return ASTLayout(location, binding, index, set, builtin, originUpperLeft,
-                             overrideCoverage, blendSupportAllEquations);
+            return ASTLayout(location, binding, index, set, builtin, originUpperLeft);
         }
         for (;;) {
             Token t = this->nextToken();
@@ -522,10 +496,6 @@
                 builtin = this->layoutInt();
             } else if (t.fText == "origin_upper_left") {
                 originUpperLeft = true;
-            } else if (t.fText == "override_coverage") {
-                overrideCoverage = true;
-            } else if (t.fText == "blend_support_all_equations") {
-                blendSupportAllEquations = true;
             } else {
                 this->error(t.fPosition, ("'" + t.fText + 
                                           "' is not a valid layout qualifier").c_str());
@@ -539,8 +509,7 @@
             }
         }
     }
-    return ASTLayout(location, binding, index, set, builtin, originUpperLeft, overrideCoverage,
-                     blendSupportAllEquations);
+    return ASTLayout(location, binding, index, set, builtin, originUpperLeft);
 }
 
 /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE)* */
@@ -1242,11 +1211,10 @@
 /* postfixExpression | (PLUS | MINUS | NOT | PLUSPLUS | MINUSMINUS) unaryExpression */
 std::unique_ptr<ASTExpression> Parser::unaryExpression() {
     switch (this->peek().fKind) {
-        case Token::PLUS:       // fall through
-        case Token::MINUS:      // fall through
-        case Token::LOGICALNOT: // fall through
-        case Token::BITWISENOT: // fall through
-        case Token::PLUSPLUS:   // fall through
+        case Token::PLUS:     // fall through
+        case Token::MINUS:    // fall through
+        case Token::NOT:      // fall through
+        case Token::PLUSPLUS: // fall through
         case Token::MINUSMINUS: {
             Token t = this->nextToken();
             std::unique_ptr<ASTExpression> expr = this->unaryExpression();
@@ -1286,16 +1254,12 @@
     }
 }
 
-/* LBRACKET expression? RBRACKET | DOT IDENTIFIER | LPAREN parameters RPAREN | 
+/* LBRACKET expression RBRACKET | DOT IDENTIFIER | LPAREN parameters RPAREN | 
    PLUSPLUS | MINUSMINUS */
 std::unique_ptr<ASTSuffix> Parser::suffix() {
     Token next = this->nextToken();
     switch (next.fKind) {
         case Token::LBRACKET: {
-            if (this->peek().fKind == Token::RBRACKET) {
-                this->nextToken();
-                return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(next.fPosition));
-            }
             std::unique_ptr<ASTExpression> e = this->expression();
             if (!e) {
                 return nullptr;
diff --git a/src/sksl/SkSLParser.h b/src/sksl/SkSLParser.h
index d1ae0d0..75f304b 100644
--- a/src/sksl/SkSLParser.h
+++ b/src/sksl/SkSLParser.h
@@ -35,7 +35,6 @@
 struct ASTLayout;
 struct ASTModifiers;
 struct ASTParameter;
-struct ASTPrecision;
 struct ASTReturnStatement;
 struct ASTStatement;
 struct ASTSuffix;
@@ -101,7 +100,7 @@
     // don't need to call any of these outside of the parser. The function declarations in the .cpp
     // file have comments describing the grammar rules.
 
-    std::unique_ptr<ASTDeclaration> precision();
+    void precision();
 
     std::unique_ptr<ASTDeclaration> directive();
 
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index 5403ba3..d17e3c4 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -15,7 +15,6 @@
 #include "ir/SkSLExtension.h"
 #include "ir/SkSLIndexExpression.h"
 #include "ir/SkSLVariableReference.h"
-#include "SkSLCompiler.h"
 
 namespace SkSL {
 
@@ -2163,19 +2162,13 @@
             lv->store(result, out);
             return result;
         }
-        case Token::LOGICALNOT: {
+        case Token::NOT: {
             ASSERT(p.fOperand->fType == *fContext.fBool_Type);
             SpvId result = this->nextId();
             this->writeInstruction(SpvOpLogicalNot, this->getType(p.fOperand->fType), result,
                                    this->writeExpression(*p.fOperand, out), out);
             return result;
         }
-        case Token::BITWISENOT: {
-            SpvId result = this->nextId();
-            this->writeInstruction(SpvOpNot, this->getType(p.fOperand->fType), result,
-                                   this->writeExpression(*p.fOperand, out), out);
-            return result;
-        }
         default:
             ABORT("unsupported prefix expression: %s", p.description().c_str());
     }
@@ -2328,7 +2321,7 @@
         this->writeInstruction(SpvOpDecorate, target, SpvDecorationDescriptorSet, layout.fSet, 
                                fDecorationBuffer);
     }
-    if (layout.fBuiltin >= 0 && layout.fBuiltin != SK_FRAGCOLOR_BUILTIN) {
+    if (layout.fBuiltin >= 0) {
         this->writeInstruction(SpvOpDecorate, target, SpvDecorationBuiltIn, layout.fBuiltin, 
                                fDecorationBuffer);
     }
@@ -2370,19 +2363,10 @@
     return result;
 }
 
-#define BUILTIN_IGNORE 9999
-void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclarations& decl, 
-                                         std::ostream& out) {
+void SPIRVCodeGenerator::writeGlobalVars(const VarDeclarations& decl, std::ostream& out) {
     for (size_t i = 0; i < decl.fVars.size(); i++) {
         const VarDeclaration& varDecl = decl.fVars[i];
         const Variable* var = varDecl.fVar;
-        if (var->fModifiers.fLayout.fBuiltin == BUILTIN_IGNORE) {
-            continue;
-        }
-        if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOLOR_BUILTIN &&
-            kind != Program::kFragment_Kind) {
-            continue;
-        }
         if (!var->fIsReadFrom && !var->fIsWrittenTo &&
                 !(var->fModifiers.fFlags & (Modifiers::kIn_Flag |
                                             Modifiers::kOut_Flag |
@@ -2578,8 +2562,7 @@
     }
     for (size_t i = 0; i < program.fElements.size(); i++) {
         if (program.fElements[i]->fKind == ProgramElement::kVar_Kind) {
-            this->writeGlobalVars(program.fKind, ((VarDeclarations&) *program.fElements[i]), 
-                                  body);
+            this->writeGlobalVars(((VarDeclarations&) *program.fElements[i]), body);
         }
     }
     for (size_t i = 0; i < program.fElements.size(); i++) {
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h
index 2800a86..e7b2b30 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.h
+++ b/src/sksl/SkSLSPIRVCodeGenerator.h
@@ -115,7 +115,7 @@
 
     SpvId writeFunction(const FunctionDefinition& f, std::ostream& out);
 
-    void writeGlobalVars(Program::Kind kind, const VarDeclarations& v, std::ostream& out);
+    void writeGlobalVars(const VarDeclarations& v, std::ostream& out);
 
     void writeVarDeclarations(const VarDeclarations& decl, std::ostream& out);
 
diff --git a/src/sksl/SkSLToken.h b/src/sksl/SkSLToken.h
index b8a364c..29fa81e 100644
--- a/src/sksl/SkSLToken.h
+++ b/src/sksl/SkSLToken.h
@@ -49,11 +49,10 @@
         BITWISEOR,
         BITWISEXOR,
         BITWISEAND,
-        BITWISENOT,
         LOGICALOR,
         LOGICALXOR,
         LOGICALAND,
-        LOGICALNOT,
+        NOT,
         QUESTION,
         COLON,
         EQ,
@@ -112,11 +111,9 @@
             case Token::PERCENT:      return "%";
             case Token::SHL:          return "<<";
             case Token::SHR:          return ">>";
-            case Token::LOGICALNOT:   return "!";
             case Token::LOGICALAND:   return "&&";
             case Token::LOGICALOR:    return "||";
             case Token::LOGICALXOR:   return "^^";
-            case Token::BITWISENOT:   return "~";
             case Token::BITWISEAND:   return "&";
             case Token::BITWISEOR:    return "|";
             case Token::BITWISEXOR:   return "^";
@@ -142,6 +139,7 @@
             case Token::BITWISEXOREQ: return "^=";
             case Token::PLUSPLUS:     return "++";
             case Token::MINUSMINUS:   return "--";
+            case Token::NOT:          return "!";
             default:
                 ABORT("unsupported operator: %d\n", kind); 
         }        
diff --git a/src/sksl/SkSLUtil.cpp b/src/sksl/SkSLUtil.cpp
index 2b51cff..327bffe 100644
--- a/src/sksl/SkSLUtil.cpp
+++ b/src/sksl/SkSLUtil.cpp
@@ -9,48 +9,7 @@
 
 namespace SkSL {
 
-std::string to_string(double value) {
-    std::stringstream buffer;
-    buffer << std::setprecision(std::numeric_limits<double>::digits10) << value;
-    std::string result = buffer.str();
-    if (result.find_last_of(".") == std::string::npos && 
-        result.find_last_of("e") == std::string::npos) {
-        result += ".0";
-    }
-    return result;
-}
-
-std::string to_string(int32_t value) {
-    std::stringstream buffer;
-    buffer << value;
-    return buffer.str();
-}
-
-std::string to_string(uint32_t value) {
-    std::stringstream buffer;
-    buffer << value;
-    return buffer.str();
-}
-
-std::string to_string(int64_t value) {
-    std::stringstream buffer;
-    buffer << value;
-    return buffer.str();
-}
-
-std::string to_string(uint64_t value) {
-    std::stringstream buffer;
-    buffer << value;
-    return buffer.str();
-}
-
 int stoi(std::string s) {
-    if (s.size() > 2 && s[0] == '0' && s[1] == 'x') {
-        char* p;
-        int result = strtoul(s.substr(2).c_str(), &p, 16);
-        ASSERT(*p == 0);
-        return result;
-    }
     return atoi(s.c_str());
 }
 
@@ -59,12 +18,6 @@
 }
 
 long stol(std::string s) {
-    if (s.size() > 2 && s[0] == '0' && s[1] == 'x') {
-        char* p;
-        int result = strtoul(s.substr(2).c_str(), &p, 16);
-        ASSERT(*p == 0);
-        return result;
-    }
     return atol(s.c_str());
 }
 
diff --git a/src/sksl/SkSLUtil.h b/src/sksl/SkSLUtil.h
index efffaae..33611cd 100644
--- a/src/sksl/SkSLUtil.h
+++ b/src/sksl/SkSLUtil.h
@@ -19,15 +19,11 @@
 
 // our own definitions of certain std:: functions, because they are not always present on Android
 
-std::string to_string(double value);
-
-std::string to_string(int32_t value);
-
-std::string to_string(uint32_t value);
-
-std::string to_string(int64_t value);
-
-std::string to_string(uint64_t value);
+template <typename T> std::string to_string(T value) {
+    std::stringstream buffer;
+    buffer << std::setprecision(std::numeric_limits<T>::digits10) << value;
+    return buffer.str();
+}
 
 #if _MSC_VER
 #define NORETURN __declspec(noreturn)
diff --git a/src/sksl/ast/SkSLASTDeclaration.h b/src/sksl/ast/SkSLASTDeclaration.h
index 70f0ebc..8b55ecf 100644
--- a/src/sksl/ast/SkSLASTDeclaration.h
+++ b/src/sksl/ast/SkSLASTDeclaration.h
@@ -20,9 +20,7 @@
         kVar_Kind,
         kFunction_Kind,
         kInterfaceBlock_Kind,
-        kExtension_Kind,
-        kPrecision_Kind,
-        kModifiers_Kind
+        kExtension_Kind
     };
 
     ASTDeclaration(Position position, Kind kind)
diff --git a/src/sksl/ast/SkSLASTIndexSuffix.h b/src/sksl/ast/SkSLASTIndexSuffix.h
index 755029b..44d91fa 100644
--- a/src/sksl/ast/SkSLASTIndexSuffix.h
+++ b/src/sksl/ast/SkSLASTIndexSuffix.h
@@ -14,27 +14,17 @@
 namespace SkSL {
 
 /**
- * A bracketed expression, as in '[0]', indicating an array access. Empty brackets (as occur in
- * 'float[](5, 6)' are represented with a null fExpression.
+ * A bracketed expression, as in '[0]', indicating an array access. 
  */
 struct ASTIndexSuffix : public ASTSuffix {
-    ASTIndexSuffix(Position position) 
-    : INHERITED(position, ASTSuffix::kIndex_Kind)
-    , fExpression(nullptr) {}
-
     ASTIndexSuffix(std::unique_ptr<ASTExpression> expression) 
-    : INHERITED(expression ? expression->fPosition : Position(), ASTSuffix::kIndex_Kind)
+    : INHERITED(expression->fPosition, ASTSuffix::kIndex_Kind)
     , fExpression(std::move(expression)) {}
 
     std::string description() const override {
-        if (fExpression) {
-            return "[" + fExpression->description() + "]";
-        } else {
-            return "[]";
-        }
+        return "[" + fExpression->description() + "]";
     }
 
-    // may be null
     std::unique_ptr<ASTExpression> fExpression;
 
     typedef ASTSuffix INHERITED;
diff --git a/src/sksl/ast/SkSLASTLayout.h b/src/sksl/ast/SkSLASTLayout.h
index 515eb2b..08d6753 100644
--- a/src/sksl/ast/SkSLASTLayout.h
+++ b/src/sksl/ast/SkSLASTLayout.h
@@ -20,16 +20,13 @@
  */
 struct ASTLayout : public ASTNode {
     // For all parameters, a -1 means no value
-    ASTLayout(int location, int binding, int index, int set, int builtin, bool originUpperLeft,
-              bool overrideCoverage, bool blendSupportAllEquations)
+    ASTLayout(int location, int binding, int index, int set, int builtin, bool originUpperLeft)
     : fLocation(location)
     , fBinding(binding)
     , fIndex(index)
     , fSet(set)
     , fBuiltin(builtin)
-    , fOriginUpperLeft(originUpperLeft)
-    , fOverrideCoverage(overrideCoverage)
-    , fBlendSupportAllEquations(blendSupportAllEquations) {}
+    , fOriginUpperLeft(originUpperLeft) {}
 
     std::string description() const {
         std::string result;
@@ -58,14 +55,6 @@
             result += separator + "origin_upper_left";
             separator = ", ";
         }
-        if (fOverrideCoverage) {
-            result += separator + "override_coverage";
-            separator = ", ";
-        }
-        if (fBlendSupportAllEquations) {
-            result += separator + "blend_support_all_equations";
-            separator = ", ";
-        }
         if (result.length() > 0) {
             result = "layout (" + result + ")";
         }
@@ -78,8 +67,6 @@
     const int fSet;
     const int fBuiltin;
     const bool fOriginUpperLeft;
-    const bool fOverrideCoverage;
-    const bool fBlendSupportAllEquations;
 };
 
 } // namespace
diff --git a/src/sksl/ast/SkSLASTModifiersDeclaration.h b/src/sksl/ast/SkSLASTModifiersDeclaration.h
deleted file mode 100644
index f5cc620..0000000
--- a/src/sksl/ast/SkSLASTModifiersDeclaration.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- 
-#ifndef SKSL_ASTMODIFIERDECLARATION
-#define SKSL_ASTMODIFIERDECLARATION
-
-#include "SkSLASTDeclaration.h"
-#include "SkSLASTModifiers.h"
-
-namespace SkSL {
-
-/**
- * A declaration that consists only of modifiers, e.g.:
- *
- * layout(blend_support_all_equations) out;
- */
-struct ASTModifiersDeclaration : public ASTDeclaration {
-    ASTModifiersDeclaration(ASTModifiers modifiers)
-    : INHERITED(Position(), kModifiers_Kind)
-    , fModifiers(modifiers) {}
-
-    std::string description() const {
-        return fModifiers.description() + ";";
-    }
-
-    ASTModifiers fModifiers;
-
-    typedef ASTDeclaration INHERITED;
-};
-
-} // namespace
-
-#endif
diff --git a/src/sksl/ast/SkSLASTPrecision.h b/src/sksl/ast/SkSLASTPrecision.h
deleted file mode 100644
index a7df579..0000000
--- a/src/sksl/ast/SkSLASTPrecision.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- 
-#ifndef SKSL_ASTPRECISION
-#define SKSL_ASTPRECISION
-
-#include "SkSLASTDeclaration.h"
-#include "../ir/SkSLModifiers.h"
-
-namespace SkSL {
-
-/**
- * Represents a precision declaration (e.g. 'precision mediump float;').
- */
-struct ASTPrecision : public ASTDeclaration {
-    // FIXME handle the type
-    ASTPrecision(Position position, Modifiers::Flag precision)
-    : INHERITED(position, kPrecision_Kind)
-    , fPrecision(precision) {}
-
-    std::string description() const {
-        switch (fPrecision) {
-            case Modifiers::kLowp_Flag: return "precision lowp float;";
-            case Modifiers::kMediump_Flag: return "precision mediump float;";
-            case Modifiers::kHighp_Flag: return "precision highp float;";
-            default: 
-                ASSERT(false); 
-                return "<error>";
-        }
-        ASSERT(false);
-        return "<error>";
-    }
-
-    const Modifiers::Flag fPrecision;
-
-    typedef ASTDeclaration INHERITED;
-};
-
-} // namespace
-
-#endif
diff --git a/src/sksl/ir/SkSLIndexExpression.h b/src/sksl/ir/SkSLIndexExpression.h
index 319e06f..f5b0d09 100644
--- a/src/sksl/ir/SkSLIndexExpression.h
+++ b/src/sksl/ir/SkSLIndexExpression.h
@@ -19,7 +19,7 @@
 static const Type& index_type(const Context& context, const Type& type) {
     if (type.kind() == Type::kMatrix_Kind) {
         if (type.componentType() == *context.fFloat_Type) {
-            switch (type.rows()) {
+            switch (type.columns()) {
                 case 2: return *context.fVec2_Type;
                 case 3: return *context.fVec3_Type;
                 case 4: return *context.fVec4_Type;
@@ -47,7 +47,7 @@
     : INHERITED(base->fPosition, kIndex_Kind, index_type(context, base->fType))
     , fBase(std::move(base))
     , fIndex(std::move(index)) {
-        ASSERT(fIndex->fType == *context.fInt_Type || fIndex->fType == *context.fUInt_Type);
+        ASSERT(fIndex->fType == *context.fInt_Type);
     }
 
     std::string description() const override {
diff --git a/src/sksl/ir/SkSLIntLiteral.h b/src/sksl/ir/SkSLIntLiteral.h
index 8921c28..2bc5657 100644
--- a/src/sksl/ir/SkSLIntLiteral.h
+++ b/src/sksl/ir/SkSLIntLiteral.h
@@ -18,8 +18,8 @@
 struct IntLiteral : public Expression {
     // FIXME: we will need to revisit this if/when we add full support for both signed and unsigned
     // 64-bit integers, but for right now an int64_t will hold every value we care about
-    IntLiteral(const Context& context, Position position, int64_t value, const Type* type = nullptr)
-    : INHERITED(position, kIntLiteral_Kind, type ? *type : *context.fInt_Type)
+    IntLiteral(const Context& context, Position position, int64_t value)
+    : INHERITED(position, kIntLiteral_Kind, *context.fInt_Type)
     , fValue(value) {}
 
     virtual std::string description() const override {
diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h
index 24087d0..d8dc980 100644
--- a/src/sksl/ir/SkSLLayout.h
+++ b/src/sksl/ir/SkSLLayout.h
@@ -22,20 +22,15 @@
     , fIndex(layout.fIndex)
     , fSet(layout.fSet)
     , fBuiltin(layout.fBuiltin)
-    , fOriginUpperLeft(layout.fOriginUpperLeft)
-    , fOverrideCoverage(layout.fOverrideCoverage)
-    , fBlendSupportAllEquations(layout.fBlendSupportAllEquations) {}
+    , fOriginUpperLeft(layout.fOriginUpperLeft) {}
 
-    Layout(int location, int binding, int index, int set, int builtin, bool originUpperLeft,
-           bool overrideCoverage, bool blendSupportAllEquations)
+    Layout(int location, int binding, int index, int set, int builtin, bool originUpperLeft)
     : fLocation(location)
     , fBinding(binding)
     , fIndex(index)
     , fSet(set)
     , fBuiltin(builtin)
-    , fOriginUpperLeft(originUpperLeft)
-    , fOverrideCoverage(overrideCoverage)
-    , fBlendSupportAllEquations(blendSupportAllEquations) {}
+    , fOriginUpperLeft(originUpperLeft) {}
 
     std::string description() const {
         std::string result;
@@ -64,14 +59,6 @@
             result += separator + "origin_upper_left";
             separator = ", ";
         }
-        if (fOverrideCoverage) {
-            result += separator + "override_coverage";
-            separator = ", ";
-        }
-        if (fBlendSupportAllEquations) {
-            result += separator + "blend_support_all_equations";
-            separator = ", ";
-        }
         if (result.length() > 0) {
             result = "layout (" + result + ")";
         }
@@ -79,14 +66,11 @@
     }
 
     bool operator==(const Layout& other) const {
-        return fLocation                 == other.fLocation &&
-               fBinding                  == other.fBinding &&
-               fIndex                    == other.fIndex &&
-               fSet                      == other.fSet &&
-               fBuiltin                  == other.fBuiltin &&
-               fOriginUpperLeft          == other.fOriginUpperLeft &&
-               fOverrideCoverage         == other.fOverrideCoverage &&
-               fBlendSupportAllEquations == other.fBlendSupportAllEquations;
+        return fLocation == other.fLocation &&
+               fBinding  == other.fBinding &&
+               fIndex    == other.fIndex &&
+               fSet      == other.fSet &&
+               fBuiltin  == other.fBuiltin;
     }
 
     bool operator!=(const Layout& other) const {
@@ -101,8 +85,6 @@
     int fSet;
     int fBuiltin;
     bool fOriginUpperLeft;
-    bool fOverrideCoverage;
-    bool fBlendSupportAllEquations;
 };
 
 } // namespace
diff --git a/src/sksl/ir/SkSLModifiersDeclaration.h b/src/sksl/ir/SkSLModifiersDeclaration.h
deleted file mode 100644
index 0066fab..0000000
--- a/src/sksl/ir/SkSLModifiersDeclaration.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- 
-#ifndef SKSL_MODIFIERDECLARATION
-#define SKSL_MODIFIERDECLARATION
-
-#include "SkSLProgramElement.h"
-#include "SkSLModifiers.h"
-
-namespace SkSL {
-
-/**
- * A declaration that consists only of modifiers, e.g.:
- *
- * layout(blend_support_all_equations) out;
- */
-struct ModifiersDeclaration : public ProgramElement {
-    ModifiersDeclaration(Modifiers modifiers)
-    : INHERITED(Position(), kModifiers_Kind)
-    , fModifiers(modifiers) {}
-
-    std::string description() const {
-        return fModifiers.description() + ";";
-    }
-
-    Modifiers fModifiers;
-
-    typedef ProgramElement INHERITED;
-};
-
-} // namespace
-
-#endif
diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h
index 3a842e9..205db6e 100644
--- a/src/sksl/ir/SkSLProgram.h
+++ b/src/sksl/ir/SkSLProgram.h
@@ -11,7 +11,6 @@
 #include <vector>
 #include <memory>
 
-#include "SkSLModifiers.h"
 #include "SkSLProgramElement.h"
 #include "SkSLSymbolTable.h"
 
@@ -26,20 +25,16 @@
         kVertex_Kind
     };
 
-    Program(Kind kind, 
-            Modifiers::Flag defaultPrecision,
-            std::vector<std::unique_ptr<ProgramElement>> elements, 
+    Program(Kind kind, std::vector<std::unique_ptr<ProgramElement>> elements, 
             std::shared_ptr<SymbolTable> symbols)
     : fKind(kind) 
-    , fDefaultPrecision(defaultPrecision)
     , fElements(std::move(elements))
     , fSymbols(symbols) {}
 
     Kind fKind;
-    Modifiers::Flag fDefaultPrecision;
+
     std::vector<std::unique_ptr<ProgramElement>> fElements;
     std::shared_ptr<SymbolTable> fSymbols;
-    // FIXME handle different types; currently it assumes this is for floats
 };
 
 } // namespace
diff --git a/src/sksl/ir/SkSLProgramElement.h b/src/sksl/ir/SkSLProgramElement.h
index 2f1ce77..44fc340 100644
--- a/src/sksl/ir/SkSLProgramElement.h
+++ b/src/sksl/ir/SkSLProgramElement.h
@@ -20,8 +20,7 @@
         kVar_Kind,
         kFunction_Kind,
         kInterfaceBlock_Kind,
-        kExtension_Kind,
-        kModifiers_Kind
+        kExtension_Kind
     };
 
     ProgramElement(Position position, Kind kind)
diff --git a/src/sksl/lex.sksl.c b/src/sksl/lex.sksl.c
index cd4f4e3..4993fac 100644
--- a/src/sksl/lex.sksl.c
+++ b/src/sksl/lex.sksl.c
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
- 
+
 #line 3 "lex.sksl.c"
 
 #define  YY_INT_ALIGNED short int
@@ -14,7 +14,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
+#define YY_FLEX_SUBMINOR_VERSION 37
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -52,7 +52,6 @@
 typedef uint16_t flex_uint16_t;
 typedef int32_t flex_int32_t;
 typedef uint32_t flex_uint32_t;
-typedef uint64_t flex_uint64_t;
 #else
 typedef signed char flex_int8_t;
 typedef short int flex_int16_t;
@@ -60,7 +59,6 @@
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -91,6 +89,8 @@
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#endif /* ! C99 */
+
 #endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
@@ -194,7 +194,7 @@
      */
     #define  YY_LESS_LINENO(n) \
             do { \
-                yy_size_t yyl;\
+                int yyl;\
                 for ( yyl = n; yyl < yyleng; ++yyl )\
                     if ( yytext[yyl] == '\n' )\
                         --yylineno;\
@@ -360,13 +360,13 @@
  */
 #define YY_DO_BEFORE_ACTION \
 	yyg->yytext_ptr = yy_bp; \
-	yyleng = (yy_size_t) (yy_cp - yy_bp); \
+	yyleng = (size_t) (yy_cp - yy_bp); \
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 84
-#define YY_END_OF_BUFFER 85
+#define YY_NUM_RULES 82
+#define YY_END_OF_BUFFER 83
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -374,31 +374,30 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[205] =
+static yyconst flex_int16_t yy_accept[201] =
     {   0,
-        0,    0,   85,   83,   82,   82,   56,   83,   30,   46,
-       51,   32,   33,   44,   42,   39,   43,   38,   45,    4,
-        4,   58,   79,   63,   59,   62,   57,   36,   37,   50,
-       30,   30,   30,   30,   30,   30,   30,   30,   30,   30,
-       30,   30,   30,   30,   30,   30,   30,   34,   49,   35,
-       52,   82,   61,   31,   30,   70,   55,   75,   68,   40,
-       66,   41,   67,    1,    0,   80,   69,    2,    4,    0,
-        0,   47,   65,   60,   64,   48,   74,   54,   30,   30,
-       30,   12,   30,   30,   30,   30,   30,    8,   17,   30,
-       30,   30,   30,   30,   30,   30,   30,   30,   30,   30,
+        0,    0,   83,   81,   80,   80,   54,   81,   29,   45,
+       50,   31,   32,   43,   41,   38,   42,   37,   44,    4,
+       56,   77,   61,   57,   60,   55,   35,   36,   49,   29,
+       29,   29,   29,   29,   29,   29,   29,   29,   29,   29,
+       29,   29,   29,   29,   29,   29,   33,   48,   34,   80,
+       59,   30,   29,   68,   53,   73,   66,   39,   64,   40,
+       65,    1,    0,   78,   67,    2,    4,    0,   46,   63,
+       58,   62,   47,   72,   52,   29,   29,   29,   11,   29,
+       29,   29,   29,   29,    7,   16,   29,   29,   29,   29,
+       29,   29,   29,   29,   29,   29,   29,   71,   51,   30,
 
-       73,   53,   31,   78,    0,    0,    0,   80,    1,    0,
-        0,    3,    5,   71,   72,   77,   30,   30,   30,   30,
-       30,   30,   10,   30,   30,   30,   30,   30,   30,   18,
-       30,   30,   30,   30,   30,   30,   76,    0,    1,   81,
-        0,    0,    2,   30,   30,   30,   30,    9,   30,   25,
-       30,   30,   30,   22,   30,   30,   30,   30,   30,    6,
-       30,   30,    0,    1,   13,   21,   30,   30,    7,   24,
-       19,   30,   30,   30,   30,   30,   30,   30,   11,   30,
-       30,   28,   30,   30,   30,   16,   27,   30,   30,   15,
-       23,   30,   30,   20,   14,   30,   30,   30,   29,   30,
+       76,    0,    0,    0,   78,    1,    0,    0,    3,   69,
+       70,   75,   29,   29,   29,   29,   29,   29,    9,   29,
+       29,   29,   29,   29,   29,   17,   29,   29,   29,   29,
+       29,   29,   74,    0,    1,   79,    0,    0,    2,   29,
+       29,   29,   29,    8,   29,   24,   29,   29,   29,   21,
+       29,   29,   29,   29,   29,    5,   29,   29,    0,    1,
+       12,   20,   29,   29,    6,   23,   18,   29,   29,   29,
+       29,   29,   29,   29,   10,   29,   29,   27,   29,   29,
+       29,   15,   26,   29,   29,   14,   22,   29,   29,   19,
+       13,   29,   29,   29,   28,   29,   29,   29,   25,    0
 
-       30,   30,   26,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -407,16 +406,16 @@
         1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    2,    4,    1,    5,    6,    7,    8,    1,    9,
-       10,   11,   12,   13,   14,   15,   16,   17,   18,   18,
-       18,   18,   18,   18,   18,   18,   18,   19,   20,   21,
-       22,   23,   24,    1,   25,   25,   25,   25,   26,   25,
-       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
-       25,   25,   25,   25,   25,   25,   25,   25,   25,   25,
-       27,    1,   28,   29,    6,    1,   30,   31,   32,   33,
+       10,   11,   12,   13,   14,   15,   16,   17,   17,   17,
+       17,   17,   17,   17,   17,   17,   17,   18,   19,   20,
+       21,   22,   23,    1,    6,    6,    6,    6,   24,    6,
+        6,    6,    6,    6,    6,    6,    6,    6,    6,    6,
+        6,    6,    6,    6,    6,    6,    6,    6,    6,    6,
+       25,    1,   26,   27,    6,    1,   28,   29,   30,   31,
 
-       34,   35,   36,   37,   38,   25,   39,   40,   41,   42,
-       43,   44,   25,   45,   46,   47,   48,   49,   50,   51,
-       52,   25,   53,   54,   55,   56,    1,    1,    1,    1,
+       32,   33,   34,   35,   36,    6,   37,   38,   39,   40,
+       41,   42,    6,   43,   44,   45,   46,   47,   48,    6,
+       49,    6,   50,   51,   52,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -433,158 +432,152 @@
         1,    1,    1,    1,    1
     } ;
 
-static yyconst flex_int32_t yy_meta[57] =
+static yyconst flex_int32_t yy_meta[53] =
     {   0,
         1,    1,    2,    1,    1,    3,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    4,    4,    1,    1,
-        1,    1,    1,    1,    5,    5,    1,    1,    1,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
-        5,    5,    1,    1,    1,    1
+        1,    1,    1,    1,    1,    1,    4,    1,    1,    1,
+        1,    1,    1,    3,    1,    1,    1,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    1,
+        1,    1
     } ;
 
-static yyconst flex_int16_t yy_base[211] =
+static yyconst flex_int16_t yy_base[206] =
     {   0,
-        0,    0,  273,  274,   55,   57,  250,    0,    0,  249,
-       53,  274,  274,  248,   50,  274,   49,   47,   57,   52,
-       59,  274,  274,   59,  247,   60,  274,  274,  274,   62,
-      223,  224,   49,  226,   58,  227,   54,   64,  230,  220,
-      214,  216,  226,  212,  213,  215,  219,  274,   68,  274,
-      274,   97,  274,    0,    0,  274,  233,  274,  274,  274,
-      274,  274,  274,   87,  243,    0,  274,   91,   97,  112,
-        0,  231,  274,  274,  274,  230,  274,  229,  216,  207,
-      202,    0,  201,  206,  215,  199,  207,    0,  199,  189,
-      190,  206,  194,  190,  202,  188,  189,  185,  194,  193,
+        0,    0,  238,  239,   51,   53,  216,    0,    0,  215,
+       49,  239,  239,  214,   46,  239,   45,  217,   52,   45,
+      239,  239,   44,  212,   50,  239,  239,  239,   53,  189,
+      190,   40,  192,   47,  193,   46,   50,  196,  186,  180,
+      182,  192,  178,  179,  181,  185,  239,   61,  239,   81,
+      239,    0,    0,  239,  198,  239,  239,  239,  239,  239,
+      239,   70,  207,    0,  239,   72,   75,   81,  196,  239,
+      239,  239,  195,  239,  194,  182,  173,  168,    0,  167,
+      172,  181,  165,  173,    0,  165,  156,  156,  172,  160,
+      156,  168,  154,  155,  151,  160,  159,  239,  173,    0,
 
-      274,  208,    0,  274,  120,  218,  212,    0,   93,  127,
-      118,  125,    0,  274,  274,  274,  197,  100,  194,  191,
-      178,  176,    0,  185,  173,  177,  175,  180,  183,    0,
-      184,  167,  166,  179,  177,  171,  274,  131,  133,  274,
-      140,  138,  142,  171,  162,  170,  177,    0,  172,    0,
-      161,  157,  155,    0,  154,  156,  162,  154,  166,    0,
-      154,  162,  144,  146,    0,    0,  153,  149,    0,    0,
-        0,  146,  151,  145,  144,  147,  141,  142,    0,  138,
-      147,    0,  122,  109,  102,    0,    0,   92,   94,    0,
-        0,   86,   75,    0,    0,   84,   64,   55,    0,   59,
+      239,   89,  182,  176,    0,   91,   97,  174,  173,  239,
+      239,  239,  161,   72,  158,  155,  142,  140,    0,  149,
+      137,  141,  139,  144,  147,    0,  148,  131,  130,  143,
+      141,  135,  239,  155,  154,  239,  107,  153,  152,  131,
+      122,  130,  137,    0,  132,    0,  121,  117,  115,    0,
+      114,  116,  122,  114,  126,    0,  114,  122,  136,  135,
+        0,    0,  111,  107,    0,    0,    0,  104,  109,  103,
+      102,  105,   99,  100,    0,   96,  110,    0,   98,   97,
+      102,    0,    0,   98,  102,    0,    0,   90,   79,    0,
+        0,   88,   73,   65,    0,   69,   53,   65,    0,  239,
 
-       46,   32,    0,  274,  162,  165,  168,  173,  178,  180
+       58,  122,  124,  128,  132
     } ;
 
-static yyconst flex_int16_t yy_def[211] =
+static yyconst flex_int16_t yy_def[206] =
     {   0,
-      204,    1,  204,  204,  204,  204,  204,  205,  206,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  204,  204,  204,
-      204,  204,  204,  207,  206,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  208,  209,  204,  204,  204,  204,
-      210,  204,  204,  204,  204,  204,  204,  204,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
+      200,    1,  200,  200,  200,  200,  200,  201,  202,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  200,  200,  200,  200,
+      200,  203,  202,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  204,  205,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  202,  200,  200,  203,
 
-      204,  204,  207,  204,  204,  208,  208,  209,  204,  204,
-      204,  204,  210,  204,  204,  204,  206,  206,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
-      206,  206,  206,  206,  206,  206,  204,  204,  204,  204,
-      204,  204,  204,  206,  206,  206,  206,  206,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
-      206,  206,  204,  204,  206,  206,  206,  206,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
+      200,  200,  204,  204,  205,  200,  200,  200,  200,  200,
+      200,  200,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  200,  200,  200,  200,  200,  200,  200,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  200,  200,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,    0,
 
-      206,  206,  206,    0,  204,  204,  204,  204,  204,  204
+      200,  200,  200,  200,  200
     } ;
 
-static yyconst flex_int16_t yy_nxt[331] =
+static yyconst flex_int16_t yy_nxt[292] =
     {   0,
         4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
        14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
-       24,   25,   26,   27,    9,    9,   28,   29,   30,    9,
-       31,   32,   33,   34,   35,    9,   36,   37,    9,   38,
-       39,   40,   41,   42,   43,   44,   45,   46,    9,   47,
-        9,    9,   48,   49,   50,   51,   52,   52,   52,   52,
-       57,   60,   62,   64,   64,  203,   68,   65,   69,   69,
-       63,   61,   66,   68,   58,   69,   69,   70,   67,   72,
-       73,   75,   76,   77,   70,   70,   81,   84,   88,  101,
-       78,   82,   70,   90,  202,   89,  201,   85,   52,   52,
+       24,   25,   26,    9,   27,   28,   29,    9,   30,   31,
+       32,   33,   34,    9,   35,   36,    9,   37,   38,   39,
+       40,   41,   42,   43,   44,   45,    9,   46,    9,   47,
+       48,   49,   50,   50,   50,   50,   55,   58,   60,   66,
+       52,   67,   63,   69,   70,   61,   59,   64,   68,   56,
+       72,   73,   65,   74,   81,   78,   68,   87,   85,   75,
+       79,   98,   50,   50,   82,   86,   62,   83,  106,   66,
+       88,   67,  108,  102,  108,  107,  199,  109,   68,  198,
 
-       86,  200,   71,   64,   64,  199,   91,  109,  109,  109,
-      109,   68,  105,   69,   69,  198,  110,  197,  141,  196,
-      105,  102,   70,  111,  110,  111,  141,  195,  112,  112,
-       70,  138,  194,  138,  112,  112,  139,  139,  142,  193,
-      142,  112,  112,  143,  143,  145,  146,  139,  139,  139,
-      139,  163,  192,  163,  143,  143,  164,  164,  143,  143,
-      164,  164,  164,  164,   54,  191,   54,   55,   55,   55,
-      103,  103,  103,  106,  106,  106,  106,  106,  108,  190,
-      108,  108,  108,  113,  113,  189,  188,  187,  186,  185,
-      184,  183,  182,  181,  180,  179,  178,  177,  176,  175,
+      134,  102,  134,  107,  197,  135,   68,  106,  138,  196,
+      138,   99,  195,  139,  137,  141,  142,  194,  159,  193,
+      159,  192,  137,  160,   53,   53,  100,  100,  103,  103,
+      103,  103,  105,  191,  105,  105,  190,  189,  188,  187,
+      186,  185,  184,  183,  182,  181,  180,  179,  178,  177,
+      176,  160,  160,  175,  174,  173,  172,  171,  170,  169,
+      168,  167,  166,  165,  164,  163,  162,  161,  139,  139,
+      135,  135,  158,  157,  156,  155,  154,  153,  152,  151,
+      150,  149,  148,  147,  146,  145,  144,  143,  140,  109,
+      109,  136,  104,  133,  132,  131,  130,  129,  128,  127,
 
-      174,  173,  172,  171,  170,  169,  168,  167,  166,  165,
-      162,  161,  160,  159,  158,  157,  156,  155,  154,  153,
-      152,  151,  150,  149,  148,  147,  144,  140,  107,  137,
-      136,  135,  134,  133,  132,  131,  130,  129,  128,  127,
       126,  125,  124,  123,  122,  121,  120,  119,  118,  117,
-      116,  115,  114,  107,  104,  100,   99,   98,   97,   96,
-       95,   94,   93,   92,   87,   83,   80,   79,   74,   59,
-       56,   53,  204,    3,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
+      116,  115,  114,  113,  112,  111,  110,  104,  101,   97,
+       96,   95,   94,   93,   92,   91,   90,   89,   84,   80,
+       77,   76,   71,   62,   57,   54,   51,  200,    3,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200
 
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204
     } ;
 
-static yyconst flex_int16_t yy_chk[331] =
+static yyconst flex_int16_t yy_chk[292] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    5,    5,    6,    6,
-       11,   15,   17,   18,   18,  202,   20,   19,   20,   20,
-       17,   15,   19,   21,   11,   21,   21,   20,   19,   24,
-       24,   26,   26,   30,   21,   20,   33,   35,   37,   49,
-       30,   33,   21,   38,  201,   37,  200,   35,   52,   52,
+        1,    1,    5,    5,    6,    6,   11,   15,   17,   20,
+      201,   20,   19,   23,   23,   17,   15,   19,   20,   11,
+       25,   25,   19,   29,   34,   32,   20,   37,   36,   29,
+       32,   48,   50,   50,   34,   36,   62,   34,   66,   67,
+       37,   67,   68,   62,   68,   66,  198,   68,   67,  197,
 
-       35,  198,   20,   64,   64,  197,   38,   68,   68,  109,
-      109,   69,   64,   69,   69,  196,   68,  193,  109,  192,
-       64,   49,   69,   70,   68,   70,  109,  189,   70,   70,
-       69,  105,  188,  105,  111,  111,  105,  105,  110,  185,
-      110,  112,  112,  110,  110,  118,  118,  138,  138,  139,
-      139,  141,  184,  141,  142,  142,  141,  141,  143,  143,
-      163,  163,  164,  164,  205,  183,  205,  206,  206,  206,
-      207,  207,  207,  208,  208,  208,  208,  208,  209,  181,
-      209,  209,  209,  210,  210,  180,  178,  177,  176,  175,
-      174,  173,  172,  168,  167,  162,  161,  159,  158,  157,
+      102,   62,  102,   66,  196,  102,   67,  106,  107,  194,
+      107,   48,  193,  107,  106,  114,  114,  192,  137,  189,
+      137,  188,  106,  137,  202,  202,  203,  203,  204,  204,
+      204,  204,  205,  185,  205,  205,  184,  181,  180,  179,
+      177,  176,  174,  173,  172,  171,  170,  169,  168,  164,
+      163,  160,  159,  158,  157,  155,  154,  153,  152,  151,
+      149,  148,  147,  145,  143,  142,  141,  140,  139,  138,
+      135,  134,  132,  131,  130,  129,  128,  127,  125,  124,
+      123,  122,  121,  120,  118,  117,  116,  115,  113,  109,
+      108,  104,  103,   99,   97,   96,   95,   94,   93,   92,
 
-      156,  155,  153,  152,  151,  149,  147,  146,  145,  144,
-      136,  135,  134,  133,  132,  131,  129,  128,  127,  126,
-      125,  124,  122,  121,  120,  119,  117,  107,  106,  102,
-      100,   99,   98,   97,   96,   95,   94,   93,   92,   91,
-       90,   89,   87,   86,   85,   84,   83,   81,   80,   79,
-       78,   76,   72,   65,   57,   47,   46,   45,   44,   43,
-       42,   41,   40,   39,   36,   34,   32,   31,   25,   14,
-       10,    7,    3,  204,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
+       91,   90,   89,   88,   87,   86,   84,   83,   82,   81,
+       80,   78,   77,   76,   75,   73,   69,   63,   55,   46,
+       45,   44,   43,   42,   41,   40,   39,   38,   35,   33,
+       31,   30,   24,   18,   14,   10,    7,    3,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200,  200,  200,  200,  200,  200,  200,  200,  200,  200,
+      200
 
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204,
-      204,  204,  204,  204,  204,  204,  204,  204,  204,  204
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[85] =
+static yyconst flex_int32_t yy_rule_can_match_eol[83] =
     {   0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 1, 1, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
+    1, 0, 0,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -607,7 +600,7 @@
     
 */
 #define YY_NO_UNISTD_H 1
-#line 605 "lex.sksl.c"
+#line 598 "lex.sksl.c"
 
 #define INITIAL 0
 
@@ -692,6 +685,10 @@
 
 void skslset_lineno (int line_number ,yyscan_t yyscanner );
 
+int skslget_column  (yyscan_t yyscanner );
+
+void skslset_column (int column_no ,yyscan_t yyscanner );
+
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -734,7 +731,7 @@
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -745,7 +742,7 @@
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		yy_size_t n; \
+		size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -831,7 +828,7 @@
 #line 23 "sksl.flex"
 
 
-#line 829 "lex.sksl.c"
+#line 826 "lex.sksl.c"
 
 	if ( !yyg->yy_init )
 		{
@@ -884,13 +881,13 @@
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 205 )
+				if ( yy_current_state >= 201 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 204 );
+		while ( yy_current_state != 200 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -901,7 +898,7 @@
 
 		if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
 			{
-			yy_size_t yyl;
+			int yyl;
 			for ( yyl = 0; yyl < yyleng; ++yyl )
 				if ( yytext[yyl] == '\n' )
 					   
@@ -945,406 +942,396 @@
 case 5:
 YY_RULE_SETUP
 #line 33 "sksl.flex"
-{ return SkSL::Token::INT_LITERAL; }
+{ return SkSL::Token::TRUE_LITERAL; }
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
 #line 35 "sksl.flex"
-{ return SkSL::Token::TRUE_LITERAL; }
+{ return SkSL::Token::FALSE_LITERAL; }
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
 #line 37 "sksl.flex"
-{ return SkSL::Token::FALSE_LITERAL; }
+{ return SkSL::Token::IF; }
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
 #line 39 "sksl.flex"
-{ return SkSL::Token::IF; }
+{ return SkSL::Token::ELSE; }
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
 #line 41 "sksl.flex"
-{ return SkSL::Token::ELSE; }
+{ return SkSL::Token::FOR; }
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
 #line 43 "sksl.flex"
-{ return SkSL::Token::FOR; }
+{ return SkSL::Token::WHILE; }
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
 #line 45 "sksl.flex"
-{ return SkSL::Token::WHILE; }
+{ return SkSL::Token::DO; }
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
 #line 47 "sksl.flex"
-{ return SkSL::Token::DO; }
+{ return SkSL::Token::BREAK; }
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
 #line 49 "sksl.flex"
-{ return SkSL::Token::BREAK; }
+{ return SkSL::Token::CONTINUE; }
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
 #line 51 "sksl.flex"
-{ return SkSL::Token::CONTINUE; }
+{ return SkSL::Token::DISCARD; }
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
 #line 53 "sksl.flex"
-{ return SkSL::Token::DISCARD; }
+{ return SkSL::Token::RETURN; }
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
 #line 55 "sksl.flex"
-{ return SkSL::Token::RETURN; }
+{ return SkSL::Token::IN; }
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
 #line 57 "sksl.flex"
-{ return SkSL::Token::IN; }
+{ return SkSL::Token::OUT; }
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
 #line 59 "sksl.flex"
-{ return SkSL::Token::OUT; }
+{ return SkSL::Token::INOUT; }
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
 #line 61 "sksl.flex"
-{ return SkSL::Token::INOUT; }
+{ return SkSL::Token::UNIFORM; }
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
 #line 63 "sksl.flex"
-{ return SkSL::Token::UNIFORM; }
+{ return SkSL::Token::CONST; }
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
 #line 65 "sksl.flex"
-{ return SkSL::Token::CONST; }
+{ return SkSL::Token::LOWP; }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
 #line 67 "sksl.flex"
-{ return SkSL::Token::LOWP; }
+{ return SkSL::Token::MEDIUMP; }
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
 #line 69 "sksl.flex"
-{ return SkSL::Token::MEDIUMP; }
+{ return SkSL::Token::HIGHP; }
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
 #line 71 "sksl.flex"
-{ return SkSL::Token::HIGHP; }
+{ return SkSL::Token::FLAT; }
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
 #line 73 "sksl.flex"
-{ return SkSL::Token::FLAT; }
+{ return SkSL::Token::NOPERSPECTIVE; }
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
 #line 75 "sksl.flex"
-{ return SkSL::Token::NOPERSPECTIVE; }
+{ return SkSL::Token::STRUCT; }
 	YY_BREAK
 case 27:
 YY_RULE_SETUP
 #line 77 "sksl.flex"
-{ return SkSL::Token::STRUCT; }
+{ return SkSL::Token::LAYOUT; }
 	YY_BREAK
 case 28:
 YY_RULE_SETUP
 #line 79 "sksl.flex"
-{ return SkSL::Token::LAYOUT; }
+{ return SkSL::Token::PRECISION; }
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
 #line 81 "sksl.flex"
-{ return SkSL::Token::PRECISION; }
+{ return SkSL::Token::IDENTIFIER; }
 	YY_BREAK
 case 30:
 YY_RULE_SETUP
 #line 83 "sksl.flex"
-{ return SkSL::Token::IDENTIFIER; }
+{ return SkSL::Token::DIRECTIVE; }
 	YY_BREAK
 case 31:
 YY_RULE_SETUP
 #line 85 "sksl.flex"
-{ return SkSL::Token::DIRECTIVE; }
+{ return SkSL::Token::LPAREN; }
 	YY_BREAK
 case 32:
 YY_RULE_SETUP
 #line 87 "sksl.flex"
-{ return SkSL::Token::LPAREN; }
+{ return SkSL::Token::RPAREN; }
 	YY_BREAK
 case 33:
 YY_RULE_SETUP
 #line 89 "sksl.flex"
-{ return SkSL::Token::RPAREN; }
+{ return SkSL::Token::LBRACE; }
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
 #line 91 "sksl.flex"
-{ return SkSL::Token::LBRACE; }
+{ return SkSL::Token::RBRACE; }
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
 #line 93 "sksl.flex"
-{ return SkSL::Token::RBRACE; }
+{ return SkSL::Token::LBRACKET; }
 	YY_BREAK
 case 36:
 YY_RULE_SETUP
 #line 95 "sksl.flex"
-{ return SkSL::Token::LBRACKET; }
+{ return SkSL::Token::RBRACKET; }
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
 #line 97 "sksl.flex"
-{ return SkSL::Token::RBRACKET; }
+{ return SkSL::Token::DOT; }
 	YY_BREAK
 case 38:
 YY_RULE_SETUP
 #line 99 "sksl.flex"
-{ return SkSL::Token::DOT; }
+{ return SkSL::Token::COMMA; }
 	YY_BREAK
 case 39:
 YY_RULE_SETUP
 #line 101 "sksl.flex"
-{ return SkSL::Token::COMMA; }
+{ return SkSL::Token::PLUSPLUS; }
 	YY_BREAK
 case 40:
 YY_RULE_SETUP
 #line 103 "sksl.flex"
-{ return SkSL::Token::PLUSPLUS; }
+{ return SkSL::Token::MINUSMINUS; }
 	YY_BREAK
 case 41:
 YY_RULE_SETUP
 #line 105 "sksl.flex"
-{ return SkSL::Token::MINUSMINUS; }
+{ return SkSL::Token::PLUS; }
 	YY_BREAK
 case 42:
 YY_RULE_SETUP
 #line 107 "sksl.flex"
-{ return SkSL::Token::PLUS; }
+{ return SkSL::Token::MINUS; }
 	YY_BREAK
 case 43:
 YY_RULE_SETUP
 #line 109 "sksl.flex"
-{ return SkSL::Token::MINUS; }
+{ return SkSL::Token::STAR; }
 	YY_BREAK
 case 44:
 YY_RULE_SETUP
 #line 111 "sksl.flex"
-{ return SkSL::Token::STAR; }
+{ return SkSL::Token::SLASH; }
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 113 "sksl.flex"
-{ return SkSL::Token::SLASH; }
+{ return SkSL::Token::PERCENT; }
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 115 "sksl.flex"
-{ return SkSL::Token::PERCENT; }
+{ return SkSL::Token::SHL; }
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 117 "sksl.flex"
-{ return SkSL::Token::SHL; }
+{ return SkSL::Token::SHR; }
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 119 "sksl.flex"
-{ return SkSL::Token::SHR; }
+{ return SkSL::Token::BITWISEOR; }
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 121 "sksl.flex"
-{ return SkSL::Token::BITWISEOR; }
+{ return SkSL::Token::BITWISEXOR; }
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 123 "sksl.flex"
-{ return SkSL::Token::BITWISEXOR; }
+{ return SkSL::Token::BITWISEAND; }
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 125 "sksl.flex"
-{ return SkSL::Token::BITWISEAND; }
+{ return SkSL::Token::LOGICALOR; }
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 127 "sksl.flex"
-{ return SkSL::Token::BITWISENOT; }
+{ return SkSL::Token::LOGICALXOR; }
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
 #line 129 "sksl.flex"
-{ return SkSL::Token::LOGICALOR; }
+{ return SkSL::Token::LOGICALAND; }
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
 #line 131 "sksl.flex"
-{ return SkSL::Token::LOGICALXOR; }
+{ return SkSL::Token::NOT; }
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
 #line 133 "sksl.flex"
-{ return SkSL::Token::LOGICALAND; }
+{ return SkSL::Token::QUESTION; }
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
 #line 135 "sksl.flex"
-{ return SkSL::Token::LOGICALNOT; }
+{ return SkSL::Token::COLON; }
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
 #line 137 "sksl.flex"
-{ return SkSL::Token::QUESTION; }
+{ return SkSL::Token::EQ; }
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
 #line 139 "sksl.flex"
-{ return SkSL::Token::COLON; }
+{ return SkSL::Token::EQEQ; }
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
 #line 141 "sksl.flex"
-{ return SkSL::Token::EQ; }
+{ return SkSL::Token::NEQ; }
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
 #line 143 "sksl.flex"
-{ return SkSL::Token::EQEQ; }
+{ return SkSL::Token::GT; }
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
 #line 145 "sksl.flex"
-{ return SkSL::Token::NEQ; }
+{ return SkSL::Token::LT; }
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
 #line 147 "sksl.flex"
-{ return SkSL::Token::GT; }
+{ return SkSL::Token::GTEQ; }
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
 #line 149 "sksl.flex"
-{ return SkSL::Token::LT; }
+{ return SkSL::Token::LTEQ; }
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
 #line 151 "sksl.flex"
-{ return SkSL::Token::GTEQ; }
+{ return SkSL::Token::PLUSEQ; }
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
 #line 153 "sksl.flex"
-{ return SkSL::Token::LTEQ; }
+{ return SkSL::Token::MINUSEQ; }
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
 #line 155 "sksl.flex"
-{ return SkSL::Token::PLUSEQ; }
+{ return SkSL::Token::STAREQ; }
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
 #line 157 "sksl.flex"
-{ return SkSL::Token::MINUSEQ; }
+{ return SkSL::Token::SLASHEQ; }
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
 #line 159 "sksl.flex"
-{ return SkSL::Token::STAREQ; }
+{ return SkSL::Token::PERCENTEQ; }
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
 #line 161 "sksl.flex"
-{ return SkSL::Token::SLASHEQ; }
+{ return SkSL::Token::SHLEQ; }
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
 #line 163 "sksl.flex"
-{ return SkSL::Token::PERCENTEQ; }
+{ return SkSL::Token::SHREQ; }
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
 #line 165 "sksl.flex"
-{ return SkSL::Token::SHLEQ; }
+{ return SkSL::Token::BITWISEOREQ; }
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
 #line 167 "sksl.flex"
-{ return SkSL::Token::SHREQ; }
+{ return SkSL::Token::BITWISEXOREQ; }
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
 #line 169 "sksl.flex"
-{ return SkSL::Token::BITWISEOREQ; }
+{ return SkSL::Token::BITWISEANDEQ; }
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
 #line 171 "sksl.flex"
-{ return SkSL::Token::BITWISEXOREQ; }
+{ return SkSL::Token::LOGICALOREQ; }
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
 #line 173 "sksl.flex"
-{ return SkSL::Token::BITWISEANDEQ; }
+{ return SkSL::Token::LOGICALXOREQ; }
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
 #line 175 "sksl.flex"
-{ return SkSL::Token::LOGICALOREQ; }
+{ return SkSL::Token::LOGICALANDEQ; }
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
 #line 177 "sksl.flex"
-{ return SkSL::Token::LOGICALXOREQ; }
+{ return SkSL::Token::SEMICOLON; }
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
 #line 179 "sksl.flex"
-{ return SkSL::Token::LOGICALANDEQ; }
-	YY_BREAK
-case 79:
-YY_RULE_SETUP
-#line 181 "sksl.flex"
-{ return SkSL::Token::SEMICOLON; }
-	YY_BREAK
-case 80:
-YY_RULE_SETUP
-#line 183 "sksl.flex"
 /* line comment */
 	YY_BREAK
-case 81:
-/* rule 81 can match eol */
+case 79:
+/* rule 79 can match eol */
 YY_RULE_SETUP
-#line 185 "sksl.flex"
+#line 181 "sksl.flex"
 /* block comment */
 	YY_BREAK
-case 82:
-/* rule 82 can match eol */
+case 80:
+/* rule 80 can match eol */
 YY_RULE_SETUP
-#line 187 "sksl.flex"
+#line 183 "sksl.flex"
 /* whitespace */
 	YY_BREAK
-case 83:
+case 81:
 YY_RULE_SETUP
-#line 189 "sksl.flex"
+#line 185 "sksl.flex"
 { return SkSL::Token::INVALID_TOKEN; }
 	YY_BREAK
-case 84:
+case 82:
 YY_RULE_SETUP
-#line 191 "sksl.flex"
+#line 187 "sksl.flex"
 ECHO;
 	YY_BREAK
-#line 1342 "lex.sksl.c"
+#line 1329 "lex.sksl.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -1539,7 +1526,7 @@
 			{ /* Not enough room in the buffer - grow it. */
 
 			/* just a shorter name for the current buffer */
-			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
 
 			int yy_c_buf_p_offset =
 				(int) (yyg->yy_c_buf_p - b->yy_ch_buf);
@@ -1639,7 +1626,7 @@
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 205 )
+			if ( yy_current_state >= 201 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1668,12 +1655,13 @@
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 205 )
+		if ( yy_current_state >= 201 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 204);
+	yy_is_jam = (yy_current_state == 200);
 
+	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
@@ -1768,7 +1756,7 @@
 				case EOB_ACT_END_OF_FILE:
 					{
 					if ( skslwrap(yyscanner ) )
-						return 0;
+						return EOF;
 
 					if ( ! yyg->yy_did_buffer_switch_on_eof )
 						YY_NEW_FILE;
@@ -2124,8 +2112,8 @@
 
 /** Setup the input buffer state to scan the given bytes. The next call to sksllex() will
  * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
@@ -2133,7 +2121,8 @@
 {
 	YY_BUFFER_STATE b;
 	char *buf;
-	yy_size_t n, i;
+	yy_size_t n;
+	int i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
 	n = _yybytes_len + 2;
@@ -2279,7 +2268,7 @@
 
         /* lineno is only valid if an input buffer exists. */
         if (! YY_CURRENT_BUFFER )
-           yy_fatal_error( "skslset_lineno called with no buffer" , yyscanner); 
+           YY_FATAL_ERROR( "skslset_lineno called with no buffer" );
     
     yylineno = line_number;
 }
@@ -2294,7 +2283,7 @@
 
         /* column is only valid if an input buffer exists. */
         if (! YY_CURRENT_BUFFER )
-           yy_fatal_error( "skslset_column called with no buffer" , yyscanner); 
+           YY_FATAL_ERROR( "skslset_column called with no buffer" );
     
     yycolumn = column_no;
 }
@@ -2506,7 +2495,7 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 191 "sksl.flex"
+#line 187 "sksl.flex"
 
 
 
diff --git a/src/sksl/sksl.flex b/src/sksl/sksl.flex
index 30dc376..67b48e9 100644
--- a/src/sksl/sksl.flex
+++ b/src/sksl/sksl.flex
@@ -30,8 +30,6 @@
 
 {DIGIT}+ { return SkSL::Token::INT_LITERAL; }
 
-"0x"[0-9a-zA-Z]+ { return SkSL::Token::INT_LITERAL; }
-
 true { return SkSL::Token::TRUE_LITERAL; }
 
 false { return SkSL::Token::FALSE_LITERAL; }
@@ -124,15 +122,13 @@
 
 "&" { return SkSL::Token::BITWISEAND; }
 
-"~" { return SkSL::Token::BITWISENOT; }
-
 "||" { return SkSL::Token::LOGICALOR; }
 
 "^^" { return SkSL::Token::LOGICALXOR; }
 
 "&&" { return SkSL::Token::LOGICALAND; }
 
-"!" { return SkSL::Token::LOGICALNOT; }
+"!" { return SkSL::Token::NOT; }
 
 "?" { return SkSL::Token::QUESTION; }
 
diff --git a/src/sksl/sksl.include b/src/sksl/sksl.include
index 6dc1ff8..4fd5511 100644
--- a/src/sksl/sksl.include
+++ b/src/sksl/sksl.include
@@ -244,8 +244,6 @@
 $gvec4 texture($gsampler1D sampler, float P);
 $gvec4 texture($gsampler1D sampler, float P, float bias);
 $gvec4 texture($gsampler2D sampler, vec2 P);
-vec4 texture(samplerExternalOES sampler, vec2 P, float bias);
-vec4 texture(samplerExternalOES sampler, vec2 P);
 $gvec4 texture($gsampler2D sampler, vec2 P, float bias);
 $gvec4 texture($gsampler3D sampler, vec3 P);
 $gvec4 texture($gsampler3D sampler, vec3 P, float bias);
@@ -466,7 +464,6 @@
 vec4 texture1DProjLod(sampler1D sampler, vec2 coord, float lod);
 vec4 texture1DProjLod(sampler1D sampler, vec4 coord, float lod);
 vec4 texture2D(sampler2D sampler, vec2 coord);
-vec4 texture2D(samplerExternalOES sampler, vec2 coord);
 vec4 texture2D(sampler2D sampler, vec2 coord, float bias);
 vec4 texture2DProj(sampler2D sampler, vec3 coord);
 vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);
diff --git a/src/sksl/sksl_frag.include b/src/sksl/sksl_frag.include
index ed63d4a..123c339 100644
--- a/src/sksl/sksl_frag.include
+++ b/src/sksl/sksl_frag.include
@@ -4,16 +4,5 @@
 
 layout(builtin=15) in vec4 gl_FragCoord;
 
-// 9999 is a temporary value that causes us to ignore these declarations beyond
-// adding them to the symbol table. This works fine in GLSL (where they do not
-// require any further handling) but will fail in SPIR-V. We'll have a better
-// solution for this soon.
-layout(builtin=9999) vec4 gl_LastFragData[1];
-layout(builtin=9999) vec4 gl_LastFragColor;
-layout(builtin=9999) vec4 gl_LastFragColorARM;
-layout(builtin=9999) int gl_SampleMaskIn[];
-layout(builtin=9999) out int gl_SampleMask[];
-
-layout(location=0,index=0,builtin=10001) out vec4 sk_FragColor;
-
 )
+
diff --git a/tests/SkSLErrorTest.cpp b/tests/SkSLErrorTest.cpp
index 400ab6d..75fa20d 100644
--- a/tests/SkSLErrorTest.cpp
+++ b/tests/SkSLErrorTest.cpp
@@ -263,8 +263,8 @@
                  "void main() { int x = 2[0]; }",
                  "error: 1: expected array, but found 'int'\n1 error\n");
     test_failure(r,
-                 "void main() { vec2 x = vec2(0); int y = x[0][0]; }",
-                 "error: 1: expected array, but found 'float'\n1 error\n");
+                 "void main() { vec2 x = vec2(0); int y = x[0]; }",
+                 "error: 1: expected array, but found 'vec2'\n1 error\n");
 }
 
 DEF_TEST(SkSLTernaryMismatch, r) {
diff --git a/tests/SkSLGLSLTest.cpp b/tests/SkSLGLSLTest.cpp
index d9d7464..3906f67 100644
--- a/tests/SkSLGLSLTest.cpp
+++ b/tests/SkSLGLSLTest.cpp
@@ -26,52 +26,46 @@
     }
 }
 
-static SkSL::GLCaps default_caps() {
-    return { 
-             400, 
-             SkSL::GLCaps::kGL_Standard,
-             false, // isCoreProfile
-             false, // usesPrecisionModifiers;
-             false, // mustDeclareFragmentShaderOutput
-             true   // canUseMinAndAbsTogether
-           };
-}
-
 DEF_TEST(SkSLHelloWorld, r) {
+    SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
     test(r,
-         "void main() { sk_FragColor = vec4(0.75); }",
-         default_caps(),
+         "out vec4 fragColor; void main() { fragColor = vec4(0.75); }",
+         caps,
          "#version 400\n"
+         "out vec4 fragColor;\n"
          "void main() {\n"
-         "    gl_FragColor = vec4(0.75);\n"
+         "    fragColor = vec4(0.75);\n"
          "}\n");
 }
 
 DEF_TEST(SkSLControl, r) {
+    SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
     test(r,
+         "out vec4 fragColor;"
          "void main() {"
-         "if (1 + 2 + 3 > 5) { sk_FragColor = vec4(0.75); } else { discard; }"
+         "if (1 + 2 + 3 > 5) { fragColor = vec4(0.75); } else { discard; }"
          "int i = 0;"
-         "while (i < 10) sk_FragColor *= 0.5;"
-         "do { sk_FragColor += 0.01; } while (sk_FragColor.x < 0.7);"
+         "while (i < 10) fragColor *= 0.5;"
+         "do { fragColor += 0.01; } while (fragColor.x < 0.7);"
          "for (int i = 0; i < 10; i++) {"
          "if (i % 0 == 1) break; else continue;"
          "}"
          "return;"
          "}",
-         default_caps(),
+         caps,
          "#version 400\n"
+         "out vec4 fragColor;\n"
          "void main() {\n"
          "    if ((1 + 2) + 3 > 5) {\n"
-         "        gl_FragColor = vec4(0.75);\n"
+         "        fragColor = vec4(0.75);\n"
          "    } else {\n"
          "        discard;\n"
          "    }\n"
          "    int i = 0;\n"
-         "    while (i < 10) gl_FragColor *= 0.5;\n"
+         "    while (i < 10) fragColor *= 0.5;\n"
          "    do {\n"
-         "        gl_FragColor += 0.01;\n"
-         "    } while (gl_FragColor.x < 0.7);\n"
+         "        fragColor += 0.01;\n"
+         "    } while (fragColor.x < 0.7);\n"
          "    for (int i = 0;i < 10; i++) {\n"
          "        if (i % 0 == 1) break; else continue;\n"
          "    }\n"
@@ -80,30 +74,34 @@
 }
 
 DEF_TEST(SkSLFunctions, r) {
+    SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
     test(r,
+         "out vec4 fragColor;"
          "float foo(float v[2]) { return v[0] * v[1]; }"
          "void bar(inout float x) { float y[2], z; y[0] = x; y[1] = x * 2; z = foo(y); x = z; }"
-         "void main() { float x = 10; bar(x); sk_FragColor = vec4(x); }",
-         default_caps(),
+         "void main() { float x = 10; bar(x); fragColor = vec4(x); }",
+         caps,
          "#version 400\n"
-         "float foo(in float v[2]) {\n"
+         "out vec4 fragColor;\n"
+         "float foo(in float[2] v) {\n"
          "    return v[0] * v[1];\n"
          "}\n"
          "void bar(inout float x) {\n"
          "    float y[2], z;\n"
          "    y[0] = x;\n"
-         "    y[1] = x * 2.0;\n"
+         "    y[1] = x * 2;\n"
          "    z = foo(y);\n"
          "    x = z;\n"
          "}\n"
          "void main() {\n"
-         "    float x = 10.0;\n"
+         "    float x = 10;\n"
          "    bar(x);\n"
-         "    gl_FragColor = vec4(x);\n"
+         "    fragColor = vec4(x);\n"
          "}\n");
 }
 
 DEF_TEST(SkSLOperators, r) {
+    SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
     test(r,
          "void main() {"
          "float x = 1, y = 2;"
@@ -125,17 +123,17 @@
          "z <<= 4;"
          "z %= 5;"
          "}",
-         default_caps(),
+         caps,
          "#version 400\n"
          "void main() {\n"
-         "    float x = 1.0, y = 2.0;\n"
+         "    float x = 1, y = 2;\n"
          "    int z = 3;\n"
          "    x = x + ((y * float(z)) * x) * (y - float(z));\n"
          "    y = (x / y) / float(z);\n"
          "    z = (((z / 2) % 3 << 4) >> 2) << 1;\n"
-         "    bool b = x > 4.0 == x < 2.0 || (2 >= 5 && y <= float(z)) && 12 != 11;\n"
-         "    x += 12.0;\n"
-         "    x -= 12.0;\n"
+         "    bool b = x > 4 == x < 2 || (2 >= 5 && y <= float(z)) && 12 != 11;\n"
+         "    x += 12;\n"
+         "    x -= 12;\n"
          "    x *= (y /= float(z = 10));\n"
          "    b ||= false;\n"
          "    b &&= true;\n"
@@ -150,6 +148,7 @@
 }
 
 DEF_TEST(SkSLMatrices, r) {
+    SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
     test(r,
          "void main() {"
          "mat2x4 x = mat2x4(1);"
@@ -158,18 +157,19 @@
          "vec3 v1 = mat3(1) * vec3(1);"
          "vec3 v2 = vec3(1) * mat3(1);"
          "}",
-         default_caps(),
+         caps,
          "#version 400\n"
          "void main() {\n"
-         "    mat2x4 x = mat2x4(1.0);\n"
-         "    mat3x2 y = mat3x2(1.0, 0.0, 0.0, 1.0, vec2(2.0, 2.0));\n"
+         "    mat2x4 x = mat2x4(1);\n"
+         "    mat3x2 y = mat3x2(1, 0, 0, 1, vec2(2, 2));\n"
          "    mat3x4 z = x * y;\n"
-         "    vec3 v1 = mat3(1.0) * vec3(1.0);\n"
-         "    vec3 v2 = vec3(1.0) * mat3(1.0);\n"
+         "    vec3 v1 = mat3(1) * vec3(1);\n"
+         "    vec3 v2 = vec3(1) * mat3(1);\n"
          "}\n");
 }
 
 DEF_TEST(SkSLInterfaceBlock, r) {
+    SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
     test(r,
          "uniform testBlock {"
          "float x;"
@@ -179,12 +179,12 @@
          "};"
          "void main() {"
          "}",
-         default_caps(),
+         caps,
          "#version 400\n"
          "uniform testBlock {\n"
          "    float x;\n"
          "    float[2] y;\n"
-         "    layout (binding = 12) mat3x2 z;\n"
+         "    layout (binding = 12)mat3x2 z;\n"
          "    bool w;\n"
          "};\n"
          "void main() {\n"
@@ -192,6 +192,7 @@
 }
 
 DEF_TEST(SkSLStructs, r) {
+    SkSL::GLCaps caps = { 400, SkSL::GLCaps::kGL_Standard };
     test(r,
          "struct A {"
          "int x;"
@@ -206,7 +207,7 @@
          "B b1, b2, b3;"
          "void main() {"
          "}",
-         default_caps(),
+         caps,
          "#version 400\n"
          "struct A {\n"
          "    int x;\n"
@@ -217,149 +218,10 @@
          "struct B {\n"
          "    float x;\n"
          "    float[2] y;\n"
-         "    layout (binding = 1) A z;\n"
+         "    layout (binding = 1)A z;\n"
          "}\n"
          " b1, b2, b3;\n"
          "void main() {\n"
          "}\n");
-}
 
-DEF_TEST(SkSLVersion, r) {
-    SkSL::GLCaps caps = default_caps();
-    caps.fVersion = 450;
-    caps.fIsCoreProfile = true;
-    test(r,
-         "in float test; void main() { sk_FragColor = vec4(0.75); }",
-         caps,
-         "#version 450 core\n"
-         "in float test;\n"
-         "void main() {\n"
-         "    gl_FragColor = vec4(0.75);\n"
-         "}\n");
-    caps.fVersion = 110;
-    caps.fIsCoreProfile = false;
-    test(r,
-         "in float test; void main() { sk_FragColor = vec4(0.75); }",
-         caps,
-         "#version 110\n"
-         "varying float test;\n"
-         "void main() {\n"
-         "    gl_FragColor = vec4(0.75);\n"
-         "}\n");
-}
-
-DEF_TEST(SkSLDeclareOutput, r) {
-    SkSL::GLCaps caps = default_caps();    
-    caps.fMustDeclareFragmentShaderOutput = true;
-    test(r,
-         "void main() { sk_FragColor = vec4(0.75); }",
-         caps,
-         "#version 400\n"
-         "out vec4 sk_FragColor;\n"
-         "void main() {\n"
-         "    sk_FragColor = vec4(0.75);\n"
-         "}\n");    
-}
-
-DEF_TEST(SkSLUsesPrecisionModifiers, r) {
-    SkSL::GLCaps caps = default_caps();
-    test(r,
-         "void main() { float x = 0.75; highp float y = 1; }",
-         caps,
-         "#version 400\n"
-         "void main() {\n"
-         "    float x = 0.75;\n"
-         "    float y = 1.0;\n"
-         "}\n");    
-    caps.fStandard = SkSL::GLCaps::kGLES_Standard;
-    caps.fUsesPrecisionModifiers = true;
-    test(r,
-         "void main() { float x = 0.75; highp float y = 1; }",
-         caps,
-         "#version 400 es\n"
-         "precision highp float;\n"
-         "void main() {\n"
-         "    float x = 0.75;\n"
-         "    highp float y = 1.0;\n"
-         "}\n");    
-}
-
-DEF_TEST(SkSLMinAbs, r) {
-    test(r,
-         "void main() {"
-         "float x = -5;"
-         "x = min(abs(x), 6);"
-         "}",
-         default_caps(),
-         "#version 400\n"
-         "void main() {\n"
-         "    float x = -5.0;\n"
-         "    x = min(abs(x), 6.0);\n"
-         "}\n");
-
-    SkSL::GLCaps caps = default_caps();
-    caps.fCanUseMinAndAbsTogether = false;
-    test(r,
-         "void main() {"
-         "float x = -5.0;"
-         "x = min(abs(x), 6.0);"
-         "}",
-         caps,
-         "#version 400\n"
-         "void main() {\n"
-         "    float minAbsHackVar0;\n"
-         "    float x = -5.0;\n"
-         "    x = (abs(x) > (minAbsHackVar0 = 6.0) ? minAbsHackVar0 : abs(x));\n"
-         "}\n");
-}
-
-DEF_TEST(SkSLModifiersDeclaration, r) {
-    test(r,
-         "layout(blend_support_all_equations) out;"
-         "void main() { }",
-         default_caps(),
-         "#version 400\n"
-         "layout (blend_support_all_equations) out ;\n"
-         "void main() {\n"
-         "}\n");
-}
-
-DEF_TEST(SkSLHex, r) {
-    test(r,
-         "void main() {"
-         "int i1 = 0x0;"
-         "int i2 = 0x1234abcd;"
-         "int i3 = 0x7fffffff;"
-         "int i4 = 0xffffffff;"
-         "int i5 = -0xbeef;"
-         "uint u1 = 0x0;"
-         "uint u2 = 0x1234abcd;"
-         "uint u3 = 0x7fffffff;"
-         "uint u4 = 0xffffffff;"
-         "}",
-         default_caps(),
-         "#version 400\n"
-         "void main() {\n"
-         "    int i1 = 0;\n"
-         "    int i2 = 305441741;\n"
-         "    int i3 = 2147483647;\n"
-         "    int i4 = -1;\n"
-         "    int i5 = -48879;\n"
-         "    uint u1 = 0u;\n"
-         "    uint u2 = 305441741u;\n"
-         "    uint u3 = 2147483647u;\n"
-         "    uint u4 = 4294967295u;\n"
-         "}\n");
-}
-
-DEF_TEST(SkSLArrayConstructors, r) {
-    test(r,
-         "float test1[] = float[](1, 2, 3, 4);"
-         "vec2 test2[] = vec2[](vec2(1, 2), vec2(3, 4));"
-         "mat4 test3[] = mat4[]();",
-         default_caps(),
-         "#version 400\n"
-         "float test1[] = float[](1.0, 2.0, 3.0, 4.0);\n"
-         "vec2 test2[] = vec2[](vec2(1.0, 2.0), vec2(3.0, 4.0));\n"
-         "mat4 test3[] = mat4[]();\n");
 }