Add support for SPIRV reading to BUILD.gn

BUG=dawn:16

Change-Id: I1da30fed82a310007674801e3b1e853b25d5b573
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/19640
Reviewed-by: dan sinclair <dsinclair@google.com>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index bbc3277..aebdacf 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -13,16 +13,30 @@
 # limitations under the License.
 
 import("//build_overrides/build.gni")
-import("//build_overrides/tint.gni")
+import("tint_overrides_with_defaults.gni")
 
 config("tint_common_config") {
   cflags = []
   ldflags = []
   include_dirs = []
   defines = []
+
+  if (tint_build_spv_reader) {
+    defines += [ "TINT_BUILD_SPV_READER=1" ]
+  } else {
+    defines += [ "TINT_BUILD_SPV_READER=0" ]
+  }
 }
 
-source_set("libtint") {
+# libtint source sets are divided into a non-optional core in :libtint_core and
+# optional :libtint_* subsets, because ninja does not like having multiple source
+# files with the same name, like function.cc, in the same source set target.
+#
+# Targets that want to use tint as a library should depend on ":libtint" and use
+# the build flags to control what is included, instead of trying to specify the
+# subsets that they want.
+
+source_set("libtint_core") {
   sources = [
     "src/ast/array_accessor_expression.cc",
     "src/ast/array_accessor_expression.h",
@@ -192,6 +206,58 @@
   }
 }
 
+config("tint_spv_reader_config") {
+  include_dirs = [
+    "${tint_spirv_tools_dir}/",
+    "${tint_spirv_tools_dir}/include",
+    "${target_gen_dir}/${tint_spirv_tools_gen}",
+  ]
+}
+
+source_set("libtint_spv_reader") {
+  sources = [
+    "src/reader/spirv/enum_converter.cc",
+    "src/reader/spirv/enum_converter.h",
+    "src/reader/spirv/fail_stream.h",
+    "src/reader/spirv/function.cc",
+    "src/reader/spirv/function.h",
+    "src/reader/spirv/namer.cc",
+    "src/reader/spirv/namer.h",
+    "src/reader/spirv/parser.cc",
+    "src/reader/spirv/parser.h",
+    "src/reader/spirv/parser_impl.cc",
+    "src/reader/spirv/parser_impl.h",
+  ]
+
+  deps = [
+    "${tint_spirv_headers_dir}/:spv_headers",
+    "${tint_spirv_tools_dir}/:spvtools_opt",
+    "${tint_spirv_tools_dir}/:spvtools_val",
+  ]
+
+  configs += [ ":tint_common_config" ]
+  configs += [ ":tint_spv_reader_config" ]
+
+  if (build_with_chromium) {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+}
+
+source_set("libtint") {
+  deps = [ ":libtint_core" ]
+  if (tint_build_spv_reader) {
+    deps += [ ":libtint_spv_reader" ]
+  }
+
+  configs += [ ":tint_common_config" ]
+
+  if (build_with_chromium) {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
+}
+
 executable("tint") {
   sources = [ "samples/main.cc" ]
   deps = [ ":libtint" ]
diff --git a/build_overrides/spirv_tools.gni b/build_overrides/spirv_tools.gni
new file mode 100644
index 0000000..a886b46
--- /dev/null
+++ b/build_overrides/spirv_tools.gni
@@ -0,0 +1,20 @@
+# Copyright 2020 The Tint Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# We are building inside Tint
+spirv_tools_standalone = false
+
+# Paths to SPIRV-Tools dependencies in Tint
+spirv_tools_googletest_dir = "//third_party/googletest"
+spirv_tools_spirv_headers_dir = "//third_party/spirv-headers"
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index 56abe50..cd36971 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -806,7 +806,7 @@
     return std::make_unique<ast::ScalarConstructorExpression>(
         std::make_unique<ast::BoolLiteral>(ast_type, value));
   }
-  auto spirv_composite_const = spirv_const->AsCompositeConstant();
+  auto* spirv_composite_const = spirv_const->AsCompositeConstant();
   if (spirv_composite_const != nullptr) {
     // Handle vector, matrix, array, and struct
 
diff --git a/tint.gni b/tint_overrides_with_defaults.gni
similarity index 65%
rename from tint.gni
rename to tint_overrides_with_defaults.gni
index 8986907..dc7d731 100644
--- a/tint.gni
+++ b/tint_overrides_with_defaults.gni
@@ -17,13 +17,31 @@
 # This file contains Tint-related build flags.
 
 declare_args() {
+  # Path to spirv-tools checkout
+  if (!defined(tint_spirv_tools_dir)) {
+    tint_spirv_tools_dir = "//third_party/spirv-tools"
+  }
+
+  # Path to spirv-tools generated files, relative to |target_gen_dir|
+  if (!defined(tint_spirv_tools_gen)) {
+    tint_spirv_tools_gen = "third_party/spirv-tools"
+  }
+
+  # Path to spirv-headers checkout
+  if (!defined(tint_spirv_headers_dir)) {
+    tint_spirv_headers_dir = "//third_party/spirv-headers"
+  }
+
   # Generate documentation
   # TODO(rharrison): Implement documentation support
   tint_build_doc = false
 
-  # Generate SPIR-V input parser
-  # TODO(rharrison): Implement SPIR-V input parser support
-  tint_build_spv_parser = false
+  # Build the SPIR-V input reader
+  if (!defined(tint_build_spv_reader)) {
+    tint_build_spv_reader = false
+  }
+
+  # TODO(rharrison): Implement support for the reset of the reader/writers
 
   # Generate fuzzers
   # TODO(rharrison): Implement fuzzer support
@@ -40,4 +58,4 @@
   # Enable undefined behaviour sanitizer
   # TODO(rharrison): Implement sanitizer support
   tint_enable_ubsan = false
-}
\ No newline at end of file
+}