Revert "Re-land sksl fragment processor support"

This reverts commit c070939fd1a954b7a492bc30f0cf64a664b90181.

Reason for revert: 

This has some knock-on effects in the generation of Android.bp from our GN files.  See gn/gn_to_bp.py?  We're seeing things like "tmp/tmpsBVycx/gen/" end up in the include search path in Android.bp, which obviously don't exist there...

Original change's description:
> Re-land sksl fragment processor support
> 
> This reverts commit ed50200682e0de72c3abecaa4d5324ebcd1ed9f9.
> 
> Bug: skia:
> Change-Id: I9caa7454b391450620d6989dc472abb3cf7a2cab
> Reviewed-on: https://skia-review.googlesource.com/20965
> Reviewed-by: Ben Wagner <benjaminwagner@google.com>
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>

TBR=benjaminwagner@google.com,ethannicholas@google.com

Change-Id: I502486b5405923b322429219f4cc396a45a14cea
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/20990
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 7595076..9ba71b2 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -139,7 +139,6 @@
     "src/utils/win",
     "src/xml",
     "third_party/gif",
-    "$target_gen_dir",
   ]
 
   defines = [ "SK_GAMMA_APPLY_TO_A8" ]
@@ -346,9 +345,6 @@
 
 optional("effects") {
   enabled = skia_enable_effects
-  deps = [
-    ":compile_processors",
-  ]
   sources =
       skia_effects_sources + [ "src/ports/SkGlobalInitialization_default.cpp" ]
   sources_when_disabled = [ "src/ports/SkGlobalInitialization_none.cpp" ]
@@ -414,68 +410,12 @@
   ]
 }
 
-if (skia_enable_gpu && skia_gpu_processor_sources != []) {
-  executable("skslc") {
-    defines = [ "SKSL_STANDALONE" ]
-    sources = [
-      "src/sksl/SkSLMain.cpp",
-    ]
-    sources += skia_sksl_sources
-    include_dirs = [
-      "src/gpu",
-      "src/sksl",
-    ]
-    deps = [
-      "//third_party/spirv-tools",
-    ]
-  }
-
-  skia_gpu_processor_outputs = []
-  foreach(src, skia_gpu_processor_sources) {
-    name = get_path_info(src, "name")
-    skia_gpu_processor_outputs += [
-      "$target_gen_dir/effects/$name.h",
-      "$target_gen_dir/effects/$name.cpp",
-    ]
-  }
-
-  action("compile_processors") {
-    script = "gn/compile_processors.py"
-    deps = [
-      ":skslc(//gn/toolchain:$host_toolchain)",
-    ]
-    sources = skia_gpu_processor_sources
-    outputs = skia_gpu_processor_outputs
-    skslc_path = "$root_out_dir/"
-    if (host_toolchain != default_toolchain_name) {
-      skslc_path += "$host_toolchain/"
-    }
-    skslc_path += "skslc"
-    if (host_os == "win") {
-      skslc_path = ".exe"
-    }
-    args = [
-      rebase_path(skslc_path),
-      rebase_path("$target_gen_dir/effects"),
-    ]
-    args += rebase_path(skia_gpu_processor_sources)
-  }
-} else {
-  skia_gpu_processor_outputs = []
-  group("compile_processors") {
-  }
-}
-
 optional("gpu") {
   enabled = skia_enable_gpu
-  deps = [
-    ":compile_processors",
-  ]
   public_defines = []
 
   sources = skia_gpu_sources + skia_sksl_sources +
-            [ "src/gpu/gl/GrGLDefaultInterface_native.cpp" ] +
-            skia_gpu_processor_outputs
+            [ "src/gpu/gl/GrGLDefaultInterface_native.cpp" ]
 
   # These paths need to be absolute to match the ones produced by shared_sources.gni.
   sources -= get_path_info([
@@ -519,7 +459,9 @@
     }
   }
   if (skia_enable_spirv_validation) {
-    deps += [ "//third_party/spirv-tools" ]
+    deps = [
+      "//third_party/spirv-tools",
+    ]
     public_defines += [ "SK_ENABLE_SPIRV_VALIDATION" ]
   }
 }
@@ -1588,4 +1530,15 @@
       ]
     }
   }
+
+  if (skia_enable_gpu) {
+    test_app("skslc") {
+      defines = [ "SKSL_STANDALONE" ]
+      sources = [
+        "src/sksl/SkSLMain.cpp",
+      ]
+      sources += skia_sksl_sources
+      include_dirs = [ "src/sksl" ]
+    }
+  }
 }
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index d275bd6..fdd50b1 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -4,14 +4,48 @@
 # found in the LICENSE file.
 
 declare_args() {
+  ar = "ar"
+  cc = "cc"
+  cxx = "c++"
+
+  if (is_android) {
+    if (host_os == "win") {
+      ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar.exe"
+      cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang.exe"
+      cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++.exe"
+    } else {
+      ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar"
+      cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang"
+      cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++"
+    }
+  }
+
+  msvc = 2015
+
   extra_asmflags = []
   extra_cflags = []
   extra_cflags_c = []
   extra_cflags_cc = []
   extra_ldflags = []
 
+  cc_wrapper = ""
   malloc = ""
 }
+declare_args() {
+  if (msvc == 2015) {
+    windk = "C:/Program Files (x86)/Microsoft Visual Studio 14.0"
+  } else {
+    windk = "C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional"
+  }
+}
+
+if (host_os == "win") {
+  python = "python.bat"
+  stamp = "cmd.exe /c echo >"
+} else {
+  python = "python"
+  stamp = "touch"
+}
 
 is_clang = is_android || is_ios || is_mac || (cc == "clang" && cxx == "clang++")
 if (!is_clang && !is_win) {
@@ -439,3 +473,247 @@
     ]
   }
 }
+
+toolchain("msvc") {
+  lib_dir_switch = "/LIBPATH:"
+
+  if (msvc == 2015) {
+    bin = "$windk/VC/bin/amd64"
+    env_setup = ""
+    if (target_cpu == "x86") {
+      bin += "_x86"
+      env_setup = "cmd /c $windk/win_sdk/bin/SetEnv.cmd /x86 && "
+    }
+  } else {
+    bin = "$windk/VC/Tools/MSVC/14.10.25017/bin/HostX64/$target_cpu"
+    env_setup = ""
+    if (target_cpu == "x86") {
+      print("Be sure to run")
+      print("$windk/VC/Auxiliary/Build/vcvarsall.bat amd64_x86")
+      print("to set up your environment before running ninja.")
+    }
+  }
+
+  tool("asm") {
+    _ml = "ml"
+    if (target_cpu == "x64") {
+      _ml += "64"
+    }
+    command = "$env_setup$bin/$_ml.exe /nologo /c /Fo {{output}} {{source}}"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
+    ]
+    description = "assemble {{source}}"
+  }
+
+  tool("cc") {
+    rspfile = "{{output}}.rsp"
+    precompiled_header_type = "msvc"
+    pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
+
+    # Label names may have spaces so pdbname must be quoted.
+    command = "$env_setup$bin/cl.exe /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
+    depsformat = "msvc"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
+    ]
+    rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
+    description = "compile {{source}}"
+  }
+
+  tool("cxx") {
+    rspfile = "{{output}}.rsp"
+    precompiled_header_type = "msvc"
+    pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
+
+    # Label names may have spaces so pdbname must be quoted.
+    command = "$env_setup$bin/cl.exe /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
+    depsformat = "msvc"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
+    ]
+    rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
+    description = "compile {{source}}"
+  }
+
+  tool("alink") {
+    rspfile = "{{output}}.rsp"
+
+    command = "$env_setup$bin/lib.exe /nologo /ignore:4221 {{arflags}} /OUT:{{output}} @$rspfile"
+    outputs = [
+      # Ignore {{output_extension}} and always use .lib, there's no reason to
+      # allow targets to override this extension on Windows.
+      "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
+    ]
+    default_output_extension = ".lib"
+    default_output_dir = "{{target_out_dir}}"
+
+    # inputs_newline works around a fixed per-line buffer size in the linker.
+    rspfile_content = "{{inputs_newline}}"
+    description = "link {{output}}"
+  }
+
+  tool("solink") {
+    dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
+    libname = "${dllname}.lib"
+    pdbname = "${dllname}.pdb"
+    rspfile = "${dllname}.rsp"
+
+    command = "$env_setup$bin/link.exe /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile"
+    outputs = [
+      dllname,
+      libname,
+      pdbname,
+    ]
+    default_output_extension = ".dll"
+    default_output_dir = "{{root_out_dir}}"
+
+    link_output = libname
+    depend_output = libname
+    runtime_outputs = [
+      dllname,
+      pdbname,
+    ]
+
+    # I don't quite understand this.  Aping Chrome's toolchain/win/BUILD.gn.
+    restat = true
+
+    # inputs_newline works around a fixed per-line buffer size in the linker.
+    rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
+    description = "link {{output}}"
+  }
+
+  tool("link") {
+    exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
+    pdbname = "$exename.pdb"
+    rspfile = "$exename.rsp"
+
+    command =
+        "$env_setup$bin/link.exe /nologo /OUT:$exename /PDB:$pdbname @$rspfile"
+
+    default_output_extension = ".exe"
+    default_output_dir = "{{root_out_dir}}"
+    outputs = [
+      exename,
+    ]
+
+    # inputs_newline works around a fixed per-line buffer size in the linker.
+    rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
+    description = "link {{output}}"
+  }
+
+  tool("stamp") {
+    command = "$stamp {{output}}"
+    description = "stamp {{output}}"
+  }
+
+  tool("copy") {
+    cp_py = rebase_path("cp.py")
+    command = "$python $cp_py {{source}} {{output}}"
+    description = "copy {{source}} {{output}}"
+  }
+}
+
+toolchain("gcc_like") {
+  lib_switch = "-l"
+  lib_dir_switch = "-L"
+
+  tool("cc") {
+    depfile = "{{output}}.d"
+    command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
+    depsformat = "gcc"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+    ]
+    description = "compile {{source}}"
+  }
+
+  tool("cxx") {
+    depfile = "{{output}}.d"
+    command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
+    depsformat = "gcc"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+    ]
+    description = "compile {{source}}"
+  }
+
+  tool("objc") {
+    depfile = "{{output}}.d"
+    command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objc}} -c {{source}} -o {{output}}"
+    depsformat = "gcc"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+    ]
+    description = "compile {{source}}"
+  }
+
+  tool("objcxx") {
+    depfile = "{{output}}.d"
+    command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objc}} -c {{source}} -o {{output}}"
+    depsformat = "gcc"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+    ]
+    description = "compile {{source}}"
+  }
+
+  tool("asm") {
+    depfile = "{{output}}.d"
+    command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
+    depsformat = "gcc"
+    outputs = [
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+    ]
+    description = "assemble {{source}}"
+  }
+
+  tool("alink") {
+    rspfile = "{{output}}.rsp"
+    rspfile_content = "{{inputs}}"
+    ar_py = rebase_path("ar.py")
+    command = "$python $ar_py $ar {{output}} $rspfile"
+    outputs = [
+      "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
+    ]
+    default_output_extension = ".a"
+    output_prefix = "lib"
+    description = "link {{output}}"
+  }
+
+  tool("solink") {
+    soname = "{{target_output_name}}{{output_extension}}"
+
+    rpath = "-Wl,-soname,$soname"
+    if (is_mac) {
+      rpath = "-Wl,-install_name,@rpath/$soname"
+    }
+
+    command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
+    outputs = [
+      "{{root_out_dir}}/$soname",
+    ]
+    output_prefix = "lib"
+    default_output_extension = ".so"
+    description = "link {{output}}"
+  }
+
+  tool("link") {
+    command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
+    outputs = [
+      "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
+    ]
+    description = "link {{output}}"
+  }
+
+  tool("stamp") {
+    command = "$stamp {{output}}"
+    description = "stamp {{output}}"
+  }
+
+  tool("copy") {
+    cp_py = rebase_path("cp.py")
+    command = "$python $cp_py {{source}} {{output}}"
+    description = "copy {{source}} {{output}}"
+  }
+}
diff --git a/gn/BUILDCONFIG.gn b/gn/BUILDCONFIG.gn
index 43f66f8..2b3ae33 100644
--- a/gn/BUILDCONFIG.gn
+++ b/gn/BUILDCONFIG.gn
@@ -17,21 +17,9 @@
     ndk_api = 21
   }
   sanitize = ""
-
-  ar = "ar"
-  cc = "cc"
-  cxx = "c++"
-
-  msvc = 2015
 }
 declare_args() {
   is_debug = !is_official_build
-
-  if (msvc == 2015) {
-    windk = "C:/Program Files (x86)/Microsoft Visual Studio 14.0"
-  } else {
-    windk = "C:/Program Files (x86)/Microsoft Visual Studio/2017/Professional"
-  }
 }
 
 assert(!(is_debug && is_official_build))
@@ -176,12 +164,8 @@
 
 if (is_win) {
   # Windows tool chain
-  set_default_toolchain("//gn/toolchain:msvc")
-  default_toolchain_name = "msvc"
-  host_toolchain = "msvc"
+  set_default_toolchain("//gn:msvc")
 } else {
   # GCC-like toolchains, including Clang.
-  set_default_toolchain("//gn/toolchain:gcc_like")
-  default_toolchain_name = "gcc_like"
-  host_toolchain = "gcc_like_host"
+  set_default_toolchain("//gn:gcc_like")
 }
diff --git a/gn/compile_processors.py b/gn/compile_processors.py
deleted file mode 100755
index 72f23fe..0000000
--- a/gn/compile_processors.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2017 Google Inc.
-#
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import subprocess
-import sys
-
-skslc = sys.argv[1]
-dst = sys.argv[2]
-processors = sys.argv[3:]
-for p in processors:
-    path, _ = os.path.splitext(p)
-    filename = os.path.split(path)[1]
-    subprocess.check_call([skslc, p, os.path.join(dst, filename + ".h")])
-    subprocess.check_call([skslc, p, os.path.join(dst, filename + ".cpp")])
diff --git a/gn/sksl.gni b/gn/sksl.gni
index d133930..a1cab82 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -11,16 +11,11 @@
   "$_src/sksl/SkSLCompiler.cpp",
   "$_src/sksl/SkSLIRGenerator.cpp",
   "$_src/sksl/SkSLParser.cpp",
-  "$_src/sksl/SkSLCPPCodeGenerator.cpp",
-  "$_src/sksl/SkSLHCodeGenerator.cpp",
   "$_src/sksl/SkSLGLSLCodeGenerator.cpp",
   "$_src/sksl/SkSLSPIRVCodeGenerator.cpp",
   "$_src/sksl/SkSLString.cpp",
   "$_src/sksl/SkSLUtil.cpp",
   "$_src/sksl/lex.layout.cpp",
   "$_src/sksl/ir/SkSLSymbolTable.cpp",
-  "$_src/sksl/ir/SkSLSetting.cpp",
   "$_src/sksl/ir/SkSLType.cpp",
 ]
-
-skia_gpu_processor_sources = []
diff --git a/gn/tests.gni b/gn/tests.gni
index fde7df6..6843a6f 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -216,7 +216,6 @@
   "$_tests/SkResourceCacheTest.cpp",
   "$_tests/SkSharedMutexTest.cpp",
   "$_tests/SkSLErrorTest.cpp",
-  "$_tests/SkSLFPTest.cpp",
   "$_tests/SkSLGLSLTest.cpp",
   "$_tests/SkSLMemoryLayoutTest.cpp",
   "$_tests/SkSLSPIRVTest.cpp",
diff --git a/gn/toolchain/BUILD.gn b/gn/toolchain/BUILD.gn
deleted file mode 100644
index a4c13a7..0000000
--- a/gn/toolchain/BUILD.gn
+++ /dev/null
@@ -1,301 +0,0 @@
-declare_args() {
-  host_ar = ar
-  host_cc = cc
-  host_cxx = cxx
-
-  if (is_android) {
-    if (host_os == "win") {
-      target_ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar.exe"
-      target_cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang.exe"
-      target_cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++.exe"
-    } else {
-      target_ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar"
-      target_cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang"
-      target_cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++"
-    }
-  } else {
-    target_ar = ar
-    target_cc = cc
-    target_cxx = cxx
-  }
-
-  cc_wrapper = ""
-}
-
-if (host_os == "win") {
-  python = "python.bat"
-  stamp = "cmd.exe /c echo >"
-} else {
-  python = "python"
-  stamp = "touch"
-}
-
-toolchain("msvc") {
-  lib_dir_switch = "/LIBPATH:"
-
-  if (msvc == 2015) {
-    bin = "$windk/VC/bin/amd64"
-    env_setup = ""
-    if (target_cpu == "x86") {
-      bin += "_x86"
-      env_setup = "cmd /c $windk/win_sdk/bin/SetEnv.cmd /x86 && "
-    }
-  } else {
-    bin = "$windk/VC/Tools/MSVC/14.10.25017/bin/HostX64/$target_cpu"
-    env_setup = ""
-    if (target_cpu == "x86") {
-      print("Be sure to run")
-      print("$windk/VC/Auxiliary/Build/vcvarsall.bat amd64_x86")
-      print("to set up your environment before running ninja.")
-    }
-  }
-
-  tool("asm") {
-    _ml = "ml"
-    if (target_cpu == "x64") {
-      _ml += "64"
-    }
-    command = "$env_setup$bin/$_ml.exe /nologo /c /Fo {{output}} {{source}}"
-    outputs = [
-      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
-    ]
-    description = "assemble {{source}}"
-  }
-
-  tool("cc") {
-    rspfile = "{{output}}.rsp"
-    precompiled_header_type = "msvc"
-    pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
-
-    # Label names may have spaces so pdbname must be quoted.
-    command = "$env_setup$bin/cl.exe /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
-    depsformat = "msvc"
-    outputs = [
-      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
-    ]
-    rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
-    description = "compile {{source}}"
-  }
-
-  tool("cxx") {
-    rspfile = "{{output}}.rsp"
-    precompiled_header_type = "msvc"
-    pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
-
-    # Label names may have spaces so pdbname must be quoted.
-    command = "$env_setup$bin/cl.exe /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
-    depsformat = "msvc"
-    outputs = [
-      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
-    ]
-    rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
-    description = "compile {{source}}"
-  }
-
-  tool("alink") {
-    rspfile = "{{output}}.rsp"
-
-    command = "$env_setup$bin/lib.exe /nologo /ignore:4221 {{arflags}} /OUT:{{output}} @$rspfile"
-    outputs = [
-      # Ignore {{output_extension}} and always use .lib, there's no reason to
-      # allow targets to override this extension on Windows.
-      "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
-    ]
-    default_output_extension = ".lib"
-    default_output_dir = "{{target_out_dir}}"
-
-    # inputs_newline works around a fixed per-line buffer size in the linker.
-    rspfile_content = "{{inputs_newline}}"
-    description = "link {{output}}"
-  }
-
-  tool("solink") {
-    dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
-    libname = "${dllname}.lib"
-    pdbname = "${dllname}.pdb"
-    rspfile = "${dllname}.rsp"
-
-    command = "$env_setup$bin/link.exe /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile"
-    outputs = [
-      dllname,
-      libname,
-      pdbname,
-    ]
-    default_output_extension = ".dll"
-    default_output_dir = "{{root_out_dir}}"
-
-    link_output = libname
-    depend_output = libname
-    runtime_outputs = [
-      dllname,
-      pdbname,
-    ]
-
-    # I don't quite understand this.  Aping Chrome's toolchain/win/BUILD.gn.
-    restat = true
-
-    # inputs_newline works around a fixed per-line buffer size in the linker.
-    rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
-    description = "link {{output}}"
-  }
-
-  tool("link") {
-    exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
-    pdbname = "$exename.pdb"
-    rspfile = "$exename.rsp"
-
-    command =
-        "$env_setup$bin/link.exe /nologo /OUT:$exename /PDB:$pdbname @$rspfile"
-
-    default_output_extension = ".exe"
-    default_output_dir = "{{root_out_dir}}"
-    outputs = [
-      exename,
-    ]
-
-    # inputs_newline works around a fixed per-line buffer size in the linker.
-    rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
-    description = "link {{output}}"
-  }
-
-  tool("stamp") {
-    command = "$stamp {{output}}"
-    description = "stamp {{output}}"
-  }
-
-  tool("copy") {
-    cp_py = rebase_path("../cp.py")
-    command = "$python $cp_py {{source}} {{output}}"
-    description = "copy {{source}} {{output}}"
-  }
-}
-
-template("gcc_like_toolchain") {
-  toolchain(target_name) {
-    ar = invoker.ar
-    cc = invoker.cc
-    cxx = invoker.cxx
-    lib_switch = "-l"
-    lib_dir_switch = "-L"
-
-    tool("cc") {
-      depfile = "{{output}}.d"
-      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
-      depsformat = "gcc"
-      outputs = [
-        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
-      ]
-      description = "compile {{source}}"
-    }
-
-    tool("cxx") {
-      depfile = "{{output}}.d"
-      command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
-      depsformat = "gcc"
-      outputs = [
-        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
-      ]
-      description = "compile {{source}}"
-    }
-
-    tool("objc") {
-      depfile = "{{output}}.d"
-      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objc}} -c {{source}} -o {{output}}"
-      depsformat = "gcc"
-      outputs = [
-        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
-      ]
-      description = "compile {{source}}"
-    }
-
-    tool("objcxx") {
-      depfile = "{{output}}.d"
-      command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objc}} -c {{source}} -o {{output}}"
-      depsformat = "gcc"
-      outputs = [
-        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
-      ]
-      description = "compile {{source}}"
-    }
-
-    tool("asm") {
-      depfile = "{{output}}.d"
-      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
-      depsformat = "gcc"
-      outputs = [
-        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
-      ]
-      description = "assemble {{source}}"
-    }
-
-    tool("alink") {
-      rspfile = "{{output}}.rsp"
-      rspfile_content = "{{inputs}}"
-      ar_py = rebase_path("../ar.py")
-      command = "$python $ar_py $ar {{output}} $rspfile"
-      outputs = [
-        "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
-      ]
-      default_output_extension = ".a"
-      output_prefix = "lib"
-      description = "link {{output}}"
-    }
-
-    tool("solink") {
-      soname = "{{target_output_name}}{{output_extension}}"
-
-      rpath = "-Wl,-soname,$soname"
-      if (is_mac) {
-        rpath = "-Wl,-install_name,@rpath/$soname"
-      }
-
-      command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
-      outputs = [
-        "{{root_out_dir}}/$soname",
-      ]
-      output_prefix = "lib"
-      default_output_extension = ".so"
-      description = "link {{output}}"
-    }
-
-    tool("link") {
-      command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
-      outputs = [
-        "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
-      ]
-      description = "link {{output}}"
-    }
-
-    tool("stamp") {
-      command = "$stamp {{output}}"
-      description = "stamp {{output}}"
-    }
-
-    tool("copy") {
-      cp_py = rebase_path("../cp.py")
-      command = "$python $cp_py {{source}} {{output}}"
-      description = "copy {{source}} {{output}}"
-    }
-
-    toolchain_args = {
-      current_cpu = invoker.cpu
-      current_os = invoker.os
-    }
-  }
-}
-
-gcc_like_toolchain("gcc_like") {
-  cpu = current_cpu
-  os = current_os
-  ar = target_ar
-  cc = target_cc
-  cxx = target_cxx
-}
-
-gcc_like_toolchain("gcc_like_host") {
-  cpu = host_cpu
-  os = host_os
-  ar = host_ar
-  cc = host_cc
-  cxx = host_cxx
-}
diff --git a/src/sksl/README b/src/sksl/README
index 0c1712d..a16dd80 100644
--- a/src/sksl/README
+++ b/src/sksl/README
@@ -9,7 +9,6 @@
 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
 =====================
 
@@ -57,58 +56,3 @@
 
 SkSL is still under development, and is expected to diverge further from GLSL
 over time.
-
-
-SkSL Fragment Processors
-========================
-
-An extension of SkSL allows for the creation of fragment processors in pure
-SkSL. The program defines its inputs similarly to a normal SkSL program (with
-'in' and 'uniform' variables), but the 'main()' function represents only this
-fragment processor's portion of the overall fragment shader.
-
-Within an '.fp' fragment processor file:
-
-* C++ code can be embedded in sections of the form:
-
-  @section_name { <arbitrary C++ code> }
-
-  Supported section are:
-    @header            (in the .h file, outside the class declaration)
-    @class             (in the .h file, inside the class declaration)
-    @cpp               (in the .cpp file)
-    @constructorParams (extra parameters to the constructor, comma-separated)
-    @constructor       (replaces the default constructor)
-    @initializers      (constructor initializer list, comma-separated)
-    @emitCode          (extra code for the emitCode function)
-    @fields            (extra private fields, each terminated with a semicolon)
-    @make              (replaces the default Make function)
-    @setData(<pdman>)  (extra code for the setData function, where <pdman> is
-                        the name of the GrGLSLProgramDataManager)
-    @test(<testData>)  (the body of the TestCreate function, where <testData> is
-                        the name of the GrProcessorTestData* parameter)
-* global 'in' variables represent data passed to the fragment processor at
-  construction time. These variables become constructor parameters and are
-  stored in fragment processor fields. vec2s map to SkPoints, and vec4s map to
-  SkRects (in x, y, width, height) order.
-* 'uniform' variables become, as one would expect, top-level uniforms. By
-  default they do not have any data provided to them; you will need to provide
-  them with data via the @setData section.
-* 'in uniform' variables are uniforms that are automatically wired up to
-  fragment processor constructor parameters
-* the 'sk_TransformedCoords2D' array provides access to 2D transformed
-  coordinates. sk_TransformedCoords2D[0] is equivalent to calling
-  fragBuilder->ensureCoords2D(args.fTransformedCoords[0]) (and the result is
-  cached, so you need not worry about using the value repeatedly).
-* 'colorSpaceXform' is a supported type. It is reflected within SkSL as a mat4,
-  and on the C++ side as sk_sp<GrColorSpaceXform>.
-* the texture() function can be passed a colorSpaceXform as an additional
-  parameter
-* Uniform variables support an additional 'when' layout key.
-  'layout(when=foo) uniform int x;' means that this uniform will only be
-  emitted when the 'foo' expression is true.
-* 'in' variables support an additional 'key' layout key.
-  'layout(key) uniform int x;' means that this uniform should be included in
-  the program's key. Matrix variables additionally support 'key=identity',
-  which causes the key to consider only whether or not the matrix is an
-  identity matrix.
diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp
index e8964db..df10c62 100644
--- a/src/sksl/SkSLCFGGenerator.cpp
+++ b/src/sksl/SkSLCFGGenerator.cpp
@@ -231,7 +231,6 @@
         case Expression::kBoolLiteral_Kind:  // fall through
         case Expression::kFloatLiteral_Kind: // fall through
         case Expression::kIntLiteral_Kind:   // fall through
-        case Expression::kSetting_Kind:      // fall through
         case Expression::kVariableReference_Kind:
             *iter = fNodes.erase(*iter);
             return true;
@@ -381,7 +380,6 @@
         case Expression::kBoolLiteral_Kind:  // fall through
         case Expression::kFloatLiteral_Kind: // fall through
         case Expression::kIntLiteral_Kind:   // fall through
-        case Expression::kSetting_Kind:      // fall through
         case Expression::kVariableReference_Kind:
             cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kExpression_Kind,
                                                          constantPropagate, e, nullptr });
diff --git a/src/sksl/SkSLCPP.h b/src/sksl/SkSLCPP.h
deleted file mode 100644
index 47f8a40..0000000
--- a/src/sksl/SkSLCPP.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SKSL_CPP
-#define SKSL_CPP
-
-// functions used by CPP programs created by skslc
-
-#include "SkPoint.h"
-
-// macros to make sk_Caps.<cap name> work from C++ code
-#define sk_Caps (*args.fShaderCaps)
-
-#define floatPrecisionVaries floatPrecisionVaries()
-
-// functions to make GLSL constructors work from C++ code
-inline SkPoint vec2(float xy) { return SkPoint::Make(xy, xy); }
-
-inline SkPoint vec2(float x, float y) { return SkPoint::Make(x, y); }
-
-#endif
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
deleted file mode 100644
index 0b3c7d5..0000000
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ /dev/null
@@ -1,600 +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.
- */
-
-#include "SkSLCPPCodeGenerator.h"
-
-#include "SkSLCompiler.h"
-#include "SkSLHCodeGenerator.h"
-
-namespace SkSL {
-
-static bool needs_uniform_var(const Variable& var) {
-    return (var.fModifiers.fFlags & Modifiers::kUniform_Flag) &&
-           strcmp(var.fType.fName.c_str(), "colorSpaceXform");
-}
-
-CPPCodeGenerator::CPPCodeGenerator(const Context* context, const Program* program,
-                                   ErrorReporter* errors, String name, OutputStream* out)
-: INHERITED(context, program, errors, out)
-, fName(std::move(name))
-, fFullName(String::printf("Gr%s", fName.c_str()))
-, fSectionAndParameterHelper(*program, *errors) {
-    fLineEnding = "\\n";
-}
-
-void CPPCodeGenerator::writef(const char* s, va_list va) {
-    static constexpr int BUFFER_SIZE = 1024;
-    char buffer[BUFFER_SIZE];
-    int length = vsnprintf(buffer, BUFFER_SIZE, s, va);
-    if (length < BUFFER_SIZE) {
-        fOut->write(buffer, length);
-    } else {
-        std::unique_ptr<char[]> heap(new char[length + 1]);
-        vsprintf(heap.get(), s, va);
-        fOut->write(heap.get(), length);
-    }
-}
-
-void CPPCodeGenerator::writef(const char* s, ...) {
-    va_list va;
-    va_start(va, s);
-    this->writef(s, va);
-    va_end(va);
-}
-
-void CPPCodeGenerator::writeHeader() {
-}
-
-void CPPCodeGenerator::writePrecisionModifier() {
-}
-
-void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
-                                             Precedence parentPrecedence) {
-    if (b.fOperator == Token::PERCENT) {
-        // need to use "%%" instead of "%" b/c the code will be inside of a printf
-        Precedence precedence = GetBinaryPrecedence(b.fOperator);
-        if (precedence >= parentPrecedence) {
-            this->write("(");
-        }
-        this->writeExpression(*b.fLeft, precedence);
-        this->write(" %% ");
-        this->writeExpression(*b.fRight, precedence);
-        if (precedence >= parentPrecedence) {
-            this->write(")");
-        }
-    } else {
-        INHERITED::writeBinaryExpression(b, parentPrecedence);
-    }
-}
-
-void CPPCodeGenerator::writeIndexExpression(const IndexExpression& i) {
-    const Expression& base = *i.fBase;
-    if (base.fKind == Expression::kVariableReference_Kind) {
-        int builtin = ((VariableReference&) base).fVariable.fModifiers.fLayout.fBuiltin;
-        if (SK_TRANSFORMEDCOORDS2D_BUILTIN == builtin) {
-            this->write("%s");
-            if (i.fIndex->fKind != Expression::kIntLiteral_Kind) {
-                fErrors.error(i.fIndex->fPosition,
-                              "index into sk_TransformedCoords2D must be an integer literal");
-                return;
-            }
-            int64_t index = ((IntLiteral&) *i.fIndex).fValue;
-            String name = "sk_TransformedCoords2D_" + to_string(index);
-            fFormatArgs.push_back(name + ".c_str()");
-            if (fWrittenTransformedCoords.find(index) == fWrittenTransformedCoords.end()) {
-                fExtraEmitCodeCode += "        SkSL::String " + name +
-                                      " = fragBuilder->ensureCoords2D(args.fTransformedCoords[" +
-                                      to_string(index) + "]);\n";
-                fWrittenTransformedCoords.insert(index);
-            }
-            return;
-        } else if (SK_TEXTURESAMPLERS_BUILTIN == builtin) {
-            this->write("%s");
-            if (i.fIndex->fKind != Expression::kIntLiteral_Kind) {
-                fErrors.error(i.fIndex->fPosition,
-                              "index into sk_TextureSamplers must be an integer literal");
-                return;
-            }
-            int64_t index = ((IntLiteral&) *i.fIndex).fValue;
-            fFormatArgs.push_back("        fragBuilder->getProgramBuilder()->samplerVariable("
-                                            "args.fTexSamplers[" + to_string(index) + "]).c_str()");
-            return;
-        }
-    }
-    INHERITED::writeIndexExpression(i);
-}
-
-static const char* default_value(const Type& type) {
-    const char* name = type.name().c_str();
-    if (!strcmp(name, "float")) {
-        return "0.0";
-    } else if (!strcmp(name, "vec2")) {
-        return "vec2(0.0)";
-    } else if (!strcmp(name, "vec3")) {
-        return "vec3(0.0)";
-    } else if (!strcmp(name, "vec4")) {
-        return "vec4(0.0)";
-    } else if (!strcmp(name, "mat4") || !strcmp(name, "colorSpaceXform")) {
-        return "mat4(1.0)";
-    }
-    ABORT("unsupported default_value type\n");
-}
-
-static bool is_private(const Variable& var) {
-    return !(var.fModifiers.fFlags & Modifiers::kUniform_Flag) &&
-           !(var.fModifiers.fFlags & Modifiers::kIn_Flag) &&
-           var.fStorage == Variable::kGlobal_Storage &&
-           var.fModifiers.fLayout.fBuiltin == -1;
-}
-
-void CPPCodeGenerator::writeRuntimeValue(const Type& type, const String& cppCode) {
-    if (type == *fContext.fFloat_Type) {
-        this->write("%f");
-        fFormatArgs.push_back(cppCode);
-    } else if (type == *fContext.fInt_Type) {
-        this->write("%d");
-        fFormatArgs.push_back(cppCode);
-    } else if (type == *fContext.fBool_Type) {
-        this->write("%s");
-        fFormatArgs.push_back("(" + cppCode + " ? \"true\" : \"false\")");
-    } else if (type == *fContext.fVec2_Type) {
-        this->write("vec2(%f, %f)");
-        fFormatArgs.push_back(cppCode + ".fX");
-        fFormatArgs.push_back(cppCode + ".fY");
-    } else {
-        printf("%s\n", type.name().c_str());
-        ABORT("unsupported runtime value type\n");
-    }
-}
-
-void CPPCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
-    if (is_private(var)) {
-        this->writeRuntimeValue(var.fType, var.fName);
-    } else {
-        this->writeExpression(value, kTopLevel_Precedence);
-    }
-}
-
-void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
-    switch (ref.fVariable.fModifiers.fLayout.fBuiltin) {
-        case SK_INCOLOR_BUILTIN:
-            this->write("%s");
-            fFormatArgs.push_back(String("args.fInputColor ? args.fInputColor : \"vec4(1)\""));
-            break;
-        case SK_OUTCOLOR_BUILTIN:
-            this->write("%s");
-            fFormatArgs.push_back(String("args.fOutputColor"));
-            break;
-        default:
-            if (ref.fVariable.fType.kind() == Type::kSampler_Kind) {
-                int samplerCount = 0;
-                for (const auto param : fSectionAndParameterHelper.fParameters) {
-                    if (&ref.fVariable == param) {
-                        this->write("%s");
-                        fFormatArgs.push_back("fragBuilder->getProgramBuilder()->samplerVariable("
-                                              "args.fTexSamplers[" + to_string(samplerCount) +
-                                              "]).c_str()");
-                        return;
-                    }
-                    if (param->fType.kind() == Type::kSampler_Kind) {
-                        ++samplerCount;
-                    }
-                }
-                ABORT("should have found sampler in parameters\n");
-            }
-            if (ref.fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag) {
-                this->write("%s");
-                String name = ref.fVariable.fName;
-                String var;
-                if (ref.fVariable.fType == *fContext.fColorSpaceXform_Type) {
-                    ASSERT(fNeedColorSpaceHelper);
-                    var = String::printf("fColorSpaceHelper.isValid() ? "
-                                         "args.fUniformHandler->getUniformCStr("
-                                                  "fColorSpaceHelper.gamutXformUniform()) : \"%s\"",
-                           default_value(ref.fVariable.fType));
-                } else {
-                    var = String::printf("args.fUniformHandler->getUniformCStr(%sVar)",
-                                         HCodeGenerator::FieldName(name.c_str()).c_str());
-                }
-                String code;
-                if (ref.fVariable.fModifiers.fLayout.fWhen.size()) {
-                    code = String::printf("%sVar.isValid() ? %s : \"%s\"",
-                                          HCodeGenerator::FieldName(name.c_str()).c_str(),
-                                          var.c_str(),
-                                          default_value(ref.fVariable.fType));
-                } else {
-                    code = var;
-                }
-                fFormatArgs.push_back(code);
-            } else if (SectionAndParameterHelper::IsParameter(ref.fVariable)) {
-                const char* name = ref.fVariable.fName.c_str();
-                this->writeRuntimeValue(ref.fVariable.fType,
-                                        String::printf("_outer.%s()", name).c_str());
-            } else {
-                this->write(ref.fVariable.fName.c_str());
-            }
-    }
-}
-
-void CPPCodeGenerator::writeFunction(const FunctionDefinition& f) {
-    if (f.fDeclaration.fName == "main") {
-        fFunctionHeader = "";
-        OutputStream* oldOut = fOut;
-        StringStream buffer;
-        fOut = &buffer;
-        for (const auto& s : ((Block&) *f.fBody).fStatements) {
-            this->writeStatement(*s);
-            this->writeLine();
-        }
-
-        fOut = oldOut;
-        this->write(fFunctionHeader);
-        this->write(buffer.str());
-    } else {
-        INHERITED::writeFunction(f);
-    }
-}
-
-void CPPCodeGenerator::writeSetting(const Setting& s) {
-    static constexpr const char* kPrefix = "sk_Args.";
-    if (!strncmp(s.fName.c_str(), kPrefix, strlen(kPrefix))) {
-        const char* name = s.fName.c_str() + strlen(kPrefix);
-        this->writeRuntimeValue(s.fType, HCodeGenerator::FieldName(name).c_str());
-    } else {
-        this->write(s.fName.c_str());
-    }
-}
-
-void CPPCodeGenerator::writeSection(const char* name, const char* prefix) {
-    const auto found = fSectionAndParameterHelper.fSections.find(String(name));
-    if (found != fSectionAndParameterHelper.fSections.end()) {
-        this->writef("%s%s", prefix, found->second->fText.c_str());
-    }
-}
-
-void CPPCodeGenerator::writeProgramElement(const ProgramElement& p) {
-    if (p.fKind == ProgramElement::kSection_Kind) {
-        return;
-    }
-    if (p.fKind == ProgramElement::kVar_Kind) {
-        const VarDeclarations& decls = (const VarDeclarations&) p;
-        if (!decls.fVars.size()) {
-            return;
-        }
-        const Variable& var = *((VarDeclaration&) *decls.fVars[0]).fVar;
-        if (var.fModifiers.fFlags & (Modifiers::kIn_Flag | Modifiers::kUniform_Flag) ||
-            -1 != var.fModifiers.fLayout.fBuiltin) {
-            return;
-        }
-    }
-    INHERITED::writeProgramElement(p);
-}
-
-void CPPCodeGenerator::addUniform(const Variable& var) {
-    if (!needs_uniform_var(var)) {
-        return;
-    }
-    const char* precision;
-    if (var.fModifiers.fFlags & Modifiers::kHighp_Flag) {
-        precision = "kHigh_GrSLPrecision";
-    } else if (var.fModifiers.fFlags & Modifiers::kMediump_Flag) {
-        precision = "kMedium_GrSLPrecision";
-    } else if (var.fModifiers.fFlags & Modifiers::kLowp_Flag) {
-        precision = "kLow_GrSLPrecision";
-    } else {
-        precision = "kDefault_GrSLPrecision";
-    }
-    const char* type;
-    if (var.fType == *fContext.fFloat_Type) {
-        type = "kFloat_GrSLType";
-    } else if (var.fType == *fContext.fVec2_Type) {
-        type = "kVec2f_GrSLType";
-    } else if (var.fType == *fContext.fVec4_Type) {
-        type = "kVec4f_GrSLType";
-    } else if (var.fType == *fContext.fMat4x4_Type ||
-               var.fType == *fContext.fColorSpaceXform_Type) {
-        type = "kMat44f_GrSLType";
-    } else {
-        ABORT("unsupported uniform type: %s %s;\n", var.fType.name().c_str(), var.fName.c_str());
-    }
-    if (var.fModifiers.fLayout.fWhen.size()) {
-        this->writef("        if (%s) {\n    ", var.fModifiers.fLayout.fWhen.c_str());
-    }
-    const char* name = var.fName.c_str();
-    this->writef("        %sVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, %s, "
-                 "%s, \"%s\");\n", HCodeGenerator::FieldName(name).c_str(), type, precision, name);
-    if (var.fModifiers.fLayout.fWhen.size()) {
-        this->write("        }\n");
-    }
-}
-
-void CPPCodeGenerator::writePrivateVars() {
-    for (const auto& p : fProgram.fElements) {
-        if (ProgramElement::kVar_Kind == p->fKind) {
-            const VarDeclarations* decls = (const VarDeclarations*) p.get();
-            for (const auto& raw : decls->fVars) {
-                VarDeclaration& decl = (VarDeclaration&) *raw;
-                if (is_private(*decl.fVar)) {
-                    this->writef("%s %s;\n",
-                                 HCodeGenerator::FieldType(decl.fVar->fType).c_str(),
-                                 decl.fVar->fName.c_str());
-                }
-            }
-        }
-    }
-}
-
-void CPPCodeGenerator::writePrivateVarValues() {
-    for (const auto& p : fProgram.fElements) {
-        if (ProgramElement::kVar_Kind == p->fKind) {
-            const VarDeclarations* decls = (const VarDeclarations*) p.get();
-            for (const auto& raw : decls->fVars) {
-                VarDeclaration& decl = (VarDeclaration&) *raw;
-                if (is_private(*decl.fVar) && decl.fValue) {
-                    this->writef("%s = %s;\n",
-                                 decl.fVar->fName.c_str(),
-                                 decl.fValue->description().c_str());
-                }
-            }
-        }
-    }
-}
-
-bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
-    this->write("    void emitCode(EmitArgs& args) override {\n"
-                "        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n");
-    this->writef("        const %s& _outer = args.fFp.cast<%s>();\n"
-                 "        (void) _outer;\n",
-                 fFullName.c_str(), fFullName.c_str());
-    this->writePrivateVarValues();
-    for (const auto u : uniforms) {
-        this->addUniform(*u);
-        if (u->fType == *fContext.fColorSpaceXform_Type) {
-            if (fNeedColorSpaceHelper) {
-                fErrors.error(u->fPosition, "only a single ColorSpaceXform is supported");
-            }
-            fNeedColorSpaceHelper = true;
-            this->writef("        fColorSpaceHelper.emitCode(args.fUniformHandler, "
-                                                            "_outer.%s().get());\n",
-                         u->fName.c_str());
-        }
-    }
-    this->writeSection(EMIT_CODE_SECTION);
-    OutputStream* old = fOut;
-    StringStream mainBuffer;
-    fOut = &mainBuffer;
-    bool result = INHERITED::generateCode();
-    fOut = old;
-    this->writef("%s        fragBuilder->codeAppendf(\"%s\"", fExtraEmitCodeCode.c_str(),
-                 mainBuffer.str().c_str());
-    for (const auto& s : fFormatArgs) {
-        this->writef(", %s", s.c_str());
-    }
-    this->write(");\n"
-                "    }\n");
-    return result;
-}
-
-void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
-    const char* fullName = fFullName.c_str();
-    auto section = fSectionAndParameterHelper.fSections.find(String(SET_DATA_SECTION));
-    const char* pdman = section != fSectionAndParameterHelper.fSections.end() ?
-                                                                section->second->fArgument.c_str() :
-                                                                "pdman";
-    this->writef("    void onSetData(const GrGLSLProgramDataManager& %s, "
-                                    "const GrFragmentProcessor& _proc) override {\n",
-                 pdman);
-    bool wroteProcessor = false;
-    for (const auto u : uniforms) {
-        if (u->fModifiers.fFlags & Modifiers::kIn_Flag) {
-            if (!wroteProcessor) {
-                this->writef("        const %s& _outer = _proc.cast<%s>();\n", fullName, fullName);
-                wroteProcessor = true;
-                this->writef("        {\n");
-            }
-            const char* name = u->fName.c_str();
-            if (u->fType == *fContext.fVec4_Type) {
-                this->writef("        const SkRect %sValue = _outer.%s();\n"
-                             "        %s.set4fv(%sVar, 4, (float*) &%sValue);\n",
-                             name, name, pdman, HCodeGenerator::FieldName(name).c_str(), name);
-            } else if (u->fType == *fContext.fMat4x4_Type) {
-                this->writef("        float %sValue[16];\n"
-                             "        _outer.%s().asColMajorf(%sValue);\n"
-                             "        %s.setMatrix4f(%sVar, %sValue);\n",
-                             name, name, name, pdman, HCodeGenerator::FieldName(name).c_str(),
-                             name);
-            } else if (u->fType == *fContext.fColorSpaceXform_Type) {
-                ASSERT(fNeedColorSpaceHelper);
-                this->writef("        if (fColorSpaceHelper.isValid()) {\n"
-                             "            fColorSpaceHelper.setData(%s, _outer.%s().get());\n"
-                             "        }\n",
-                             pdman, name);
-            } else {
-                this->writef("        %s.set1f(%sVar, _outer.%s());\n",
-                             pdman, HCodeGenerator::FieldName(name).c_str(), name);
-            }
-        }
-    }
-    if (wroteProcessor) {
-        this->writef("        }\n");
-    }
-    if (section != fSectionAndParameterHelper.fSections.end()) {
-        for (const auto& p : fProgram.fElements) {
-            if (ProgramElement::kVar_Kind == p->fKind) {
-                const VarDeclarations* decls = (const VarDeclarations*) p.get();
-                for (const auto& raw : decls->fVars) {
-                    VarDeclaration& decl = (VarDeclaration&) *raw;
-                    if (needs_uniform_var(*decl.fVar)) {
-                        const char* name = decl.fVar->fName.c_str();
-                        this->writef("        UniformHandle& %s = %sVar;\n"
-                                     "        (void) %s;\n",
-                                     name, HCodeGenerator::FieldName(name).c_str(), name);
-                    } else if (SectionAndParameterHelper::IsParameter(*decl.fVar)) {
-                        const char* name = decl.fVar->fName.c_str();
-                        if (!wroteProcessor) {
-                            this->writef("        const %s& _outer = _proc.cast<%s>();\n", fullName,
-                                         fullName);
-                            wroteProcessor = true;
-                        }
-                        this->writef("        auto %s = _outer.%s();\n"
-                                     "        (void) %s;\n",
-                                     name, name, name);
-                    }
-                }
-            }
-        }
-        this->writeSection(SET_DATA_SECTION);
-    }
-    this->write("    }\n");
-}
-
-void CPPCodeGenerator::writeTest() {
-    const auto found = fSectionAndParameterHelper.fSections.find(TEST_CODE_SECTION);
-    if (found == fSectionAndParameterHelper.fSections.end()) {
-        return;
-    }
-    const Section* test = found->second;
-    this->writef("GR_DEFINE_FRAGMENT_PROCESSOR_TEST(%s);\n"
-                 "#if GR_TEST_UTILS\n"
-                 "sk_sp<GrFragmentProcessor> %s::TestCreate(GrProcessorTestData* %s) {\n",
-                 fFullName.c_str(),
-                 fFullName.c_str(),
-                 test->fArgument.c_str());
-    this->writeSection(TEST_CODE_SECTION);
-    this->write("}\n"
-                "#endif\n");
-}
-
-void CPPCodeGenerator::writeGetKey() {
-    this->writef("void %s::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
-                                                "GrProcessorKeyBuilder* b) const {\n",
-                 fFullName.c_str());
-    for (const auto& param : fSectionAndParameterHelper.fParameters) {
-        const char* name = param->fName.c_str();
-        if (param->fType == *fContext.fColorSpaceXform_Type) {
-            this->writef("    b->add32(GrColorSpaceXform::XformKey(%s.get()));\n",
-                         HCodeGenerator::FieldName(name).c_str());
-            continue;
-        }
-        if (param->fModifiers.fLayout.fKey != Layout::kNo_Key &&
-            (param->fModifiers.fFlags & Modifiers::kUniform_Flag)) {
-            fErrors.error(param->fPosition,
-                          "layout(key) may not be specified on uniforms");
-        }
-        switch (param->fModifiers.fLayout.fKey) {
-            case Layout::kKey_Key:
-                if (param->fType == *fContext.fMat4x4_Type) {
-                    ABORT("no automatic key handling for mat4\n");
-                } else if (param->fType == *fContext.fVec2_Type) {
-                    this->writef("    b->add32(%s.fX);\n",
-                                 HCodeGenerator::FieldName(name).c_str());
-                    this->writef("    b->add32(%s.fY);\n",
-                                 HCodeGenerator::FieldName(name).c_str());
-                } else if (param->fType == *fContext.fVec4_Type) {
-                    this->writef("    b->add32(%s.x());\n",
-                                 HCodeGenerator::FieldName(name).c_str());
-                    this->writef("    b->add32(%s.y());\n",
-                                 HCodeGenerator::FieldName(name).c_str());
-                    this->writef("    b->add32(%s.width());\n",
-                                 HCodeGenerator::FieldName(name).c_str());
-                    this->writef("    b->add32(%s.height());\n",
-                                 HCodeGenerator::FieldName(name).c_str());
-                } else {
-                    this->writef("    b->add32(%s);\n",
-                                 HCodeGenerator::FieldName(name).c_str());
-                }
-                break;
-            case Layout::kIdentity_Key:
-                if (param->fType.kind() != Type::kMatrix_Kind) {
-                    fErrors.error(param->fPosition,
-                                  "layout(key=identity) requires matrix type");
-                }
-                this->writef("    b->add32(%s.isIdentity() ? 1 : 0);\n",
-                             HCodeGenerator::FieldName(name).c_str());
-                break;
-            case Layout::kNo_Key:
-                break;
-        }
-    }
-    this->write("}\n");
-}
-
-bool CPPCodeGenerator::generateCode() {
-    std::vector<const Variable*> uniforms;
-    for (const auto& p : fProgram.fElements) {
-        if (ProgramElement::kVar_Kind == p->fKind) {
-            const VarDeclarations* decls = (const VarDeclarations*) p.get();
-            for (const auto& raw : decls->fVars) {
-                VarDeclaration& decl = (VarDeclaration&) *raw;
-                if ((decl.fVar->fModifiers.fFlags & Modifiers::kUniform_Flag) &&
-                           decl.fVar->fType.kind() != Type::kSampler_Kind) {
-                    uniforms.push_back(decl.fVar);
-                }
-            }
-        }
-    }
-    const char* baseName = fName.c_str();
-    const char* fullName = fFullName.c_str();
-    this->writef("/*\n"
-                 " * This file was autogenerated from %s.fp.\n"
-                 " */\n"
-                 "#include \"%s.h\"\n"
-                 "#include \"glsl/GrGLSLColorSpaceXformHelper.h\"\n"
-                 "#include \"glsl/GrGLSLFragmentProcessor.h\"\n"
-                 "#include \"glsl/GrGLSLFragmentShaderBuilder.h\"\n"
-                 "#include \"glsl/GrGLSLProgramBuilder.h\"\n"
-                 "#include \"GrResourceProvider.h\"\n"
-                 "#include \"SkSLCPP.h\"\n"
-                 "#include \"SkSLUtil.h\"\n"
-                 "class GrGLSL%s : public GrGLSLFragmentProcessor {\n"
-                 "public:\n"
-                 "    GrGLSL%s() {}\n",
-                 fullName, fullName, baseName, baseName);
-    bool result = this->writeEmitCode(uniforms);
-    this->write("private:\n");
-    this->writeSetData(uniforms);
-    this->writePrivateVars();
-    for (const auto& u : uniforms) {
-        const char* name = u->fName.c_str();
-        if (needs_uniform_var(*u) && !(u->fModifiers.fFlags & Modifiers::kIn_Flag)) {
-            this->writef("    UniformHandle %sVar;\n", HCodeGenerator::FieldName(name).c_str());
-        }
-    }
-    for (const auto& param : fSectionAndParameterHelper.fParameters) {
-        const char* name = param->fName.c_str();
-        if (needs_uniform_var(*param)) {
-            this->writef("    UniformHandle %sVar;\n", HCodeGenerator::FieldName(name).c_str());
-        }
-    }
-    if (fNeedColorSpaceHelper) {
-        this->write("    GrGLSLColorSpaceXformHelper fColorSpaceHelper;\n");
-    }
-    this->writef("};\n"
-                 "GrGLSLFragmentProcessor* %s::onCreateGLSLInstance() const {\n"
-                 "    return new GrGLSL%s();\n"
-                 "}\n",
-                 fullName, baseName);
-    this->writeGetKey();
-    this->writef("bool %s::onIsEqual(const GrFragmentProcessor& other) const {\n"
-                 "    const %s& that = other.cast<%s>();\n"
-                 "    (void) that;\n",
-                 fullName, fullName, fullName);
-    for (const auto& param : fSectionAndParameterHelper.fParameters) {
-        const char* name = param->fName.c_str();
-        this->writef("    if (%s != that.%s) return false;\n",
-                     HCodeGenerator::FieldName(name).c_str(),
-                     HCodeGenerator::FieldName(name).c_str());
-    }
-    this->write("    return true;\n"
-                "}\n");
-    this->writeSection(CPP_SECTION);
-    this->writeTest();
-    result &= 0 == fErrors.errorCount();
-    return result;
-}
-
-} // namespace
diff --git a/src/sksl/SkSLCPPCodeGenerator.h b/src/sksl/SkSLCPPCodeGenerator.h
deleted file mode 100644
index c7388ad..0000000
--- a/src/sksl/SkSLCPPCodeGenerator.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SKSL_CPPCODEGENERATOR
-#define SKSL_CPPCODEGENERATOR
-
-#include "SkSLGLSLCodeGenerator.h"
-#include "SkSLSectionAndParameterHelper.h"
-
-#include <set>
-
-namespace SkSL {
-
-class CPPCodeGenerator : public GLSLCodeGenerator {
-public:
-    CPPCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
-                     String name, OutputStream* out);
-
-    bool generateCode() override;
-
-private:
-    void writef(const char* s, va_list va) SKSL_PRINTF_LIKE(2, 0);
-
-    void writef(const char* s, ...) SKSL_PRINTF_LIKE(2, 3);
-
-    void writeSection(const char* name, const char* prefix = "");
-
-    void writeHeader() override;
-
-    void writePrecisionModifier() override;
-
-    void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence) override;
-
-    void writeIndexExpression(const IndexExpression& i) override;
-
-    void writeVariableReference(const VariableReference& ref) override;
-
-    void writeFunction(const FunctionDefinition& f) override;
-
-    void writeSetting(const Setting& s) override;
-
-    void writeProgramElement(const ProgramElement& p) override;
-
-    void addUniform(const Variable& var);
-
-    // writes a printf escape that will be filled in at runtime by the given C++ expression string
-    void writeRuntimeValue(const Type& type, const String& cppCode);
-
-    void writeVarInitializer(const Variable& var, const Expression& value) override;
-
-    void writePrivateVars();
-
-    void writePrivateVarValues();
-
-    bool writeEmitCode(std::vector<const Variable*>& uniforms);
-
-    void writeSetData(std::vector<const Variable*>& uniforms);
-
-    void writeGetKey();
-
-    void writeTest();
-
-    String fName;
-    String fFullName;
-    SectionAndParameterHelper fSectionAndParameterHelper;
-    String fExtraEmitCodeCode;
-    std::vector<String> fFormatArgs;
-    std::set<int> fWrittenTransformedCoords;
-    bool fNeedColorSpaceHelper = false;
-
-    typedef GLSLCodeGenerator INHERITED;
-};
-
-}
-
-#endif
diff --git a/src/sksl/SkSLCodeGenerator.h b/src/sksl/SkSLCodeGenerator.h
index 1f577b5..f6f9905 100644
--- a/src/sksl/SkSLCodeGenerator.h
+++ b/src/sksl/SkSLCodeGenerator.h
@@ -9,7 +9,6 @@
 #define SKSL_CODEGENERATOR
 
 #include "ir/SkSLProgram.h"
-#include "SkSLOutputStream.h"
 
 namespace SkSL {
 
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 593397b..39ac315 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -8,9 +8,7 @@
 #include "SkSLCompiler.h"
 
 #include "SkSLCFGGenerator.h"
-#include "SkSLCPPCodeGenerator.h"
 #include "SkSLGLSLCodeGenerator.h"
-#include "SkSLHCodeGenerator.h"
 #include "SkSLIRGenerator.h"
 #include "SkSLSPIRVCodeGenerator.h"
 #include "ir/SkSLExpression.h"
@@ -47,11 +45,6 @@
 #include "sksl_geom.include"
 ;
 
-static const char* SKSL_FP_INCLUDE =
-#include "sksl_fp.include"
-;
-
-
 namespace SkSL {
 
 Compiler::Compiler()
@@ -153,18 +146,12 @@
     ADD_TYPE(SamplerCubeArrayShadow);
     ADD_TYPE(GSampler2DArrayShadow);
     ADD_TYPE(GSamplerCubeArrayShadow);
-    ADD_TYPE(ColorSpaceXform);
 
     String skCapsName("sk_Caps");
     Variable* skCaps = new Variable(Position(), Modifiers(), skCapsName,
                                     *fContext.fSkCaps_Type, Variable::kGlobal_Storage);
     fIRGenerator->fSymbolTable->add(skCapsName, std::unique_ptr<Symbol>(skCaps));
 
-    String skArgsName("sk_Args");
-    Variable* skArgs = new Variable(Position(), Modifiers(), skArgsName,
-                                    *fContext.fSkArgs_Type, Variable::kGlobal_Storage);
-    fIRGenerator->fSymbolTable->add(skArgsName, std::unique_ptr<Symbol>(skArgs));
-
     Modifiers::Flag ignored1;
     std::vector<std::unique_ptr<ProgramElement>> ignored2;
     fIRGenerator->convertProgram(String(SKSL_INCLUDE), *fTypes, &ignored1, &ignored2);
@@ -791,6 +778,7 @@
     }
 }
 
+
 // returns true if this statement could potentially execute a break at the current level (we ignore
 // nested loops and switches, since any breaks inside of them will merely break the loop / switch)
 static bool contains_break(Statement& s) {
@@ -1109,9 +1097,6 @@
         case Program::kGeometry_Kind:
             fIRGenerator->convertProgram(String(SKSL_GEOM_INCLUDE), *fTypes, &ignored, &elements);
             break;
-        case Program::kFragmentProcessor_Kind:
-            fIRGenerator->convertProgram(String(SKSL_FP_INCLUDE), *fTypes, &ignored, &elements);
-            break;
     }
     fIRGenerator->fSymbolTable->markAllFunctionsBuiltin();
     Modifiers::Flag defaultPrecision;
@@ -1142,16 +1127,15 @@
     bool result = cg.generateCode();
     if (result) {
         spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
-        const String& data = buffer.str();
-        ASSERT(0 == data.size() % 4);
+        ASSERT(0 == buffer.size() % 4);
         auto dumpmsg = [](spv_message_level_t, const char*, const spv_position_t&, const char* m) {
             SkDebugf("SPIR-V validation error: %s\n", m);
         };
         tools.SetMessageConsumer(dumpmsg);
         // Verify that the SPIR-V we produced is valid. If this assert fails, check the logs prior
         // to the failure to see the validation errors.
-        ASSERT_RESULT(tools.Validate((const uint32_t*) data.c_str(), data.size() / 4));
-        out.write(data.c_str(), data.size());
+        ASSERT_RESULT(tools.Validate((const uint32_t*) buffer.data(), buffer.size() / 4));
+        out.write(buffer.data(), buffer.size());
     }
 #else
     SPIRVCodeGenerator cg(&fContext, &program, this, &out);
@@ -1165,7 +1149,7 @@
     StringStream buffer;
     bool result = this->toSPIRV(program, buffer);
     if (result) {
-        *out = buffer.str();
+        *out = String(buffer.data(), buffer.size());
     }
     return result;
 }
@@ -1181,24 +1165,11 @@
     StringStream buffer;
     bool result = this->toGLSL(program, buffer);
     if (result) {
-        *out = buffer.str();
+        *out = String(buffer.data(), buffer.size());
     }
     return result;
 }
 
-bool Compiler::toCPP(const Program& program, String name, OutputStream& out) {
-    CPPCodeGenerator cg(&fContext, &program, this, name, &out);
-    bool result = cg.generateCode();
-    this->writeErrorCount();
-    return result;
-}
-
-bool Compiler::toH(const Program& program, String name, OutputStream& out) {
-    HCodeGenerator cg(&program, this, name, &out);
-    bool result = cg.generateCode();
-    this->writeErrorCount();
-    return result;
-}
 
 void Compiler::error(Position position, String msg) {
     fErrorCount++;
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index 2acb559..bc9a196 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -18,16 +18,12 @@
 #include "SkSLErrorReporter.h"
 #include "SkSLIRGenerator.h"
 
-#define SK_FRAGCOLOR_BUILTIN           10001
-#define SK_IN_BUILTIN                  10002
-#define SK_INCOLOR_BUILTIN             10003
-#define SK_OUTCOLOR_BUILTIN            10004
-#define SK_TRANSFORMEDCOORDS2D_BUILTIN 10005
-#define SK_TEXTURESAMPLERS_BUILTIN     10006
-#define SK_FRAGCOORD_BUILTIN              15
-#define SK_VERTEXID_BUILTIN                5
-#define SK_CLIPDISTANCE_BUILTIN            3
-#define SK_INVOCATIONID_BUILTIN            8
+#define SK_FRAGCOLOR_BUILTIN    10001
+#define SK_IN_BUILTIN           10002
+#define SK_FRAGCOORD_BUILTIN       15
+#define SK_VERTEXID_BUILTIN         5
+#define SK_CLIPDISTANCE_BUILTIN     3
+#define SK_INVOCATIONID_BUILTIN     8
 
 namespace SkSL {
 
@@ -58,10 +54,6 @@
 
     bool toGLSL(const Program& program, String* out);
 
-    bool toCPP(const Program& program, String name, OutputStream& out);
-
-    bool toH(const Program& program, String name, OutputStream& out);
-
     void error(Position position, String msg) override;
 
     String errorText();
diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h
index 1155af4..53e5ea0 100644
--- a/src/sksl/SkSLContext.h
+++ b/src/sksl/SkSLContext.h
@@ -66,7 +66,8 @@
     , fSamplerExternalOES_Type(new Type(String("samplerExternalOES"), SpvDim2D, false, false,
                                         false, true))
     , fSamplerCube_Type(new Type(String("samplerCube"), SpvDimCube, false, false, false, true))
-    , fSampler2DRect_Type(new Type(String("sampler2DRect"), SpvDimRect, false, false, false, true))
+    , fSampler2DRect_Type(new Type(String("sampler2DRect"), SpvDimRect, false, false, false,
+                                   true))
     , fSampler1DArray_Type(new Type(String("sampler1DArray")))
     , fSampler2DArray_Type(new Type(String("sampler2DArray")))
     , fSamplerCubeArray_Type(new Type(String("samplerCubeArray")))
@@ -150,8 +151,6 @@
     , fBVec_Type(new Type(String("$bvec"), { fInvalid_Type.get(), fBVec2_Type.get(),
                                                fBVec3_Type.get(), fBVec4_Type.get() }))
     , fSkCaps_Type(new Type(String("$sk_Caps")))
-    , fSkArgs_Type(new Type(String("$sk_Args")))
-    , fColorSpaceXform_Type(new Type(String("colorSpaceXform"), *fFloat_Type, 4, 4))
     , fDefined_Expression(new Defined(*fInvalid_Type)) {}
 
     static std::vector<const Type*> static_type(const Type& t) {
@@ -226,6 +225,7 @@
     const std::unique_ptr<Type> fSampler2DArrayShadow_Type;
     const std::unique_ptr<Type> fSamplerCubeArrayShadow_Type;
 
+
     const std::unique_ptr<Type> fISampler2D_Type;
 
     const std::unique_ptr<Type> fImage2D_Type;
@@ -269,8 +269,6 @@
     const std::unique_ptr<Type> fBVec_Type;
 
     const std::unique_ptr<Type> fSkCaps_Type;
-    const std::unique_ptr<Type> fSkArgs_Type;
-    const std::unique_ptr<Type> fColorSpaceXform_Type;
 
     // dummy expression used to mark that a variable has a value during dataflow analysis (when it
     // could have several different values, or the analyzer is otherwise unable to assign it a
@@ -283,14 +281,14 @@
         Defined(const Type& type)
         : INHERITED(Position(), kDefined_Kind, type) {}
 
+        virtual String description() const override {
+            return String("<defined>");
+        }
+        
         bool hasSideEffects() const override {
             return false;
         }
 
-        String description() const override {
-            return String("<defined>");
-        }
-
         typedef Expression INHERITED;
     };
 };
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 4d3d3e3..4326f4c 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -34,7 +34,7 @@
 
 void GLSLCodeGenerator::writeLine(const char* s) {
     this->write(s);
-    fOut->writeText(fLineEnding);
+    fOut->write8('\n');
     fAtLineStart = true;
 }
 
@@ -108,9 +108,6 @@
         case Expression::kPostfix_Kind:
             this->writePostfixExpression((PostfixExpression&) expr, parentPrecedence);
             break;
-        case Expression::kSetting_Kind:
-            this->writeSetting((Setting&) expr);
-            break;
         case Expression::kSwizzle_Kind:
             this->writeSwizzle((Swizzle&) expr);
             break;
@@ -374,7 +371,7 @@
     }
 }
 
-GLSLCodeGenerator::Precedence GLSLCodeGenerator::GetBinaryPrecedence(Token::Kind op) {
+static GLSLCodeGenerator::Precedence get_binary_precedence(Token::Kind op) {
     switch (op) {
         case Token::STAR:         // fall through
         case Token::SLASH:        // fall through
@@ -416,7 +413,7 @@
 
 void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
                                               Precedence parentPrecedence) {
-    Precedence precedence = GetBinaryPrecedence(b.fOperator);
+    Precedence precedence = get_binary_precedence(b.fOperator);
     if (precedence >= parentPrecedence) {
         this->write("(");
     }
@@ -483,10 +480,6 @@
     this->write(to_string(f.fValue));
 }
 
-void GLSLCodeGenerator::writeSetting(const Setting& s) {
-    ABORT("internal error; setting was not folded to a constant during compilation\n");
-}
-
 void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
     this->writeType(f.fDeclaration.fReturnType);
     this->write(" " + f.fDeclaration.fName + "(");
@@ -524,7 +517,7 @@
 
     fOut = oldOut;
     this->write(fFunctionHeader);
-    this->write(buffer.str());
+    this->write(String(buffer.data(), buffer.size()));
 }
 
 void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
@@ -624,10 +617,6 @@
     this->writeLine(";");
 }
 
-void GLSLCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
-    this->writeExpression(value, kTopLevel_Precedence);
-}
-
 void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool global) {
     ASSERT(decl.fVars.size() > 0);
     bool wroteType = false;
@@ -651,7 +640,7 @@
         }
         if (var.fValue) {
             this->write(" = ");
-            this->writeVarInitializer(*var.fVar, *var.fValue);
+            this->writeExpression(*var.fValue, kTopLevel_Precedence);
         }
         if (!fFoundImageDecl && var.fVar->fType == *fContext.fImage2D_Type) {
             if (fProgram.fSettings.fCaps->imageLoadStoreExtensionString()) {
@@ -808,7 +797,10 @@
     this->write(";");
 }
 
-void GLSLCodeGenerator::writeHeader() {
+bool GLSLCodeGenerator::generateCode() {
+    OutputStream* rawOut = fOut;
+    fOut = &fHeader;
+    fProgramKind = fProgram.fKind;
     this->write(fProgram.fSettings.fCaps->versionDeclString());
     this->writeLine();
     for (const auto& e : fProgram.fElements) {
@@ -816,9 +808,8 @@
             this->writeExtension((Extension&) *e);
         }
     }
-}
-
-void GLSLCodeGenerator::writePrecisionModifier() {
+    StringStream body;
+    fOut = &body;
     if (fProgram.fSettings.fCaps->usesPrecisionModifiers()) {
         this->write("precision ");
         switch (fProgram.fDefaultPrecision) {
@@ -837,59 +828,47 @@
         }
         this->writeLine(" float;");
     }
-}
-
-void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
-    switch (e.fKind) {
-        case ProgramElement::kExtension_Kind:
-            break;
-        case ProgramElement::kVar_Kind: {
-            VarDeclarations& decl = (VarDeclarations&) e;
-            if (decl.fVars.size() > 0) {
-                int builtin = ((VarDeclaration&) *decl.fVars[0]).fVar->fModifiers.fLayout.fBuiltin;
-                if (builtin == -1) {
-                    // normal var
-                    this->writeVarDeclarations(decl, true);
-                    this->writeLine();
-                } else if (builtin == SK_FRAGCOLOR_BUILTIN &&
-                           fProgram.fSettings.fCaps->mustDeclareFragmentShaderOutput()) {
-                    this->write("out ");
-                    if (fProgram.fSettings.fCaps->usesPrecisionModifiers()) {
-                        this->write("mediump ");
-                    }
-                    this->writeLine("vec4 sk_FragColor;");
-                }
-            }
-            break;
-        }
-        case ProgramElement::kInterfaceBlock_Kind:
-            this->writeInterfaceBlock((InterfaceBlock&) e);
-            break;
-        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");
-    }
-}
-
-bool GLSLCodeGenerator::generateCode() {
-    OutputStream* rawOut = fOut;
-    fOut = &fHeader;
-    fProgramKind = fProgram.fKind;
-    this->writeHeader();
-    StringStream body;
-    fOut = &body;
-    this->writePrecisionModifier();
     for (const auto& e : fProgram.fElements) {
-        this->writeProgramElement(*e);
+        switch (e->fKind) {
+            case ProgramElement::kExtension_Kind:
+                break;
+            case ProgramElement::kVar_Kind: {
+                VarDeclarations& decl = (VarDeclarations&) *e;
+                if (decl.fVars.size() > 0) {
+                    ASSERT(decl.fVars[0]->fKind == Statement::kVarDeclaration_Kind);
+                    int builtin =
+                               ((VarDeclaration&) *decl.fVars[0]).fVar->fModifiers.fLayout.fBuiltin;
+                    if (builtin == -1) {
+                        // normal var
+                        this->writeVarDeclarations(decl, true);
+                        this->writeLine();
+                    } else if (builtin == SK_FRAGCOLOR_BUILTIN &&
+                               fProgram.fSettings.fCaps->mustDeclareFragmentShaderOutput()) {
+                        this->write("out ");
+                        if (fProgram.fSettings.fCaps->usesPrecisionModifiers()) {
+                            this->write("mediump ");
+                        }
+                        this->writeLine("vec4 sk_FragColor;");
+                    }
+                }
+                break;
+            }
+            case ProgramElement::kInterfaceBlock_Kind:
+                this->writeInterfaceBlock((InterfaceBlock&) *e);
+                break;
+            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");
+        }
     }
-    fOut = rawOut;
+    fOut = nullptr;
 
     write_stringstream(fHeader, *rawOut);
     write_stringstream(body, *rawOut);
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index aaf0369..032b70e 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -13,7 +13,6 @@
 #include <unordered_map>
 
 #include "SkSLCodeGenerator.h"
-#include "SkSLStringStream.h"
 #include "ir/SkSLBinaryExpression.h"
 #include "ir/SkSLBoolLiteral.h"
 #include "ir/SkSLConstructor.h"
@@ -33,7 +32,6 @@
 #include "ir/SkSLPostfixExpression.h"
 #include "ir/SkSLProgramElement.h"
 #include "ir/SkSLReturnStatement.h"
-#include "ir/SkSLSetting.h"
 #include "ir/SkSLStatement.h"
 #include "ir/SkSLSwitchStatement.h"
 #include "ir/SkSLSwizzle.h"
@@ -76,12 +74,11 @@
     GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
                       OutputStream* out)
     : INHERITED(program, errors, out)
-    , fLineEnding("\n")
     , fContext(*context) {}
 
-    bool generateCode() override;
+    virtual bool generateCode() override;
 
-protected:
+private:
     void write(const char* s);
 
     void writeLine();
@@ -92,10 +89,6 @@
 
     void writeLine(const String& s);
 
-    virtual void writeHeader();
-
-    virtual void writePrecisionModifier();
-
     void writeType(const Type& type);
 
     void writeExtension(const Extension& ext);
@@ -106,7 +99,7 @@
 
     void writeFunctionDeclaration(const FunctionDeclaration& f);
 
-    virtual void writeFunction(const FunctionDefinition& f);
+    void writeFunction(const FunctionDefinition& f);
 
     void writeLayout(const Layout& layout);
 
@@ -114,13 +107,11 @@
 
     void writeGlobalVars(const VarDeclaration& vs);
 
-    virtual void writeVarInitializer(const Variable& var, const Expression& value);
-
     void writeVarDeclarations(const VarDeclarations& decl, bool global);
 
     void writeFragCoord();
 
-    virtual void writeVariableReference(const VariableReference& ref);
+    void writeVariableReference(const VariableReference& ref);
 
     void writeExpression(const Expression& expr, Precedence parentPrecedence);
 
@@ -136,13 +127,11 @@
 
     void writeSwizzle(const Swizzle& swizzle);
 
-    static Precedence GetBinaryPrecedence(Token::Kind op);
-
-    virtual void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
+    void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
 
     void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
 
-    virtual void writeIndexExpression(const IndexExpression& expr);
+    void writeIndexExpression(const IndexExpression& expr);
 
     void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
 
@@ -154,8 +143,6 @@
 
     void writeFloatLiteral(const FloatLiteral& f);
 
-    virtual void writeSetting(const Setting& s);
-
     void writeStatement(const Statement& s);
 
     void writeStatements(const std::vector<std::unique_ptr<Statement>>& statements);
@@ -174,9 +161,6 @@
 
     void writeReturnStatement(const ReturnStatement& r);
 
-    virtual void writeProgramElement(const ProgramElement& e);
-
-    const char* fLineEnding;
     const Context& fContext;
     StringStream fHeader;
     String fFunctionHeader;
diff --git a/src/sksl/SkSLHCodeGenerator.cpp b/src/sksl/SkSLHCodeGenerator.cpp
deleted file mode 100644
index 0eb43df..0000000
--- a/src/sksl/SkSLHCodeGenerator.cpp
+++ /dev/null
@@ -1,236 +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.
- */
-
-#include "SkSLHCodeGenerator.h"
-
-#include "SkSLUtil.h"
-#include "ir/SkSLFunctionDeclaration.h"
-#include "ir/SkSLFunctionDefinition.h"
-#include "ir/SkSLSection.h"
-#include "ir/SkSLVarDeclarations.h"
-
-namespace SkSL {
-
-HCodeGenerator::HCodeGenerator(const Program* program, ErrorReporter* errors, String name,
-                               OutputStream* out)
-: INHERITED(program, errors, out)
-, fName(std::move(name))
-, fFullName(String::printf("Gr%s", fName.c_str()))
-, fSectionAndParameterHelper(*program, *errors) {}
-
-String HCodeGenerator::ParameterType(const Type& type) {
-    if (type.fName == "vec2") {
-        return "SkPoint";
-    } else if (type.fName == "ivec4") {
-        return "SkIRect";
-    } else if (type.fName == "vec4") {
-        return "SkRect";
-    } else if (type.fName == "mat4") {
-        return "SkMatrix44";
-    } else if (type.kind() == Type::kSampler_Kind) {
-        return "sk_sp<GrTextureProxy>";
-    } else if (type.fName == "colorSpaceXform") {
-        return "sk_sp<GrColorSpaceXform>";
-    }
-    return type.name();
-}
-
-String HCodeGenerator::FieldType(const Type& type) {
-    if (type.kind() == Type::kSampler_Kind) {
-        return "TextureSampler";
-    }
-    return ParameterType(type);
-}
-
-void HCodeGenerator::writef(const char* s, va_list va) {
-    static constexpr int BUFFER_SIZE = 1024;
-    char buffer[BUFFER_SIZE];
-    int length = vsnprintf(buffer, BUFFER_SIZE, s, va);
-    if (length < BUFFER_SIZE) {
-        fOut->write(buffer, length);
-    } else {
-        std::unique_ptr<char[]> heap(new char[length + 1]);
-        vsprintf(heap.get(), s, va);
-        fOut->write(heap.get(), length);
-    }
-}
-
-void HCodeGenerator::writef(const char* s, ...) {
-    va_list va;
-    va_start(va, s);
-    this->writef(s, va);
-    va_end(va);
-}
-
-bool HCodeGenerator::writeSection(const char* name, const char* prefix) {
-    const auto found = fSectionAndParameterHelper.fSections.find(String(name));
-    if (found != fSectionAndParameterHelper.fSections.end()) {
-        this->writef("%s%s", prefix, found->second->fText.c_str());
-        return true;
-    }
-    return false;
-}
-
-void HCodeGenerator::writeExtraConstructorParams(const char* separator) {
-    // super-simple parse, just assume the last token before a comma is the name of a parameter
-    // (which is true as long as there are no multi-parameter template types involved). Will replace
-    // this with something more robust if the need arises.
-    const auto found = fSectionAndParameterHelper.fSections.find(
-                                                                String(CONSTRUCTOR_PARAMS_SECTION));
-    if (found != fSectionAndParameterHelper.fSections.end()) {
-        const char* s = found->second->fText.c_str();
-        #define BUFFER_SIZE 64
-        char lastIdentifier[BUFFER_SIZE];
-        int lastIdentifierLength = 0;
-        bool foundBreak = false;
-        while (*s) {
-            char c = *s;
-            ++s;
-            if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
-                c == '_') {
-                if (foundBreak) {
-                    lastIdentifierLength = 0;
-                    foundBreak = false;
-                }
-                ASSERT(lastIdentifierLength < BUFFER_SIZE);
-                lastIdentifier[lastIdentifierLength] = c;
-                ++lastIdentifierLength;
-            } else {
-                foundBreak = true;
-                if (c == ',') {
-                    ASSERT(lastIdentifierLength < BUFFER_SIZE);
-                    lastIdentifier[lastIdentifierLength] = 0;
-                    this->writef("%s%s", separator, lastIdentifier);
-                    separator = ", ";
-                } else if (c != ' ' && c != '\t' && c != '\n' && c != '\r') {
-                    lastIdentifierLength = 0;
-                }
-            }
-        }
-        if (lastIdentifierLength) {
-            ASSERT(lastIdentifierLength < BUFFER_SIZE);
-            lastIdentifier[lastIdentifierLength] = 0;
-            this->writef("%s%s", separator, lastIdentifier);
-        }
-    }
-}
-
-void HCodeGenerator::writeMake() {
-    const char* separator;
-    if (!this->writeSection(MAKE_SECTION)) {
-        this->writef("    static sk_sp<GrFragmentProcessor> Make(");
-        separator = "";
-        for (const auto& param : fSectionAndParameterHelper.fParameters) {
-            this->writef("%s%s %s", separator, ParameterType(param->fType).c_str(),
-                         param->fName.c_str());
-            separator = ", ";
-        }
-        this->writeSection(CONSTRUCTOR_PARAMS_SECTION, separator);
-        this->writef(") {\n"
-                     "        return sk_sp<GrFragmentProcessor>(new %s(",
-                     fFullName.c_str());
-        separator = "";
-        for (const auto& param : fSectionAndParameterHelper.fParameters) {
-            this->writef("%s%s", separator, param->fName.c_str());
-            separator = ", ";
-        }
-        this->writeExtraConstructorParams(separator);
-        this->writef("));\n"
-                     "    }\n");
-    }
-}
-
-void HCodeGenerator::writeConstructor() {
-    if (this->writeSection(CONSTRUCTOR_SECTION)) {
-        return;
-    }
-    this->writef("    %s(", fFullName.c_str());
-    const char* separator = "";
-    for (const auto& param : fSectionAndParameterHelper.fParameters) {
-        this->writef("%s%s %s", separator, ParameterType(param->fType).c_str(),
-                     param->fName.c_str());
-        separator = ", ";
-    }
-    this->writeSection(CONSTRUCTOR_PARAMS_SECTION, separator);
-    this->writef(")\n"
-                 "    : INHERITED(");
-    if (!this->writeSection(OPTIMIZATION_FLAGS_SECTION, "(OptimizationFlags) ")) {
-        this->writef("kNone_OptimizationFlags");
-    }
-    this->writef(")");
-    this->writeSection(INITIALIZERS_SECTION, "\n    , ");
-    for (const auto& param : fSectionAndParameterHelper.fParameters) {
-        const char* name = param->fName.c_str();
-        if (param->fType.kind() == Type::kSampler_Kind) {
-            this->writef("\n    , %s(resourceProvider, std::move(%s))", FieldName(name).c_str(),
-                         name);
-        } else {
-            this->writef("\n    , %s(%s)", FieldName(name).c_str(), name);
-        }
-    }
-    this->writef(" {\n");
-    this->writeSection(CONSTRUCTOR_CODE_SECTION);
-    for (const auto& param : fSectionAndParameterHelper.fParameters) {
-        if (param->fType.kind() == Type::kSampler_Kind) {
-            this->writef("        this->addTextureSampler(&%s);\n",
-                         FieldName(param->fName.c_str()).c_str());
-        }
-    }
-    this->writef("        this->initClassID<%s>();\n"
-                 "    }\n",
-                 fFullName.c_str());
-}
-
-void HCodeGenerator::writeFields() {
-    this->writeSection(FIELDS_SECTION);
-    for (const auto& param : fSectionAndParameterHelper.fParameters) {
-        const char* name = param->fName.c_str();
-        this->writef("    %s %s;\n", FieldType(param->fType).c_str(), FieldName(name).c_str());
-    }
-}
-
-bool HCodeGenerator::generateCode() {
-    this->writef("/*\n"
-                 " * This file was autogenerated from %s.fp.\n"
-                 " */\n"
-                 "#ifndef %s_DEFINED\n"
-                 "#define %s_DEFINED\n"
-                 "#include \"GrFragmentProcessor.h\"\n"
-                 "#include \"GrCoordTransform.h\"\n"
-                 "#include \"effects/GrProxyMove.h\"\n",
-                 fFullName.c_str(), fFullName.c_str(), fFullName.c_str());
-    this->writeSection(HEADER_SECTION);
-    this->writef("class %s : public GrFragmentProcessor {\n"
-                 "public:\n",
-                 fFullName.c_str());
-    this->writeSection(CLASS_SECTION);
-    for (const auto& param : fSectionAndParameterHelper.fParameters) {
-        if (param->fType.kind() == Type::kSampler_Kind) {
-            continue;
-        }
-        const char* name = param->fName.c_str();
-        this->writef("%s %s() const { return %s; }\n",
-                     FieldType(param->fType).c_str(), name, FieldName(name).c_str());
-    }
-    this->writeMake();
-    this->writef("    const char* name() const override { return \"%s\"; }\n"
-                 "private:\n",
-                 fName.c_str());
-    this->writeConstructor();
-    this->writef("    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n"
-                 "    void onGetGLSLProcessorKey(const GrShaderCaps&,"
-                                                "GrProcessorKeyBuilder*) const override;\n"
-                 "    bool onIsEqual(const GrFragmentProcessor&) const override;\n"
-                 "    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;\n");
-    this->writeFields();
-    this->writef("    typedef GrFragmentProcessor INHERITED;\n"
-                 "};\n"
-                 "#endif\n");
-    return 0 == fErrors.errorCount();
-}
-
-} // namespace
diff --git a/src/sksl/SkSLHCodeGenerator.h b/src/sksl/SkSLHCodeGenerator.h
deleted file mode 100644
index 1025d7f..0000000
--- a/src/sksl/SkSLHCodeGenerator.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SKSL_HCODEGENERATOR
-#define SKSL_HCODEGENERATOR
-
-#include "SkSLCodeGenerator.h"
-#include "SkSLSectionAndParameterHelper.h"
-#include "ir/SkSLType.h"
-#include "ir/SkSLVariable.h"
-
-#include <cctype>
-
-namespace SkSL {
-
-class HCodeGenerator : public CodeGenerator {
-public:
-    HCodeGenerator(const Program* program, ErrorReporter* errors, String name, OutputStream* out);
-
-    bool generateCode() override;
-
-    static String ParameterType(const Type& type);
-
-    static String FieldType(const Type& type);
-
-    static String FieldName(const char* varName) {
-        return String::printf("f%c%s", toupper(varName[0]), varName + 1);
-    }
-
-private:
-    void writef(const char* s, va_list va) SKSL_PRINTF_LIKE(2, 0);
-
-    void writef(const char* s, ...) SKSL_PRINTF_LIKE(2, 3);
-
-    bool writeSection(const char* name, const char* prefix = "");
-
-    // given a @constructorParams section of e.g. 'int x, float y', writes out "<separator>x, y".
-    // Writes nothing (not even the separator) if there is no @constructorParams section.
-    void writeExtraConstructorParams(const char* separator);
-
-    void writeMake();
-
-    void writeConstructor();
-
-    void writeFields();
-
-    String fName;
-    String fFullName;
-    SectionAndParameterHelper fSectionAndParameterHelper;
-
-    typedef CodeGenerator INHERITED;
-};
-
-} // namespace SkSL
-
-#endif
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 78672cb..159ede4 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -42,7 +42,6 @@
 #include "ir/SkSLPostfixExpression.h"
 #include "ir/SkSLPrefixExpression.h"
 #include "ir/SkSLReturnStatement.h"
-#include "ir/SkSLSetting.h"
 #include "ir/SkSLSwitchCase.h"
 #include "ir/SkSLSwitchStatement.h"
 #include "ir/SkSLSwizzle.h"
@@ -105,11 +104,9 @@
                          ErrorReporter& errorReporter)
 : fContext(*context)
 , fCurrentFunction(nullptr)
-, fRootSymbolTable(symbolTable)
-, fSymbolTable(symbolTable)
+, fSymbolTable(std::move(symbolTable))
 , fLoopLevel(0)
 , fSwitchLevel(0)
-, fTmpCount(0)
 , fErrors(errorReporter) {}
 
 void IRGenerator::pushSymbolTable() {
@@ -120,10 +117,8 @@
     fSymbolTable = fSymbolTable->fParent;
 }
 
-static void fill_caps(const SKSL_CAPS_CLASS& caps,
-                      std::unordered_map<String, Program::Settings::Value>* capsMap) {
-#define CAP(name) capsMap->insert(std::make_pair(String(#name), \
-                                  Program::Settings::Value(caps.name())));
+static void fill_caps(const SKSL_CAPS_CLASS& caps, std::unordered_map<String, CapValue>* capsMap) {
+#define CAP(name) capsMap->insert(std::make_pair(String(#name), CapValue(caps.name())));
     CAP(fbFetchSupport);
     CAP(fbFetchNeedsCustomOutput);
     CAP(bindlessTextureSupport);
@@ -140,7 +135,6 @@
     CAP(mustEnableSpecificAdvBlendEqs);
     CAP(mustDeclareFragmentShaderOutput);
     CAP(canUseAnyFunctionInShader);
-    CAP(floatPrecisionVaries);
 #undef CAP
 }
 
@@ -679,12 +673,7 @@
         bool needInvocationIDWorkaround = fSettings->fCaps &&
                                           fSettings->fCaps->mustImplementGSInvocationsWithLoop() &&
                                           fInvocations != -1 && f.fName == "main";
-        ASSERT(!fExtraVars.size());
         std::unique_ptr<Block> body = this->convertBlock(*f.fBody);
-        for (auto& v : fExtraVars) {
-            body->fStatements.insert(body->fStatements.begin(), std::move(v));
-        }
-        fExtraVars.clear();
         fCurrentFunction = nullptr;
         if (!body) {
             return;
@@ -856,7 +845,6 @@
         }
         case Symbol::kVariable_Kind: {
             const Variable* var = (const Variable*) result;
-#ifndef SKSL_STANDALONE
             if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN) {
                 fInputs.fFlipY = true;
                 if (fSettings->fFlipY &&
@@ -865,7 +853,6 @@
                     fInputs.fRTHeight = true;
                 }
             }
-#endif
             // default to kRead_RefKind; this will be corrected later if the variable is written to
             return std::unique_ptr<VariableReference>(new VariableReference(
                                                                  identifier.fPosition,
@@ -889,13 +876,9 @@
         default:
             ABORT("unsupported symbol type %d\n", result->fKind);
     }
-}
 
-std::unique_ptr<Section> IRGenerator::convertSection(const ASTSection& s) {
-    return std::unique_ptr<Section>(new Section(s.fPosition, s.fName, s.fArgument, s.fText));
 }
 
-
 std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr,
                                                 const Type& type) {
     if (!expr) {
@@ -921,9 +904,6 @@
         ASSERT(ctor);
         return this->call(Position(), std::move(ctor), std::move(args));
     }
-    if (type == *fContext.fColorSpaceXform_Type && expr->fType == *fContext.fMat4x4_Type) {
-        return expr;
-    }
     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)));
@@ -1352,7 +1332,7 @@
             return nullptr;
         }
         if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifiers::kOut_Flag)) {
-            this->markWrittenTo(*arguments[i],
+            this->markWrittenTo(*arguments[i], 
                                 function.fParameters[i]->fModifiers.fFlags & Modifiers::kIn_Flag);
         }
     }
@@ -1393,87 +1373,6 @@
     return true;
 }
 
-std::unique_ptr<Expression> IRGenerator::applyColorSpace(std::unique_ptr<Expression> texture,
-                                                         const Variable* xform) {
-    // Before:
-    // vec4 color = texture(img, coords, xform);
-    // After:
-    // vec4 tmp;
-    // vec4 color = (tmp = texture(img, coords) ,
-    //               xform != mat4(1) ?
-    //                            vec4(clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a), tmp.a) :
-    //                            tmp);
-
-    // a few macros to keep line lengths manageable
-    #define EXPR std::unique_ptr<Expression>
-    #define REF(v) EXPR(new VariableReference(p, *v))
-    #define FLOAT(x) EXPR(new FloatLiteral(fContext, p, x))
-    using std::move;
-    Position p = Position();
-    // vec4 tmp;
-    Variable* tmp = new Variable(p, Modifiers(), "_tmp" + to_string(fTmpCount++), texture->fType,
-                                 Variable::kLocal_Storage);
-    fRootSymbolTable->takeOwnership(tmp);
-    std::vector<std::unique_ptr<VarDeclaration>> decls;
-    decls.emplace_back(new VarDeclaration(tmp, std::vector<std::unique_ptr<Expression>>(),
-                                          nullptr));
-    const Type& type = texture->fType;
-    fExtraVars.emplace_back(new VarDeclarationsStatement(std::unique_ptr<VarDeclarations>(
-                                       new VarDeclarations(p, &type, move(decls)))));
-    // tmp = texture
-    EXPR assignment = EXPR(new BinaryExpression(p,
-                                                EXPR(new VariableReference(p, *tmp,
-                                                                VariableReference::kWrite_RefKind)),
-                                                Token::EQ,
-                                                move(texture), type));
-    // 1.0
-    std::vector<EXPR> matArgs;
-    matArgs.push_back(FLOAT(1.0));
-    // mat4(1.0)
-    EXPR mat = EXPR(new Constructor(p, *fContext.fMat4x4_Type, move(matArgs)));
-    // <xform> != mat4(1.0)
-    EXPR matNeq = EXPR(new BinaryExpression(p, REF(xform), Token::NEQ, move(mat),
-                                            *fContext.fBool_Type));
-    // tmp.rgb
-    std::vector<int> rgb { 0, 1, 2 };
-    EXPR tmpRgb = EXPR(new Swizzle(fContext, REF(tmp), rgb));
-    // vec4(tmp.rgb, 1.0)
-    std::vector<EXPR> tmpVecArgs;
-    tmpVecArgs.push_back(move(tmpRgb));
-    tmpVecArgs.push_back(FLOAT(1.0));
-    EXPR tmpVec = EXPR(new Constructor(p, *fContext.fVec4_Type, move(tmpVecArgs)));
-    // xform * vec4(tmp.rgb, 1.0)
-    EXPR mul = EXPR(new BinaryExpression(p, REF(xform), Token::STAR, move(tmpVec),
-                                         *fContext.fVec4_Type));
-    // (xform * vec4(tmp.rgb, 1.0)).rgb
-    EXPR mulRGB = EXPR(new Swizzle(fContext, std::move(mul), rgb));
-    // tmp.a
-    std::vector<int> a { 3 };
-    EXPR tmpA = EXPR(new Swizzle(fContext, REF(tmp), a));
-    // clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a)
-    EXPR clamp = this->convertIdentifier(ASTIdentifier(p, "clamp"));
-    std::vector<EXPR> clampArgs;
-    clampArgs.push_back(move(mulRGB));
-    clampArgs.push_back(FLOAT(0));
-    clampArgs.push_back(move(tmpA));
-    EXPR clampCall = this->call(p, move(clamp), move(clampArgs));
-    // tmp.a
-    tmpA = EXPR(new Swizzle(fContext, REF(tmp), a));
-    // vec4(clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a), tmp.a)
-    std::vector<EXPR> finalVecArgs;
-    finalVecArgs.push_back(move(clampCall));
-    finalVecArgs.push_back(move(tmpA));
-    EXPR finalVec = EXPR(new Constructor(p, *fContext.fVec4_Type, move(finalVecArgs)));
-    // xform != mat4(1) ? vec4(clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a), tmp.a) : tmp)
-    EXPR ternary = EXPR(new TernaryExpression(p, move(matNeq), move(finalVec), REF(tmp)));
-    // (tmp = texture ,
-    //   xform != mat4(1) ? vec4(clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a), tmp.a) : tmp))
-    return EXPR(new BinaryExpression(p, move(assignment), Token::COMMA, move(ternary), type));
-    #undef EXPR
-    #undef REF
-    #undef FLOAT
-}
-
 std::unique_ptr<Expression> IRGenerator::call(Position position,
                                               std::unique_ptr<Expression> functionValue,
                                               std::vector<std::unique_ptr<Expression>> arguments) {
@@ -1487,17 +1386,6 @@
         return nullptr;
     }
     FunctionReference* ref = (FunctionReference*) functionValue.get();
-    if (ref->fFunctions[0]->fName == "texture" &&
-        arguments.back()->fType == *fContext.fColorSpaceXform_Type) {
-        std::unique_ptr<Expression> colorspace = std::move(arguments.back());
-        ASSERT(colorspace->fKind == Expression::kVariableReference_Kind);
-        arguments.pop_back();
-        return this->applyColorSpace(this->call(position,
-                                                std::move(functionValue),
-                                                std::move(arguments)),
-                                     &((VariableReference&) *colorspace).fVariable);
-    }
-
     int bestCost = INT_MAX;
     const FunctionDeclaration* best = nullptr;
     if (ref->fFunctions.size() > 1) {
@@ -1563,7 +1451,7 @@
                                 args[0]->fType.description() + "')");
         return nullptr;
     }
-    return std::unique_ptr<Expression>(new Constructor(position, type, std::move(args)));
+    return std::unique_ptr<Expression>(new Constructor(position, std::move(type), std::move(args)));
 }
 
 int component_count(const Type& type) {
@@ -1585,7 +1473,8 @@
     if (type.kind() == Type::kMatrix_Kind && args.size() == 1 &&
         args[0]->fType.kind() == Type::kMatrix_Kind) {
         // matrix from matrix is always legal
-        return std::unique_ptr<Expression>(new Constructor(position, type, std::move(args)));
+        return std::unique_ptr<Expression>(new Constructor(position, std::move(type),
+                                                           std::move(args)));
     }
     int actual = 0;
     int expected = type.rows() * type.columns();
@@ -1622,7 +1511,7 @@
             return nullptr;
         }
     }
-    return std::unique_ptr<Expression>(new Constructor(position, type, std::move(args)));
+    return std::unique_ptr<Expression>(new Constructor(position, std::move(type), std::move(args)));
 }
 
 std::unique_ptr<Expression> IRGenerator::convertConstructor(
@@ -1645,7 +1534,8 @@
                 return nullptr;
             }
         }
-        return std::unique_ptr<Expression>(new Constructor(position, type, std::move(args)));
+        return std::unique_ptr<Expression>(new Constructor(position, std::move(type),
+                                                           std::move(args)));
     } else if (kind == Type::kVector_Kind || kind == Type::kMatrix_Kind) {
         return this->convertCompoundConstructor(position, type, std::move(args));
     } else {
@@ -1837,21 +1727,16 @@
         fErrors.error(position, "unknown capability flag '" + name + "'");
         return nullptr;
     }
-    String fullName = "sk_Caps." + name;
-    return std::unique_ptr<Expression>(new Setting(position, fullName,
-                                                   found->second.literal(fContext, position)));
-}
-
-std::unique_ptr<Expression> IRGenerator::getArg(Position position, String name) {
-    auto found = fSettings->fArgs.find(name);
-    if (found == fSettings->fArgs.end()) {
-        fErrors.error(position, "unknown argument '" + name + "'");
-        return nullptr;
+    switch (found->second.fKind) {
+        case CapValue::kBool_Kind:
+            return std::unique_ptr<Expression>(new BoolLiteral(fContext, position,
+                                                               (bool) found->second.fValue));
+        case CapValue::kInt_Kind:
+            return std::unique_ptr<Expression>(new IntLiteral(fContext, position,
+                                                              found->second.fValue));
     }
-    String fullName = "sk_Args." + name;
-    return std::unique_ptr<Expression>(new Setting(position,
-                                                   fullName,
-                                                   found->second.literal(fContext, position)));
+    ASSERT(false);
+    return nullptr;
 }
 
 std::unique_ptr<Expression> IRGenerator::convertSuffixExpression(
@@ -1895,10 +1780,6 @@
                 return this->getCap(expression.fPosition,
                                     ((ASTFieldSuffix&) *expression.fSuffix).fField);
             }
-            if (base->fType == *fContext.fSkArgs_Type) {
-                return this->getArg(expression.fPosition,
-                                    ((ASTFieldSuffix&) *expression.fSuffix).fField);
-            }
             switch (base->fType.kind()) {
                 case Type::kVector_Kind:
                     return this->convertSwizzle(std::move(base),
@@ -2043,13 +1924,6 @@
                 }
                 break;
             }
-            case ASTDeclaration::kSection_Kind: {
-                std::unique_ptr<Section> s = this->convertSection((ASTSection&) decl);
-                if (s) {
-                    out->push_back(std::move(s));
-                }
-                break;
-            }
             case ASTDeclaration::kPrecision_Kind: {
                 *defaultPrecision = ((ASTPrecision&) decl).fPrecision;
                 break;
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index 3078a9e..29513d8 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -27,7 +27,6 @@
 #include "ast/SkSLASTModifiersDeclaration.h"
 #include "ast/SkSLASTPrefixExpression.h"
 #include "ast/SkSLASTReturnStatement.h"
-#include "ast/SkSLASTSection.h"
 #include "ast/SkSLASTStatement.h"
 #include "ast/SkSLASTSuffixExpression.h"
 #include "ast/SkSLASTSwitchStatement.h"
@@ -43,7 +42,6 @@
 #include "ir/SkSLModifiers.h"
 #include "ir/SkSLModifiersDeclaration.h"
 #include "ir/SkSLProgram.h"
-#include "ir/SkSLSection.h"
 #include "ir/SkSLSymbolTable.h"
 #include "ir/SkSLStatement.h"
 #include "ir/SkSLType.h"
@@ -52,6 +50,28 @@
 
 namespace SkSL {
 
+struct CapValue {
+    CapValue()
+    : fKind(kInt_Kind)
+    , fValue(-1) {
+        ASSERT(false);
+    }
+
+    CapValue(bool b)
+    : fKind(kBool_Kind)
+    , fValue(b) {}
+
+    CapValue(int i)
+    : fKind(kInt_Kind)
+    , fValue(i) {}
+
+    enum {
+        kBool_Kind,
+        kInt_Kind,
+    } fKind;
+    int fValue;
+};
+
 /**
  * Performs semantic analysis on an abstract syntax tree (AST) and produces the corresponding
  * (unoptimized) intermediate representation (IR).
@@ -75,7 +95,6 @@
                                              Token::Kind op,
                                              const Expression& right) const;
     Program::Inputs fInputs;
-    const Program::Settings* fSettings;
     const Context& fContext;
 
 private:
@@ -141,9 +160,7 @@
     Modifiers convertModifiers(const Modifiers& m);
     std::unique_ptr<Expression> convertPrefixExpression(const ASTPrefixExpression& expression);
     std::unique_ptr<Statement> convertReturn(const ASTReturnStatement& r);
-    std::unique_ptr<Section> convertSection(const ASTSection& e);
     std::unique_ptr<Expression> getCap(Position position, String name);
-    std::unique_ptr<Expression> getArg(Position position, String name);
     std::unique_ptr<Expression> convertSuffixExpression(const ASTSuffixExpression& expression);
     std::unique_ptr<Expression> convertField(std::unique_ptr<Expression> base,
                                              const String& field);
@@ -156,26 +173,16 @@
                                                  std::unique_ptr<Block> main,
                                                  std::vector<std::unique_ptr<ProgramElement>>* out);
 
-    /**
-     * Wraps an expression in code that applies a colorspace transformation to it. This is used
-     * to implement texture(sampler, coord, colorSpaceXForm).
-     */
-    std::unique_ptr<Expression> applyColorSpace(std::unique_ptr<Expression> texture,
-                                                const Variable* xform);
     void fixRectSampling(std::vector<std::unique_ptr<Expression>>& arguments);
     void checkValid(const Expression& expr);
     void markWrittenTo(const Expression& expr, bool readWrite);
 
     const FunctionDeclaration* fCurrentFunction;
-    std::unordered_map<String, Program::Settings::Value> fCapsMap;
-    std::shared_ptr<SymbolTable> fRootSymbolTable;
+    const Program::Settings* fSettings;
+    std::unordered_map<String, CapValue> fCapsMap;
     std::shared_ptr<SymbolTable> fSymbolTable;
-    // holds extra temp variable declarations needed for the current function
-    std::vector<std::unique_ptr<Statement>> fExtraVars;
     int fLoopLevel;
     int fSwitchLevel;
-    // count of temporary variables we have created
-    int fTmpCount;
     ErrorReporter& fErrors;
     int fInvocations;
 
diff --git a/src/sksl/SkSLMain.cpp b/src/sksl/SkSLMain.cpp
index ee868fb..1461bf9 100644
--- a/src/sksl/SkSLMain.cpp
+++ b/src/sksl/SkSLMain.cpp
@@ -5,28 +5,11 @@
  * found in the LICENSE file.
  */
 
+#include "stdio.h"
 #include <fstream>
 #include "SkSLCompiler.h"
 #include "SkSLFileOutputStream.h"
 
-// Given the path to a file (e.g. src/gpu/effects/GrFooFragmentProcessor.fp) and the expected
-// filename prefix and suffix (e.g. "Gr" and ".fp"), returns the "base name" of the
-// file (in this case, 'FooFragmentProcessor'). If no match, returns the empty string.
-static SkSL::String base_name(const char* fpPath, const char* prefix, const char* suffix) {
-    SkSL::String result;
-    const char* end = fpPath + strlen(fpPath);
-    const char* fileName = end;
-    // back up until we find a slash
-    while (fileName != fpPath && '/' != *(fileName - 1) && '\\' != *(fileName - 1)) {
-        --fileName;
-    }
-    if (!strncmp(fileName, prefix, strlen(prefix)) &&
-        !strncmp(end - strlen(suffix), suffix, strlen(suffix))) {
-        result.append(fileName + strlen(prefix), end - fileName - strlen(prefix) - strlen(suffix));
-    }
-    return result;
-}
-
 /**
  * Very simple standalone executable to facilitate testing.
  */
@@ -36,17 +19,15 @@
         exit(1);
     }
     SkSL::Program::Kind kind;
-    String input(argv[1]);
-    if (input.endsWith(".vert")) {
+    size_t len = strlen(argv[1]);
+    if (len > 5 && !strcmp(argv[1] + strlen(argv[1]) - 5, ".vert")) {
         kind = SkSL::Program::kVertex_Kind;
-    } else if (input.endsWith(".frag")) {
+    } else if (len > 5 && !strcmp(argv[1] + strlen(argv[1]) - 5, ".frag")) {
         kind = SkSL::Program::kFragment_Kind;
-    } else if (input.endsWith(".geom")) {
+    } else if (len > 5 && !strcmp(argv[1] + strlen(argv[1]) - 5, ".geom")) {
         kind = SkSL::Program::kGeometry_Kind;
-    } else if (input.endsWith(".fp")) {
-        kind = SkSL::Program::kFragmentProcessor_Kind;
     } else {
-        printf("input filename must end in '.vert', '.frag', '.geom', or '.fp'\n");
+        printf("input filename must end in '.vert', '.frag', or '.geom'\n");
         exit(1);
     }
 
@@ -59,7 +40,6 @@
         exit(2);
     }
     SkSL::Program::Settings settings;
-    settings.fArgs.insert(std::make_pair("gpImplementsDistanceVector", 1));
     SkSL::String name(argv[2]);
     if (name.endsWith(".spirv")) {
         SkSL::FileOutputStream out(argv[2]);
@@ -93,41 +73,7 @@
             printf("error writing '%s'\n", argv[2]);
             exit(4);
         }
-    } else if (name.endsWith(".h")) {
-        SkSL::FileOutputStream out(argv[2]);
-        SkSL::Compiler compiler;
-        if (!out.isValid()) {
-            printf("error writing '%s'\n", argv[2]);
-            exit(4);
-        }
-        settings.fReplaceSettings = false;
-        std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, text, settings);
-        if (!program || !compiler.toH(*program, base_name(argv[1], "Gr", ".fp"), out)) {
-            printf("%s", compiler.errorText().c_str());
-            exit(3);
-        }
-        if (!out.close()) {
-            printf("error writing '%s'\n", argv[2]);
-            exit(4);
-        }
-    } else if (name.endsWith(".cpp")) {
-        SkSL::FileOutputStream out(argv[2]);
-        SkSL::Compiler compiler;
-        if (!out.isValid()) {
-            printf("error writing '%s'\n", argv[2]);
-            exit(4);
-        }
-        settings.fReplaceSettings = false;
-        std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, text, settings);
-        if (!program || !compiler.toCPP(*program, base_name(argv[1], "Gr", ".fp"), out)) {
-            printf("%s", compiler.errorText().c_str());
-            exit(3);
-        }
-        if (!out.close()) {
-            printf("error writing '%s'\n", argv[2]);
-            exit(4);
-        }
     } else {
-        printf("expected output filename to end with '.spirv', '.glsl', '.cpp', or '.h'");
+        printf("expected output filename to end with '.spirv' or '.glsl'");
     }
 }
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 18ca311..5e8ec63 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -52,7 +52,6 @@
 #include "ast/SkSLASTPrecision.h"
 #include "ast/SkSLASTPrefixExpression.h"
 #include "ast/SkSLASTReturnStatement.h"
-#include "ast/SkSLASTSection.h"
 #include "ast/SkSLASTStatement.h"
 #include "ast/SkSLASTSuffixExpression.h"
 #include "ast/SkSLASTSwitchCase.h"
@@ -114,7 +113,7 @@
     layoutlex_destroy(fLayoutScanner);
 }
 
-/* (precision | directive | section | declaration)* END_OF_FILE */
+/* (precision | directive | declaration)* END_OF_FILE */
 std::vector<std::unique_ptr<ASTDeclaration>> Parser::file() {
     std::vector<std::unique_ptr<ASTDeclaration>> result;
     for (;;) {
@@ -135,13 +134,6 @@
                 }
                 break;
             }
-            case Token::SECTION: {
-                std::unique_ptr<ASTDeclaration> section = this->section();
-                if (section) {
-                    result.push_back(std::move(section));
-                }
-                break;
-            }
             default: {
                 std::unique_ptr<ASTDeclaration> decl = this->declaration();
                 if (!decl) {
@@ -153,7 +145,7 @@
     }
 }
 
-Token Parser::nextRawToken() {
+Token Parser::nextToken() {
     if (fPushback.fKind != Token::INVALID_TOKEN) {
         Token result = fPushback;
         fPushback.fKind = Token::INVALID_TOKEN;
@@ -161,16 +153,25 @@
         return result;
     }
     int token = sksllex(fScanner);
-    return Token(Position(skslget_lineno(fScanner), -1), (Token::Kind) token,
-                 String(skslget_text(fScanner)));
-}
-
-Token Parser::nextToken() {
-    Token token;
-    do {
-        token = this->nextRawToken();
-    } while (token.fKind == Token::WHITESPACE);
-    return token;
+    String text;
+    switch ((Token::Kind) token) {
+        case Token::IDENTIFIER:    // fall through
+        case Token::INT_LITERAL:   // fall through
+        case Token::FLOAT_LITERAL: // fall through
+        case Token::DIRECTIVE:
+            text = String(skslget_text(fScanner));
+            break;
+        default:
+#ifdef SK_DEBUG
+            text = String(skslget_text(fScanner));
+#endif
+            break;
+    }
+    Position p = Position(skslget_lineno(fScanner), -1);
+    if (token == Token::INVALID_TOKEN) {
+        this->error(p, "invalid token: '" + text + "'");
+    }
+    return Token(p, (Token::Kind) token, text);
 }
 
 void Parser::pushback(Token t) {
@@ -295,56 +296,6 @@
     }
 }
 
-/* SECTION LBRACE (LPAREN IDENTIFIER RPAREN)? <any sequence of tokens with balanced braces>
-   RBRACE */
-std::unique_ptr<ASTDeclaration> Parser::section() {
-    Token start;
-    if (!this->expect(Token::SECTION, "a section token", &start)) {
-        return nullptr;
-    }
-    String argument;
-    if (this->peek().fKind == Token::LPAREN) {
-        this->nextToken();
-        Token argToken;
-        if (!this->expect(Token::IDENTIFIER, "an identifier", &argToken)) {
-            return nullptr;
-        }
-        argument = argToken.fText;
-        if (!this->expect(Token::RPAREN, "')'")) {
-            return nullptr;
-        }
-    }
-    if (!this->expect(Token::LBRACE, "'{'")) {
-        return nullptr;
-    }
-    String text;
-    int level = 1;
-    for (;;) {
-        Token next = this->nextRawToken();
-        switch (next.fKind) {
-            case Token::LBRACE:
-                ++level;
-                break;
-            case Token::RBRACE:
-                --level;
-                break;
-            case Token::END_OF_FILE:
-                this->error(start.fPosition, "reached end of file while parsing section");
-                return nullptr;
-            default:
-                break;
-        }
-        if (!level) {
-            break;
-        }
-        text += next.fText;
-    }
-    return std::unique_ptr<ASTDeclaration>(new ASTSection(start.fPosition,
-                                                          String(start.fText.c_str() + 1),
-                                                          argument,
-                                                          text));
-}
-
 /* modifiers (structVarDeclaration | type IDENTIFIER ((LPAREN parameter
    (COMMA parameter)* RPAREN (block | SEMICOLON)) | SEMICOLON) | interfaceBlock) */
 std::unique_ptr<ASTDeclaration> Parser::declaration() {
@@ -593,61 +544,6 @@
     return -1;
 }
 
-/** EQ <any sequence of tokens with balanced parentheses and no top-level comma> */
-String Parser::layoutCode() {
-    if (!this->expect(Token::EQ, "'='")) {
-        return "";
-    }
-    Token start = this->peek();
-    String code;
-    int level = 1;
-    bool done = false;
-    while (!done) {
-        Token next = this->peek();
-        switch (next.fKind) {
-            case Token::LPAREN:
-                ++level;
-                break;
-            case Token::RPAREN:
-                --level;
-                break;
-            case Token::COMMA:
-                if (level == 1) {
-                    done = true;
-                }
-                break;
-            case Token::END_OF_FILE:
-                this->error(start.fPosition, "reached end of file while parsing layout");
-                return nullptr;
-            default:
-                break;
-        }
-        if (!level) {
-            done = true;
-        }
-        if (!done) {
-            code += this->nextRawToken().fText;
-        }
-    }
-    return code;
-}
-
-/** (EQ IDENTIFIER('identity'))? */
-Layout::Key Parser::layoutKey() {
-    if (this->peek().fKind == Token::EQ) {
-        this->expect(Token::EQ, "'='");
-        Token key;
-        if (this->expect(Token::IDENTIFIER, "an identifer", &key)) {
-            if (key.fText == "identity") {
-                return Layout::kIdentity_Key;
-            } else {
-                this->error(key.fPosition, "unsupported layout key");
-            }
-        }
-    }
-    return Layout::kKey_Key;
-}
-
 /* LAYOUT LPAREN IDENTIFIER (EQ INT_LITERAL)? (COMMA IDENTIFIER (EQ INT_LITERAL)?)* RPAREN */
 Layout Parser::layout() {
     int location = -1;
@@ -665,13 +561,11 @@
     Layout::Primitive primitive = Layout::kUnspecified_Primitive;
     int maxVertices = -1;
     int invocations = -1;
-    String when;
-    Layout::Key key = Layout::kNo_Key;
     if (this->checkNext(Token::LAYOUT)) {
         if (!this->expect(Token::LPAREN, "'('")) {
             return Layout(location, offset, binding, index, set, builtin, inputAttachmentIndex,
                           originUpperLeft, overrideCoverage, blendSupportAllEquations, format,
-                          pushConstant, primitive, maxVertices, invocations, when, key);
+                          pushConstant, primitive, maxVertices, invocations);
         }
         for (;;) {
             Token t = this->nextToken();
@@ -741,12 +635,6 @@
                     case Token::INVOCATIONS:
                         invocations = this->layoutInt();
                         break;
-                    case Token::WHEN:
-                        when = this->layoutCode();
-                        break;
-                    case Token::KEY:
-                        key = this->layoutKey();
-                        break;
                 }
             } else if (Layout::ReadFormat(t.fText, &format)) {
                // AST::ReadFormat stored the result in 'format'.
@@ -764,7 +652,7 @@
     }
     return Layout(location, offset, binding, index, set, builtin, inputAttachmentIndex,
                   originUpperLeft, overrideCoverage, blendSupportAllEquations, format,
-                  pushConstant, primitive, maxVertices, invocations, when, key);
+                  pushConstant, primitive, maxVertices, invocations);
 }
 
 /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE |
diff --git a/src/sksl/SkSLParser.h b/src/sksl/SkSLParser.h
index e820484..2f55b34 100644
--- a/src/sksl/SkSLParser.h
+++ b/src/sksl/SkSLParser.h
@@ -13,7 +13,6 @@
 #include <unordered_map>
 #include <unordered_set>
 #include "SkSLErrorReporter.h"
-#include "ir/SkSLLayout.h"
 #include "SkSLToken.h"
 
 struct yy_buffer_state;
@@ -43,6 +42,7 @@
 struct ASTType;
 struct ASTWhileStatement;
 struct ASTVarDeclarations;
+struct Layout;
 struct Modifiers;
 class SymbolTable;
 
@@ -64,12 +64,7 @@
 
 private:
     /**
-     * Return the next token, including whitespace tokens, from the parse stream.
-     */
-    Token nextRawToken();
-
-    /**
-     * Return the next non-whitespace token from the parse stream.
+     * Return the next token from the parse stream.
      */
     Token nextToken();
 
@@ -81,7 +76,7 @@
     void pushback(Token t);
 
     /**
-     * Returns the next non-whitespace token without consuming it from the stream.
+     * Returns the next token without consuming it from the stream.
      */
     Token peek();
 
@@ -92,8 +87,8 @@
     bool checkNext(Token::Kind kind, Token* result = nullptr);
 
     /**
-     * Reads the next non-whitespace token and generates an error if it is not the expected type.
-     * The 'expected' string is part of the error message, which reads:
+     * Reads the next token and generates an error if it is not the expected type. The 'expected'
+     * string is part of the error message, which reads:
      *
      * "expected <expected>, but found '<actual text>'"
      *
@@ -120,8 +115,6 @@
 
     std::unique_ptr<ASTDeclaration> directive();
 
-    std::unique_ptr<ASTDeclaration> section();
-
     std::unique_ptr<ASTDeclaration> declaration();
 
     std::unique_ptr<ASTVarDeclarations> varDeclarations();
@@ -138,10 +131,6 @@
 
     int layoutInt();
 
-    String layoutCode();
-
-    Layout::Key layoutKey();
-
     Layout layout();
 
     Modifiers modifiers();
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index 94e8a58..fda9820 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -1906,7 +1906,7 @@
             Type intfStruct(Position(), name, fields);
             Layout layout(-1, -1, 1, -1, -1, -1, -1, false, false, false,
                           Layout::Format::kUnspecified, false, Layout::kUnspecified_Primitive, -1,
-                          -1, "", Layout::kNo_Key);
+                          -1);
             Variable* intfVar = new Variable(Position(),
                                              Modifiers(layout, Modifiers::kUniform_Flag),
                                              name,
@@ -2948,8 +2948,6 @@
         case Program::kGeometry_Kind:
             this->writeWord(SpvExecutionModelGeometry, out);
             break;
-        default:
-            ABORT("cannot write this kind of program to SPIR-V\n");
     }
     this->writeWord(fFunctionMap[main], out);
     this->writeString(main->fName.c_str(), out);
diff --git a/src/sksl/SkSLSectionAndParameterHelper.h b/src/sksl/SkSLSectionAndParameterHelper.h
deleted file mode 100644
index 81e5f3b..0000000
--- a/src/sksl/SkSLSectionAndParameterHelper.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SKSL_SECTIONANDPARAMETERHELPER
-#define SKSL_SECTIONANDPARAMETERHELPER
-
-#include "SkSLErrorReporter.h"
-#include "ir/SkSLProgram.h"
-#include "ir/SkSLSection.h"
-#include "ir/SkSLVarDeclarations.h"
-#include <unordered_map>
-#include <vector>
-
-namespace SkSL {
-
-#define CLASS_SECTION              "class"
-#define CPP_SECTION                "cpp"
-#define HEADER_SECTION             "header"
-#define CONSTRUCTOR_PARAMS_SECTION "constructorParams"
-#define CONSTRUCTOR_SECTION        "constructor"
-#define CONSTRUCTOR_CODE_SECTION   "constructorCode"
-#define INITIALIZERS_SECTION       "initializers"
-#define EMIT_CODE_SECTION          "emitCode"
-#define FIELDS_SECTION             "fields"
-#define MAKE_SECTION               "make"
-#define OPTIMIZATION_FLAGS_SECTION "optimizationFlags"
-#define SET_DATA_SECTION           "setData"
-#define TEST_CODE_SECTION          "test"
-
-class SectionAndParameterHelper {
-public:
-    SectionAndParameterHelper(const Program& program, ErrorReporter& errors) {
-        for (const auto& p : program.fElements) {
-            switch (p->fKind) {
-                case ProgramElement::kVar_Kind: {
-                    const VarDeclarations* decls = (const VarDeclarations*) p.get();
-                    for (const auto& raw : decls->fVars) {
-                        const VarDeclaration& decl = (VarDeclaration&) *raw;
-                        if (IsParameter(*decl.fVar)) {
-                            fParameters.push_back(decl.fVar);
-                        }
-                    }
-                    break;
-                }
-                case ProgramElement::kSection_Kind: {
-                    const Section* s = (const Section*) p.get();
-                    if (IsSupportedSection(s->fName.c_str())) {
-                        if (SectionAcceptsArgument(s->fName.c_str())) {
-                            if (!s->fArgument.size()) {
-                                errors.error(s->fPosition,
-                                             ("section '@" + s->fName +
-                                              "' requires one parameter").c_str());
-                            }
-                        } else if (s->fArgument.size()) {
-                            errors.error(s->fPosition,
-                                         ("section '@" + s->fName + "' has no parameters").c_str());
-                        }
-                    } else {
-                        errors.error(s->fPosition,
-                                     ("unsupported section '@" + s->fName + "'").c_str());
-                    }
-                    if (fSections.find(s->fName) != fSections.end()) {
-                        errors.error(s->fPosition,
-                                     ("duplicate section '@" + s->fName + "'").c_str());
-                    }
-                    fSections[s->fName] = s;
-                    break;
-                }
-                default:
-                    break;
-            }
-        }
-    }
-
-    static bool IsParameter(const Variable& var) {
-        return (var.fModifiers.fFlags & Modifiers::kIn_Flag) &&
-               -1 == var.fModifiers.fLayout.fBuiltin;
-    }
-
-    static bool IsSupportedSection(const char* name) {
-        return !strcmp(name, CLASS_SECTION) ||
-               !strcmp(name, CPP_SECTION) ||
-               !strcmp(name, HEADER_SECTION) ||
-               !strcmp(name, CONSTRUCTOR_SECTION) ||
-               !strcmp(name, CONSTRUCTOR_CODE_SECTION) ||
-               !strcmp(name, CONSTRUCTOR_PARAMS_SECTION) ||
-               !strcmp(name, EMIT_CODE_SECTION) ||
-               !strcmp(name, FIELDS_SECTION) ||
-               !strcmp(name, INITIALIZERS_SECTION) ||
-               !strcmp(name, MAKE_SECTION) ||
-               !strcmp(name, OPTIMIZATION_FLAGS_SECTION) ||
-               !strcmp(name, SET_DATA_SECTION) ||
-               !strcmp(name, TEST_CODE_SECTION);
-    }
-
-    static bool SectionAcceptsArgument(const char* name) {
-        return !strcmp(name, SET_DATA_SECTION) ||
-               !strcmp(name, TEST_CODE_SECTION);
-    }
-
-    std::vector<const Variable*> fParameters;
-    std::unordered_map<String, const Section*> fSections;
-};
-
-} // namespace SkSL
-
-#endif
diff --git a/src/sksl/SkSLString.cpp b/src/sksl/SkSLString.cpp
index fb8fd56..9b2c178 100644
--- a/src/sksl/SkSLString.cpp
+++ b/src/sksl/SkSLString.cpp
@@ -40,16 +40,15 @@
 #endif
     #define BUFFER_SIZE 256
     char buffer[BUFFER_SIZE];
-    va_list reuse;
-    va_copy(reuse, args);
     size_t size = VSNPRINTF(buffer, BUFFER_SIZE, fmt, args);
     if (BUFFER_SIZE >= size) {
         this->append(buffer, size);
     } else {
-        auto newBuffer = std::unique_ptr<char[]>(new char[size + 1]);
-        VSNPRINTF(newBuffer.get(), size + 1, fmt, reuse);
+        auto newBuffer = std::unique_ptr<char[]>(new char[size]);
+        VSNPRINTF(newBuffer.get(), size, fmt, args);
         this->append(newBuffer.get(), size);
     }
+    va_end(args);
 }
 
 
diff --git a/src/sksl/SkSLStringStream.h b/src/sksl/SkSLStringStream.h
index a869066..9061432 100644
--- a/src/sksl/SkSLStringStream.h
+++ b/src/sksl/SkSLStringStream.h
@@ -28,8 +28,12 @@
         fBuffer.append((const char*) s, size);
     }
 
-    const String& str() const {
-        return fBuffer;
+    const char* data() const {
+        return fBuffer.c_str();
+    }
+
+    size_t size() const {
+        return fBuffer.size();
     }
 
     void reset() {
@@ -50,33 +54,42 @@
 class StringStream : public OutputStream {
 public:
     void write8(uint8_t b) override {
+        SkASSERT(!fData);
         fStream.write8(b);
     }
 
     void writeText(const char* s) override {
+        SkASSERT(!fData);
         fStream.writeText(s);
     }
 
     void write(const void* s, size_t size) override {
+        SkASSERT(!fData);
         fStream.write(s, size);
     }
 
-    const String& str() const {
-        if (!fString.size()) {
-            sk_sp<SkData> data = fStream.detachAsData();
-            fString = String((const char*) data->data(), data->size());
+    const char* data() const {
+        if (!fData) {
+            fData = fStream.detachAsData();
         }
-        return fString;
+        return (const char*) fData->data();
+    }
+
+    size_t size() const {
+        if (!fData) {
+            fData = fStream.detachAsData();
+        }
+        return fData->size();
     }
 
     void reset() {
         fStream.reset();
-        fString = "";
+        fData = nullptr;
     }
 
 private:
     mutable SkDynamicMemoryWStream fStream;
-    mutable String fString;
+    mutable sk_sp<SkData> fData;
 };
 
 #endif // SKSL_STANDALONE
diff --git a/src/sksl/SkSLToken.h b/src/sksl/SkSLToken.h
index 2857a82..92193b9 100644
--- a/src/sksl/SkSLToken.h
+++ b/src/sksl/SkSLToken.h
@@ -24,7 +24,6 @@
 struct Token {
     enum Kind {
         END_OF_FILE,
-        WHITESPACE,
         IDENTIFIER,
         INT_LITERAL,
         FLOAT_LITERAL,
@@ -78,8 +77,6 @@
         LOGICALXOREQ,
         LOGICALANDEQ,
         SEMICOLON,
-        ARROW,
-        COLONCOLON,
         IF,
         STATIC_IF,
         ELSE,
@@ -114,7 +111,6 @@
         STRUCT,
         LAYOUT,
         DIRECTIVE,
-        SECTION,
         PRECISION,
         LOCATION,
         OFFSET,
@@ -136,8 +132,6 @@
         TRIANGLES_ADJACENCY,
         MAX_VERTICES,
         INVOCATIONS,
-        WHEN,
-        KEY,
         INVALID_TOKEN
     };
 
diff --git a/src/sksl/SkSLUtil.cpp b/src/sksl/SkSLUtil.cpp
index 49d37e3..c715cf1 100644
--- a/src/sksl/SkSLUtil.cpp
+++ b/src/sksl/SkSLUtil.cpp
@@ -27,7 +27,7 @@
 }
 
 void write_stringstream(const StringStream& s, OutputStream& out) {
-    out.write(s.str().c_str(), s.str().size());
+    out.write(s.data(), s.size());
 }
 
 } // namespace
diff --git a/src/sksl/SkSLUtil.h b/src/sksl/SkSLUtil.h
index 64f1e81..b56ae16 100644
--- a/src/sksl/SkSLUtil.h
+++ b/src/sksl/SkSLUtil.h
@@ -135,10 +135,6 @@
         return false;
     }
 
-    bool floatPrecisionVaries() const {
-        return false;
-    }
-
     const char* shaderDerivativeExtensionString() const {
         return nullptr;
     }
@@ -214,7 +210,6 @@
         result->fVersionDeclString = "#version 400";
         result->fShaderDerivativeSupport = true;
         result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
-        result->fUsesPrecisionModifiers = true;
         return result;
     }
 
diff --git a/src/sksl/ast/SkSLASTDeclaration.h b/src/sksl/ast/SkSLASTDeclaration.h
index 873c6b2..0395ef9 100644
--- a/src/sksl/ast/SkSLASTDeclaration.h
+++ b/src/sksl/ast/SkSLASTDeclaration.h
@@ -22,8 +22,7 @@
         kInterfaceBlock_Kind,
         kExtension_Kind,
         kPrecision_Kind,
-        kModifiers_Kind,
-        kSection_Kind
+        kModifiers_Kind
     };
 
     ASTDeclaration(Position position, Kind kind)
diff --git a/src/sksl/ast/SkSLASTFunction.h b/src/sksl/ast/SkSLASTFunction.h
index 36d8a3a..0dff3ae 100644
--- a/src/sksl/ast/SkSLASTFunction.h
+++ b/src/sksl/ast/SkSLASTFunction.h
@@ -20,7 +20,7 @@
  */
 struct ASTFunction : public ASTDeclaration {
     ASTFunction(Position position, Modifiers modifiers,  std::unique_ptr<ASTType> returnType,
-                String name, std::vector<std::unique_ptr<ASTParameter>> parameters,
+                String name, std::vector<std::unique_ptr<ASTParameter>> parameters, 
                 std::unique_ptr<ASTBlock> body)
     : INHERITED(position, kFunction_Kind)
     , fModifiers(modifiers)
diff --git a/src/sksl/ast/SkSLASTSection.h b/src/sksl/ast/SkSLASTSection.h
deleted file mode 100644
index d0887e2..0000000
--- a/src/sksl/ast/SkSLASTSection.h
+++ /dev/null
@@ -1,43 +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_ASTSECTION
-#define SKSL_ASTSECTION
-
-#include "SkSLASTDeclaration.h"
-
-namespace SkSL {
-
-/**
- * A section declaration (e.g. @body { body code here })..
- */
-struct ASTSection : public ASTDeclaration {
-    ASTSection(Position position, String name, String arg, String text)
-    : INHERITED(position, kSection_Kind)
-    , fName(std::move(name))
-    , fArgument(std::move(arg))
-    , fText(std::move(text)) {}
-
-    String description() const override {
-        String result = "@" + fName;
-        if (fArgument.size()) {
-            result += "(" + fArgument + ")";
-        }
-        result += " { " + fText + " }";
-        return result;
-    }
-
-    const String fName;
-    const String fArgument;
-    const String fText;
-
-    typedef ASTDeclaration INHERITED;
-};
-
-} // namespace
-
-#endif
diff --git a/src/sksl/ir/SkSLExpression.h b/src/sksl/ir/SkSLExpression.h
index 89a1a1e..07dad1d 100644
--- a/src/sksl/ir/SkSLExpression.h
+++ b/src/sksl/ir/SkSLExpression.h
@@ -36,7 +36,6 @@
         kIndex_Kind,
         kPrefix_Kind,
         kPostfix_Kind,
-        kSetting_Kind,
         kSwizzle_Kind,
         kVariableReference_Kind,
         kTernary_Kind,
diff --git a/src/sksl/ir/SkSLFunctionDeclaration.h b/src/sksl/ir/SkSLFunctionDeclaration.h
index 64236d3..8704c9a 100644
--- a/src/sksl/ir/SkSLFunctionDeclaration.h
+++ b/src/sksl/ir/SkSLFunctionDeclaration.h
@@ -71,7 +71,7 @@
     bool determineFinalTypes(const std::vector<std::unique_ptr<Expression>>& arguments,
                              std::vector<const Type*>* outParameterTypes,
                              const Type** outReturnType) const {
-        ASSERT(arguments.size() == fParameters.size());
+        assert(arguments.size() == fParameters.size());
         int genericIndex = -1;
         for (size_t i = 0; i < arguments.size(); i++) {
             if (fParameters[i]->fType.kind() == Type::kGeneric_Kind) {
@@ -93,7 +93,7 @@
             }
         }
         if (fReturnType.kind() == Type::kGeneric_Kind) {
-            ASSERT(genericIndex != -1);
+            assert(genericIndex != -1);
             *outReturnType = fReturnType.coercibleTypes()[genericIndex];
         } else {
             *outReturnType = &fReturnType;
diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h
index 8bf0472..3a8416ac 100644
--- a/src/sksl/ir/SkSLLayout.h
+++ b/src/sksl/ir/SkSLLayout.h
@@ -8,7 +8,6 @@
 #ifndef SKSL_LAYOUT
 #define SKSL_LAYOUT
 
-#include "SkSLString.h"
 #include "SkSLUtil.h"
 
 namespace SkSL {
@@ -43,16 +42,6 @@
         kR8I,
     };
 
-    // used by SkSL processors
-    enum Key {
-        // field is not a key
-        kNo_Key,
-        // field is a key
-        kKey_Key,
-        // key is 0 or 1 depending on whether the matrix is an identity matrix
-        kIdentity_Key,
-    };
-
     static const char* FormatToStr(Format format) {
         switch (format) {
             case Format::kUnspecified:  return "";
@@ -66,6 +55,7 @@
             case Format::kR8I:          return "r8i";
         }
         ABORT("Unexpected format");
+        return "";
     }
 
     static bool ReadFormat(String str, Format* format) {
@@ -100,7 +90,7 @@
     Layout(int location, int offset, int binding, int index, int set, int builtin,
            int inputAttachmentIndex, bool originUpperLeft, bool overrideCoverage,
            bool blendSupportAllEquations, Format format, bool pushconstant, Primitive primitive,
-           int maxVertices, int invocations, String when, Key key)
+           int maxVertices, int invocations)
     : fLocation(location)
     , fOffset(offset)
     , fBinding(binding)
@@ -115,9 +105,7 @@
     , fPushConstant(pushconstant)
     , fPrimitive(primitive)
     , fMaxVertices(maxVertices)
-    , fInvocations(invocations)
-    , fWhen(when)
-    , fKey(key) {}
+    , fInvocations(invocations) {}
 
     Layout()
     : fLocation(-1)
@@ -134,8 +122,7 @@
     , fPushConstant(false)
     , fPrimitive(kUnspecified_Primitive)
     , fMaxVertices(-1)
-    , fInvocations(-1)
-    , fKey(kNo_Key) {}
+    , fInvocations(-1) {}
 
     String description() const {
         String result;
@@ -228,22 +215,6 @@
             result += separator + "invocations = " + to_string(fInvocations);
             separator = ", ";
         }
-        if (fWhen.size()) {
-            result += separator + "when = " + fWhen;
-            separator = ", ";
-        }
-        switch (fKey) {
-            case kNo_Key:
-                break;
-            case kKey_Key:
-                result += separator + "key";
-                separator = ", ";
-                break;
-            case kIdentity_Key:
-                result += separator + "key=identity";
-                separator = ", ";
-                break;
-        }
         if (result.size() > 0) {
             result = "layout (" + result + ")";
         }
@@ -290,8 +261,6 @@
     Primitive fPrimitive;
     int fMaxVertices;
     int fInvocations;
-    String fWhen;
-    Key fKey;
 };
 
 } // namespace
diff --git a/src/sksl/ir/SkSLPrefixExpression.h b/src/sksl/ir/SkSLPrefixExpression.h
index 5ac84c6..acab37e 100644
--- a/src/sksl/ir/SkSLPrefixExpression.h
+++ b/src/sksl/ir/SkSLPrefixExpression.h
@@ -33,8 +33,9 @@
                fOperand->hasSideEffects();
     }
 
-    std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
-                                                  const DefinitionMap& definitions) override {
+    virtual std::unique_ptr<Expression> constantPropagate(
+                                                        const IRGenerator& irGenerator,
+                                                        const DefinitionMap& definitions) override {
         if (fOperand->fKind == Expression::kFloatLiteral_Kind) {
             return std::unique_ptr<Expression>(new FloatLiteral(
                                                               irGenerator.fContext,
diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h
index a3eeaa3..96bd5c4 100644
--- a/src/sksl/ir/SkSLProgram.h
+++ b/src/sksl/ir/SkSLProgram.h
@@ -11,9 +11,7 @@
 #include <vector>
 #include <memory>
 
-#include "SkSLBoolLiteral.h"
-#include "SkSLExpression.h"
-#include "SkSLIntLiteral.h"
+#include "SkSLContext.h"
 #include "SkSLModifiers.h"
 #include "SkSLProgramElement.h"
 #include "SkSLSymbolTable.h"
@@ -23,46 +21,11 @@
 
 namespace SkSL {
 
-class Context;
-
 /**
  * Represents a fully-digested program, ready for code generation.
  */
 struct Program {
     struct Settings {
-        struct Value {
-            Value(bool b)
-            : fKind(kBool_Kind)
-            , fValue(b) {}
-
-            Value(int i)
-            : fKind(kInt_Kind)
-            , fValue(i) {}
-
-            std::unique_ptr<Expression> literal(const Context& context, Position position) const {
-                switch (fKind) {
-                    case Program::Settings::Value::kBool_Kind:
-                        return std::unique_ptr<Expression>(new BoolLiteral(context,
-                                                                           position,
-                                                                           fValue));
-                    case Program::Settings::Value::kInt_Kind:
-                        return std::unique_ptr<Expression>(new IntLiteral(context,
-                                                                          position,
-                                                                          fValue));
-                    default:
-                        ASSERT(false);
-                        return nullptr;
-                }
-            }
-
-            enum {
-                kBool_Kind,
-                kInt_Kind,
-            } fKind;
-
-            int fValue;
-        };
-
 #ifdef SKSL_STANDALONE
         const StandaloneShaderCaps* fCaps = &standaloneCaps;
 #else
@@ -71,10 +34,6 @@
         // if false, sk_FragCoord is exactly the same as gl_FragCoord. If true, the y coordinate
         // must be flipped.
         bool fFlipY = false;
-        // if true, Setting objects (e.g. sk_Caps.fbFetchSupport) should be replaced with their
-        // constant equivalents during compilation
-        bool fReplaceSettings = true;
-        std::unordered_map<String, Value> fArgs;
     };
 
     struct Inputs {
@@ -98,8 +57,7 @@
     enum Kind {
         kFragment_Kind,
         kVertex_Kind,
-        kGeometry_Kind,
-        kFragmentProcessor_Kind
+        kGeometry_Kind
     };
 
     Program(Kind kind,
diff --git a/src/sksl/ir/SkSLProgramElement.h b/src/sksl/ir/SkSLProgramElement.h
index 1e2bb48..ebb4e9a 100644
--- a/src/sksl/ir/SkSLProgramElement.h
+++ b/src/sksl/ir/SkSLProgramElement.h
@@ -21,8 +21,7 @@
         kFunction_Kind,
         kInterfaceBlock_Kind,
         kExtension_Kind,
-        kModifiers_Kind,
-        kSection_Kind
+        kModifiers_Kind
     };
 
     ProgramElement(Position position, Kind kind)
diff --git a/src/sksl/ir/SkSLSection.h b/src/sksl/ir/SkSLSection.h
deleted file mode 100644
index f9815b1..0000000
--- a/src/sksl/ir/SkSLSection.h
+++ /dev/null
@@ -1,43 +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_SECTION
-#define SKSL_SECTION
-
-#include "SkSLProgramElement.h"
-
-namespace SkSL {
-
-/**
- * A section declaration (e.g. @body { body code here })..
- */
-struct Section : public ProgramElement {
-    Section(Position position, String name, String arg, String text)
-    : INHERITED(position, kSection_Kind)
-    , fName(std::move(name))
-    , fArgument(std::move(arg))
-    , fText(std::move(text)) {}
-
-    String description() const override {
-        String result = "@" + fName;
-        if (fArgument.size()) {
-            result += "(" + fArgument + ")";
-        }
-        result += " { " + fText + " }";
-        return result;
-    }
-
-    const String fName;
-    const String fArgument;
-    const String fText;
-
-    typedef ProgramElement INHERITED;
-};
-
-} // namespace
-
-#endif
diff --git a/src/sksl/ir/SkSLSetting.cpp b/src/sksl/ir/SkSLSetting.cpp
deleted file mode 100644
index 2d4a8ba..0000000
--- a/src/sksl/ir/SkSLSetting.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkSLSetting.h"
-#include "SkSLIRGenerator.h"
-#include "SkSLVariableReference.h"
-
-namespace SkSL {
-
-std::unique_ptr<Expression> Setting::constantPropagate(const IRGenerator& irGenerator,
-                                                       const DefinitionMap& definitions) {
-        if (irGenerator.fSettings->fReplaceSettings) {
-            return VariableReference::copy_constant(irGenerator, fValue.get());
-        }
-        return nullptr;
-    }
-} // namespace
-
diff --git a/src/sksl/ir/SkSLSetting.h b/src/sksl/ir/SkSLSetting.h
deleted file mode 100644
index 995fcf5..0000000
--- a/src/sksl/ir/SkSLSetting.h
+++ /dev/null
@@ -1,51 +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_SETTING
-#define SKSL_SETTING
-
-#include "SkSLContext.h"
-#include "SkSLExpression.h"
-
-namespace SkSL {
-
-/**
- * Represents a compile-time constant setting, such as sk_Caps.fbFetchSupport. These are generally
- * collapsed down to their constant representations during the compilation process.
- */
-struct Setting : public Expression {
-    Setting(Position position, String name, std::unique_ptr<Expression> value)
-    : INHERITED(position, kSetting_Kind, value->fType)
-    , fName(std::move(name))
-    , fValue(std::move(value)) {
-        ASSERT(fValue->isConstant());
-    }
-
-    std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
-                                                  const DefinitionMap& definitions) override;
-
-    String description() const override {
-        return fName;
-    }
-
-    bool hasSideEffects() const override {
-        return false;
-    }
-
-    bool isConstant() const override {
-        return true;
-    }
-
-    const String fName;
-    std::unique_ptr<Expression> fValue;
-
-    typedef Expression INHERITED;
-};
-
-} // namespace
-
-#endif
diff --git a/src/sksl/ir/SkSLSwizzle.h b/src/sksl/ir/SkSLSwizzle.h
index 442e92f..1e36c41 100644
--- a/src/sksl/ir/SkSLSwizzle.h
+++ b/src/sksl/ir/SkSLSwizzle.h
@@ -71,8 +71,10 @@
         ASSERT(fComponents.size() >= 1 && fComponents.size() <= 4);
     }
 
-    std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
-                                                  const DefinitionMap& definitions) override {
+    virtual std::unique_ptr<Expression> constantPropagate(
+                                                        const IRGenerator& irGenerator,
+                                                        const DefinitionMap& definitions) override {
+
         if (fBase->fKind == Expression::kConstructor_Kind && fBase->isConstant()) {
             // we're swizzling a constant vector, e.g. vec4(1).x. Simplify it.
             ASSERT(fBase->fKind == Expression::kConstructor_Kind);
diff --git a/src/sksl/ir/SkSLVarDeclarations.h b/src/sksl/ir/SkSLVarDeclarations.h
index 1eda87e..c07fee8 100644
--- a/src/sksl/ir/SkSLVarDeclarations.h
+++ b/src/sksl/ir/SkSLVarDeclarations.h
@@ -55,7 +55,7 @@
  * A variable declaration statement, which may consist of one or more individual variables.
  */
 struct VarDeclarations : public ProgramElement {
-    VarDeclarations(Position position, const Type* baseType,
+    VarDeclarations(Position position, const Type* baseType, 
                     std::vector<std::unique_ptr<VarDeclaration>> vars)
     : INHERITED(position, kVar_Kind)
     , fBaseType(*baseType) {
diff --git a/src/sksl/ir/SkSLVariableReference.h b/src/sksl/ir/SkSLVariableReference.h
index ba17437..92aef94 100644
--- a/src/sksl/ir/SkSLVariableReference.h
+++ b/src/sksl/ir/SkSLVariableReference.h
@@ -14,7 +14,6 @@
 #include "SkSLFloatLiteral.h"
 #include "SkSLIRGenerator.h"
 #include "SkSLIntLiteral.h"
-#include "SkSLSetting.h"
 
 namespace SkSL {
 
@@ -105,12 +104,6 @@
                 return std::unique_ptr<Expression>(new Constructor(Position(), c->fType,
                                                                    std::move(args)));
             }
-            case Expression::kSetting_Kind: {
-                const Setting* s = (const Setting*) expr;
-                return std::unique_ptr<Expression>(new Setting(Position(), s->fName,
-                                                               copy_constant(irGenerator,
-                                                                             s->fValue.get())));
-            }
             default:
                 ABORT("unsupported constant\n");
         }
diff --git a/src/sksl/layout.flex b/src/sksl/layout.flex
index 4e6695c..412bd47 100644
--- a/src/sksl/layout.flex
+++ b/src/sksl/layout.flex
@@ -51,8 +51,6 @@
 "triangles_adjacency"         { return SkSL::Token::TRIANGLES_ADJACENCY; }
 "max_vertices"                { return SkSL::Token::MAX_VERTICES; }
 "invocations"                 { return SkSL::Token::INVOCATIONS; }
-"when"                        { return SkSL::Token::WHEN; }
-"key"                         { return SkSL::Token::KEY; }
 
 . { return SkSL::Token::INVALID_TOKEN; }
 
diff --git a/src/sksl/lex.layout.c b/src/sksl/lex.layout.c
index 63369fe..42db0fe 100644
--- a/src/sksl/lex.layout.c
+++ b/src/sksl/lex.layout.c
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#line 3 "lex.layout.c"
+#line 2 "lex.layout.c"
 
 #define  YY_INT_ALIGNED short int
 
@@ -14,11 +14,81 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 6
-#define YY_FLEX_SUBMINOR_VERSION 1
+#define YY_FLEX_SUBMINOR_VERSION 3
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
 
+    #define yy_create_buffer layout_create_buffer
+
+    #define yy_delete_buffer layout_delete_buffer
+
+    #define yy_scan_buffer layout_scan_buffer
+
+    #define yy_scan_string layout_scan_string
+
+    #define yy_scan_bytes layout_scan_bytes
+
+    #define yy_init_buffer layout_init_buffer
+
+    #define yy_flush_buffer layout_flush_buffer
+
+    #define yy_load_buffer_state layout_load_buffer_state
+
+    #define yy_switch_to_buffer layout_switch_to_buffer
+
+    #define yypush_buffer_state layoutpush_buffer_state
+
+    #define yypop_buffer_state layoutpop_buffer_state
+
+    #define yyensure_buffer_stack layoutensure_buffer_stack
+
+    #define yylex layoutlex
+
+    #define yyrestart layoutrestart
+
+    #define yylex_init layoutlex_init
+
+    #define yylex_init_extra layoutlex_init_extra
+
+    #define yylex_destroy layoutlex_destroy
+
+    #define yyget_debug layoutget_debug
+
+    #define yyset_debug layoutset_debug
+
+    #define yyget_extra layoutget_extra
+
+    #define yyset_extra layoutset_extra
+
+    #define yyget_in layoutget_in
+
+    #define yyset_in layoutset_in
+
+    #define yyget_out layoutget_out
+
+    #define yyset_out layoutset_out
+
+    #define yyget_leng layoutget_leng
+
+    #define yyget_text layoutget_text
+
+    #define yyget_lineno layoutget_lineno
+
+    #define yyset_lineno layoutset_lineno
+
+        #define yyget_column layoutget_column
+
+        #define yyset_column layoutset_column
+
+    #define yywrap layoutwrap
+
+    #define yyalloc layoutalloc
+
+    #define yyrealloc layoutrealloc
+
+    #define yyfree layoutfree
+
 /* First, we deal with  platform-specific or compiler-specific issues. */
 
 /* begin standard C headers. */
@@ -105,12 +175,10 @@
 /* Returned upon end-of-file. */
 #define YY_NULL 0
 
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
+/* Promotes a possibly negative, possibly signed char to an
+ *   integer in range [0..255] for use as an array index.
  */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
 
 /* An opaque pointer. */
 #ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -134,20 +202,16 @@
  * definition of BEGIN.
  */
 #define BEGIN yyg->yy_start = 1 + 2 *
-
 /* Translate the current start state into a value that can be later handed
  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  * compatibility.
  */
 #define YY_START ((yyg->yy_start - 1) / 2)
 #define YYSTATE YY_START
-
 /* Action number for EOF rule of a given start state. */
 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
 /* Special action meaning "start processing a new file". */
 #define YY_NEW_FILE layoutrestart(yyin ,yyscanner )
-
 #define YY_END_OF_BUFFER_CHAR 0
 
 /* Size of default input buffer. */
@@ -180,10 +244,10 @@
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
-
+    
     /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
      *       access to the local variable yy_act. Since yyless() is a macro, it would break
-     *       existing scanners that call yyless() from OUTSIDE layoutlex. 
+     *       existing scanners that call yyless() from OUTSIDE layoutlex.
      *       One obvious solution it to make yy_act a global. I tried that, and saw
      *       a 5% performance hit in a non-yylineno scanner, because yy_act is
      *       normally declared as a register variable-- so it is not worth it.
@@ -216,7 +280,6 @@
 		YY_DO_BEFORE_ACTION; /* set up yytext again */ \
 		} \
 	while ( 0 )
-
 #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -259,7 +322,7 @@
 
     int yy_bs_lineno; /**< The line count. */
     int yy_bs_column; /**< The column count. */
-    
+
 	/* Whether to try to fill the input buffer when we reach the
 	 * end of it.
 	 */
@@ -293,36 +356,33 @@
 #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
                           ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
                           : NULL)
-
 /* Same as previous macro, but useful when we know that the buffer stack is not
  * NULL or when we need an lvalue. For internal use only.
  */
 #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
 
-void layoutrestart (FILE *input_file ,yyscan_t yyscanner );
-void layout_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE layout_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void layout_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void layout_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void layoutpush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void layoutpop_buffer_state (yyscan_t yyscanner );
+void layoutrestart ( FILE *input_file , yyscan_t yyscanner );
+void layout_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE layout_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void layout_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void layout_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void layoutpush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void layoutpop_buffer_state ( yyscan_t yyscanner );
 
-static void layoutensure_buffer_stack (yyscan_t yyscanner );
-static void layout_load_buffer_state (yyscan_t yyscanner );
-static void layout_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-
+static void layoutensure_buffer_stack ( yyscan_t yyscanner );
+static void layout_load_buffer_state ( yyscan_t yyscanner );
+static void layout_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
 #define YY_FLUSH_BUFFER layout_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
 
-YY_BUFFER_STATE layout_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE layout_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE layout_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+YY_BUFFER_STATE layout_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE layout_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE layout_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
 
-void *layoutalloc (yy_size_t ,yyscan_t yyscanner );
-void *layoutrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void layoutfree (void * ,yyscan_t yyscanner );
+void *layoutalloc ( yy_size_t , yyscan_t yyscanner );
+void *layoutrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void layoutfree ( void * , yyscan_t yyscanner );
 
 #define yy_new_buffer layout_create_buffer
-
 #define yy_set_interactive(is_interactive) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){ \
@@ -332,7 +392,6 @@
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
 	}
-
 #define yy_set_bol(at_bol) \
 	{ \
 	if ( ! YY_CURRENT_BUFFER ){\
@@ -342,21 +401,19 @@
 	} \
 	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
 	}
-
 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
 
 /* Begin user sect3 */
-
-typedef unsigned char YY_CHAR;
+typedef flex_uint8_t YY_CHAR;
 
 typedef int yy_state_type;
 
 #define yytext_ptr yytext_r
 
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yynoreturn yy_fatal_error (yyconst char* msg ,yyscan_t yyscanner );
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state  , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
 
 /* Done after the current pattern has been matched and before the
  * corresponding action - sets up yytext.
@@ -367,9 +424,8 @@
 	yyg->yy_hold_char = *yy_cp; \
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 24
-#define YY_END_OF_BUFFER 25
+#define YY_NUM_RULES 22
+#define YY_END_OF_BUFFER 23
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -377,34 +433,34 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[211] =
+static const flex_int16_t yy_accept[204] =
     {   0,
-        0,    0,   25,   23,   24,   23,   23,   23,   23,   23,
-       23,   23,   23,   23,   23,    0,    0,    0,    0,    0,
+        0,    0,   23,   21,   22,   21,   21,   21,   21,   21,
+       21,   21,   21,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,   22,    0,    0,
-        0,    0,    0,    0,    0,    0,    5,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,   21,    0,    0,    0,    4,    0,
-        0,    0,   13,    0,    0,    0,    0,    0,    0,    0,
+        0,    5,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        2,    0,    0,   12,    0,    0,    3,    0,    6,    0,
+        0,    4,    0,    0,    0,   13,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    2,    0,    0,   12,    0,    0,    3,
+        0,    6,    0,    0,    0,    0,    0,    0,    0,    0,
 
+        0,    0,    0,    0,    0,    0,    0,    1,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    1,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       16,    0,    0,    0,   14,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,   20,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,   19,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,   11,    0,    0,    0,
-        0,    0,    0,    0,   17,    0,    0,    0,   15,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    8,
-        9,    0,    0,    0,    0,    0,    0,   18,    0,    0,
+        0,    0,    0,   16,    0,    0,    0,   14,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   20,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   19,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,   11,
+        0,    0,    0,    0,    0,    0,    0,   17,    0,    0,
+        0,   15,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    8,    9,    0,    0,    0,    0,    0,    0,
+       18,    0,    0,    0,    0,    0,    7,    0,    0,    0,
 
-        0,    0,    0,    7,    0,    0,    0,    0,   10,    0
+        0,   10,    0
     } ;
 
-static yyconst YY_CHAR yy_ec[256] =
+static const YY_CHAR yy_ec[256] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    2,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -417,9 +473,9 @@
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    3,    1,    4,    5,    6,    7,
 
-        8,    9,   10,   11,   12,   13,   14,   15,   16,   17,
-       18,   19,   20,   21,   22,   23,   24,   25,   26,   27,
-       28,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        8,    9,   10,   11,   12,   13,    1,   14,   15,   16,
+       17,   18,   19,   20,   21,   22,   23,   24,    1,   25,
+       26,    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,
@@ -436,138 +492,134 @@
         1,    1,    1,    1,    1
     } ;
 
-static yyconst YY_CHAR yy_meta[29] =
+static const YY_CHAR yy_meta[27] =
     {   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
     } ;
 
-static yyconst flex_uint16_t yy_base[212] =
+static const flex_int16_t yy_base[205] =
     {   0,
-        0,   25,  227,  228,  228,    5,  209,  217,   13,  220,
-       24,   10,  215,  201,  210,  203,  211,  206,   17,  189,
-      199,  209,  187,  204,  200,  203,  198,  187,  185,  195,
-      198,  198,  187,  188,  194,  177,  182,  228,  191,  194,
-      194,  174,  185,  173,  176,  181,  228,  187,  173,  177,
-      181,  164,  159,  162,  178,   10,  160,  157,  173,  168,
-      158,  155,  174,  159,  228,  158,  171,  161,  228,  169,
-      167,  148,  166,  156,  159,  143,  148,  152,  141,  156,
-      151,  150,  137,  141,  153,  133,  132,  150,  135,  131,
-      228,  148,  143,  228,  131,  133,  228,  123,  228,  123,
+        0,   21,  218,  219,  219,   17,  201,    7,  212,   21,
+       11,  207,  194,  197,  204,  199,   30,  194,  203,  183,
+      198,  194,  197,  192,  182,  180,  189,  193,  183,  184,
+      189,  173,  178,  186,  189,  189,  170,  180,  169,  172,
+      176,  219,  182,  173,  177,  161,  157,  159,  174,    4,
+      157,  154,  169,  164,  155,  152,  170,  156,  155,  167,
+      157,  219,  165,  163,  145,  162,  152,  155,  140,  145,
+      148,  138,  152,  147,  146,  134,  138,  149,  130,  129,
+      146,  132,  128,  219,  144,  139,  219,  128,  130,  219,
+      120,  219,  120,  129,  120,  132,  122,  115,  113,  127,
 
-      133,  123,  136,  125,  118,  116,  131,  121,  129,  117,
-      112,  116,  121,  119,  228,  119,  111,  126,  106,   32,
-      108,  122,  108,  105,  119,  116,  102,  114,   96,   96,
-      114,   98,  109,   92,  228,  107,  104,  103,   92,  105,
-       85,  103,   85,   94,  228,   96,   81,   81,   76,   83,
-       78,   91,   74,   80,   78,  228,   91,   85,   69,   79,
-       77,   86,   80,   81,   71,   64,  228,   65,   79,   78,
-       64,   52,   71,   74,  228,   71,   61,   52,  228,   65,
-       63,   64,   56,   67,   46,   60,   50,   63,   53,  228,
-      228,   58,   55,   45,   33,   40,   52,  228,   34,   49,
+      118,  125,  114,  109,  113,  117,  115,  219,  115,  108,
+      122,  103,    6,  105,  118,  105,  102,  115,  112,   99,
+      110,   93,   93,  110,   95,  105,   89,  219,  103,  100,
+       99,   89,  101,   82,   99,   82,   90,  219,   92,   78,
+       78,   73,   80,   75,   87,   71,   77,   75,  219,   87,
+       81,   66,   75,   73,   82,   76,   77,   68,   61,  219,
+       62,   75,   74,   61,   50,   67,   70,  219,   67,   58,
+       49,  219,   61,   59,   60,   53,   63,   43,   56,   47,
+       59,   49,  219,  219,   54,   51,   42,   31,   37,   48,
+      219,   30,   44,   47,   25,   27,  219,   35,   29,   28,
 
-       52,   28,   30,  228,   40,   32,   29,   16,  228,  228,
-        0
+       11,  219,  219,    0
     } ;
 
-static yyconst flex_int16_t yy_def[212] =
+static const flex_int16_t yy_def[205] =
     {   0,
-      211,  211,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
+      204,  204,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
 
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
 
-      210,  210,  210,  210,  210,  210,  210,  210,  210,    0,
-      210
+      203,  203,    0,  203
     } ;
 
-static yyconst flex_uint16_t yy_nxt[257] =
+static const flex_int16_t yy_nxt[246] =
     {   0,
-        4,    5,  210,  210,    6,  210,  210,  210,  210,  210,
-      210,    7,   72,    8,    9,   10,   16,   11,   12,   17,
-      210,   13,   14,   35,   21,   15,    5,   27,   18,    6,
-       22,   73,   24,   28,  130,   36,    7,  209,    8,    9,
-       10,   37,   11,   12,   25,  208,   13,   14,   26,  207,
-       15,  206,  205,  131,  204,  203,  202,  201,  200,  199,
-      198,  197,  196,  195,  194,  193,  192,  191,  190,  189,
-      188,  187,  186,  185,  184,  183,  182,  181,  180,  179,
-      178,  177,  176,  175,  174,  173,  172,  171,  170,  169,
-      168,  167,  166,  165,  164,  163,  162,  161,  160,  159,
+        4,    5,  203,  203,    6,  203,   65,  203,  123,  203,
+      203,    7,  203,    8,    9,  203,   10,   11,   18,  203,
+       12,   13,    5,   19,   66,    6,  124,   24,   14,   21,
+       15,  202,    7,   25,    8,    9,   31,   10,   11,   16,
+       22,   12,   13,  201,   23,  200,  199,   32,  198,  197,
+      196,  195,  194,   33,  193,  192,  191,  190,  189,  188,
+      187,  186,  185,  184,  183,  182,  181,  180,  179,  178,
+      177,  176,  175,  174,  173,  172,  171,  170,  169,  168,
+      167,  166,  165,  164,  163,  162,  161,  160,  159,  158,
+      157,  156,  155,  154,  153,  152,  151,  150,  149,  148,
 
-      158,  157,  156,  155,  154,  153,  152,  151,  150,  149,
+      147,  146,  145,  144,  143,  142,  141,  140,  139,  138,
+      137,  136,  135,  134,  133,  132,  131,  130,  129,  128,
+      127,  126,  125,  122,  121,  120,  119,  118,  117,  116,
+      115,  114,  113,  112,  111,  110,  109,  108,  107,  106,
+      105,  104,  103,  102,  101,  100,   99,   98,   97,   96,
+       95,   94,   93,   92,   91,   90,   89,   88,   87,   86,
+       85,   84,   83,   82,   81,   80,   79,   78,   77,   76,
+       75,   74,   73,   72,   71,   70,   69,   68,   67,   64,
+       63,   62,   61,   60,   59,   58,   57,   56,   55,   54,
+       53,   52,   51,   50,   49,   48,   47,   46,   45,   44,
+
+       43,   42,   41,   40,   39,   38,   37,   36,   35,   34,
+       30,   29,   28,   27,   26,   20,   17,  203,    3,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203
+    } ;
+
+static const flex_int16_t yy_chk[246] =
+    {   0,
+      204,    1,    0,    0,    1,    0,   50,    0,  113,    0,
+        0,    1,    0,    1,    1,    0,    1,    1,    8,    0,
+        1,    1,    2,    8,   50,    2,  113,   11,    6,   10,
+        6,  201,    2,   11,    2,    2,   17,    2,    2,    6,
+       10,    2,    2,  200,   10,  199,  198,   17,  196,  195,
+      194,  193,  192,   17,  190,  189,  188,  187,  186,  185,
+      182,  181,  180,  179,  178,  177,  176,  175,  174,  173,
+      171,  170,  169,  167,  166,  165,  164,  163,  162,  161,
+      159,  158,  157,  156,  155,  154,  153,  152,  151,  150,
       148,  147,  146,  145,  144,  143,  142,  141,  140,  139,
-      138,  137,  136,  135,  134,  133,  132,  129,  128,  127,
+
+      137,  136,  135,  134,  133,  132,  131,  130,  129,  127,
       126,  125,  124,  123,  122,  121,  120,  119,  118,  117,
-      116,  115,  114,  113,  112,  111,  110,  109,  108,  107,
-      106,  105,  104,  103,  102,  101,  100,   99,   98,   97,
-       96,   95,   94,   93,   92,   91,   90,   89,   88,   87,
-       86,   85,   84,   83,   82,   81,   80,   79,   78,   77,
-       76,   75,   74,   71,   70,   69,   68,   67,   66,   65,
-       64,   63,   62,   61,   60,   59,   58,   57,   56,   55,
+      116,  115,  114,  112,  111,  110,  109,  107,  106,  105,
+      104,  103,  102,  101,  100,   99,   98,   97,   96,   95,
+       94,   93,   91,   89,   88,   86,   85,   83,   82,   81,
+       80,   79,   78,   77,   76,   75,   74,   73,   72,   71,
+       70,   69,   68,   67,   66,   65,   64,   63,   61,   60,
+       59,   58,   57,   56,   55,   54,   53,   52,   51,   49,
+       48,   47,   46,   45,   44,   43,   41,   40,   39,   38,
+       37,   36,   35,   34,   33,   32,   31,   30,   29,   28,
 
-       54,   53,   52,   51,   50,   49,   48,   47,   46,   45,
-       44,   43,   42,   41,   40,   39,   38,   34,   33,   32,
-       31,   30,   29,   23,   20,   19,  210,    3,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210
-    } ;
-
-static yyconst flex_int16_t yy_chk[257] =
-    {   0,
-      211,    1,    0,    0,    1,    0,    0,    0,    0,    0,
-        0,    1,   56,    1,    1,    1,    6,    1,    1,    6,
-        0,    1,    1,   19,    9,    1,    2,   12,    6,    2,
-        9,   56,   11,   12,  120,   19,    2,  208,    2,    2,
-        2,   19,    2,    2,   11,  207,    2,    2,   11,  206,
-        2,  205,  203,  120,  202,  201,  200,  199,  197,  196,
-      195,  194,  193,  192,  189,  188,  187,  186,  185,  184,
-      183,  182,  181,  180,  178,  177,  176,  174,  173,  172,
-      171,  170,  169,  168,  166,  165,  164,  163,  162,  161,
-      160,  159,  158,  157,  155,  154,  153,  152,  151,  150,
-
-      149,  148,  147,  146,  144,  143,  142,  141,  140,  139,
-      138,  137,  136,  134,  133,  132,  131,  130,  129,  128,
-      127,  126,  125,  124,  123,  122,  121,  119,  118,  117,
-      116,  114,  113,  112,  111,  110,  109,  108,  107,  106,
-      105,  104,  103,  102,  101,  100,   98,   96,   95,   93,
-       92,   90,   89,   88,   87,   86,   85,   84,   83,   82,
-       81,   80,   79,   78,   77,   76,   75,   74,   73,   72,
-       71,   70,   68,   67,   66,   64,   63,   62,   61,   60,
-       59,   58,   57,   55,   54,   53,   52,   51,   50,   49,
-       48,   46,   45,   44,   43,   42,   41,   40,   39,   37,
-
-       36,   35,   34,   33,   32,   31,   30,   29,   28,   27,
-       26,   25,   24,   23,   22,   21,   20,   18,   17,   16,
-       15,   14,   13,   10,    8,    7,    3,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210,  210,  210,  210,  210,
-      210,  210,  210,  210,  210,  210
+       27,   26,   25,   24,   23,   22,   21,   20,   19,   18,
+       16,   15,   14,   13,   12,    9,    7,    3,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203,  203,  203,  203,  203,  203,
+      203,  203,  203,  203,  203
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[25] =
+static const flex_int32_t yy_rule_can_match_eol[23] =
     {   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,     };
 
 /* The intent behind this definition is that it'll catch
  * any uses of REJECT which flex missed.
@@ -599,7 +651,8 @@
 #define YY_NO_UNISTD_H 1
 #line 29 "layout.flex"
 #include "SkSLToken.h"
-#line 597 "lex.layout.c"
+#line 648 "lex.layout.c"
+#line 649 "lex.layout.c"
 
 #define INITIAL 0
 
@@ -649,44 +702,44 @@
 
     }; /* end struct yyguts_t */
 
-static int yy_init_globals (yyscan_t yyscanner );
+static int yy_init_globals ( yyscan_t yyscanner );
 
 int layoutlex_init (yyscan_t* scanner);
 
-int layoutlex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+int layoutlex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
 
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
-int layoutlex_destroy (yyscan_t yyscanner );
+int layoutlex_destroy ( yyscan_t yyscanner );
 
-int layoutget_debug (yyscan_t yyscanner );
+int layoutget_debug ( yyscan_t yyscanner );
 
-void layoutset_debug (int debug_flag ,yyscan_t yyscanner );
+void layoutset_debug ( int debug_flag , yyscan_t yyscanner );
 
-YY_EXTRA_TYPE layoutget_extra (yyscan_t yyscanner );
+YY_EXTRA_TYPE layoutget_extra ( yyscan_t yyscanner );
 
-void layoutset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+void layoutset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
 
-FILE *layoutget_in (yyscan_t yyscanner );
+FILE *layoutget_in ( yyscan_t yyscanner );
 
-void layoutset_in  (FILE * _in_str ,yyscan_t yyscanner );
+void layoutset_in  ( FILE * _in_str , yyscan_t yyscanner );
 
-FILE *layoutget_out (yyscan_t yyscanner );
+FILE *layoutget_out ( yyscan_t yyscanner );
 
-void layoutset_out  (FILE * _out_str ,yyscan_t yyscanner );
+void layoutset_out  ( FILE * _out_str , yyscan_t yyscanner );
 
-			int layoutget_leng (yyscan_t yyscanner );
+			int layoutget_leng ( yyscan_t yyscanner );
 
-char *layoutget_text (yyscan_t yyscanner );
+char *layoutget_text ( yyscan_t yyscanner );
 
-int layoutget_lineno (yyscan_t yyscanner );
+int layoutget_lineno ( yyscan_t yyscanner );
 
-void layoutset_lineno (int _line_number ,yyscan_t yyscanner );
+void layoutset_lineno ( int _line_number , yyscan_t yyscanner );
 
-int layoutget_column  (yyscan_t yyscanner );
+int layoutget_column  ( yyscan_t yyscanner );
 
-void layoutset_column (int _column_no ,yyscan_t yyscanner );
+void layoutset_column ( int _column_no , yyscan_t yyscanner );
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -694,32 +747,31 @@
 
 #ifndef YY_SKIP_YYWRAP
 #ifdef __cplusplus
-extern "C" int layoutwrap (yyscan_t yyscanner );
+extern "C" int layoutwrap ( yyscan_t yyscanner );
 #else
-extern int layoutwrap (yyscan_t yyscanner );
+extern int layoutwrap ( yyscan_t yyscanner );
 #endif
 #endif
 
 #ifndef YY_NO_UNPUT
     
-    static void yyunput (int c,char *buf_ptr  ,yyscan_t yyscanner);
+    static void yyunput ( int c, char *buf_ptr  , yyscan_t yyscanner);
     
 #endif
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
 #endif
 
 #ifndef YY_NO_INPUT
-
 #ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
+static int yyinput ( yyscan_t yyscanner );
 #else
-static int input (yyscan_t yyscanner );
+static int input ( yyscan_t yyscanner );
 #endif
 
 #endif
@@ -750,7 +802,7 @@
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		size_t n; \
+		int n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -763,7 +815,7 @@
 	else \
 		{ \
 		errno=0; \
-		while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+		while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
 			{ \
 			if( errno != EINTR) \
 				{ \
@@ -863,7 +915,7 @@
 #line 32 "layout.flex"
 
 
-#line 861 "lex.layout.c"
+#line 912 "lex.layout.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -890,13 +942,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 >= 211 )
-					yy_c = yy_meta[(unsigned int) yy_c];
+				if ( yy_current_state >= 204 )
+					yy_c = yy_meta[yy_c];
 				}
-			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 210 );
+		while ( yy_current_state != 203 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -907,10 +959,10 @@
 
 		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' )
-					   
+					
     do{ yylineno++;
         yycolumn=0;
     }while(0)
@@ -1030,25 +1082,15 @@
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 54 "layout.flex"
-{ return SkSL::Token::WHEN; }
+#line 55 "layout.flex"
+{ return SkSL::Token::INVALID_TOKEN; }
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 55 "layout.flex"
-{ return SkSL::Token::KEY; }
-	YY_BREAK
-case 23:
-YY_RULE_SETUP
 #line 57 "layout.flex"
-{ return SkSL::Token::INVALID_TOKEN; }
-	YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 59 "layout.flex"
 ECHO;
 	YY_BREAK
-#line 1046 "lex.layout.c"
+#line 1087 "lex.layout.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -1195,7 +1237,7 @@
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 	char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
 	char *source = yyg->yytext_ptr;
-	yy_size_t number_to_move, i;
+	int number_to_move, i;
 	int ret_val;
 
 	if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
@@ -1224,7 +1266,7 @@
 	/* Try to read more data. */
 
 	/* First move last chars to start of buffer. */
-	number_to_move = (yy_size_t) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+	number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
 
 	for ( i = 0; i < number_to_move; ++i )
 		*(dest++) = *(source++);
@@ -1260,7 +1302,7 @@
 
 				b->yy_ch_buf = (char *)
 					/* Include room in for 2 EOB chars. */
-					layoutrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+					layoutrealloc((void *) b->yy_ch_buf,(yy_size_t) (b->yy_buf_size + 2) ,yyscanner );
 				}
 			else
 				/* Can't grow it, we don't own it. */
@@ -1306,10 +1348,10 @@
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
 
-	if ((int) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+	if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
 		/* Extend the array by 50%, plus the number we really need. */
 		int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
-		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) layoutrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) layoutrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,(yy_size_t) new_size ,yyscanner );
 		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
 			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
 	}
@@ -1344,10 +1386,10 @@
 		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 >= 211 )
-				yy_c = yy_meta[(unsigned int) yy_c];
+			if ( yy_current_state >= 204 )
+				yy_c = yy_meta[yy_c];
 			}
-		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 		}
 
 	return yy_current_state;
@@ -1373,11 +1415,11 @@
 	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 >= 211 )
-			yy_c = yy_meta[(unsigned int) yy_c];
+		if ( yy_current_state >= 204 )
+			yy_c = yy_meta[yy_c];
 		}
-	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
-	yy_is_jam = (yy_current_state == 210);
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+	yy_is_jam = (yy_current_state == 203);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -1454,7 +1496,7 @@
 
 		else
 			{ /* need more input */
-			int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+			int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
 			++yyg->yy_c_buf_p;
 
 			switch ( yy_get_next_buffer( yyscanner ) )
@@ -1501,7 +1543,7 @@
 	yyg->yy_hold_char = *++yyg->yy_c_buf_p;
 
 	if ( c == '\n' )
-		   
+		
     do{ yylineno++;
         yycolumn=0;
     }while(0)
@@ -1589,12 +1631,12 @@
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in layout_create_buffer()" );
 
-	b->yy_buf_size = (yy_size_t)size;
+	b->yy_buf_size = size;
 
 	/* yy_ch_buf has to be 2 characters longer than the size given because
 	 * we need to put in 2 end-of-buffer characters.
 	 */
-	b->yy_ch_buf = (char *) layoutalloc(b->yy_buf_size + 2 ,yyscanner );
+	b->yy_ch_buf = (char *) layoutalloc((yy_size_t) (b->yy_buf_size + 2) ,yyscanner );
 	if ( ! b->yy_ch_buf )
 		YY_FATAL_ERROR( "out of dynamic memory in layout_create_buffer()" );
 
@@ -1741,7 +1783,7 @@
  */
 static void layoutensure_buffer_stack (yyscan_t yyscanner)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
 	if (!yyg->yy_buffer_stack) {
@@ -1756,9 +1798,9 @@
 								, yyscanner);
 		if ( ! yyg->yy_buffer_stack )
 			YY_FATAL_ERROR( "out of dynamic memory in layoutensure_buffer_stack()" );
-								  
+
 		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-				
+
 		yyg->yy_buffer_stack_max = num_to_alloc;
 		yyg->yy_buffer_stack_top = 0;
 		return;
@@ -1787,7 +1829,7 @@
  * @param base the character buffer
  * @param size the size in bytes of the character buffer
  * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object. 
+ * @return the newly allocated buffer state object.
  */
 YY_BUFFER_STATE layout_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
 {
@@ -1803,7 +1845,7 @@
 	if ( ! b )
 		YY_FATAL_ERROR( "out of dynamic memory in layout_scan_buffer()" );
 
-	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_size = (int) (size - 2);	/* "- 2" to take care of EOB's */
 	b->yy_buf_pos = b->yy_ch_buf = base;
 	b->yy_is_our_buffer = 0;
 	b->yy_input_file = NULL;
@@ -1826,7 +1868,7 @@
  * @note If you want to scan bytes that may contain NUL values, then use
  *       layout_scan_bytes() instead.
  */
-YY_BUFFER_STATE layout_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+YY_BUFFER_STATE layout_scan_string (const char * yystr , yyscan_t yyscanner)
 {
     
 	return layout_scan_bytes(yystr,(int) strlen(yystr) ,yyscanner);
@@ -1839,15 +1881,15 @@
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE layout_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE layout_scan_bytes  (const char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
 {
 	YY_BUFFER_STATE b;
 	char *buf;
 	yy_size_t n;
-	yy_size_t i;
+	int i;
     
 	/* Get memory for full buffer, including space for trailing EOB's. */
-	n = (yy_size_t) _yybytes_len + 2;
+	n = (yy_size_t) (_yybytes_len + 2);
 	buf = (char *) layoutalloc(n ,yyscanner );
 	if ( ! buf )
 		YY_FATAL_ERROR( "out of dynamic memory in layout_scan_bytes()" );
@@ -1873,7 +1915,7 @@
 #define YY_EXIT_FAILURE 2
 #endif
 
-static void yynoreturn yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
 {
 	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 	(void)yyg;
@@ -1915,7 +1957,7 @@
 int layoutget_lineno  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    
+
         if (! YY_CURRENT_BUFFER)
             return 0;
     
@@ -1928,7 +1970,7 @@
 int layoutget_column  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    
+
         if (! YY_CURRENT_BUFFER)
             return 0;
     
@@ -2050,9 +2092,7 @@
  * the ONLY reentrant function that doesn't take the scanner as the last argument.
  * That's why we explicitly handle the declaration, instead of using our macros.
  */
-
 int layoutlex_init(yyscan_t* ptr_yy_globals)
-
 {
     if (ptr_yy_globals == NULL){
         errno = EINVAL;
@@ -2079,9 +2119,7 @@
  * The user defined value in the first argument will be available to layoutalloc in
  * the yyextra field.
  */
-
 int layoutlex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
 {
     struct yyguts_t dummy_yyguts;
 
@@ -2091,20 +2129,20 @@
         errno = EINVAL;
         return 1;
     }
-	
+
     *ptr_yy_globals = (yyscan_t) layoutalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-	
+
     if (*ptr_yy_globals == NULL){
         errno = ENOMEM;
         return 1;
     }
-    
+
     /* By setting to 0xAA, we expose bugs in
     yy_init_globals. Leave at 0x00 for releases. */
     memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-    
+
     layoutset_extra (yy_user_defined, *ptr_yy_globals);
-    
+
     return yy_init_globals ( *ptr_yy_globals );
 }
 
@@ -2176,7 +2214,7 @@
  */
 
 #ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
 {
 	struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 	(void)yyg;
@@ -2188,7 +2226,7 @@
 #endif
 
 #ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
 {
 	int n;
 	for ( n = 0; s[n]; ++n )
@@ -2229,8 +2267,7 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 59 "layout.flex"
-
+#line 57 "layout.flex"
 
 
 int layoutwrap(yyscan_t scanner) {
diff --git a/src/sksl/lex.layout.cpp b/src/sksl/lex.layout.cpp
index 937c931..4289b11 100644
--- a/src/sksl/lex.layout.cpp
+++ b/src/sksl/lex.layout.cpp
@@ -7,6 +7,6 @@
 
 #include "disable_flex_warnings.h"
 #include "lex.layout.c"
-static_assert(YY_FLEX_MAJOR_VERSION * 10000 + YY_FLEX_MINOR_VERSION * 100 +
-              YY_FLEX_SUBMINOR_VERSION >= 20601,
+static_assert(YY_FLEX_MAJOR_VERSION * 100 + YY_FLEX_MINOR_VERSION * 10 +
+              YY_FLEX_SUBMINOR_VERSION >= 261,
               "we require Flex 2.6.1 or better for security reasons");
diff --git a/src/sksl/lex.sksl.c b/src/sksl/lex.sksl.c
index 6e44f5a..ebf94ed 100644
--- a/src/sksl/lex.sksl.c
+++ b/src/sksl/lex.sksl.c
@@ -1,9 +1,3 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * 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"
 
@@ -368,8 +362,8 @@
 	*yy_cp = '\0'; \
 	yyg->yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 99
-#define YY_END_OF_BUFFER 100
+#define YY_NUM_RULES 96
+#define YY_END_OF_BUFFER 97
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -377,39 +371,39 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[289] =
+static yyconst flex_int16_t yy_accept[285] =
     {   0,
-        0,    0,  100,   98,   95,   95,   69,   98,   42,   59,
-       64,   45,   46,   57,   55,   52,   56,   51,   58,    4,
-        4,   71,   92,   76,   72,   75,   70,   98,   49,   50,
-       63,   42,   42,   42,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,   42,   42,   42,   42,   47,
-       62,   48,   65,   95,   74,   43,   42,   83,   68,   88,
-       81,   53,   79,   54,   80,   93,    1,    0,   96,   82,
-        2,    4,    0,    0,   94,   60,   78,   73,   77,   61,
-       44,   44,   44,   87,   67,   42,   42,   42,   42,   42,
-       42,   13,   42,   42,   42,   42,   42,    8,   22,   42,
+        0,    0,   97,   95,   94,   94,   68,   95,   42,   58,
+       63,   44,   45,   56,   54,   51,   55,   50,   57,    4,
+        4,   70,   91,   75,   71,   74,   69,   95,   48,   49,
+       62,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   46,
+       61,   47,   64,   94,   73,   43,   42,   82,   67,   87,
+       80,   52,   78,   53,   79,    1,    0,   92,   81,    2,
+        4,    0,    0,   59,   77,   72,   76,   60,    0,    0,
+       86,   66,   42,   42,   42,   42,   42,   42,   13,   42,
+       42,   42,   42,   42,    8,   22,   42,   42,   42,   42,
 
        42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   86,   66,   43,   91,    0,    0,
-        0,   96,    1,    0,    0,    3,    5,   84,   85,   44,
-        9,   44,   90,   42,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   11,   42,   42,   42,   42,   42,   42,
-       23,   42,   42,   42,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   89,    0,    1,   97,    0,    0,    2,
-       44,   42,   42,   16,   42,   42,   42,   42,   42,   10,
-       42,   30,   42,   42,   42,   27,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,    6,   42,   42,   42,   42,
+       42,   85,   65,   43,   90,    0,    0,    0,   92,    1,
+        0,    0,    3,    5,   83,   84,    9,    0,   89,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   11,
+       42,   42,   42,   42,   42,   42,   23,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   88,
+        0,    1,   93,    0,    0,    2,    0,   42,   42,   16,
+       42,   42,   42,   42,   42,   10,   42,   30,   42,   42,
+       42,   27,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,    6,   42,   42,   42,   42,    0,    1,    0,   18,
 
-        0,    1,   44,   18,   42,   42,   26,   42,   42,   42,
-        7,   29,   24,   42,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,   12,   42,   44,   37,   42,
-       42,   42,   42,   40,   42,   42,   42,   42,   42,   21,
-       42,   39,   14,   42,   42,   42,   15,   42,   42,   17,
-       20,   28,   42,   42,   42,   42,   42,   25,   42,   42,
-       34,   19,   42,   42,   32,   36,   42,   35,   42,   42,
-       41,   42,   33,   42,   42,   42,   42,   42,   42,   31,
-       42,   42,   42,   42,   42,   42,   38,    0
+       42,   42,   26,   42,   42,   42,    7,   29,   24,   42,
+       42,   42,   42,   42,   42,   42,   42,   42,   42,   42,
+       42,   12,   42,    0,   37,   42,   42,   42,   42,   40,
+       42,   42,   42,   42,   42,   21,   42,   39,   14,   42,
+       42,   42,   15,   42,   42,   17,   20,   28,   42,   42,
+       42,   42,   42,   25,   42,   42,   34,   19,   42,   42,
+       32,   36,   42,   35,   42,   42,   41,   42,   33,   42,
+       42,   42,   42,   42,   42,   31,   42,   42,   42,   42,
+       42,   42,   38,    0
     } ;
 
 static yyconst YY_CHAR yy_ec[256] =
@@ -454,81 +448,77 @@
         3,    3,    3,    3,    1,    1,    1,    1
     } ;
 
-static yyconst flex_uint16_t yy_base[297] =
+static yyconst flex_uint16_t yy_base[291] =
     {   0,
-        0,    0,  360,  361,   57,   59,  337,    0,    0,  336,
-       55,  361,  361,  335,   52,  361,   53,   48,   57,   54,
-       65,  337,  361,   63,  333,   64,  361,   30,  361,  361,
-       66,   44,   57,   59,  312,   61,  313,   61,   65,  316,
-      306,  300,  302,  312,   59,  300,  302,  300,   70,  361,
-       90,  361,  361,  111,  361,    0,    0,  361,  322,  361,
-      361,  361,  361,  361,  361,  361,   98,  332,    0,  361,
-      101,  105,  112,    0,  361,  320,  361,  361,  361,  319,
-        0,  303,  287,  361,  316,  301,  299,  287,   92,  297,
-      285,    0,  284,  289,  298,  282,  290,    0,  282,  272,
+        0,    0,  353,  354,   57,   59,  330,    0,    0,  329,
+       55,  354,  354,  328,   52,  354,   51,   49,   59,   61,
+       65,  354,  354,   47,  327,   49,  354,   45,  354,  354,
+       64,   37,   57,   55,  306,   64,  307,   61,   58,  310,
+      300,  294,  296,  306,   58,  294,  296,  294,   65,  354,
+       86,  354,  354,  113,  354,    0,    0,  354,  316,  354,
+      354,  354,  354,  354,  354,  100,  326,    0,  354,  102,
+      107,  114,    0,  314,  354,  354,  354,  313,  297,  281,
+      354,  310,  295,  293,  281,   91,  291,  279,    0,  278,
+      283,  292,  276,  284,    0,  276,  266,  267,  283,  271,
 
-      273,  289,  277,  273,  285,   95,  289,  272,  278,  267,
-      276,  273,  274,  273,  361,  290,    0,  361,  121,  300,
-      294,    0,  130,  137,  135,  141,    0,  361,  361,    0,
-        0,  269,  361,  276,  270,  270,  269,  112,  272,  269,
-      266,  253,  251,    0,  260,  248,  252,  250,  255,  258,
-        0,  259,  257,  242,  240,  250,  238,  238,  250,  248,
-      252,  241,  233,  361,  145,  147,  361,  155,  153,  157,
-      232,  239,  243,    0,  231,  228,  236,  225,  242,    0,
-      237,    0,  226,  222,  220,    0,  219,  221,  227,  221,
-      218,  217,  231,  228,  227,    0,  215,  210,  222,  221,
+      267,  279,   91,  283,  266,  272,  261,  270,  267,  268,
+      267,  354,  284,    0,  354,  132,  294,  288,    0,  130,
+      141,  134,  143,    0,  354,  354,  354,  263,  354,  270,
+      264,  264,  263,  114,  266,  263,  260,  247,  245,    0,
+      254,  242,  246,  244,  249,  252,    0,  253,  251,  236,
+      234,  244,  232,  232,  244,  242,  246,  235,  227,  354,
+      147,  150,  354,  157,  155,  159,  226,  233,  237,    0,
+      225,  222,  230,  219,  236,    0,  231,    0,  220,  216,
+      214,    0,  213,  215,  221,  215,  212,  211,  225,  222,
+      221,    0,  209,  204,  216,  215,  161,  163,  216,    0,
 
-      159,  161,  222,    0,  208,  218,    0,  209,  210,  204,
-        0,    0,    0,  201,  206,  200,  199,  202,  205,  200,
-      195,  193,  202,  193,  199,    0,  193,  198,    0,  192,
-      185,  185,  198,    0,  186,  185,  190,  187,  194,    0,
-      196,    0,    0,  183,  183,  180,    0,  174,  186,    0,
-        0,    0,  185,  175,  165,  169,  169,    0,  180,  173,
-        0,    0,  180,  169,    0,    0,  172,    0,  157,  161,
-        0,  174,    0,  168,  171,  147,  156,  145,  132,    0,
-      119,  113,  109,  108,   91,   73,    0,  361,  177,  180,
-      183,  186,  191,  196,  198,  201
-
+      202,  212,    0,  203,  204,  198,    0,    0,    0,  195,
+      200,  194,  193,  196,  199,  194,  189,  187,  196,  187,
+      193,    0,  187,  192,    0,  186,  179,  179,  192,    0,
+      180,  179,  184,  181,  188,    0,  190,    0,    0,  177,
+      177,  174,  354,  168,  180,    0,    0,    0,  179,  169,
+      159,  163,  163,    0,  174,  167,    0,    0,  174,  163,
+        0,    0,  166,    0,  151,  155,    0,  168,    0,  157,
+      147,  119,  125,  118,  109,    0,  104,  100,   97,   87,
+       64,   63,    0,  354,  179,  182,  185,  190,  195,  197
     } ;
 
-static yyconst flex_int16_t yy_def[297] =
+static yyconst flex_int16_t yy_def[291] =
     {   0,
-      288,    1,  288,  288,  288,  288,  288,  289,  290,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  291,  288,  288,
-      288,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  288,
-      288,  288,  288,  288,  288,  292,  290,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  293,  294,  288,
-      288,  288,  288,  295,  288,  288,  288,  288,  288,  288,
-      296,  296,  296,  288,  288,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
+      284,    1,  284,  284,  284,  284,  284,  285,  286,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  284,
+      284,  284,  284,  284,  284,  287,  286,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  288,  289,  284,  284,
+      284,  284,  290,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
 
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  288,  288,  292,  288,  288,  293,
-      293,  294,  288,  288,  288,  288,  295,  288,  288,  296,
-      296,  296,  288,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  288,  288,  288,  288,  288,  288,  288,
-      296,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  284,  284,  287,  284,  284,  288,  288,  289,  284,
+      284,  284,  284,  290,  284,  284,  284,  284,  284,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  284,
+      284,  284,  284,  284,  284,  284,  284,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  284,  284,  284,  286,
 
-      288,  288,  296,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  296,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  296,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,  290,  290,  290,
-      290,  290,  290,  290,  290,  290,  290,    0,  288,  288,
-      288,  288,  288,  288,  288,  288
-
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  284,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  284,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,  286,  286,  286,  286,  286,  286,  286,
+      286,  286,  286,    0,  284,  284,  284,  284,  284,  284
     } ;
 
-static yyconst flex_uint16_t yy_nxt[420] =
+static yyconst flex_uint16_t yy_nxt[413] =
     {   0,
         4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
        14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
@@ -536,49 +526,49 @@
         9,    9,   32,   33,   34,   35,   36,    9,   37,   38,
         9,   39,   40,   41,   42,   43,   44,   45,   46,   47,
        48,   49,    9,    9,   50,   51,   52,   53,   54,   54,
-       54,   54,   59,   62,   67,   67,   64,   68,   71,   82,
-       72,   72,   69,   63,   65,   66,   60,   83,   70,   71,
-       73,   72,   72,   76,   77,   79,   80,   84,   88,   73,
-       86,   73,   94,   87,   90,   85,  100,   98,   91,  107,
+       54,   54,   59,   62,   64,   66,   66,   74,   75,   67,
+       77,   78,   65,   63,   68,   70,   60,   71,   71,   70,
+       69,   71,   71,   83,   79,   81,   84,   72,   85,   97,
+       87,   72,   80,   82,   88,   91,   72,   95,  104,   89,
 
-       73,   89,   95,   92,   99,   96,   74,  108,  113,  101,
-      109,  115,   54,   54,   67,   67,  114,  123,  123,   71,
-      287,   72,   72,  125,  119,  125,  153,  124,  126,  126,
-      137,   73,  165,  119,  165,  138,  124,  166,  166,  286,
-       73,  285,  154,  155,  284,  116,  123,  123,  169,  283,
-      169,  126,  126,  170,  170,  282,  168,  126,  126,  176,
-      177,  166,  166,  166,  166,  168,  201,  281,  201,  170,
-      170,  202,  202,  170,  170,  202,  202,  202,  202,   56,
-      280,   56,   57,   57,   57,   81,  279,   81,  117,  117,
-      117,  120,  120,  120,  120,  120,  122,  278,  122,  122,
+       72,   86,   98,  110,   96,   92,  105,  112,   93,  106,
+      283,  111,  282,   73,   54,   54,   66,   66,  120,  120,
+      281,   70,  149,   71,   71,  122,  116,  122,  121,  133,
+      123,  123,  280,   72,  134,  116,  279,  121,  150,  151,
+      278,  113,   72,  161,  277,  161,  120,  120,  162,  162,
+      123,  123,  165,  276,  165,  275,  164,  166,  166,  123,
+      123,  172,  173,  162,  162,  164,  162,  162,  197,  274,
+      197,  166,  166,  198,  198,  166,  166,  198,  198,  198,
+      198,   56,  273,   56,   57,   57,   57,  114,  114,  114,
+      117,  117,  117,  117,  117,  119,  272,  119,  119,  119,
 
-      122,  127,  127,  130,  130,  130,  277,  276,  275,  274,
-      273,  272,  271,  270,  269,  268,  267,  266,  265,  264,
+      124,  124,  271,  270,  269,  268,  267,  266,  265,  264,
       263,  262,  261,  260,  259,  258,  257,  256,  255,  254,
       253,  252,  251,  250,  249,  248,  247,  246,  245,  244,
       243,  242,  241,  240,  239,  238,  237,  236,  235,  234,
       233,  232,  231,  230,  229,  228,  227,  226,  225,  224,
       223,  222,  221,  220,  219,  218,  217,  216,  215,  214,
       213,  212,  211,  210,  209,  208,  207,  206,  205,  204,
-      203,  200,  199,  198,  197,  196,  195,  194,  193,  192,
+      203,  202,  201,  200,  199,  196,  195,  194,  193,  192,
       191,  190,  189,  188,  187,  186,  185,  184,  183,  182,
+      181,  180,  179,  178,  177,  176,  175,  174,  171,  170,
 
-      181,  180,  179,  178,  175,  174,  173,  172,  171,  167,
-      121,  164,  163,  162,  161,  160,  159,  158,  157,  156,
-      152,  151,  150,  149,  148,  147,  146,  145,  144,  143,
-      142,  141,  140,  139,  136,  135,  134,  133,  132,  131,
-      129,  128,  121,  118,  112,  111,  110,  106,  105,  104,
-      103,  102,   97,   93,   78,   75,   61,   58,   55,  288,
-        3,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
+      169,  168,  167,  163,  118,  160,  159,  158,  157,  156,
+      155,  154,  153,  152,  148,  147,  146,  145,  144,  143,
+      142,  141,  140,  139,  138,  137,  136,  135,  132,  131,
+      130,  129,  128,  127,  126,  125,  118,  115,  109,  108,
+      107,  103,  102,  101,  100,   99,   94,   90,   76,   61,
+       58,   55,  284,    3,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
 
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284
     } ;
 
-static yyconst flex_int16_t yy_chk[420] =
+static yyconst flex_int16_t yy_chk[413] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -586,57 +576,56 @@
         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,   18,   18,   17,   19,   20,   28,
-       20,   20,   19,   15,   17,   17,   11,   28,   19,   21,
-       20,   21,   21,   24,   24,   26,   26,   31,   33,   20,
-       32,   21,   36,   32,   34,   31,   39,   38,   34,   45,
+        6,    6,   11,   15,   17,   18,   18,   24,   24,   19,
+       26,   26,   17,   15,   19,   20,   11,   20,   20,   21,
+       19,   21,   21,   32,   28,   31,   32,   20,   33,   39,
+       34,   21,   28,   31,   34,   36,   20,   38,   45,   34,
 
-       21,   33,   36,   34,   38,   36,   20,   45,   49,   39,
-       45,   51,   54,   54,   67,   67,   49,   71,   71,   72,
-      286,   72,   72,   73,   67,   73,  106,   71,   73,   73,
-       89,   72,  119,   67,  119,   89,   71,  119,  119,  285,
-       72,  284,  106,  106,  283,   51,  123,  123,  124,  282,
-      124,  125,  125,  124,  124,  281,  123,  126,  126,  138,
-      138,  165,  165,  166,  166,  123,  168,  279,  168,  169,
-      169,  168,  168,  170,  170,  201,  201,  202,  202,  289,
-      278,  289,  290,  290,  290,  291,  277,  291,  292,  292,
-      292,  293,  293,  293,  293,  293,  294,  276,  294,  294,
+       21,   33,   39,   49,   38,   36,   45,   51,   36,   45,
+      282,   49,  281,   20,   54,   54,   66,   66,   70,   70,
+      280,   71,  103,   71,   71,   72,   66,   72,   70,   86,
+       72,   72,  279,   71,   86,   66,  278,   70,  103,  103,
+      277,   51,   71,  116,  275,  116,  120,  120,  116,  116,
+      122,  122,  121,  274,  121,  273,  120,  121,  121,  123,
+      123,  134,  134,  161,  161,  120,  162,  162,  164,  272,
+      164,  165,  165,  164,  164,  166,  166,  197,  197,  198,
+      198,  285,  271,  285,  286,  286,  286,  287,  287,  287,
+      288,  288,  288,  288,  288,  289,  270,  289,  289,  289,
 
-      294,  295,  295,  296,  296,  296,  275,  274,  272,  270,
-      269,  267,  264,  263,  260,  259,  257,  256,  255,  254,
-      253,  249,  248,  246,  245,  244,  241,  239,  238,  237,
-      236,  235,  233,  232,  231,  230,  228,  227,  225,  224,
-      223,  222,  221,  220,  219,  218,  217,  216,  215,  214,
-      210,  209,  208,  206,  205,  203,  200,  199,  198,  197,
-      195,  194,  193,  192,  191,  190,  189,  188,  187,  185,
-      184,  183,  181,  179,  178,  177,  176,  175,  173,  172,
-      171,  163,  162,  161,  160,  159,  158,  157,  156,  155,
-      154,  153,  152,  150,  149,  148,  147,  146,  145,  143,
+      290,  290,  268,  266,  265,  263,  260,  259,  256,  255,
+      253,  252,  251,  250,  249,  245,  244,  242,  241,  240,
+      237,  235,  234,  233,  232,  231,  229,  228,  227,  226,
+      224,  223,  221,  220,  219,  218,  217,  216,  215,  214,
+      213,  212,  211,  210,  206,  205,  204,  202,  201,  199,
+      196,  195,  194,  193,  191,  190,  189,  188,  187,  186,
+      185,  184,  183,  181,  180,  179,  177,  175,  174,  173,
+      172,  171,  169,  168,  167,  159,  158,  157,  156,  155,
+      154,  153,  152,  151,  150,  149,  148,  146,  145,  144,
+      143,  142,  141,  139,  138,  137,  136,  135,  133,  132,
 
-      142,  141,  140,  139,  137,  136,  135,  134,  132,  121,
-      120,  116,  114,  113,  112,  111,  110,  109,  108,  107,
-      105,  104,  103,  102,  101,  100,   99,   97,   96,   95,
-       94,   93,   91,   90,   88,   87,   86,   85,   83,   82,
-       80,   76,   68,   59,   48,   47,   46,   44,   43,   42,
-       41,   40,   37,   35,   25,   22,   14,   10,    7,    3,
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
+      131,  130,  128,  118,  117,  113,  111,  110,  109,  108,
+      107,  106,  105,  104,  102,  101,  100,   99,   98,   97,
+       96,   94,   93,   92,   91,   90,   88,   87,   85,   84,
+       83,   82,   80,   79,   78,   74,   67,   59,   48,   47,
+       46,   44,   43,   42,   41,   40,   37,   35,   25,   14,
+       10,    7,    3,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
 
-      288,  288,  288,  288,  288,  288,  288,  288,  288,  288,
-      288,  288,  288,  288,  288,  288,  288,  288,  288
+      284,  284,  284,  284,  284,  284,  284,  284,  284,  284,
+      284,  284
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[100] =
+static yyconst flex_int32_t yy_rule_can_match_eol[97] =
     {   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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 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.
@@ -665,7 +654,7 @@
 
 */
 #define YY_NO_UNISTD_H 1
-#line 663 "lex.sksl.c"
+#line 658 "lex.sksl.c"
 
 #define INITIAL 0
 
@@ -929,7 +918,7 @@
 #line 30 "sksl.flex"
 
 
-#line 927 "lex.sksl.c"
+#line 922 "lex.sksl.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -956,13 +945,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 >= 289 )
+				if ( yy_current_state >= 285 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 288 );
+		while ( yy_current_state != 284 );
 		yy_cp = yyg->yy_last_accepting_cpos;
 		yy_current_state = yyg->yy_last_accepting_state;
 
@@ -1212,286 +1201,271 @@
 case 44:
 YY_RULE_SETUP
 #line 118 "sksl.flex"
-{ return SkSL::Token::SECTION; }
+{ return SkSL::Token::LPAREN; }
 	YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 120 "sksl.flex"
-{ return SkSL::Token::LPAREN; }
+{ return SkSL::Token::RPAREN; }
 	YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 122 "sksl.flex"
-{ return SkSL::Token::RPAREN; }
+{ return SkSL::Token::LBRACE; }
 	YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 124 "sksl.flex"
-{ return SkSL::Token::LBRACE; }
+{ return SkSL::Token::RBRACE; }
 	YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 126 "sksl.flex"
-{ return SkSL::Token::RBRACE; }
+{ return SkSL::Token::LBRACKET; }
 	YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 128 "sksl.flex"
-{ return SkSL::Token::LBRACKET; }
+{ return SkSL::Token::RBRACKET; }
 	YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 130 "sksl.flex"
-{ return SkSL::Token::RBRACKET; }
+{ return SkSL::Token::DOT; }
 	YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 132 "sksl.flex"
-{ return SkSL::Token::DOT; }
+{ return SkSL::Token::COMMA; }
 	YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 134 "sksl.flex"
-{ return SkSL::Token::COMMA; }
+{ return SkSL::Token::PLUSPLUS; }
 	YY_BREAK
 case 53:
 YY_RULE_SETUP
 #line 136 "sksl.flex"
-{ return SkSL::Token::PLUSPLUS; }
+{ return SkSL::Token::MINUSMINUS; }
 	YY_BREAK
 case 54:
 YY_RULE_SETUP
 #line 138 "sksl.flex"
-{ return SkSL::Token::MINUSMINUS; }
+{ return SkSL::Token::PLUS; }
 	YY_BREAK
 case 55:
 YY_RULE_SETUP
 #line 140 "sksl.flex"
-{ return SkSL::Token::PLUS; }
+{ return SkSL::Token::MINUS; }
 	YY_BREAK
 case 56:
 YY_RULE_SETUP
 #line 142 "sksl.flex"
-{ return SkSL::Token::MINUS; }
+{ return SkSL::Token::STAR; }
 	YY_BREAK
 case 57:
 YY_RULE_SETUP
 #line 144 "sksl.flex"
-{ return SkSL::Token::STAR; }
+{ return SkSL::Token::SLASH; }
 	YY_BREAK
 case 58:
 YY_RULE_SETUP
 #line 146 "sksl.flex"
-{ return SkSL::Token::SLASH; }
+{ return SkSL::Token::PERCENT; }
 	YY_BREAK
 case 59:
 YY_RULE_SETUP
 #line 148 "sksl.flex"
-{ return SkSL::Token::PERCENT; }
+{ return SkSL::Token::SHL; }
 	YY_BREAK
 case 60:
 YY_RULE_SETUP
 #line 150 "sksl.flex"
-{ return SkSL::Token::SHL; }
+{ return SkSL::Token::SHR; }
 	YY_BREAK
 case 61:
 YY_RULE_SETUP
 #line 152 "sksl.flex"
-{ return SkSL::Token::SHR; }
+{ return SkSL::Token::BITWISEOR; }
 	YY_BREAK
 case 62:
 YY_RULE_SETUP
 #line 154 "sksl.flex"
-{ return SkSL::Token::BITWISEOR; }
+{ return SkSL::Token::BITWISEXOR; }
 	YY_BREAK
 case 63:
 YY_RULE_SETUP
 #line 156 "sksl.flex"
-{ return SkSL::Token::BITWISEXOR; }
+{ return SkSL::Token::BITWISEAND; }
 	YY_BREAK
 case 64:
 YY_RULE_SETUP
 #line 158 "sksl.flex"
-{ return SkSL::Token::BITWISEAND; }
+{ return SkSL::Token::BITWISENOT; }
 	YY_BREAK
 case 65:
 YY_RULE_SETUP
 #line 160 "sksl.flex"
-{ return SkSL::Token::BITWISENOT; }
+{ return SkSL::Token::LOGICALOR; }
 	YY_BREAK
 case 66:
 YY_RULE_SETUP
 #line 162 "sksl.flex"
-{ return SkSL::Token::LOGICALOR; }
+{ return SkSL::Token::LOGICALXOR; }
 	YY_BREAK
 case 67:
 YY_RULE_SETUP
 #line 164 "sksl.flex"
-{ return SkSL::Token::LOGICALXOR; }
+{ return SkSL::Token::LOGICALAND; }
 	YY_BREAK
 case 68:
 YY_RULE_SETUP
 #line 166 "sksl.flex"
-{ return SkSL::Token::LOGICALAND; }
+{ return SkSL::Token::LOGICALNOT; }
 	YY_BREAK
 case 69:
 YY_RULE_SETUP
 #line 168 "sksl.flex"
-{ return SkSL::Token::LOGICALNOT; }
+{ return SkSL::Token::QUESTION; }
 	YY_BREAK
 case 70:
 YY_RULE_SETUP
 #line 170 "sksl.flex"
-{ return SkSL::Token::QUESTION; }
+{ return SkSL::Token::COLON; }
 	YY_BREAK
 case 71:
 YY_RULE_SETUP
 #line 172 "sksl.flex"
-{ return SkSL::Token::COLON; }
+{ return SkSL::Token::EQ; }
 	YY_BREAK
 case 72:
 YY_RULE_SETUP
 #line 174 "sksl.flex"
-{ return SkSL::Token::EQ; }
+{ return SkSL::Token::EQEQ; }
 	YY_BREAK
 case 73:
 YY_RULE_SETUP
 #line 176 "sksl.flex"
-{ return SkSL::Token::EQEQ; }
+{ return SkSL::Token::NEQ; }
 	YY_BREAK
 case 74:
 YY_RULE_SETUP
 #line 178 "sksl.flex"
-{ return SkSL::Token::NEQ; }
+{ return SkSL::Token::GT; }
 	YY_BREAK
 case 75:
 YY_RULE_SETUP
 #line 180 "sksl.flex"
-{ return SkSL::Token::GT; }
+{ return SkSL::Token::LT; }
 	YY_BREAK
 case 76:
 YY_RULE_SETUP
 #line 182 "sksl.flex"
-{ return SkSL::Token::LT; }
+{ return SkSL::Token::GTEQ; }
 	YY_BREAK
 case 77:
 YY_RULE_SETUP
 #line 184 "sksl.flex"
-{ return SkSL::Token::GTEQ; }
+{ return SkSL::Token::LTEQ; }
 	YY_BREAK
 case 78:
 YY_RULE_SETUP
 #line 186 "sksl.flex"
-{ return SkSL::Token::LTEQ; }
+{ return SkSL::Token::PLUSEQ; }
 	YY_BREAK
 case 79:
 YY_RULE_SETUP
 #line 188 "sksl.flex"
-{ return SkSL::Token::PLUSEQ; }
+{ return SkSL::Token::MINUSEQ; }
 	YY_BREAK
 case 80:
 YY_RULE_SETUP
 #line 190 "sksl.flex"
-{ return SkSL::Token::MINUSEQ; }
+{ return SkSL::Token::STAREQ; }
 	YY_BREAK
 case 81:
 YY_RULE_SETUP
 #line 192 "sksl.flex"
-{ return SkSL::Token::STAREQ; }
+{ return SkSL::Token::SLASHEQ; }
 	YY_BREAK
 case 82:
 YY_RULE_SETUP
 #line 194 "sksl.flex"
-{ return SkSL::Token::SLASHEQ; }
+{ return SkSL::Token::PERCENTEQ; }
 	YY_BREAK
 case 83:
 YY_RULE_SETUP
 #line 196 "sksl.flex"
-{ return SkSL::Token::PERCENTEQ; }
+{ return SkSL::Token::SHLEQ; }
 	YY_BREAK
 case 84:
 YY_RULE_SETUP
 #line 198 "sksl.flex"
-{ return SkSL::Token::SHLEQ; }
+{ return SkSL::Token::SHREQ; }
 	YY_BREAK
 case 85:
 YY_RULE_SETUP
 #line 200 "sksl.flex"
-{ return SkSL::Token::SHREQ; }
+{ return SkSL::Token::BITWISEOREQ; }
 	YY_BREAK
 case 86:
 YY_RULE_SETUP
 #line 202 "sksl.flex"
-{ return SkSL::Token::BITWISEOREQ; }
+{ return SkSL::Token::BITWISEXOREQ; }
 	YY_BREAK
 case 87:
 YY_RULE_SETUP
 #line 204 "sksl.flex"
-{ return SkSL::Token::BITWISEXOREQ; }
+{ return SkSL::Token::BITWISEANDEQ; }
 	YY_BREAK
 case 88:
 YY_RULE_SETUP
 #line 206 "sksl.flex"
-{ return SkSL::Token::BITWISEANDEQ; }
+{ return SkSL::Token::LOGICALOREQ; }
 	YY_BREAK
 case 89:
 YY_RULE_SETUP
 #line 208 "sksl.flex"
-{ return SkSL::Token::LOGICALOREQ; }
+{ return SkSL::Token::LOGICALXOREQ; }
 	YY_BREAK
 case 90:
 YY_RULE_SETUP
 #line 210 "sksl.flex"
-{ return SkSL::Token::LOGICALXOREQ; }
+{ return SkSL::Token::LOGICALANDEQ; }
 	YY_BREAK
 case 91:
 YY_RULE_SETUP
 #line 212 "sksl.flex"
-{ return SkSL::Token::LOGICALANDEQ; }
+{ return SkSL::Token::SEMICOLON; }
 	YY_BREAK
 case 92:
 YY_RULE_SETUP
 #line 214 "sksl.flex"
-{ return SkSL::Token::SEMICOLON; }
+/* line comment */
 	YY_BREAK
 case 93:
+/* rule 93 can match eol */
 YY_RULE_SETUP
 #line 216 "sksl.flex"
-{ return SkSL::Token::ARROW; }
+/* block comment */
 	YY_BREAK
 case 94:
+/* rule 94 can match eol */
 YY_RULE_SETUP
 #line 218 "sksl.flex"
-{ return SkSL::Token::COLONCOLON; }
+/* whitespace */
 	YY_BREAK
 case 95:
-/* rule 95 can match eol */
 YY_RULE_SETUP
 #line 220 "sksl.flex"
-{ return SkSL::Token::WHITESPACE; }
+{ return SkSL::Token::INVALID_TOKEN; }
 	YY_BREAK
 case 96:
 YY_RULE_SETUP
 #line 222 "sksl.flex"
-/* line comment */
-	YY_BREAK
-case 97:
-/* rule 97 can match eol */
-YY_RULE_SETUP
-#line 224 "sksl.flex"
-/* block comment */
-	YY_BREAK
-case 98:
-YY_RULE_SETUP
-#line 226 "sksl.flex"
-{ return SkSL::Token::INVALID_TOKEN; }
-	YY_BREAK
-case 99:
-YY_RULE_SETUP
-#line 228 "sksl.flex"
 ECHO;
 	YY_BREAK
-#line 1489 "lex.sksl.c"
+#line 1469 "lex.sksl.c"
 case YY_STATE_EOF(INITIAL):
 	yyterminate();
 
@@ -1787,7 +1761,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 >= 289 )
+			if ( yy_current_state >= 285 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
@@ -1816,11 +1790,11 @@
 	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 >= 289 )
+		if ( yy_current_state >= 285 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c];
-	yy_is_jam = (yy_current_state == 288);
+	yy_is_jam = (yy_current_state == 284);
 
 	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
@@ -2672,7 +2646,7 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 228 "sksl.flex"
+#line 222 "sksl.flex"
 
 
 
diff --git a/src/sksl/sksl.flex b/src/sksl/sksl.flex
index 275a4e6..c5d5ec3 100644
--- a/src/sksl/sksl.flex
+++ b/src/sksl/sksl.flex
@@ -115,8 +115,6 @@
 
 "#"{LETTER}({DIGIT}|{LETTER})* { return SkSL::Token::DIRECTIVE; }
 
-"@"{LETTER}({DIGIT}|{LETTER})* { return SkSL::Token::SECTION; }
-
 "(" { return SkSL::Token::LPAREN; }
 
 ")" { return SkSL::Token::RPAREN; }
@@ -213,16 +211,12 @@
 
 ";" { return SkSL::Token::SEMICOLON; }
 
-"->" { return SkSL::Token::ARROW; }
-
-"::" { return SkSL::Token::COLONCOLON; }
-
-[ \t\r\n]+ { return SkSL::Token::WHITESPACE; }
-
 "//".* /* line comment */
 
 "/*"([^*]|"*"[^/])*"*/" /* block comment */
 
+[ \t\r\n]+  /* whitespace */
+
 .    { return SkSL::Token::INVALID_TOKEN; }
 
 %%
diff --git a/src/sksl/sksl_fp.include b/src/sksl/sksl_fp.include
deleted file mode 100644
index 566e441..0000000
--- a/src/sksl/sksl_fp.include
+++ /dev/null
@@ -1,23 +0,0 @@
-STRINGIFY(
-
-// defines built-in interfaces supported by SkiaSL fragment shaders
-
-layout(builtin=15) in vec4 sk_FragCoord;
-layout(builtin=3) float sk_ClipDistance[1];
-
-// 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[1];
-layout(builtin=9999) out int gl_SampleMask[1];
-layout(builtin=9999) vec4 gl_SecondaryFragColorEXT;
-
-layout(builtin=10003) vec4 sk_InColor;
-layout(builtin=10004) out vec4 sk_OutColor;
-layout(builtin=10005) vec2[] sk_TransformedCoords2D;
-layout(builtin=10006) sampler2D[] sk_TextureSamplers;
-)
diff --git a/tests/SkSLFPTest.cpp b/tests/SkSLFPTest.cpp
deleted file mode 100644
index 6f1326d..0000000
--- a/tests/SkSLFPTest.cpp
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkSLCompiler.h"
-
-#include "Test.h"
-
-#if SK_SUPPORT_GPU
-
-static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& caps,
-                 std::vector<const char*> expectedH, std::vector<const char*> expectedCPP) {
-    SkSL::Program::Settings settings;
-    settings.fCaps = &caps;
-    SkSL::Compiler compiler;
-    SkSL::StringStream output;
-    std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
-                                                             SkSL::Program::kFragmentProcessor_Kind,
-                                                             SkString(src),
-                                                             settings);
-    if (!program) {
-        SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
-        return;
-    }
-    REPORTER_ASSERT(r, program);
-    bool success = compiler.toH(*program, "Test", output);
-    if (!success) {
-        SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
-    }
-    REPORTER_ASSERT(r, success);
-    if (success) {
-        for (const char* expected : expectedH) {
-            bool found = strstr(output.str().c_str(), expected);
-            if (!found) {
-                SkDebugf("HEADER MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
-                         expected, output.str().c_str());
-            }
-            REPORTER_ASSERT(r, found);
-        }
-    }
-    output.reset();
-    success = compiler.toCPP(*program, "Test", output);
-    if (!success) {
-        SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
-    }
-    REPORTER_ASSERT(r, success);
-    if (success) {
-        for (const char* expected : expectedCPP) {
-            bool found = strstr(output.str().c_str(), expected);
-            if (!found) {
-                SkDebugf("CPP MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
-                         expected, output.str().c_str());
-            }
-            REPORTER_ASSERT(r, found);
-        }
-    }
-}
-
-DEF_TEST(SkSLFPHelloWorld, r) {
-    test(r,
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             "/*\n"
-             " * This file was autogenerated from GrTest.fp.\n"
-             " */\n"
-             "#ifndef GrTest_DEFINED\n"
-             "#define GrTest_DEFINED\n"
-             "#include \"GrFragmentProcessor.h\"\n"
-             "#include \"GrCoordTransform.h\"\n"
-             "#include \"effects/GrProxyMove.h\"\n"
-             "class GrTest : public GrFragmentProcessor {\n"
-             "public:\n"
-             "    static sk_sp<GrFragmentProcessor> Make() {\n"
-             "        return sk_sp<GrFragmentProcessor>(new GrTest());\n"
-             "    }\n"
-             "    const char* name() const override { return \"Test\"; }\n"
-             "private:\n"
-             "    GrTest()\n"
-             "    : INHERITED(kNone_OptimizationFlags) {\n"
-             "        this->initClassID<GrTest>();\n"
-             "    }\n"
-             "    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n"
-             "    void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) "
-                    "const override;\n"
-             "    bool onIsEqual(const GrFragmentProcessor&) const override;\n"
-             "    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;\n"
-             "    typedef GrFragmentProcessor INHERITED;\n"
-             "};\n"
-             "#endif\n"
-         },
-         {
-             "/*\n"
-             " * This file was autogenerated from GrTest.fp.\n"
-             " */\n"
-             "#include \"GrTest.h\"\n"
-             "#include \"glsl/GrGLSLColorSpaceXformHelper.h\"\n"
-             "#include \"glsl/GrGLSLFragmentProcessor.h\"\n"
-             "#include \"glsl/GrGLSLFragmentShaderBuilder.h\"\n"
-             "#include \"glsl/GrGLSLProgramBuilder.h\"\n"
-             "#include \"GrResourceProvider.h\"\n"
-             "#include \"SkSLCPP.h\"\n"
-             "#include \"SkSLUtil.h\"\n"
-             "class GrGLSLTest : public GrGLSLFragmentProcessor {\n"
-             "public:\n"
-             "    GrGLSLTest() {}\n"
-             "    void emitCode(EmitArgs& args) override {\n"
-             "        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n"
-             "        const GrTest& _outer = args.fFp.cast<GrTest>();\n"
-             "        (void) _outer;\n"
-             "        fragBuilder->codeAppendf(\"%s = vec4(1.0);\\n\", args.fOutputColor);\n"
-             "    }\n"
-             "private:\n"
-             "    void onSetData(const GrGLSLProgramDataManager& pdman, "
-                                "const GrFragmentProcessor& _proc) override {\n"
-             "    }\n"
-             "};\n"
-             "GrGLSLFragmentProcessor* GrTest::onCreateGLSLInstance() const {\n"
-             "    return new GrGLSLTest();\n"
-             "}\n"
-             "void GrTest::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
-                                                "GrProcessorKeyBuilder* b) const {\n"
-             "}\n"
-             "bool GrTest::onIsEqual(const GrFragmentProcessor& other) const {\n"
-             "    const GrTest& that = other.cast<GrTest>();\n"
-             "    (void) that;\n"
-             "    return true;\n"
-             "}\n"
-         });
-}
-
-DEF_TEST(SkSLFPInput, r) {
-    test(r,
-         "in vec2 point;"
-         "void main() {"
-         "sk_OutColor = vec4(point, point);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             "SkPoint point() const { return fPoint; }",
-             "static sk_sp<GrFragmentProcessor> Make(SkPoint point) {",
-             "return sk_sp<GrFragmentProcessor>(new GrTest(point));",
-             "GrTest(SkPoint point)",
-             ", fPoint(point)"
-         },
-         {
-             "fragBuilder->codeAppendf(\"%s = vec4(vec2(%f, %f), vec2(%f, %f));\\n\", "
-                                      "args.fOutputColor, _outer.point().fX, _outer.point().fY, "
-                                      "_outer.point().fX, _outer.point().fY);",
-             "if (fPoint != that.fPoint) return false;"
-         });
-}
-
-DEF_TEST(SkSLFPUniform, r) {
-    test(r,
-         "uniform vec4 color;"
-         "void main() {"
-         "sk_OutColor = color;"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             "static sk_sp<GrFragmentProcessor> Make()"
-         },
-         {
-            "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
-                                                         "kDefault_GrSLPrecision, \"color\");",
-         });
-}
-
-DEF_TEST(SkSLFPInUniform, r) {
-    test(r,
-         "in uniform vec4 color;"
-         "void main() {"
-         "sk_OutColor = color;"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             "static sk_sp<GrFragmentProcessor> Make(SkRect color) {",
-         },
-         {
-            "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
-                                                         "kDefault_GrSLPrecision, \"color\");",
-            "const SkRect colorValue = _outer.color();",
-            "pdman.set4fv(fColorVar, 4, (float*) &colorValue);"
-         });
-}
-
-DEF_TEST(SkSLFPSections, r) {
-    test(r,
-         "@header { header section }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             "header section class GrTest",
-         },
-         {});
-    test(r,
-         "@class { class section }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             "class GrTest : public GrFragmentProcessor {\n"
-             "public:\n"
-             " class section"
-         },
-         {});
-    test(r,
-         "@cpp { cpp section }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {},
-         {"cpp section"});
-    test(r,
-         "@constructorParams { int x, float y, std::vector<float> z }"
-         "in float w;"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             "Make(float w,  int x, float y, std::vector<float> z )",
-             "return sk_sp<GrFragmentProcessor>(new GrTest(w, x, y, z));",
-             "GrTest(float w,  int x, float y, std::vector<float> z )",
-             ", fW(w) {"
-         },
-         {});
-    test(r,
-         "@constructor { constructor section }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             "private:\n constructor section"
-         },
-         {});
-    test(r,
-         "@initializers { initializers section }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-             ": INHERITED(kNone_OptimizationFlags)\n    ,  initializers section"
-         },
-         {});
-    test(r,
-         "float x = 10;"
-         "@emitCode { fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2); }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {},
-         {
-            "x = 10.0;\n"
-            " fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2);"
-         });
-    test(r,
-         "@fields { fields section }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-            "GR_DECLARE_FRAGMENT_PROCESSOR_TEST;\n"
-            " fields section     typedef GrFragmentProcessor INHERITED;"
-         },
-         {});
-    test(r,
-         "@make { make section }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-            "public:\n"
-            " make section"
-         },
-         {});
-    test(r,
-         "uniform float calculated;"
-         "in float provided;"
-         "@setData(varName) { varName.set1f(calculated, provided * 2); }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {},
-         {
-             "void onSetData(const GrGLSLProgramDataManager& varName, "
-                            "const GrFragmentProcessor& _proc) override {\n",
-             "UniformHandle& calculated = fCalculatedVar;",
-             "auto provided = _outer.provided();",
-             "varName.set1f(calculated, provided * 2);"
-         });
-    test(r,
-         "@test(testDataName) { testDataName section }"
-         "void main() {"
-         "sk_OutColor = vec4(1);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {},
-         {
-             "#if GR_TEST_UTILS\n"
-             "sk_sp<GrFragmentProcessor> GrTest::TestCreate(GrProcessorTestData* testDataName) {\n"
-             " testDataName section }\n"
-             "#endif"
-         });
-}
-
-DEF_TEST(SkSLFPColorSpaceXform, r) {
-    test(r,
-         "in uniform sampler2D image;"
-         "in uniform colorSpaceXform colorXform;"
-         "void main() {"
-         "sk_OutColor = sk_InColor * texture(image, vec2(0, 0), colorXform);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {
-            "sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; }",
-            "GrTest(sk_sp<GrTextureProxy> image, sk_sp<GrColorSpaceXform> colorXform)",
-            "this->addTextureSampler(&fImage);",
-            "sk_sp<GrColorSpaceXform> fColorXform;"
-         },
-         {
-            "fragBuilder->codeAppendf(\"vec4 _tmp0;\\n%s = %s * "
-            "(_tmp0 = texture(%s, vec2(0.0, 0.0)) , %s != mat4(1.0) ? "
-            "vec4(clamp((%s * vec4(_tmp0.xyz, 1.0)).xyz, 0.0, _tmp0.w), _tmp0.w) : "
-            "_tmp0);\\n\", args.fOutputColor, args.fInputColor ? args.fInputColor : "
-            "\"vec4(1)\", fragBuilder->getProgramBuilder()->samplerVariable("
-            "args.fTexSamplers[0]).c_str(), fColorSpaceHelper.isValid() ? "
-            "args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "
-            "\"mat4(1.0)\", fColorSpaceHelper.isValid() ? "
-            "args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "
-            "\"mat4(1.0)\");"
-         });
-}
-
-DEF_TEST(SkSLFPTransformedCoords, r) {
-    test(r,
-         "void main() {"
-         "sk_OutColor = vec4(sk_TransformedCoords2D[0], sk_TransformedCoords2D[0]);"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {},
-         {
-            "SkSL::String sk_TransformedCoords2D_0 = "
-                                         "fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);",
-            "fragBuilder->codeAppendf(\"%s = vec4(%s, %s);\\n\", args.fOutputColor, "
-                              "sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str());"
-         });
-
-}
-
-DEF_TEST(SkSLFPLayoutWhen, r) {
-    test(r,
-         "layout(when=someExpression(someOtherExpression())) uniform float sometimes;"
-         "void main() {"
-         "}",
-         *SkSL::ShaderCapsFactory::Default(),
-         {},
-         {
-            "if (someExpression(someOtherExpression())) {\n"
-            "            fSometimesVar = args.fUniformHandler->addUniform"
-         });
-
-}
-
-#endif
diff --git a/tests/SkSLGLSLTest.cpp b/tests/SkSLGLSLTest.cpp
index 8f09d6b..a4a3c0e 100644
--- a/tests/SkSLGLSLTest.cpp
+++ b/tests/SkSLGLSLTest.cpp
@@ -487,8 +487,7 @@
          "void main() { sk_FragColor.r = 1; }",
          *SkSL::ShaderCapsFactory::ShaderDerivativeExtensionString(),
          "#version 400\n"
-         "precision highp float;\n"
-         "out mediump vec4 sk_FragColor;\n"
+         "out vec4 sk_FragColor;\n"
          "void main() {\n"
          "    sk_FragColor.x = 1.0;\n"
          "}\n");
@@ -497,8 +496,7 @@
          *SkSL::ShaderCapsFactory::ShaderDerivativeExtensionString(),
          "#version 400\n"
          "#extension GL_OES_standard_derivatives : require\n"
-         "precision highp float;\n"
-         "out mediump vec4 sk_FragColor;\n"
+         "out vec4 sk_FragColor;\n"
          "void main() {\n"
          "    sk_FragColor.x = dFdx(1.0);\n"
          "}\n");