[shuffle] Move spirv reader to new structure.

This CL moves the `spirv/reader` to `spirv/reader/parser/`.

Bug: tint:1988
Change-Id: I220b4618677bd39ab05d2c2f86be53692ed72b36
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/143420
Reviewed-by: James Price <jrprice@google.com>
Auto-Submit: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/docs/tint/spirv-reader-overview.md b/docs/tint/spirv-reader-overview.md
index 7411e16..dc9031b 100644
--- a/docs/tint/spirv-reader-overview.md
+++ b/docs/tint/spirv-reader-overview.md
@@ -3,7 +3,7 @@
 This document describes the challenges in converting SPIR-V into WGSL.
 
 Note: Unless otherwise specified, the namespace for C++ code is
-`tint::reader::spirv::`.
+`tint::spirv::reader::`.
 
 ## Overall flow
 
diff --git a/include/tint/tint.h b/include/tint/tint.h
index 4fba869..fe3a787 100644
--- a/include/tint/tint.h
+++ b/include/tint/tint.h
@@ -36,7 +36,7 @@
 #include "tint/external_texture_options.h"
 
 #if TINT_BUILD_SPV_READER
-#include "src/tint/lang/spirv/reader/parser.h"
+#include "src/tint/lang/spirv/reader/reader.h"
 #endif  // TINT_BUILD_SPV_READER
 
 #if TINT_BUILD_WGSL_READER
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 0eb480b..5502912 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -319,11 +319,11 @@
 ResultOrError<tint::Program> ParseSPIRV(const std::vector<uint32_t>& spirv,
                                         OwnedCompilationMessages* outMessages,
                                         const DawnShaderModuleSPIRVOptionsDescriptor* optionsDesc) {
-    tint::reader::spirv::Options options;
+    tint::spirv::reader::Options options;
     if (optionsDesc) {
         options.allow_non_uniform_derivatives = optionsDesc->allowNonUniformDerivatives;
     }
-    tint::Program program = tint::reader::spirv::Parse(spirv, options);
+    tint::Program program = tint::spirv::reader::Parse(spirv, options);
     if (outMessages != nullptr) {
         DAWN_TRY(outMessages->AddMessages(program.Diagnostics()));
     }
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 602daa8..d16559c 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -927,26 +927,26 @@
 
 libtint_source_set("libtint_spv_reader_src") {
   sources = [
-    "lang/spirv/reader/attributes.h",
-    "lang/spirv/reader/construct.cc",
-    "lang/spirv/reader/construct.h",
-    "lang/spirv/reader/entry_point_info.cc",
-    "lang/spirv/reader/entry_point_info.h",
-    "lang/spirv/reader/enum_converter.cc",
-    "lang/spirv/reader/enum_converter.h",
-    "lang/spirv/reader/fail_stream.h",
-    "lang/spirv/reader/function.cc",
-    "lang/spirv/reader/function.h",
-    "lang/spirv/reader/namer.cc",
-    "lang/spirv/reader/namer.h",
-    "lang/spirv/reader/parser.cc",
-    "lang/spirv/reader/parser.h",
-    "lang/spirv/reader/parser_impl.cc",
-    "lang/spirv/reader/parser_impl.h",
-    "lang/spirv/reader/parser_type.cc",
-    "lang/spirv/reader/parser_type.h",
-    "lang/spirv/reader/usage.cc",
-    "lang/spirv/reader/usage.h",
+    "lang/spirv/reader/ast_parser/ast_parser.cc",
+    "lang/spirv/reader/ast_parser/ast_parser.h",
+    "lang/spirv/reader/ast_parser/attributes.h",
+    "lang/spirv/reader/ast_parser/construct.cc",
+    "lang/spirv/reader/ast_parser/construct.h",
+    "lang/spirv/reader/ast_parser/entry_point_info.cc",
+    "lang/spirv/reader/ast_parser/entry_point_info.h",
+    "lang/spirv/reader/ast_parser/enum_converter.cc",
+    "lang/spirv/reader/ast_parser/enum_converter.h",
+    "lang/spirv/reader/ast_parser/fail_stream.h",
+    "lang/spirv/reader/ast_parser/function.cc",
+    "lang/spirv/reader/ast_parser/function.h",
+    "lang/spirv/reader/ast_parser/namer.cc",
+    "lang/spirv/reader/ast_parser/namer.h",
+    "lang/spirv/reader/ast_parser/type.cc",
+    "lang/spirv/reader/ast_parser/type.h",
+    "lang/spirv/reader/ast_parser/usage.cc",
+    "lang/spirv/reader/ast_parser/usage.h",
+    "lang/spirv/reader/reader.cc",
+    "lang/spirv/reader/reader.h",
   ]
 
   deps = [
@@ -1966,40 +1966,39 @@
 
   tint_unittests_source_set("tint_unittests_spv_reader_src") {
     sources = [
-      "lang/spirv/reader/enum_converter_test.cc",
-      "lang/spirv/reader/fail_stream_test.cc",
-      "lang/spirv/reader/function_arithmetic_test.cc",
-      "lang/spirv/reader/function_bit_test.cc",
-      "lang/spirv/reader/function_call_test.cc",
-      "lang/spirv/reader/function_cfg_test.cc",
-      "lang/spirv/reader/function_composite_test.cc",
-      "lang/spirv/reader/function_conversion_test.cc",
-      "lang/spirv/reader/function_decl_test.cc",
-      "lang/spirv/reader/function_glsl_std_450_test.cc",
-      "lang/spirv/reader/function_logical_test.cc",
-      "lang/spirv/reader/function_memory_test.cc",
-      "lang/spirv/reader/function_misc_test.cc",
-      "lang/spirv/reader/function_var_test.cc",
-      "lang/spirv/reader/namer_test.cc",
-      "lang/spirv/reader/parser_impl_barrier_test.cc",
-      "lang/spirv/reader/parser_impl_constant_test.cc",
-      "lang/spirv/reader/parser_impl_convert_member_decoration_test.cc",
-      "lang/spirv/reader/parser_impl_convert_type_test.cc",
-      "lang/spirv/reader/parser_impl_function_decl_test.cc",
-      "lang/spirv/reader/parser_impl_get_decorations_test.cc",
-      "lang/spirv/reader/parser_impl_handle_test.cc",
-      "lang/spirv/reader/parser_impl_import_test.cc",
-      "lang/spirv/reader/parser_impl_module_var_test.cc",
-      "lang/spirv/reader/parser_impl_named_types_test.cc",
-      "lang/spirv/reader/parser_impl_test.cc",
-      "lang/spirv/reader/parser_impl_test_helper.cc",
-      "lang/spirv/reader/parser_impl_test_helper.h",
-      "lang/spirv/reader/parser_impl_user_name_test.cc",
-      "lang/spirv/reader/parser_test.cc",
-      "lang/spirv/reader/parser_type_test.cc",
-      "lang/spirv/reader/spirv_tools_helpers_test.cc",
-      "lang/spirv/reader/spirv_tools_helpers_test.h",
-      "lang/spirv/reader/usage_test.cc",
+      "lang/spirv/reader/ast_parser/ast_parser_test.cc",
+      "lang/spirv/reader/ast_parser/barrier_test.cc",
+      "lang/spirv/reader/ast_parser/constant_test.cc",
+      "lang/spirv/reader/ast_parser/convert_member_decoration_test.cc",
+      "lang/spirv/reader/ast_parser/convert_type_test.cc",
+      "lang/spirv/reader/ast_parser/enum_converter_test.cc",
+      "lang/spirv/reader/ast_parser/fail_stream_test.cc",
+      "lang/spirv/reader/ast_parser/function_arithmetic_test.cc",
+      "lang/spirv/reader/ast_parser/function_bit_test.cc",
+      "lang/spirv/reader/ast_parser/function_call_test.cc",
+      "lang/spirv/reader/ast_parser/function_cfg_test.cc",
+      "lang/spirv/reader/ast_parser/function_composite_test.cc",
+      "lang/spirv/reader/ast_parser/function_conversion_test.cc",
+      "lang/spirv/reader/ast_parser/function_decl_test.cc",
+      "lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc",
+      "lang/spirv/reader/ast_parser/function_logical_test.cc",
+      "lang/spirv/reader/ast_parser/function_memory_test.cc",
+      "lang/spirv/reader/ast_parser/function_misc_test.cc",
+      "lang/spirv/reader/ast_parser/function_var_test.cc",
+      "lang/spirv/reader/ast_parser/get_decorations_test.cc",
+      "lang/spirv/reader/ast_parser/handle_test.cc",
+      "lang/spirv/reader/ast_parser/import_test.cc",
+      "lang/spirv/reader/ast_parser/module_function_decl_test.cc",
+      "lang/spirv/reader/ast_parser/module_var_test.cc",
+      "lang/spirv/reader/ast_parser/named_types_test.cc",
+      "lang/spirv/reader/ast_parser/namer_test.cc",
+      "lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc",
+      "lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h",
+      "lang/spirv/reader/ast_parser/test_helper.cc",
+      "lang/spirv/reader/ast_parser/test_helper.h",
+      "lang/spirv/reader/ast_parser/type_test.cc",
+      "lang/spirv/reader/ast_parser/usage_test.cc",
+      "lang/spirv/reader/ast_parser/user_name_test.cc",
     ]
 
     deps = [
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 1a4a3ec..24472ad 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -597,26 +597,26 @@
 
 if(${TINT_BUILD_SPV_READER})
   list(APPEND TINT_LIB_SRCS
-    lang/spirv/reader/attributes.h
-    lang/spirv/reader/construct.h
-    lang/spirv/reader/construct.cc
-    lang/spirv/reader/entry_point_info.h
-    lang/spirv/reader/entry_point_info.cc
-    lang/spirv/reader/enum_converter.h
-    lang/spirv/reader/enum_converter.cc
-    lang/spirv/reader/fail_stream.h
-    lang/spirv/reader/function.cc
-    lang/spirv/reader/function.h
-    lang/spirv/reader/namer.cc
-    lang/spirv/reader/namer.h
-    lang/spirv/reader/parser_type.cc
-    lang/spirv/reader/parser_type.h
-    lang/spirv/reader/parser.cc
-    lang/spirv/reader/parser.h
-    lang/spirv/reader/parser_impl.cc
-    lang/spirv/reader/parser_impl.h
-    lang/spirv/reader/usage.cc
-    lang/spirv/reader/usage.h
+    lang/spirv/reader/ast_parser/ast_parser.cc
+    lang/spirv/reader/ast_parser/ast_parser.h
+    lang/spirv/reader/ast_parser/attributes.h
+    lang/spirv/reader/ast_parser/construct.cc
+    lang/spirv/reader/ast_parser/construct.h
+    lang/spirv/reader/ast_parser/entry_point_info.cc
+    lang/spirv/reader/ast_parser/entry_point_info.h
+    lang/spirv/reader/ast_parser/enum_converter.cc
+    lang/spirv/reader/ast_parser/enum_converter.h
+    lang/spirv/reader/ast_parser/fail_stream.h
+    lang/spirv/reader/ast_parser/function.cc
+    lang/spirv/reader/ast_parser/function.h
+    lang/spirv/reader/ast_parser/namer.cc
+    lang/spirv/reader/ast_parser/namer.h
+    lang/spirv/reader/ast_parser/type.cc
+    lang/spirv/reader/ast_parser/type.h
+    lang/spirv/reader/ast_parser/usage.cc
+    lang/spirv/reader/ast_parser/usage.h
+    lang/spirv/reader/reader.cc
+    lang/spirv/reader/reader.h
   )
 endif()
 
@@ -1194,40 +1194,40 @@
 
   if(${TINT_BUILD_SPV_READER} AND ${TINT_BUILD_WGSL_WRITER})
     list(APPEND TINT_TEST_SRCS
-      lang/spirv/reader/enum_converter_test.cc
-      lang/spirv/reader/fail_stream_test.cc
-      lang/spirv/reader/function_arithmetic_test.cc
-      lang/spirv/reader/function_bit_test.cc
-      lang/spirv/reader/function_cfg_test.cc
-      lang/spirv/reader/function_call_test.cc
-      lang/spirv/reader/function_composite_test.cc
-      lang/spirv/reader/function_conversion_test.cc
-      lang/spirv/reader/function_decl_test.cc
-      lang/spirv/reader/function_glsl_std_450_test.cc
-      lang/spirv/reader/function_logical_test.cc
-      lang/spirv/reader/function_memory_test.cc
-      lang/spirv/reader/function_misc_test.cc
-      lang/spirv/reader/function_var_test.cc
-      lang/spirv/reader/namer_test.cc
-      lang/spirv/reader/parser_impl_barrier_test.cc
-      lang/spirv/reader/parser_impl_constant_test.cc
-      lang/spirv/reader/parser_impl_convert_member_decoration_test.cc
-      lang/spirv/reader/parser_impl_convert_type_test.cc
-      lang/spirv/reader/parser_impl_function_decl_test.cc
-      lang/spirv/reader/parser_impl_get_decorations_test.cc
-      lang/spirv/reader/parser_impl_handle_test.cc
-      lang/spirv/reader/parser_impl_import_test.cc
-      lang/spirv/reader/parser_impl_module_var_test.cc
-      lang/spirv/reader/parser_impl_named_types_test.cc
-      lang/spirv/reader/parser_impl_test_helper.cc
-      lang/spirv/reader/parser_impl_test_helper.h
-      lang/spirv/reader/parser_impl_test.cc
-      lang/spirv/reader/parser_impl_user_name_test.cc
-      lang/spirv/reader/parser_type_test.cc
-      lang/spirv/reader/parser_test.cc
-      lang/spirv/reader/spirv_tools_helpers_test.cc
-      lang/spirv/reader/spirv_tools_helpers_test.h
-      lang/spirv/reader/usage_test.cc
+      lang/spirv/reader/ast_parser/ast_parser_test.cc
+      lang/spirv/reader/ast_parser/barrier_test.cc
+      lang/spirv/reader/ast_parser/constant_test.cc
+      lang/spirv/reader/ast_parser/convert_member_decoration_test.cc
+      lang/spirv/reader/ast_parser/convert_type_test.cc
+      lang/spirv/reader/ast_parser/enum_converter_test.cc
+      lang/spirv/reader/ast_parser/fail_stream_test.cc
+      lang/spirv/reader/ast_parser/function_arithmetic_test.cc
+      lang/spirv/reader/ast_parser/function_bit_test.cc
+      lang/spirv/reader/ast_parser/function_call_test.cc
+      lang/spirv/reader/ast_parser/function_cfg_test.cc
+      lang/spirv/reader/ast_parser/function_composite_test.cc
+      lang/spirv/reader/ast_parser/function_conversion_test.cc
+      lang/spirv/reader/ast_parser/module_function_decl_test.cc
+      lang/spirv/reader/ast_parser/function_decl_test.cc
+      lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc
+      lang/spirv/reader/ast_parser/function_logical_test.cc
+      lang/spirv/reader/ast_parser/function_memory_test.cc
+      lang/spirv/reader/ast_parser/function_misc_test.cc
+      lang/spirv/reader/ast_parser/function_var_test.cc
+      lang/spirv/reader/ast_parser/get_decorations_test.cc
+      lang/spirv/reader/ast_parser/handle_test.cc
+      lang/spirv/reader/ast_parser/import_test.cc
+      lang/spirv/reader/ast_parser/module_var_test.cc
+      lang/spirv/reader/ast_parser/named_types_test.cc
+      lang/spirv/reader/ast_parser/namer_test.cc
+      lang/spirv/reader/ast_parser/parser_test.cc
+      lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc
+      lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h
+      lang/spirv/reader/ast_parser/test_helper.cc
+      lang/spirv/reader/ast_parser/test_helper.h
+      lang/spirv/reader/ast_parser/type_test.cc
+      lang/spirv/reader/ast_parser/usage_test.cc
+      lang/spirv/reader/ast_parser/user_name_test.cc
     )
   endif()
 
diff --git a/src/tint/bench/benchmark.cc b/src/tint/bench/benchmark.cc
index 6daf142..ca90fc1 100644
--- a/src/tint/bench/benchmark.cc
+++ b/src/tint/bench/benchmark.cc
@@ -101,7 +101,7 @@
     if (utils::HasSuffix(path, ".spv")) {
         auto spirv = ReadFile<uint32_t>(path);
         if (auto* buf = std::get_if<std::vector<uint32_t>>(&spirv)) {
-            auto program = tint::reader::spirv::Parse(*buf, {});
+            auto program = tint::spirv::reader::Parse(*buf, {});
             if (!program.IsValid()) {
                 return Error{program.Diagnostics().str()};
             }
diff --git a/src/tint/cmd/helper.cc b/src/tint/cmd/helper.cc
index da30d78..f04077a 100644
--- a/src/tint/cmd/helper.cc
+++ b/src/tint/cmd/helper.cc
@@ -127,7 +127,7 @@
                 exit(1);
             }
             program = std::make_unique<tint::Program>(
-                tint::reader::spirv::Parse(data, opts.spirv_reader_options));
+                tint::spirv::reader::Parse(data, opts.spirv_reader_options));
             break;
 #else
             std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
@@ -152,7 +152,7 @@
                 exit(1);
             }
             program = std::make_unique<tint::Program>(
-                tint::reader::spirv::Parse(data, opts.spirv_reader_options));
+                tint::spirv::reader::Parse(data, opts.spirv_reader_options));
             break;
 #else
             std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
diff --git a/src/tint/cmd/helper.h b/src/tint/cmd/helper.h
index 6878288..6215059 100644
--- a/src/tint/cmd/helper.h
+++ b/src/tint/cmd/helper.h
@@ -56,7 +56,7 @@
     std::string filename;
 #if TINT_BUILD_SPV_READER
     /// Spirv-reader options
-    tint::reader::spirv::Options spirv_reader_options;
+    tint::spirv::reader::Options spirv_reader_options;
 #endif
 };
 
diff --git a/src/tint/cmd/info.cc b/src/tint/cmd/info.cc
index acd8990..83421bc 100644
--- a/src/tint/cmd/info.cc
+++ b/src/tint/cmd/info.cc
@@ -33,7 +33,7 @@
     bool show_help = false;
 
 #if TINT_BUILD_SPV_READER
-    tint::reader::spirv::Options spirv_reader_options;
+    tint::spirv::reader::Options spirv_reader_options;
 #endif
 
     std::string input_filename;
diff --git a/src/tint/cmd/loopy.cc b/src/tint/cmd/loopy.cc
index 9bff701..26b9d20 100644
--- a/src/tint/cmd/loopy.cc
+++ b/src/tint/cmd/loopy.cc
@@ -353,7 +353,7 @@
 
             uint32_t loop_count = options.loop_count;
             for (uint32_t i = 0; i < loop_count; ++i) {
-                program = std::make_unique<tint::Program>(tint::reader::spirv::Parse(data, {}));
+                program = std::make_unique<tint::Program>(tint::spirv::reader::Parse(data, {}));
             }
 #else
             std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc
index 2302f12..8f0c3f4 100644
--- a/src/tint/cmd/main.cc
+++ b/src/tint/cmd/main.cc
@@ -123,7 +123,7 @@
     bool rename_all = false;
 
 #if TINT_BUILD_SPV_READER
-    tint::reader::spirv::Options spirv_reader_options;
+    tint::spirv::reader::Options spirv_reader_options;
 #endif
 
     tint::utils::Vector<std::string, 4> transforms;
diff --git a/src/tint/fuzzers/tint_common_fuzzer.cc b/src/tint/fuzzers/tint_common_fuzzer.cc
index 809eef2..c153c96 100644
--- a/src/tint/fuzzers/tint_common_fuzzer.cc
+++ b/src/tint/fuzzers/tint_common_fuzzer.cc
@@ -184,7 +184,7 @@
             if (dump_input_) {
                 dump_input_data(spirv_input, ".spv");
             }
-            program = reader::spirv::Parse(spirv_input);
+            program = spirv::reader::Parse(spirv_input);
 #endif  // TINT_BUILD_SPV_READER
             break;
         }
diff --git a/src/tint/lang/spirv/reader/README.md b/src/tint/lang/spirv/reader/ast_parser/README.md
similarity index 94%
rename from src/tint/lang/spirv/reader/README.md
rename to src/tint/lang/spirv/reader/ast_parser/README.md
index f782e21..bf11a77 100644
--- a/src/tint/lang/spirv/reader/README.md
+++ b/src/tint/lang/spirv/reader/ast_parser/README.md
@@ -2,7 +2,7 @@
 
 This component translates SPIR-V written for Vulkan into the Tint AST.
 
-The SPIR-V reader entry point is `tint::reader::spirv::Parser`, which
+The SPIR-V reader entry point is `tint::spirv::reader::Parser`, which
 implements the Reader interface in `tint::reader::Reader`.
 
 It's usable from the Tint command line:
diff --git a/src/tint/lang/spirv/reader/parser_impl.cc b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
similarity index 93%
rename from src/tint/lang/spirv/reader/parser_impl.cc
rename to src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
index 10c1c2b..a98e1a0 100644
--- a/src/tint/lang/spirv/reader/parser_impl.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/parser_impl.h"
+#include "src/tint/lang/spirv/reader/ast_parser/ast_parser.h"
 
 #include <algorithm>
 #include <limits>
@@ -24,7 +24,7 @@
 #include "src/tint/lang/core/type/multisampled_texture.h"
 #include "src/tint/lang/core/type/sampled_texture.h"
 #include "src/tint/lang/core/type/texture_dimension.h"
-#include "src/tint/lang/spirv/reader/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
 #include "src/tint/lang/wgsl/ast/bitcast_expression.h"
 #include "src/tint/lang/wgsl/ast/disable_validation_attribute.h"
 #include "src/tint/lang/wgsl/ast/id_attribute.h"
@@ -33,7 +33,7 @@
 #include "src/tint/utils/containers/unique_vector.h"
 #include "src/tint/utils/rtti/switch.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 namespace {
 
@@ -276,7 +276,7 @@
 TypedExpression::TypedExpression(const Type* type_in, const ast::Expression* expr_in)
     : type(type_in), expr(expr_in) {}
 
-ParserImpl::ParserImpl(const std::vector<uint32_t>& spv_binary)
+ASTParser::ASTParser(const std::vector<uint32_t>& spv_binary)
     : spv_binary_(spv_binary),
       fail_stream_(&success_, &errors_),
       namer_(fail_stream_),
@@ -300,9 +300,9 @@
     };
 }
 
-ParserImpl::~ParserImpl() = default;
+ASTParser::~ASTParser() = default;
 
-bool ParserImpl::Parse() {
+bool ASTParser::Parse() {
     // Set up use of SPIRV-Tools utilities.
     spvtools::SpirvTools spv_tools(kInputEnv);
 
@@ -330,13 +330,13 @@
     return success_;
 }
 
-Program ParserImpl::Program() {
+Program ASTParser::Program() {
     // TODO(dneto): Should we clear out spv_binary_ here, to reduce
     // memory usage?
     return tint::Program(std::move(builder_));
 }
 
-const Type* ParserImpl::ConvertType(uint32_t type_id, PtrAs ptr_as) {
+const Type* ASTParser::ConvertType(uint32_t type_id, PtrAs ptr_as) {
     if (!success_) {
         return nullptr;
     }
@@ -394,7 +394,7 @@
     return nullptr;
 }
 
-DecorationList ParserImpl::GetDecorationsFor(uint32_t id) const {
+DecorationList ASTParser::GetDecorationsFor(uint32_t id) const {
     DecorationList result;
     const auto& decorations = deco_mgr_->GetDecorationsFor(id, true);
     std::unordered_set<uint32_t> visited;
@@ -423,7 +423,7 @@
     return result;
 }
 
-DecorationList ParserImpl::GetDecorationsForMember(uint32_t id, uint32_t member_index) const {
+DecorationList ASTParser::GetDecorationsForMember(uint32_t id, uint32_t member_index) const {
     DecorationList result;
     const auto& decorations = deco_mgr_->GetDecorationsFor(id, true);
     std::unordered_set<uint32_t> visited;
@@ -451,7 +451,7 @@
     return result;
 }
 
-std::string ParserImpl::ShowType(uint32_t type_id) {
+std::string ASTParser::ShowType(uint32_t type_id) {
     if (def_use_mgr_) {
         const auto* type_inst = def_use_mgr_->GetDef(type_id);
         if (type_inst) {
@@ -461,10 +461,10 @@
     return "SPIR-V type " + std::to_string(type_id);
 }
 
-Attributes ParserImpl::ConvertMemberDecoration(uint32_t struct_type_id,
-                                               uint32_t member_index,
-                                               const Type* member_ty,
-                                               const Decoration& decoration) {
+Attributes ASTParser::ConvertMemberDecoration(uint32_t struct_type_id,
+                                              uint32_t member_index,
+                                              const Type* member_ty,
+                                              const Decoration& decoration) {
     if (decoration.empty()) {
         Fail() << "malformed SPIR-V decoration: it's empty";
         return {};
@@ -532,7 +532,7 @@
     return out;
 }
 
-bool ParserImpl::BuildInternalModule() {
+bool ASTParser::BuildInternalModule() {
     if (!success_) {
         return false;
     }
@@ -555,7 +555,7 @@
     return success_;
 }
 
-void ParserImpl::ResetInternalModule() {
+void ASTParser::ResetInternalModule() {
     ir_context_.reset(nullptr);
     module_ = nullptr;
     def_use_mgr_ = nullptr;
@@ -566,7 +566,7 @@
     glsl_std_450_imports_.clear();
 }
 
-bool ParserImpl::ParseInternalModule() {
+bool ASTParser::ParseInternalModule() {
     if (!success_) {
         return false;
     }
@@ -580,7 +580,7 @@
     return success_;
 }
 
-void ParserImpl::RegisterLineNumbers() {
+void ASTParser::RegisterLineNumbers() {
     Source::Location instruction_number{};
 
     // Has there been an OpLine since the last OpNoLine or start of the module?
@@ -611,11 +611,11 @@
         run_on_debug_insts);
 }
 
-Source ParserImpl::GetSourceForResultIdForTest(uint32_t id) const {
+Source ASTParser::GetSourceForResultIdForTest(uint32_t id) const {
     return GetSourceForInst(def_use_mgr_->GetDef(id));
 }
 
-Source ParserImpl::GetSourceForInst(const spvtools::opt::Instruction* inst) const {
+Source ASTParser::GetSourceForInst(const spvtools::opt::Instruction* inst) const {
     auto where = inst_source_.find(inst);
     if (where == inst_source_.end()) {
         return {};
@@ -623,7 +623,7 @@
     return Source{where->second};
 }
 
-bool ParserImpl::ParseInternalModuleExceptFunctions() {
+bool ASTParser::ParseInternalModuleExceptFunctions() {
     if (!success_) {
         return false;
     }
@@ -657,7 +657,7 @@
     return success_;
 }
 
-bool ParserImpl::RegisterExtendedInstructionImports() {
+bool ASTParser::RegisterExtendedInstructionImports() {
     for (const spvtools::opt::Instruction& import : module_->ext_inst_imports()) {
         std::string name(reinterpret_cast<const char*>(import.GetInOperand(0).words.data()));
         // TODO(dneto): Handle other extended instruction sets when needed.
@@ -672,17 +672,17 @@
     return true;
 }
 
-bool ParserImpl::IsGlslExtendedInstruction(const spvtools::opt::Instruction& inst) const {
+bool ASTParser::IsGlslExtendedInstruction(const spvtools::opt::Instruction& inst) const {
     return (opcode(inst) == spv::Op::OpExtInst) &&
            (glsl_std_450_imports_.count(inst.GetSingleWordInOperand(0)) > 0);
 }
 
-bool ParserImpl::IsIgnoredExtendedInstruction(const spvtools::opt::Instruction& inst) const {
+bool ASTParser::IsIgnoredExtendedInstruction(const spvtools::opt::Instruction& inst) const {
     return (opcode(inst) == spv::Op::OpExtInst) &&
            (ignored_imports_.count(inst.GetSingleWordInOperand(0)) > 0);
 }
 
-bool ParserImpl::RegisterUserAndStructMemberNames() {
+bool ASTParser::RegisterUserAndStructMemberNames() {
     if (!success_) {
         return false;
     }
@@ -756,7 +756,7 @@
     return true;
 }
 
-bool ParserImpl::IsValidIdentifier(const std::string& str) {
+bool ASTParser::IsValidIdentifier(const std::string& str) {
     if (str.empty()) {
         return false;
     }
@@ -779,7 +779,7 @@
     return true;
 }
 
-bool ParserImpl::RegisterWorkgroupSizeBuiltin() {
+bool ASTParser::RegisterWorkgroupSizeBuiltin() {
     WorkgroupSizeInfo& info = workgroup_size_builtin_;
     for (const spvtools::opt::Instruction& inst : module_->annotations()) {
         if (opcode(inst) != spv::Op::OpDecorate) {
@@ -841,7 +841,7 @@
            set_param(&info.z_id, &info.z_value, 2);
 }
 
-bool ParserImpl::RegisterEntryPoints() {
+bool ASTParser::RegisterEntryPoints() {
     // Mapping from entry point ID to GridSize computed from LocalSize
     // decorations.
     std::unordered_map<uint32_t, GridSize> local_size;
@@ -934,7 +934,7 @@
     return success_;
 }
 
-const Type* ParserImpl::ConvertType(const spvtools::opt::analysis::Integer* int_ty) {
+const Type* ASTParser::ConvertType(const spvtools::opt::analysis::Integer* int_ty) {
     if (int_ty->width() == 32) {
         return int_ty->IsSigned() ? static_cast<const Type*>(ty_.I32())
                                   : static_cast<const Type*>(ty_.U32());
@@ -943,7 +943,7 @@
     return nullptr;
 }
 
-const Type* ParserImpl::ConvertType(const spvtools::opt::analysis::Float* float_ty) {
+const Type* ASTParser::ConvertType(const spvtools::opt::analysis::Float* float_ty) {
     if (float_ty->width() == 32) {
         return ty_.F32();
     }
@@ -951,7 +951,7 @@
     return nullptr;
 }
 
-const Type* ParserImpl::ConvertType(const spvtools::opt::analysis::Vector* vec_ty) {
+const Type* ASTParser::ConvertType(const spvtools::opt::analysis::Vector* vec_ty) {
     const auto num_elem = vec_ty->element_count();
     auto* ast_elem_ty = ConvertType(type_mgr_->GetId(vec_ty->element_type()));
     if (ast_elem_ty == nullptr) {
@@ -960,7 +960,7 @@
     return ty_.Vector(ast_elem_ty, num_elem);
 }
 
-const Type* ParserImpl::ConvertType(const spvtools::opt::analysis::Matrix* mat_ty) {
+const Type* ASTParser::ConvertType(const spvtools::opt::analysis::Matrix* mat_ty) {
     const auto* vec_ty = mat_ty->element_type()->AsVector();
     const auto* scalar_ty = vec_ty->element_type();
     const auto num_rows = vec_ty->element_count();
@@ -972,8 +972,8 @@
     return ty_.Matrix(ast_scalar_ty, num_columns, num_rows);
 }
 
-const Type* ParserImpl::ConvertType(uint32_t type_id,
-                                    const spvtools::opt::analysis::RuntimeArray* rtarr_ty) {
+const Type* ASTParser::ConvertType(uint32_t type_id,
+                                   const spvtools::opt::analysis::RuntimeArray* rtarr_ty) {
     auto* ast_elem_ty = ConvertType(type_mgr_->GetId(rtarr_ty->element_type()));
     if (ast_elem_ty == nullptr) {
         return nullptr;
@@ -986,8 +986,7 @@
     return MaybeGenerateAlias(type_id, rtarr_ty, result);
 }
 
-const Type* ParserImpl::ConvertType(uint32_t type_id,
-                                    const spvtools::opt::analysis::Array* arr_ty) {
+const Type* ASTParser::ConvertType(uint32_t type_id, const spvtools::opt::analysis::Array* arr_ty) {
     // Get the element type. The SPIR-V optimizer's types representation
     // deduplicates array types that have the same parameterization.
     // We don't want that deduplication, so get the element type from
@@ -1035,8 +1034,8 @@
     return MaybeGenerateAlias(type_id, arr_ty, result);
 }
 
-bool ParserImpl::ParseArrayDecorations(const spvtools::opt::analysis::Type* spv_type,
-                                       uint32_t* array_stride) {
+bool ASTParser::ParseArrayDecorations(const spvtools::opt::analysis::Type* spv_type,
+                                      uint32_t* array_stride) {
     *array_stride = 0;  // Implicit stride case.
     const auto type_id = type_mgr_->GetId(spv_type);
     for (auto& decoration : this->GetDecorationsFor(type_id)) {
@@ -1055,8 +1054,8 @@
     return true;
 }
 
-const Type* ParserImpl::ConvertType(uint32_t type_id,
-                                    const spvtools::opt::analysis::Struct* struct_ty) {
+const Type* ASTParser::ConvertType(uint32_t type_id,
+                                   const spvtools::opt::analysis::Struct* struct_ty) {
     // Compute the struct decoration.
     auto struct_decorations = this->GetDecorationsFor(type_id);
     if (struct_decorations.size() == 1) {
@@ -1184,16 +1183,16 @@
     return result;
 }
 
-void ParserImpl::AddTypeDecl(Symbol name, const ast::TypeDecl* decl) {
+void ASTParser::AddTypeDecl(Symbol name, const ast::TypeDecl* decl) {
     auto iter = declared_types_.insert(name);
     if (iter.second) {
         builder_.AST().AddTypeDecl(decl);
     }
 }
 
-const Type* ParserImpl::ConvertType(uint32_t type_id,
-                                    PtrAs ptr_as,
-                                    const spvtools::opt::analysis::Pointer*) {
+const Type* ASTParser::ConvertType(uint32_t type_id,
+                                   PtrAs ptr_as,
+                                   const spvtools::opt::analysis::Pointer*) {
     const auto* inst = def_use_mgr_->GetDef(type_id);
     const auto pointee_type_id = inst->GetSingleWordInOperand(1);
     const auto storage_class = spv::StorageClass(inst->GetSingleWordInOperand(0));
@@ -1233,7 +1232,7 @@
     return nullptr;
 }
 
-bool ParserImpl::RegisterTypes() {
+bool ASTParser::RegisterTypes() {
     if (!success_) {
         return false;
     }
@@ -1281,7 +1280,7 @@
     return success_;
 }
 
-bool ParserImpl::RejectInvalidPointerRoots() {
+bool ASTParser::RejectInvalidPointerRoots() {
     if (!success_) {
         return false;
     }
@@ -1306,7 +1305,7 @@
     return success();
 }
 
-bool ParserImpl::EmitScalarSpecConstants() {
+bool ASTParser::EmitScalarSpecConstants() {
     if (!success_) {
         return false;
     }
@@ -1382,9 +1381,9 @@
     return success_;
 }
 
-const Type* ParserImpl::MaybeGenerateAlias(uint32_t type_id,
-                                           const spvtools::opt::analysis::Type* type,
-                                           const Type* ast_type) {
+const Type* ASTParser::MaybeGenerateAlias(uint32_t type_id,
+                                          const spvtools::opt::analysis::Type* type,
+                                          const Type* ast_type) {
     if (!success_) {
         return nullptr;
     }
@@ -1422,7 +1421,7 @@
     return ty_.Alias(sym, ast_underlying_type);
 }
 
-bool ParserImpl::EmitModuleScopeVariables() {
+bool ASTParser::EmitModuleScopeVariables() {
     if (!success_) {
         return false;
     }
@@ -1552,7 +1551,7 @@
 // @param var_id SPIR-V id of an OpVariable, assumed to be pointer
 // to an array
 // @returns the IntConstant for the size of the array, or nullptr
-const spvtools::opt::analysis::IntConstant* ParserImpl::GetArraySize(uint32_t var_id) {
+const spvtools::opt::analysis::IntConstant* ASTParser::GetArraySize(uint32_t var_id) {
     auto* var = def_use_mgr_->GetDef(var_id);
     if (!var || opcode(var) != spv::Op::OpVariable) {
         return nullptr;
@@ -1572,8 +1571,8 @@
     return size->AsIntConstant();
 }
 
-builtin::Access ParserImpl::VarAccess(const Type* storage_type,
-                                      builtin::AddressSpace address_space) {
+builtin::Access ASTParser::VarAccess(const Type* storage_type,
+                                     builtin::AddressSpace address_space) {
     if (address_space != builtin::AddressSpace::kStorage) {
         return builtin::Access::kUndefined;
     }
@@ -1587,12 +1586,12 @@
     return read_only ? builtin::Access::kRead : builtin::Access::kReadWrite;
 }
 
-const ast::Var* ParserImpl::MakeVar(uint32_t id,
-                                    builtin::AddressSpace address_space,
-                                    builtin::Access access,
-                                    const Type* storage_type,
-                                    const ast::Expression* initializer,
-                                    Attributes attrs) {
+const ast::Var* ASTParser::MakeVar(uint32_t id,
+                                   builtin::AddressSpace address_space,
+                                   builtin::Access access,
+                                   const Type* storage_type,
+                                   const ast::Expression* initializer,
+                                   Attributes attrs) {
     if (storage_type == nullptr) {
         Fail() << "internal error: can't make ast::Variable for null type";
         return nullptr;
@@ -1615,15 +1614,15 @@
                         address_space, access, initializer, std::move(attrs.list));
 }
 
-const ast::Let* ParserImpl::MakeLet(uint32_t id, const ast::Expression* initializer) {
+const ast::Let* ASTParser::MakeLet(uint32_t id, const ast::Expression* initializer) {
     auto sym = builder_.Symbols().Register(namer_.Name(id));
     return builder_.Let(Source{}, sym, initializer, utils::Empty);
 }
 
-const ast::Override* ParserImpl::MakeOverride(uint32_t id,
-                                              const Type* type,
-                                              const ast::Expression* initializer,
-                                              Attributes attrs) {
+const ast::Override* ASTParser::MakeOverride(uint32_t id,
+                                             const Type* type,
+                                             const ast::Expression* initializer,
+                                             Attributes attrs) {
     if (!ConvertDecorationsForVariable(id, &type, attrs, false)) {
         return nullptr;
     }
@@ -1632,7 +1631,7 @@
                              std::move(attrs.list));
 }
 
-const ast::Parameter* ParserImpl::MakeParameter(uint32_t id, const Type* type, Attributes attrs) {
+const ast::Parameter* ASTParser::MakeParameter(uint32_t id, const Type* type, Attributes attrs) {
     if (!ConvertDecorationsForVariable(id, &type, attrs, false)) {
         return nullptr;
     }
@@ -1641,10 +1640,10 @@
     return builder_.Param(Source{}, sym, type->Build(builder_), attrs.list);
 }
 
-bool ParserImpl::ConvertDecorationsForVariable(uint32_t id,
-                                               const Type** store_type,
-                                               Attributes& attrs,
-                                               bool transfer_pipeline_io) {
+bool ASTParser::ConvertDecorationsForVariable(uint32_t id,
+                                              const Type** store_type,
+                                              Attributes& attrs,
+                                              bool transfer_pipeline_io) {
     DecorationList non_builtin_pipeline_decorations;
     for (auto& deco : GetDecorationsFor(id)) {
         if (deco.empty()) {
@@ -1733,8 +1732,8 @@
     return success();
 }
 
-DecorationList ParserImpl::GetMemberPipelineDecorations(const Struct& struct_type,
-                                                        int member_index) {
+DecorationList ASTParser::GetMemberPipelineDecorations(const Struct& struct_type,
+                                                       int member_index) {
     // Yes, I could have used std::copy_if or std::copy_if.
     DecorationList result;
     for (const auto& deco : GetDecorationsForMember(struct_id_for_symbol_[struct_type.name],
@@ -1746,7 +1745,7 @@
     return result;
 }
 
-void ParserImpl::SetLocation(Attributes& attributes, const ast::Attribute* replacement) {
+void ASTParser::SetLocation(Attributes& attributes, const ast::Attribute* replacement) {
     if (!replacement) {
         return;
     }
@@ -1764,9 +1763,9 @@
     return;
 }
 
-bool ParserImpl::ConvertPipelineDecorations(const Type* store_type,
-                                            const DecorationList& decorations,
-                                            Attributes& attributes) {
+bool ASTParser::ConvertPipelineDecorations(const Type* store_type,
+                                           const DecorationList& decorations,
+                                           Attributes& attributes) {
     // Vulkan defaults to perspective-correct interpolation.
     builtin::InterpolationType type = builtin::InterpolationType::kPerspective;
     builtin::InterpolationSampling sampling = builtin::InterpolationSampling::kUndefined;
@@ -1832,7 +1831,7 @@
     return success();
 }
 
-bool ParserImpl::CanMakeConstantExpression(uint32_t id) {
+bool ASTParser::CanMakeConstantExpression(uint32_t id) {
     if ((id == workgroup_size_builtin_.id) || (id == workgroup_size_builtin_.x_id) ||
         (id == workgroup_size_builtin_.y_id) || (id == workgroup_size_builtin_.z_id)) {
         return true;
@@ -1847,7 +1846,7 @@
     return nullptr != constant_mgr_->FindDeclaredConstant(id);
 }
 
-TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
+TypedExpression ASTParser::MakeConstantExpression(uint32_t id) {
     if (!success_) {
         return {};
     }
@@ -1986,7 +1985,7 @@
     return {};
 }
 
-TypedExpression ParserImpl::MakeConstantExpressionForScalarSpirvConstant(
+TypedExpression ASTParser::MakeConstantExpressionForScalarSpirvConstant(
     Source source,
     const Type* original_ast_type,
     const spvtools::opt::analysis::Constant* spirv_const) {
@@ -2040,7 +2039,7 @@
         });
 }
 
-const ast::Expression* ParserImpl::MakeNullValue(const Type* type) {
+const ast::Expression* ASTParser::MakeNullValue(const Type* type) {
     // TODO(dneto): Use the no-operands initializer syntax when it becomes
     // available in Tint.
     // https://github.com/gpuweb/gpuweb/issues/685
@@ -2086,11 +2085,11 @@
         });
 }
 
-TypedExpression ParserImpl::MakeNullExpression(const Type* type) {
+TypedExpression ASTParser::MakeNullExpression(const Type* type) {
     return {type, MakeNullValue(type)};
 }
 
-const Type* ParserImpl::UnsignedTypeFor(const Type* type) {
+const Type* ASTParser::UnsignedTypeFor(const Type* type) {
     if (type->Is<I32>()) {
         return ty_.U32();
     }
@@ -2102,7 +2101,7 @@
     return {};
 }
 
-const Type* ParserImpl::SignedTypeFor(const Type* type) {
+const Type* ASTParser::SignedTypeFor(const Type* type) {
     if (type->Is<U32>()) {
         return ty_.I32();
     }
@@ -2114,8 +2113,8 @@
     return {};
 }
 
-TypedExpression ParserImpl::RectifyOperandSignedness(const spvtools::opt::Instruction& inst,
-                                                     TypedExpression&& expr) {
+TypedExpression ASTParser::RectifyOperandSignedness(const spvtools::opt::Instruction& inst,
+                                                    TypedExpression&& expr) {
     bool requires_signed = false;
     bool requires_unsigned = false;
     if (IsGlslExtendedInstruction(inst)) {
@@ -2157,9 +2156,9 @@
     return std::move(expr);
 }
 
-TypedExpression ParserImpl::RectifySecondOperandSignedness(const spvtools::opt::Instruction& inst,
-                                                           const Type* first_operand_type,
-                                                           TypedExpression&& second_operand_expr) {
+TypedExpression ASTParser::RectifySecondOperandSignedness(const spvtools::opt::Instruction& inst,
+                                                          const Type* first_operand_type,
+                                                          TypedExpression&& second_operand_expr) {
     const Type* target_type = first_operand_type->UnwrapRef();
     if ((target_type != second_operand_expr.type->UnwrapRef()) &&
         AssumesSecondOperandSignednessMatchesFirstOperand(opcode(inst))) {
@@ -2171,8 +2170,8 @@
     return std::move(second_operand_expr);
 }
 
-const Type* ParserImpl::ForcedResultType(const spvtools::opt::Instruction& inst,
-                                         const Type* first_operand_type) {
+const Type* ASTParser::ForcedResultType(const spvtools::opt::Instruction& inst,
+                                        const Type* first_operand_type) {
     first_operand_type = first_operand_type->UnwrapRef();
     const auto op = opcode(inst);
     if (AssumesResultSignednessMatchesFirstOperand(op)) {
@@ -2187,7 +2186,7 @@
     return nullptr;
 }
 
-const Type* ParserImpl::GetSignedIntMatchingShape(const Type* other) {
+const Type* ASTParser::GetSignedIntMatchingShape(const Type* other) {
     if (other == nullptr) {
         Fail() << "no type provided";
     }
@@ -2201,7 +2200,7 @@
     return nullptr;
 }
 
-const Type* ParserImpl::GetUnsignedIntMatchingShape(const Type* other) {
+const Type* ASTParser::GetUnsignedIntMatchingShape(const Type* other) {
     if (other == nullptr) {
         Fail() << "no type provided";
         return nullptr;
@@ -2216,9 +2215,9 @@
     return nullptr;
 }
 
-TypedExpression ParserImpl::RectifyForcedResultType(TypedExpression expr,
-                                                    const spvtools::opt::Instruction& inst,
-                                                    const Type* first_operand_type) {
+TypedExpression ASTParser::RectifyForcedResultType(TypedExpression expr,
+                                                   const spvtools::opt::Instruction& inst,
+                                                   const Type* first_operand_type) {
     auto* forced_result_ty = ForcedResultType(inst, first_operand_type);
     if ((!forced_result_ty) || (forced_result_ty == expr.type)) {
         return expr;
@@ -2226,7 +2225,7 @@
     return {expr.type, builder_.Bitcast(Source{}, expr.type->Build(builder_), expr.expr)};
 }
 
-TypedExpression ParserImpl::AsUnsigned(TypedExpression expr) {
+TypedExpression ASTParser::AsUnsigned(TypedExpression expr) {
     if (expr.type && expr.type->IsSignedScalarOrVector()) {
         auto* new_type = GetUnsignedIntMatchingShape(expr.type);
         return {new_type, builder_.Bitcast(Source{}, new_type->Build(builder_), expr.expr)};
@@ -2234,7 +2233,7 @@
     return expr;
 }
 
-TypedExpression ParserImpl::AsSigned(TypedExpression expr) {
+TypedExpression ASTParser::AsSigned(TypedExpression expr) {
     if (expr.type && expr.type->IsUnsignedScalarOrVector()) {
         auto* new_type = GetSignedIntMatchingShape(expr.type);
         return {new_type, builder_.Bitcast(Source{}, new_type->Build(builder_), expr.expr)};
@@ -2242,7 +2241,7 @@
     return expr;
 }
 
-bool ParserImpl::EmitFunctions() {
+bool ASTParser::EmitFunctions() {
     if (!success_) {
         return false;
     }
@@ -2269,7 +2268,7 @@
     return success_;
 }
 
-const spvtools::opt::Instruction* ParserImpl::GetMemoryObjectDeclarationForHandle(
+const spvtools::opt::Instruction* ASTParser::GetMemoryObjectDeclarationForHandle(
     uint32_t id,
     bool follow_image) {
     auto saved_id = id;
@@ -2355,7 +2354,7 @@
     }
 }
 
-const spvtools::opt::Instruction* ParserImpl::GetSpirvTypeForHandleOrHandleMemoryObjectDeclaration(
+const spvtools::opt::Instruction* ASTParser::GetSpirvTypeForHandleOrHandleMemoryObjectDeclaration(
     const spvtools::opt::Instruction& obj) {
     if (!success()) {
         return nullptr;
@@ -2421,7 +2420,7 @@
     return raw_handle_type;
 }
 
-const Type* ParserImpl::GetHandleTypeForSpirvHandle(const spvtools::opt::Instruction& obj) {
+const Type* ASTParser::GetHandleTypeForSpirvHandle(const spvtools::opt::Instruction& obj) {
     auto where = handle_type_.find(&obj);
     if (where != handle_type_.end()) {
         return where->second;
@@ -2586,7 +2585,7 @@
     return ast_handle_type;
 }
 
-const Type* ParserImpl::GetComponentTypeForFormat(builtin::TexelFormat format) {
+const Type* ASTParser::GetComponentTypeForFormat(builtin::TexelFormat format) {
     switch (format) {
         case builtin::TexelFormat::kR32Uint:
         case builtin::TexelFormat::kRgba8Uint:
@@ -2616,7 +2615,7 @@
     return nullptr;
 }
 
-unsigned ParserImpl::GetChannelCountForFormat(builtin::TexelFormat format) {
+unsigned ASTParser::GetChannelCountForFormat(builtin::TexelFormat format) {
     switch (format) {
         case builtin::TexelFormat::kR32Float:
         case builtin::TexelFormat::kR32Sint:
@@ -2650,7 +2649,7 @@
     return 0;
 }
 
-const Type* ParserImpl::GetTexelTypeForFormat(builtin::TexelFormat format) {
+const Type* ASTParser::GetTexelTypeForFormat(builtin::TexelFormat format) {
     const auto* component_type = GetComponentTypeForFormat(format);
     if (!component_type) {
         return nullptr;
@@ -2658,7 +2657,7 @@
     return ty_.Vector(component_type, 4);
 }
 
-bool ParserImpl::RegisterHandleUsage() {
+bool ASTParser::RegisterHandleUsage() {
     if (!success_) {
         return false;
     }
@@ -2803,7 +2802,7 @@
     return success_;
 }
 
-Usage ParserImpl::GetHandleUsage(uint32_t id) const {
+Usage ASTParser::GetHandleUsage(uint32_t id) const {
     const auto where = handle_usage_.find(def_use_mgr_->GetDef(id));
     if (where != handle_usage_.end()) {
         return where->second;
@@ -2811,11 +2810,11 @@
     return Usage();
 }
 
-const spvtools::opt::Instruction* ParserImpl::GetInstructionForTest(uint32_t id) const {
+const spvtools::opt::Instruction* ASTParser::GetInstructionForTest(uint32_t id) const {
     return def_use_mgr_ ? def_use_mgr_->GetDef(id) : nullptr;
 }
 
-std::string ParserImpl::GetMemberName(const Struct& struct_type, int member_index) {
+std::string ASTParser::GetMemberName(const Struct& struct_type, int member_index) {
     auto where = struct_id_for_symbol_.find(struct_type.name);
     if (where == struct_id_for_symbol_.end()) {
         Fail() << "no structure type registered for symbol";
@@ -2828,4 +2827,4 @@
 
 WorkgroupSizeInfo::~WorkgroupSizeInfo() = default;
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl.h b/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
similarity index 97%
rename from src/tint/lang/spirv/reader/parser_impl.h
rename to src/tint/lang/spirv/reader/ast_parser/ast_parser.h
index 00e0480..ea62390 100644
--- a/src/tint/lang/spirv/reader/parser_impl.h
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_PARSER_IMPL_H_
-#define SRC_TINT_LANG_SPIRV_READER_PARSER_IMPL_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_AST_PARSER_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_AST_PARSER_H_
 
 #include <memory>
 #include <string>
@@ -36,12 +36,12 @@
 TINT_END_DISABLE_WARNING(OLD_STYLE_CAST);
 TINT_END_DISABLE_WARNING(NEWLINE_EOF);
 
-#include "src/tint/lang/spirv/reader/attributes.h"
-#include "src/tint/lang/spirv/reader/entry_point_info.h"
-#include "src/tint/lang/spirv/reader/enum_converter.h"
-#include "src/tint/lang/spirv/reader/namer.h"
-#include "src/tint/lang/spirv/reader/parser_type.h"
-#include "src/tint/lang/spirv/reader/usage.h"
+#include "src/tint/lang/spirv/reader/ast_parser/attributes.h"
+#include "src/tint/lang/spirv/reader/ast_parser/entry_point_info.h"
+#include "src/tint/lang/spirv/reader/ast_parser/enum_converter.h"
+#include "src/tint/lang/spirv/reader/ast_parser/namer.h"
+#include "src/tint/lang/spirv/reader/ast_parser/type.h"
+#include "src/tint/lang/spirv/reader/ast_parser/usage.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
 
 /// This is the implementation of the SPIR-V parser for Tint.
@@ -61,7 +61,7 @@
 /// familiar to Vulkan SPIR-V developers.  We will tend to use "image"
 /// and "sampler" instead of "handle".
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// The binary representation of a SPIR-V decoration enum followed by its
 /// operands, if any.
@@ -122,16 +122,16 @@
 };
 
 /// Parser implementation for SPIR-V.
-class ParserImpl {
+class ASTParser {
     using ExpressionList = utils::Vector<const ast::Expression*, 8>;
 
   public:
     /// Creates a new parser
     /// @param input the input data to parse
-    explicit ParserImpl(const std::vector<uint32_t>& input);
+    explicit ASTParser(const std::vector<uint32_t>& input);
 
     /// Destructor
-    ~ParserImpl();
+    ~ASTParser();
 
     /// Run the parser
     /// @returns true if the parse was successful, false otherwise.
@@ -927,6 +927,6 @@
     WorkgroupSizeInfo workgroup_size_builtin_;
 };
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_PARSER_IMPL_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_AST_PARSER_H_
diff --git a/src/tint/lang/spirv/reader/parser_impl_test.cc b/src/tint/lang/spirv/reader/ast_parser/ast_parser_test.cc
similarity index 78%
rename from src/tint/lang/spirv/reader/parser_impl_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/ast_parser_test.cc
index da8cc6b..44fe192 100644
--- a/src/tint/lang/spirv/reader/parser_impl_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser_test.cc
@@ -13,22 +13,22 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::HasSubstr;
 
-TEST_F(SpvParserTest, Impl_Uint32VecEmpty) {
+TEST_F(SpirvASTParserTest, Impl_Uint32VecEmpty) {
     std::vector<uint32_t> data;
     auto p = parser(data);
     EXPECT_FALSE(p->Parse());
     // TODO(dneto): What message?
 }
 
-TEST_F(SpvParserTest, Impl_InvalidModuleFails) {
+TEST_F(SpirvASTParserTest, Impl_InvalidModuleFails) {
     auto invalid_spv = test::Assemble("%ty = OpTypeInt 3 0");
     auto p = parser(invalid_spv);
     EXPECT_FALSE(p->Parse());
@@ -36,7 +36,7 @@
     EXPECT_THAT(p->error(), HasSubstr("OpTypeInt 3 0"));
 }
 
-TEST_F(SpvParserTest, Impl_GenericVulkanShader_SimpleMemoryModel) {
+TEST_F(SpirvASTParserTest, Impl_GenericVulkanShader_SimpleMemoryModel) {
     auto spv = test::Assemble(R"(
   OpCapability Shader
   OpMemoryModel Logical Simple
@@ -54,7 +54,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, Impl_GenericVulkanShader_GLSL450MemoryModel) {
+TEST_F(SpirvASTParserTest, Impl_GenericVulkanShader_GLSL450MemoryModel) {
     auto spv = test::Assemble(R"(
   OpCapability Shader
   OpMemoryModel Logical GLSL450
@@ -72,7 +72,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, Impl_GenericVulkanShader_VulkanMemoryModel) {
+TEST_F(SpirvASTParserTest, Impl_GenericVulkanShader_VulkanMemoryModel) {
     auto spv = test::Assemble(R"(
   OpCapability Shader
   OpCapability VulkanMemoryModelKHR
@@ -92,7 +92,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, Impl_OpenCLKernel_Fails) {
+TEST_F(SpirvASTParserTest, Impl_OpenCLKernel_Fails) {
     auto spv = test::Assemble(R"(
   OpCapability Kernel
   OpCapability Addresses
@@ -110,7 +110,7 @@
     EXPECT_THAT(p->error(), HasSubstr("Capability Kernel is not allowed"));
 }
 
-TEST_F(SpvParserTest, Impl_Source_NoOpLine) {
+TEST_F(SpirvASTParserTest, Impl_Source_NoOpLine) {
     auto spv = test::Assemble(R"(
   OpCapability Shader
   OpMemoryModel Logical Simple
@@ -140,7 +140,7 @@
     EXPECT_EQ(0u, s1.range.begin.column);
 }
 
-TEST_F(SpvParserTest, Impl_Source_WithOpLine_WithOpNoLine) {
+TEST_F(SpirvASTParserTest, Impl_Source_WithOpLine_WithOpNoLine) {
     auto spv = test::Assemble(R"(
   OpCapability Shader
   OpMemoryModel Logical Simple
@@ -174,7 +174,7 @@
     EXPECT_EQ(0u, s1.range.begin.column);
 }
 
-TEST_F(SpvParserTest, Impl_Source_InvalidId) {
+TEST_F(SpirvASTParserTest, Impl_Source_InvalidId) {
     auto spv = test::Assemble(R"(
   OpCapability Shader
   OpMemoryModel Logical Simple
@@ -196,28 +196,28 @@
     EXPECT_EQ(0u, s99.range.begin.column);
 }
 
-TEST_F(SpvParserTest, Impl_IsValidIdentifier) {
-    EXPECT_FALSE(ParserImpl::IsValidIdentifier(""));  // empty
-    EXPECT_FALSE(ParserImpl::IsValidIdentifier("_"));
-    EXPECT_FALSE(ParserImpl::IsValidIdentifier("__"));
-    EXPECT_TRUE(ParserImpl::IsValidIdentifier("_x"));
-    EXPECT_FALSE(ParserImpl::IsValidIdentifier("9"));    // leading digit, but ok later
-    EXPECT_FALSE(ParserImpl::IsValidIdentifier(" "));    // leading space
-    EXPECT_FALSE(ParserImpl::IsValidIdentifier("a "));   // trailing space
-    EXPECT_FALSE(ParserImpl::IsValidIdentifier("a 1"));  // space in the middle
-    EXPECT_FALSE(ParserImpl::IsValidIdentifier("."));    // weird character
+TEST_F(SpirvASTParserTest, Impl_IsValidIdentifier) {
+    EXPECT_FALSE(ASTParser::IsValidIdentifier(""));  // empty
+    EXPECT_FALSE(ASTParser::IsValidIdentifier("_"));
+    EXPECT_FALSE(ASTParser::IsValidIdentifier("__"));
+    EXPECT_TRUE(ASTParser::IsValidIdentifier("_x"));
+    EXPECT_FALSE(ASTParser::IsValidIdentifier("9"));    // leading digit, but ok later
+    EXPECT_FALSE(ASTParser::IsValidIdentifier(" "));    // leading space
+    EXPECT_FALSE(ASTParser::IsValidIdentifier("a "));   // trailing space
+    EXPECT_FALSE(ASTParser::IsValidIdentifier("a 1"));  // space in the middle
+    EXPECT_FALSE(ASTParser::IsValidIdentifier("."));    // weird character
 
     // a simple identifier
-    EXPECT_TRUE(ParserImpl::IsValidIdentifier("A"));
+    EXPECT_TRUE(ASTParser::IsValidIdentifier("A"));
     // each upper case letter
-    EXPECT_TRUE(ParserImpl::IsValidIdentifier("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+    EXPECT_TRUE(ASTParser::IsValidIdentifier("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
     // each lower case letter
-    EXPECT_TRUE(ParserImpl::IsValidIdentifier("abcdefghijklmnopqrstuvwxyz"));
-    EXPECT_TRUE(ParserImpl::IsValidIdentifier("a0123456789"));  // each digit
-    EXPECT_TRUE(ParserImpl::IsValidIdentifier("x_"));           // has underscore
+    EXPECT_TRUE(ASTParser::IsValidIdentifier("abcdefghijklmnopqrstuvwxyz"));
+    EXPECT_TRUE(ASTParser::IsValidIdentifier("a0123456789"));  // each digit
+    EXPECT_TRUE(ASTParser::IsValidIdentifier("x_"));           // has underscore
 }
 
-TEST_F(SpvParserTest, Impl_FailOnNonFiniteLiteral) {
+TEST_F(SpirvASTParserTest, Impl_FailOnNonFiniteLiteral) {
     auto spv = test::Assemble(R"(
                        OpCapability Shader
                        OpMemoryModel Logical GLSL450
@@ -248,4 +248,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/attributes.h b/src/tint/lang/spirv/reader/ast_parser/attributes.h
similarity index 91%
rename from src/tint/lang/spirv/reader/attributes.h
rename to src/tint/lang/spirv/reader/ast_parser/attributes.h
index 5a2f375..3a56fe2 100644
--- a/src/tint/lang/spirv/reader/attributes.h
+++ b/src/tint/lang/spirv/reader/ast_parser/attributes.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_ATTRIBUTES_H_
-#define SRC_TINT_LANG_SPIRV_READER_ATTRIBUTES_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ATTRIBUTES_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ATTRIBUTES_H_
 
 #include "src/tint/lang/core/builtin/builtin_value.h"
 #include "src/tint/lang/wgsl/ast/attribute.h"
@@ -21,7 +21,7 @@
 #include "src/tint/utils/containers/enum_set.h"
 #include "src/tint/utils/containers/vector.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// Attributes holds a vector of ast::Attribute pointers, and a enum-set of flags used to hold
 /// additional metadata.
@@ -76,6 +76,6 @@
     utils::EnumSet<Flags> flags;
 };
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_ATTRIBUTES_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ATTRIBUTES_H_
diff --git a/src/tint/lang/spirv/reader/parser_impl_barrier_test.cc b/src/tint/lang/spirv/reader/ast_parser/barrier_test.cc
similarity index 89%
rename from src/tint/lang/spirv/reader/parser_impl_barrier_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/barrier_test.cc
index f71e4d6..28e2e79 100644
--- a/src/tint/lang/spirv/reader/parser_impl_barrier_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/barrier_test.cc
@@ -13,13 +13,13 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/lang/wgsl/ast/call_statement.h"
 #include "src/tint/lang/wgsl/sem/call.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -35,7 +35,7 @@
             OpName %main "main"
 )";
 
-    auto p = std::make_unique<ParserImpl>(test::Assemble(preamble + spirv));
+    auto p = std::make_unique<ASTParser>(test::Assemble(preamble + spirv));
     if (!p->BuildAndParseInternalModule()) {
         ProgramBuilder builder;
         builder.Diagnostics().add_error(diag::System::Reader, p->error());
@@ -44,7 +44,7 @@
     return p->Program();
 }
 
-TEST_F(SpvParserTest, WorkgroupBarrier) {
+TEST_F(SpirvASTParserTest, WorkgroupBarrier) {
     auto program = ParseAndBuild(R"(
                OpName %helper "helper"
        %void = OpTypeVoid
@@ -76,7 +76,7 @@
     EXPECT_EQ(builtin->Type(), builtin::Function::kWorkgroupBarrier);
 }
 
-TEST_F(SpvParserTest, StorageBarrier) {
+TEST_F(SpirvASTParserTest, StorageBarrier) {
     auto program = ParseAndBuild(R"(
                OpName %helper "helper"
        %void = OpTypeVoid
@@ -109,7 +109,7 @@
     EXPECT_EQ(builtin->Type(), builtin::Function::kStorageBarrier);
 }
 
-TEST_F(SpvParserTest, ErrBarrierInvalidExecution) {
+TEST_F(SpirvASTParserTest, ErrBarrierInvalidExecution) {
     auto program = ParseAndBuild(R"(
        %void = OpTypeVoid
           %1 = OpTypeFunction %void
@@ -128,7 +128,7 @@
                 HasSubstr("unsupported control barrier execution scope"));
 }
 
-TEST_F(SpvParserTest, ErrBarrierSemanticsMissingAcquireRelease) {
+TEST_F(SpirvASTParserTest, ErrBarrierSemanticsMissingAcquireRelease) {
     auto program = ParseAndBuild(R"(
        %void = OpTypeVoid
           %1 = OpTypeFunction %void
@@ -146,7 +146,7 @@
                 HasSubstr("control barrier semantics requires acquire and release"));
 }
 
-TEST_F(SpvParserTest, ErrBarrierInvalidSemantics) {
+TEST_F(SpirvASTParserTest, ErrBarrierInvalidSemantics) {
     auto program = ParseAndBuild(R"(
        %void = OpTypeVoid
           %1 = OpTypeFunction %void
@@ -163,7 +163,7 @@
     EXPECT_THAT(program.Diagnostics().str(), HasSubstr("unsupported control barrier semantics"));
 }
 
-TEST_F(SpvParserTest, ErrWorkgroupBarrierInvalidMemory) {
+TEST_F(SpirvASTParserTest, ErrWorkgroupBarrierInvalidMemory) {
     auto program = ParseAndBuild(R"(
        %void = OpTypeVoid
           %1 = OpTypeFunction %void
@@ -182,7 +182,7 @@
                 HasSubstr("workgroupBarrier requires workgroup memory scope"));
 }
 
-TEST_F(SpvParserTest, ErrStorageBarrierInvalidMemory) {
+TEST_F(SpirvASTParserTest, ErrStorageBarrierInvalidMemory) {
     auto program = ParseAndBuild(R"(
        %void = OpTypeVoid
           %1 = OpTypeFunction %void
@@ -202,4 +202,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_constant_test.cc b/src/tint/lang/spirv/reader/ast_parser/constant_test.cc
similarity index 92%
rename from src/tint/lang/spirv/reader/parser_impl_constant_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/constant_test.cc
index 3ee4e94..46b7bf8 100644
--- a/src/tint/lang/spirv/reader/parser_impl_constant_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/constant_test.cc
@@ -13,10 +13,10 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -95,7 +95,7 @@
     return out;
 }
 
-using SpvParserConstantTest = SpvParserTestBase<::testing::TestWithParam<ConstantCase>>;
+using SpvParserConstantTest = SpirvASTParserTestBase<::testing::TestWithParam<ConstantCase>>;
 
 TEST_P(SpvParserConstantTest, ReturnValue) {
     const auto spirv_type = GetParam().spirv_type;
@@ -139,4 +139,4 @@
                              {"%float", "%float_ten", "10.0f"}}));
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/construct.cc b/src/tint/lang/spirv/reader/ast_parser/construct.cc
similarity index 95%
rename from src/tint/lang/spirv/reader/construct.cc
rename to src/tint/lang/spirv/reader/ast_parser/construct.cc
index a95a7da..609495a 100644
--- a/src/tint/lang/spirv/reader/construct.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/construct.cc
@@ -12,9 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/construct.h"
+#include "src/tint/lang/spirv/reader/ast_parser/construct.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 Construct::Construct(const Construct* the_parent,
                      int the_depth,
@@ -60,4 +60,4 @@
       end_pos(the_end_pos),
       scope_end_pos(the_scope_end_pos) {}
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/construct.h b/src/tint/lang/spirv/reader/ast_parser/construct.h
similarity index 97%
rename from src/tint/lang/spirv/reader/construct.h
rename to src/tint/lang/spirv/reader/ast_parser/construct.h
index e0b9d75..e14c8a2 100644
--- a/src/tint/lang/spirv/reader/construct.h
+++ b/src/tint/lang/spirv/reader/ast_parser/construct.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_CONSTRUCT_H_
-#define SRC_TINT_LANG_SPIRV_READER_CONSTRUCT_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_CONSTRUCT_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_CONSTRUCT_H_
 
 #include <memory>
 #include <string>
@@ -21,7 +21,7 @@
 #include "src/tint/utils/containers/vector.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// A structured control flow construct, consisting of a set of basic blocks.
 /// A construct is a span of blocks in the computed block order,
@@ -265,6 +265,6 @@
     return ss.str();
 }
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_CONSTRUCT_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_CONSTRUCT_H_
diff --git a/src/tint/lang/spirv/reader/parser_impl_convert_member_decoration_test.cc b/src/tint/lang/spirv/reader/ast_parser/convert_member_decoration_test.cc
similarity index 78%
rename from src/tint/lang/spirv/reader/parser_impl_convert_member_decoration_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/convert_member_decoration_test.cc
index c299873..bda8264 100644
--- a/src/tint/lang/spirv/reader/parser_impl_convert_member_decoration_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/convert_member_decoration_test.cc
@@ -13,14 +13,14 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_IsEmpty) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_IsEmpty) {
     auto p = parser(std::vector<uint32_t>{});
 
     auto result = p->ConvertMemberDecoration(1, 1, nullptr, {});
@@ -28,7 +28,7 @@
     EXPECT_THAT(p->error(), Eq("malformed SPIR-V decoration: it's empty"));
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithoutOperand) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_OffsetWithoutOperand) {
     auto p = parser(std::vector<uint32_t>{});
 
     auto result = p->ConvertMemberDecoration(12, 13, nullptr, {uint32_t(spv::Decoration::Offset)});
@@ -37,7 +37,7 @@
                                "operand, has 0: member 13 of SPIR-V type 12"));
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_OffsetWithTooManyOperands) {
     auto p = parser(std::vector<uint32_t>{});
 
     auto result =
@@ -47,7 +47,7 @@
                                "operand, has 2: member 13 of SPIR-V type 12"));
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_Offset) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Offset) {
     auto p = parser(std::vector<uint32_t>{});
 
     auto result = p->ConvertMemberDecoration(1, 1, nullptr, {uint32_t(spv::Decoration::Offset), 8});
@@ -60,22 +60,22 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Natural) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Natural) {
     auto p = parser(std::vector<uint32_t>{});
 
-    spirv::F32 f32;
-    spirv::Matrix matrix(&f32, 2, 2);
+    reader::F32 f32;
+    reader::Matrix matrix(&f32, 2, 2);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 8});
     EXPECT_TRUE(result.list.IsEmpty());
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Custom) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Custom) {
     auto p = parser(std::vector<uint32_t>{});
 
-    spirv::F32 f32;
-    spirv::Matrix matrix(&f32, 2, 2);
+    reader::F32 f32;
+    reader::Matrix matrix(&f32, 2, 2);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 16});
     ASSERT_FALSE(result.list.IsEmpty());
@@ -86,22 +86,22 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Natural) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Natural) {
     auto p = parser(std::vector<uint32_t>{});
 
-    spirv::F32 f32;
-    spirv::Matrix matrix(&f32, 2, 4);
+    reader::F32 f32;
+    reader::Matrix matrix(&f32, 2, 4);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 16});
     EXPECT_TRUE(result.list.IsEmpty());
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Custom) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Custom) {
     auto p = parser(std::vector<uint32_t>{});
 
-    spirv::F32 f32;
-    spirv::Matrix matrix(&f32, 2, 4);
+    reader::F32 f32;
+    reader::Matrix matrix(&f32, 2, 4);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 64});
     ASSERT_FALSE(result.list.IsEmpty());
@@ -112,11 +112,11 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_Matrix2x3_Stride_Custom) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x3_Stride_Custom) {
     auto p = parser(std::vector<uint32_t>{});
 
-    spirv::F32 f32;
-    spirv::Matrix matrix(&f32, 2, 3);
+    reader::F32 f32;
+    reader::Matrix matrix(&f32, 2, 3);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 32});
     ASSERT_FALSE(result.list.IsEmpty());
@@ -127,7 +127,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_RelaxedPrecision) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_RelaxedPrecision) {
     // WGSL does not support relaxed precision. Drop it.
     // It's functionally correct to use full precision f32 instead of
     // relaxed precision f32.
@@ -139,7 +139,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertMemberDecoration_UnhandledDecoration) {
+TEST_F(SpirvASTParserTest, ConvertMemberDecoration_UnhandledDecoration) {
     auto p = parser(std::vector<uint32_t>{});
 
     auto result = p->ConvertMemberDecoration(12, 13, nullptr, {12345678});
@@ -149,4 +149,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_convert_type_test.cc b/src/tint/lang/spirv/reader/ast_parser/convert_type_test.cc
similarity index 88%
rename from src/tint/lang/spirv/reader/parser_impl_convert_type_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/convert_type_test.cc
index fe5b282..cdb1bdd 100644
--- a/src/tint/lang/spirv/reader/parser_impl_convert_type_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/convert_type_test.cc
@@ -13,10 +13,10 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -41,7 +41,7 @@
   )";
 }
 
-TEST_F(SpvParserTest, ConvertType_PreservesExistingFailure) {
+TEST_F(SpirvASTParserTest, ConvertType_PreservesExistingFailure) {
     auto p = parser(std::vector<uint32_t>{});
     p->Fail() << "boing";
     auto* type = p->ConvertType(10);
@@ -49,14 +49,14 @@
     EXPECT_THAT(p->error(), Eq("boing"));
 }
 
-TEST_F(SpvParserTest, ConvertType_RequiresInternalRepresntation) {
+TEST_F(SpirvASTParserTest, ConvertType_RequiresInternalRepresntation) {
     auto p = parser(std::vector<uint32_t>{});
     auto* type = p->ConvertType(10);
     EXPECT_EQ(type, nullptr);
     EXPECT_THAT(p->error(), Eq("ConvertType called when the internal module has not been built"));
 }
 
-TEST_F(SpvParserTest, ConvertType_NotAnId) {
+TEST_F(SpirvASTParserTest, ConvertType_NotAnId) {
     auto assembly = Preamble() + MainBody();
     auto p = parser(test::Assemble(assembly));
     EXPECT_TRUE(p->BuildInternalModule());
@@ -67,7 +67,7 @@
     EXPECT_THAT(p->error(), Eq("ID is not a SPIR-V type: 900"));
 }
 
-TEST_F(SpvParserTest, ConvertType_IdExistsButIsNotAType) {
+TEST_F(SpirvASTParserTest, ConvertType_IdExistsButIsNotAType) {
     auto assembly = R"(
      OpCapability Shader
      %1 = OpExtInstImport "GLSL.std.450"
@@ -83,7 +83,7 @@
     EXPECT_THAT(p->error(), Eq("ID is not a SPIR-V type: 1"));
 }
 
-TEST_F(SpvParserTest, ConvertType_UnhandledType) {
+TEST_F(SpirvASTParserTest, ConvertType_UnhandledType) {
     // Pipes are an OpenCL type. Tint doesn't support them.
     auto p = parser(test::Assemble("%70 = OpTypePipe WriteOnly"));
     EXPECT_TRUE(p->BuildInternalModule());
@@ -93,7 +93,7 @@
     EXPECT_THAT(p->error(), Eq("unknown SPIR-V type with ID 70: %70 = OpTypePipe WriteOnly"));
 }
 
-TEST_F(SpvParserTest, ConvertType_Void) {
+TEST_F(SpirvASTParserTest, ConvertType_Void) {
     auto p = parser(test::Assemble(Preamble() + "%1 = OpTypeVoid" + R"(
    %voidfn = OpTypeFunction %1
    %main = OpFunction %1 None %voidfn
@@ -108,7 +108,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_Bool) {
+TEST_F(SpirvASTParserTest, ConvertType_Bool) {
     auto p = parser(test::Assemble(Preamble() + "%100 = OpTypeBool" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
 
@@ -117,7 +117,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_I32) {
+TEST_F(SpirvASTParserTest, ConvertType_I32) {
     auto p = parser(test::Assemble(Preamble() + "%2 = OpTypeInt 32 1" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
 
@@ -126,7 +126,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_U32) {
+TEST_F(SpirvASTParserTest, ConvertType_U32) {
     auto p = parser(test::Assemble(Preamble() + "%3 = OpTypeInt 32 0" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
 
@@ -135,7 +135,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_F32) {
+TEST_F(SpirvASTParserTest, ConvertType_F32) {
     auto p = parser(test::Assemble(Preamble() + "%4 = OpTypeFloat 32" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
 
@@ -144,7 +144,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_BadIntWidth) {
+TEST_F(SpirvASTParserTest, ConvertType_BadIntWidth) {
     auto p = parser(test::Assemble(Preamble() + "%5 = OpTypeInt 17 1" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
 
@@ -153,7 +153,7 @@
     EXPECT_THAT(p->error(), Eq("unhandled integer width: 17"));
 }
 
-TEST_F(SpvParserTest, ConvertType_BadFloatWidth) {
+TEST_F(SpirvASTParserTest, ConvertType_BadFloatWidth) {
     auto p = parser(test::Assemble(Preamble() + "%6 = OpTypeFloat 19" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
 
@@ -162,7 +162,7 @@
     EXPECT_THAT(p->error(), Eq("unhandled float width: 19"));
 }
 
-TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidVectorElement) {
+TEST_F(SpirvASTParserTest, DISABLED_ConvertType_InvalidVectorElement) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %5 = OpTypePipe ReadOnly
     %20 = OpTypeVector %5 2
@@ -174,7 +174,7 @@
     EXPECT_THAT(p->error(), Eq("unknown SPIR-V type: 5"));
 }
 
-TEST_F(SpvParserTest, ConvertType_VecOverF32) {
+TEST_F(SpirvASTParserTest, ConvertType_VecOverF32) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %float = OpTypeFloat 32
     %20 = OpTypeVector %float 2
@@ -201,7 +201,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_VecOverI32) {
+TEST_F(SpirvASTParserTest, ConvertType_VecOverI32) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %int = OpTypeInt 32 1
     %20 = OpTypeVector %int 2
@@ -228,7 +228,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_VecOverU32) {
+TEST_F(SpirvASTParserTest, ConvertType_VecOverU32) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %uint = OpTypeInt 32 0
     %20 = OpTypeVector %uint 2
@@ -255,7 +255,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidMatrixElement) {
+TEST_F(SpirvASTParserTest, DISABLED_ConvertType_InvalidMatrixElement) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %5 = OpTypePipe ReadOnly
     %10 = OpTypeVector %5 2
@@ -268,7 +268,7 @@
     EXPECT_THAT(p->error(), Eq("unknown SPIR-V type: 5"));
 }
 
-TEST_F(SpvParserTest, ConvertType_MatrixOverF32) {
+TEST_F(SpirvASTParserTest, ConvertType_MatrixOverF32) {
     // Matrices are only defined over floats.
     auto p = parser(test::Assemble(Preamble() + R"(
     %float = OpTypeFloat 32
@@ -346,7 +346,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_RuntimeArray) {
+TEST_F(SpirvASTParserTest, ConvertType_RuntimeArray) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %uint = OpTypeInt 32 0
     %10 = OpTypeRuntimeArray %uint
@@ -366,7 +366,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_RuntimeArray_InvalidDecoration) {
+TEST_F(SpirvASTParserTest, ConvertType_RuntimeArray_InvalidDecoration) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpDecorate %10 Block
     %uint = OpTypeInt 32 0
@@ -379,7 +379,7 @@
                 Eq("invalid array type ID 10: unknown decoration 2 with 1 total words"));
 }
 
-TEST_F(SpvParserTest, ConvertType_RuntimeArray_ArrayStride_Valid) {
+TEST_F(SpirvASTParserTest, ConvertType_RuntimeArray_ArrayStride_Valid) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpDecorate %10 ArrayStride 64
     %uint = OpTypeInt 32 0
@@ -394,7 +394,7 @@
     EXPECT_EQ(arr_type->stride, 64u);
 }
 
-TEST_F(SpvParserTest, ConvertType_RuntimeArray_ArrayStride_ZeroIsError) {
+TEST_F(SpirvASTParserTest, ConvertType_RuntimeArray_ArrayStride_ZeroIsError) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpDecorate %10 ArrayStride 0
     %uint = OpTypeInt 32 0
@@ -406,7 +406,7 @@
     EXPECT_THAT(p->error(), Eq("invalid array type ID 10: ArrayStride can't be 0"));
 }
 
-TEST_F(SpvParserTest, ConvertType_Array) {
+TEST_F(SpirvASTParserTest, ConvertType_Array) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %uint = OpTypeInt 32 0
     %uint_42 = OpConstant %uint 42
@@ -427,7 +427,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_ArrayBadLengthIsSpecConstantValue) {
+TEST_F(SpirvASTParserTest, ConvertType_ArrayBadLengthIsSpecConstantValue) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpDecorate %uint_42 SpecId 12
     %uint = OpTypeInt 32 0
@@ -441,7 +441,7 @@
     EXPECT_THAT(p->error(), Eq("Array type 10 length is a specialization constant"));
 }
 
-TEST_F(SpvParserTest, ConvertType_ArrayBadLengthIsSpecConstantExpr) {
+TEST_F(SpirvASTParserTest, ConvertType_ArrayBadLengthIsSpecConstantExpr) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %uint = OpTypeInt 32 0
     %uint_42 = OpConstant %uint 42
@@ -459,7 +459,7 @@
 // E.g. it's the ID of a type.  That won't validate, and the SPIRV-Tools
 // optimizer representation doesn't handle it and asserts out instead.
 
-TEST_F(SpvParserTest, ConvertType_ArrayBadTooBig) {
+TEST_F(SpirvASTParserTest, ConvertType_ArrayBadTooBig) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %uint64 = OpTypeInt 64 0
     %uint64_big = OpConstant %uint64 5000000000
@@ -474,7 +474,7 @@
     EXPECT_THAT(p->error(), Eq("unhandled integer width: 64"));
 }
 
-TEST_F(SpvParserTest, ConvertType_Array_InvalidDecoration) {
+TEST_F(SpirvASTParserTest, ConvertType_Array_InvalidDecoration) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpDecorate %10 Block
     %uint = OpTypeInt 32 0
@@ -488,7 +488,7 @@
                 Eq("invalid array type ID 10: unknown decoration 2 with 1 total words"));
 }
 
-TEST_F(SpvParserTest, ConvertType_ArrayStride_Valid) {
+TEST_F(SpirvASTParserTest, ConvertType_ArrayStride_Valid) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpDecorate %10 ArrayStride 8
     %uint = OpTypeInt 32 0
@@ -506,7 +506,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_ArrayStride_ZeroIsError) {
+TEST_F(SpirvASTParserTest, ConvertType_ArrayStride_ZeroIsError) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpDecorate %10 ArrayStride 0
     %uint = OpTypeInt 32 0
@@ -520,7 +520,7 @@
     EXPECT_THAT(p->error(), Eq("invalid array type ID 10: ArrayStride can't be 0"));
 }
 
-TEST_F(SpvParserTest, ConvertType_StructEmpty) {
+TEST_F(SpirvASTParserTest, ConvertType_StructEmpty) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %10 = OpTypeStruct
   )" + MainBody()));
@@ -533,7 +533,7 @@
               "OpTypeStruct");
 }
 
-TEST_F(SpvParserTest, ConvertType_StructTwoMembers) {
+TEST_F(SpirvASTParserTest, ConvertType_StructTwoMembers) {
     auto p = parser(test::Assemble(Preamble() + R"(
     %uint = OpTypeInt 32 0
     %float = OpTypeFloat 32
@@ -551,7 +551,7 @@
     EXPECT_EQ(test::ToString(program, str), "S");
 }
 
-TEST_F(SpvParserTest, ConvertType_StructWithBlockDecoration) {
+TEST_F(SpirvASTParserTest, ConvertType_StructWithBlockDecoration) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpDecorate %10 Block
     %uint = OpTypeInt 32 0
@@ -569,7 +569,7 @@
     EXPECT_EQ(test::ToString(program, str), "S");
 }
 
-TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) {
+TEST_F(SpirvASTParserTest, ConvertType_StructWithMemberDecorations) {
     auto p = parser(test::Assemble(Preamble() + R"(
     OpMemberDecorate %10 0 Offset 0
     OpMemberDecorate %10 1 Offset 8
@@ -591,7 +591,7 @@
     EXPECT_EQ(test::ToString(program, str), "S");
 }
 
-TEST_F(SpvParserTest, ConvertType_Struct_NoDeduplication) {
+TEST_F(SpirvASTParserTest, ConvertType_Struct_NoDeduplication) {
     // Prove that distinct SPIR-V structs map to distinct WGSL types.
     auto p = parser(test::Assemble(Preamble() + R"(
     %uint = OpTypeInt 32 0
@@ -620,7 +620,7 @@
     EXPECT_NE(type11, type10);
 }
 
-TEST_F(SpvParserTest, ConvertType_Array_NoDeduplication) {
+TEST_F(SpirvASTParserTest, ConvertType_Array_NoDeduplication) {
     // Prove that distinct SPIR-V arrays map to distinct WGSL types.
     auto assembly = Preamble() + R"(
     %uint = OpTypeInt 32 0
@@ -645,7 +645,7 @@
     EXPECT_NE(type21, type20);
 }
 
-TEST_F(SpvParserTest, ConvertType_RuntimeArray_NoDeduplication) {
+TEST_F(SpirvASTParserTest, ConvertType_RuntimeArray_NoDeduplication) {
     // Prove that distinct SPIR-V runtime arrays map to distinct WGSL types.
     // The implementation already de-duplicates them because it knows
     // runtime-arrays normally have stride decorations.
@@ -689,7 +689,7 @@
 // TODO(dneto): Demonstrate multiple member deocrations. Blocked on
 // crbug.com/tint/30
 
-TEST_F(SpvParserTest, ConvertType_InvalidPointeetype) {
+TEST_F(SpirvASTParserTest, ConvertType_InvalidPointeetype) {
     // Disallow pointer-to-function
     auto p = parser(test::Assemble(Preamble() + R"(
   %void = OpTypeVoid
@@ -709,7 +709,7 @@
     EXPECT_THAT(p->error(), Eq("SPIR-V pointer type with ID 3 has invalid pointee type 42"));
 }
 
-TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidAddressSpace) {
+TEST_F(SpirvASTParserTest, DISABLED_ConvertType_InvalidAddressSpace) {
     // Disallow invalid address space
     auto p = parser(test::Assemble(Preamble() + R"(
   %1 = OpTypeFloat 32
@@ -719,7 +719,7 @@
     EXPECT_FALSE(p->BuildInternalModule()) << p->error();
 }
 
-TEST_F(SpvParserTest, ConvertType_PointerInput) {
+TEST_F(SpirvASTParserTest, ConvertType_PointerInput) {
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
   %3 = OpTypePointer Input %float
@@ -735,7 +735,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_PointerOutput) {
+TEST_F(SpirvASTParserTest, ConvertType_PointerOutput) {
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
   %3 = OpTypePointer Output %float
@@ -751,7 +751,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_PointerUniform) {
+TEST_F(SpirvASTParserTest, ConvertType_PointerUniform) {
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
   %3 = OpTypePointer Uniform %float
@@ -767,7 +767,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_PointerWorkgroup) {
+TEST_F(SpirvASTParserTest, ConvertType_PointerWorkgroup) {
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
   %3 = OpTypePointer Workgroup %float
@@ -783,7 +783,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_PointerStorageBuffer) {
+TEST_F(SpirvASTParserTest, ConvertType_PointerStorageBuffer) {
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
   %3 = OpTypePointer StorageBuffer %float
@@ -799,7 +799,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_PointerPrivate) {
+TEST_F(SpirvASTParserTest, ConvertType_PointerPrivate) {
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
   %3 = OpTypePointer Private %float
@@ -815,7 +815,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_PointerFunction) {
+TEST_F(SpirvASTParserTest, ConvertType_PointerFunction) {
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
   %3 = OpTypePointer Function %float
@@ -831,7 +831,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_PointerToPointer) {
+TEST_F(SpirvASTParserTest, ConvertType_PointerToPointer) {
     // FYI:  The reader suports pointer-to-pointer even while WebGPU does not.
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
@@ -857,7 +857,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_Sampler_PretendVoid) {
+TEST_F(SpirvASTParserTest, ConvertType_Sampler_PretendVoid) {
     // We fake the type suport for samplers, images, and sampled images.
     auto p = parser(test::Assemble(Preamble() + R"(
   %1 = OpTypeSampler
@@ -869,7 +869,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_Image_PretendVoid) {
+TEST_F(SpirvASTParserTest, ConvertType_Image_PretendVoid) {
     // We fake the type suport for samplers, images, and sampled images.
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
@@ -882,7 +882,7 @@
     EXPECT_TRUE(p->error().empty());
 }
 
-TEST_F(SpvParserTest, ConvertType_SampledImage_PretendVoid) {
+TEST_F(SpirvASTParserTest, ConvertType_SampledImage_PretendVoid) {
     auto p = parser(test::Assemble(Preamble() + R"(
   %float = OpTypeFloat 32
   %im = OpTypeImage %float 2D 0 0 0 1 Unknown
@@ -896,4 +896,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/entry_point_info.cc b/src/tint/lang/spirv/reader/ast_parser/entry_point_info.cc
similarity index 91%
rename from src/tint/lang/spirv/reader/entry_point_info.cc
rename to src/tint/lang/spirv/reader/ast_parser/entry_point_info.cc
index 87dcf2c..7725a9d 100644
--- a/src/tint/lang/spirv/reader/entry_point_info.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/entry_point_info.cc
@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/entry_point_info.h"
+#include "src/tint/lang/spirv/reader/ast_parser/entry_point_info.h"
 
 #include <utility>
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 EntryPointInfo::EntryPointInfo(std::string the_name,
                                ast::PipelineStage the_stage,
@@ -37,4 +37,4 @@
 
 EntryPointInfo::~EntryPointInfo() = default;
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/entry_point_info.h b/src/tint/lang/spirv/reader/ast_parser/entry_point_info.h
similarity index 92%
rename from src/tint/lang/spirv/reader/entry_point_info.h
rename to src/tint/lang/spirv/reader/ast_parser/entry_point_info.h
index 608c50a..2a84d61 100644
--- a/src/tint/lang/spirv/reader/entry_point_info.h
+++ b/src/tint/lang/spirv/reader/ast_parser/entry_point_info.h
@@ -12,15 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_ENTRY_POINT_INFO_H_
-#define SRC_TINT_LANG_SPIRV_READER_ENTRY_POINT_INFO_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ENTRY_POINT_INFO_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ENTRY_POINT_INFO_H_
 
 #include <string>
 
 #include "src/tint/lang/wgsl/ast/pipeline_stage.h"
 #include "src/tint/utils/containers/vector.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// The size of an integer-coordinate grid, in the x, y, and z dimensions.
 struct GridSize {
@@ -86,6 +86,6 @@
     GridSize workgroup_size;
 };
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_ENTRY_POINT_INFO_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ENTRY_POINT_INFO_H_
diff --git a/src/tint/lang/spirv/reader/enum_converter.cc b/src/tint/lang/spirv/reader/ast_parser/enum_converter.cc
similarity index 97%
rename from src/tint/lang/spirv/reader/enum_converter.cc
rename to src/tint/lang/spirv/reader/ast_parser/enum_converter.cc
index e381484..c830c5b 100644
--- a/src/tint/lang/spirv/reader/enum_converter.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/enum_converter.cc
@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/enum_converter.h"
+#include "src/tint/lang/spirv/reader/ast_parser/enum_converter.h"
 
 #include "src/tint/lang/core/type/texture_dimension.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 EnumConverter::EnumConverter(const FailStream& fs) : fail_stream_(fs) {}
 
@@ -179,4 +179,4 @@
     return builtin::TexelFormat::kUndefined;
 }
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/enum_converter.h b/src/tint/lang/spirv/reader/ast_parser/enum_converter.h
similarity index 91%
rename from src/tint/lang/spirv/reader/enum_converter.h
rename to src/tint/lang/spirv/reader/ast_parser/enum_converter.h
index fb41efe..9b364b2 100644
--- a/src/tint/lang/spirv/reader/enum_converter.h
+++ b/src/tint/lang/spirv/reader/ast_parser/enum_converter.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_ENUM_CONVERTER_H_
-#define SRC_TINT_LANG_SPIRV_READER_ENUM_CONVERTER_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ENUM_CONVERTER_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ENUM_CONVERTER_H_
 
 #include "spirv/unified1/spirv.h"
 #include "spirv/unified1/spirv.hpp11"
@@ -21,10 +21,10 @@
 #include "src/tint/lang/core/builtin/builtin_value.h"
 #include "src/tint/lang/core/type/storage_texture.h"
 #include "src/tint/lang/core/type/texture_dimension.h"
-#include "src/tint/lang/spirv/reader/fail_stream.h"
+#include "src/tint/lang/spirv/reader/ast_parser/fail_stream.h"
 #include "src/tint/lang/wgsl/ast/pipeline_stage.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// A converter from SPIR-V enums to Tint AST enums.
 class EnumConverter {
@@ -91,6 +91,6 @@
     FailStream fail_stream_;
 };
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_ENUM_CONVERTER_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ENUM_CONVERTER_H_
diff --git a/src/tint/lang/spirv/reader/enum_converter_test.cc b/src/tint/lang/spirv/reader/ast_parser/enum_converter_test.cc
similarity index 98%
rename from src/tint/lang/spirv/reader/enum_converter_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/enum_converter_test.cc
index 5a29fa5..0e80701 100644
--- a/src/tint/lang/spirv/reader/enum_converter_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/enum_converter_test.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/enum_converter.h"
+#include "src/tint/lang/spirv/reader/ast_parser/enum_converter.h"
 
 #include <string>
 
@@ -20,7 +20,7 @@
 #include "src/tint/lang/core/type/texture_dimension.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 // Pipeline stage
@@ -384,4 +384,4 @@
         TexelFormatCase{spv::ImageFormat::Rg8ui, false, builtin::TexelFormat::kUndefined}));
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/fail_stream.h b/src/tint/lang/spirv/reader/ast_parser/fail_stream.h
similarity index 89%
rename from src/tint/lang/spirv/reader/fail_stream.h
rename to src/tint/lang/spirv/reader/ast_parser/fail_stream.h
index 60ab1b5..16e0a0a 100644
--- a/src/tint/lang/spirv/reader/fail_stream.h
+++ b/src/tint/lang/spirv/reader/ast_parser/fail_stream.h
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_FAIL_STREAM_H_
-#define SRC_TINT_LANG_SPIRV_READER_FAIL_STREAM_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_FAIL_STREAM_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_FAIL_STREAM_H_
 
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// A FailStream object accumulates values onto a given stream,
 /// and can be used to record failure by writing the false value
@@ -64,6 +64,6 @@
     utils::StringStream* out_;
 };
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_FAIL_STREAM_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_FAIL_STREAM_H_
diff --git a/src/tint/lang/spirv/reader/fail_stream_test.cc b/src/tint/lang/spirv/reader/ast_parser/fail_stream_test.cc
similarity index 92%
rename from src/tint/lang/spirv/reader/fail_stream_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/fail_stream_test.cc
index 7979ef6..9116955 100644
--- a/src/tint/lang/spirv/reader/fail_stream_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/fail_stream_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/fail_stream.h"
+#include "src/tint/lang/spirv/reader/ast_parser/fail_stream.h"
 
 #include "gmock/gmock.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -67,4 +67,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function.cc b/src/tint/lang/spirv/reader/ast_parser/function.cc
similarity index 99%
rename from src/tint/lang/spirv/reader/function.cc
rename to src/tint/lang/spirv/reader/ast_parser/function.cc
index d1d1ee6..e6a5c24 100644
--- a/src/tint/lang/spirv/reader/function.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
 
 #include <algorithm>
 #include <array>
@@ -143,7 +143,7 @@
 
 using namespace tint::number_suffixes;  // NOLINT
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 namespace {
 
@@ -783,7 +783,7 @@
     return nullptr;
 }
 
-FunctionEmitter::FunctionEmitter(ParserImpl* pi,
+FunctionEmitter::FunctionEmitter(ASTParser* pi,
                                  const spvtools::opt::Function& function,
                                  const EntryPointInfo* ep_info)
     : parser_impl_(*pi),
@@ -802,7 +802,7 @@
     PushNewStatementBlock(nullptr, 0, nullptr);
 }
 
-FunctionEmitter::FunctionEmitter(ParserImpl* pi, const spvtools::opt::Function& function)
+FunctionEmitter::FunctionEmitter(ASTParser* pi, const spvtools::opt::Function& function)
     : FunctionEmitter(pi, function, nullptr) {}
 
 FunctionEmitter::FunctionEmitter(FunctionEmitter&& other)
@@ -6425,9 +6425,9 @@
 FunctionEmitter::FunctionDeclaration::FunctionDeclaration() = default;
 FunctionEmitter::FunctionDeclaration::~FunctionDeclaration() = default;
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::StatementBuilder);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::SwitchStatementBuilder);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::IfStatementBuilder);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::LoopStatementBuilder);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::StatementBuilder);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::SwitchStatementBuilder);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::IfStatementBuilder);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::LoopStatementBuilder);
diff --git a/src/tint/lang/spirv/reader/function.h b/src/tint/lang/spirv/reader/ast_parser/function.h
similarity index 98%
rename from src/tint/lang/spirv/reader/function.h
rename to src/tint/lang/spirv/reader/ast_parser/function.h
index 914ae5d..ed589dd 100644
--- a/src/tint/lang/spirv/reader/function.h
+++ b/src/tint/lang/spirv/reader/ast_parser/function.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_FUNCTION_H_
-#define SRC_TINT_LANG_SPIRV_READER_FUNCTION_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_FUNCTION_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_FUNCTION_H_
 
 #include <limits>
 #include <memory>
@@ -24,13 +24,13 @@
 #include <utility>
 #include <vector>
 
-#include "src/tint/lang/spirv/reader/attributes.h"
-#include "src/tint/lang/spirv/reader/construct.h"
-#include "src/tint/lang/spirv/reader/parser_impl.h"
+#include "src/tint/lang/spirv/reader/ast_parser/ast_parser.h"
+#include "src/tint/lang/spirv/reader/ast_parser/attributes.h"
+#include "src/tint/lang/spirv/reader/ast_parser/construct.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// Kinds of CFG edges.
 //
@@ -430,15 +430,15 @@
   public:
     /// Creates a FunctionEmitter, and prepares to write to the AST module
     /// in `pi`
-    /// @param pi a ParserImpl which has already executed BuildInternalModule
+    /// @param pi a ASTParser which has already executed BuildInternalModule
     /// @param function the function to emit
-    FunctionEmitter(ParserImpl* pi, const spvtools::opt::Function& function);
+    FunctionEmitter(ASTParser* pi, const spvtools::opt::Function& function);
     /// Creates a FunctionEmitter, and prepares to write to the AST module
     /// in `pi`
-    /// @param pi a ParserImpl which has already executed BuildInternalModule
+    /// @param pi a ASTParser which has already executed BuildInternalModule
     /// @param function the function to emit
     /// @param ep_info entry point information for this function, or nullptr
-    FunctionEmitter(ParserImpl* pi,
+    FunctionEmitter(ASTParser* pi,
                     const spvtools::opt::Function& function,
                     const EntryPointInfo* ep_info);
     /// Move constructor. Only valid when the other object was newly created.
@@ -466,7 +466,7 @@
     FailStream& Fail() { return fail_stream_.Fail(); }
 
     /// @returns the parser implementation
-    ParserImpl* parser() { return &parser_impl_; }
+    ASTParser* parser() { return &parser_impl_; }
 
     /// Emits the entry point as a wrapper around its implementation function.
     /// Pipeline inputs become formal parameters, and pipeline outputs become
@@ -1293,9 +1293,9 @@
         return builder_.create<T>(std::forward<ARGS>(args)...);
     }
 
-    using PtrAs = ParserImpl::PtrAs;
+    using PtrAs = ASTParser::PtrAs;
 
-    ParserImpl& parser_impl_;
+    ASTParser& parser_impl_;
     TypeManager& ty_;
     ProgramBuilder& builder_;
     spvtools::opt::IRContext& ir_context_;
@@ -1343,6 +1343,6 @@
     const EntryPointInfo* ep_info_ = nullptr;
 };
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_FUNCTION_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_FUNCTION_H_
diff --git a/src/tint/lang/spirv/reader/function_arithmetic_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_arithmetic_test.cc
similarity index 96%
rename from src/tint/lang/spirv/reader/function_arithmetic_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_arithmetic_test.cc
index 1b6fb8b..ea98948 100644
--- a/src/tint/lang/spirv/reader/function_arithmetic_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_arithmetic_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::HasSubstr;
@@ -107,7 +107,7 @@
     return "bad case";
 }
 
-using SpvUnaryArithTest = SpvParserTestBase<::testing::Test>;
+using SpvUnaryArithTest = SpirvASTParserTestBase<::testing::Test>;
 
 TEST_F(SpvUnaryArithTest, SNegate_Int_Int) {
     const auto assembly = Preamble() + R"(
@@ -292,8 +292,8 @@
     return out;
 }
 
-using SpvBinaryArithTest = SpvParserTestBase<::testing::TestWithParam<BinaryData>>;
-using SpvBinaryArithTestBasic = SpvParserTestBase<::testing::Test>;
+using SpvBinaryArithTest = SpirvASTParserTestBase<::testing::TestWithParam<BinaryData>>;
+using SpvBinaryArithTestBasic = SpirvASTParserTestBase<::testing::Test>;
 
 TEST_P(SpvBinaryArithTest, EmitExpression) {
     const auto assembly = Preamble() + R"(
@@ -332,7 +332,8 @@
     return out;
 }
 
-using SpvBinaryArithGeneralTest = SpvParserTestBase<::testing::TestWithParam<BinaryDataGeneral>>;
+using SpvBinaryArithGeneralTest =
+    SpirvASTParserTestBase<::testing::TestWithParam<BinaryDataGeneral>>;
 
 TEST_P(SpvBinaryArithGeneralTest, EmitExpression) {
     const auto assembly = Preamble() + R"(
@@ -356,7 +357,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_IAdd,
+    SpirvASTParserTest_IAdd,
     SpvBinaryArithTest,
     ::testing::Values(
         // Both uint
@@ -369,7 +370,7 @@
                    "+", AstFor("v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_IAdd_MixedSignedness,
+    SpirvASTParserTest_IAdd_MixedSignedness,
     SpvBinaryArithGeneralTest,
     ::testing::Values(
         // Mixed, uint <- int uint
@@ -391,7 +392,7 @@
             "v2int", "v2uint_10_20", "OpIAdd", "v2int_40_30", "vec2i",
             R"(bitcast<vec2i>((vec2u(10u, 20u) + bitcast<vec2u>(vec2i(40i, 30i)))))"}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FAdd,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FAdd,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Scalar float
@@ -402,7 +403,7 @@
                                         AstFor("v2float_60_50")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ISub,
+    SpirvASTParserTest_ISub,
     SpvBinaryArithTest,
     ::testing::Values(
         // Both uint
@@ -415,7 +416,7 @@
                    "-", AstFor("v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ISub_MixedSignedness,
+    SpirvASTParserTest_ISub_MixedSignedness,
     SpvBinaryArithGeneralTest,
     ::testing::Values(
         // Mixed, uint <- int uint
@@ -437,7 +438,7 @@
             "v2int", "v2uint_10_20", "OpISub", "v2int_40_30", "vec2i",
             R"(bitcast<vec2i>((vec2u(10u, 20u) - bitcast<vec2u>(vec2i(40i, 30i)))))"}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FSub,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FSub,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Scalar float
@@ -448,7 +449,7 @@
                                         AstFor("v2float_60_50")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_IMul,
+    SpirvASTParserTest_IMul,
     SpvBinaryArithTest,
     ::testing::Values(
         // Both uint
@@ -461,7 +462,7 @@
                    "*", AstFor("v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_IMul_MixedSignedness,
+    SpirvASTParserTest_IMul_MixedSignedness,
     SpvBinaryArithGeneralTest,
     ::testing::Values(
         // Mixed, uint <- int uint
@@ -483,7 +484,7 @@
             "v2int", "v2uint_10_20", "OpIMul", "v2int_40_30", "vec2i",
             R"(bitcast<vec2i>((vec2u(10u, 20u) * bitcast<vec2u>(vec2i(40i, 30i)))))"}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FMul,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FMul,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Scalar float
@@ -493,7 +494,7 @@
                                         "vec2f", AstFor("v2float_50_60"), "*",
                                         AstFor("v2float_60_50")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_UDiv,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_UDiv,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Both uint
@@ -502,7 +503,7 @@
                              BinaryData{"v2uint", "v2uint_10_20", "OpUDiv", "v2uint_20_10", "vec2u",
                                         AstFor("v2uint_10_20"), "/", AstFor("v2uint_20_10")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_SDiv,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_SDiv,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Both int
@@ -512,7 +513,7 @@
                                         AstFor("v2int_30_40"), "/", AstFor("v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_SDiv_MixedSignednessOperands,
+    SpirvASTParserTest_SDiv_MixedSignednessOperands,
     SpvBinaryArithTest,
     ::testing::Values(
         // Mixed, returning int, second arg uint
@@ -568,7 +569,7 @@
                 HasSubstr(R"(let x_1 = bitcast<vec2u>((vec2i(30i, 40i) / vec2i(40i, 30i)));)"));
 }
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FDiv,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FDiv,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Scalar float
@@ -578,7 +579,7 @@
                                         "vec2f", AstFor("v2float_50_60"), "/",
                                         AstFor("v2float_60_50")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_UMod,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_UMod,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Both uint
@@ -590,7 +591,7 @@
 // Currently WGSL is missing a mapping for OpSRem
 // https://github.com/gpuweb/gpuweb/issues/702
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_SMod,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_SMod,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Both int
@@ -600,7 +601,7 @@
                                         AstFor("v2int_30_40"), "%", AstFor("v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_SMod_MixedSignednessOperands,
+    SpirvASTParserTest_SMod_MixedSignednessOperands,
     SpvBinaryArithTest,
     ::testing::Values(
         // Mixed, returning int, second arg uint
@@ -656,7 +657,7 @@
                 HasSubstr(R"(let x_1 = bitcast<vec2u>((vec2i(30i, 40i) % vec2i(40i, 30i)));)"));
 }
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FRem,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FRem,
                          SpvBinaryArithTest,
                          ::testing::Values(
                              // Scalar float
@@ -853,7 +854,7 @@
 }
 
 using SpvBinaryDerivativeTest =
-    SpvParserTestBase<::testing::TestWithParam<std::tuple<BuiltinData, ArgAndTypeData>>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<std::tuple<BuiltinData, ArgAndTypeData>>>;
 
 TEST_P(SpvBinaryDerivativeTest, Derivatives) {
     auto& builtin = std::get<0>(GetParam());
@@ -968,4 +969,4 @@
 // TODO(dneto): OpSMulExtended
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_bit_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_bit_test.cc
similarity index 96%
rename from src/tint/lang/spirv/reader/function_bit_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_bit_test.cc
index fe09251..9792733 100644
--- a/src/tint/lang/spirv/reader/function_bit_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_bit_test.cc
@@ -12,12 +12,12 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::HasSubstr;
@@ -92,7 +92,7 @@
     return "bad case";
 }
 
-using SpvUnaryBitTest = SpvParserTestBase<::testing::Test>;
+using SpvUnaryBitTest = SpirvASTParserTestBase<::testing::Test>;
 
 struct BinaryData {
     const std::string res_type;
@@ -111,8 +111,8 @@
     return out;
 }
 
-using SpvBinaryBitTest = SpvParserTestBase<::testing::TestWithParam<BinaryData>>;
-using SpvBinaryBitTestBasic = SpvParserTestBase<::testing::Test>;
+using SpvBinaryBitTest = SpirvASTParserTestBase<::testing::TestWithParam<BinaryData>>;
+using SpvBinaryBitTestBasic = SpirvASTParserTestBase<::testing::Test>;
 
 TEST_P(SpvBinaryBitTest, EmitExpression) {
     const auto assembly = SimplePreamble() + R"(
@@ -150,7 +150,7 @@
     return out;
 }
 
-using SpvBinaryBitGeneralTest = SpvParserTestBase<::testing::TestWithParam<BinaryDataGeneral>>;
+using SpvBinaryBitGeneralTest = SpirvASTParserTestBase<::testing::TestWithParam<BinaryDataGeneral>>;
 
 TEST_P(SpvBinaryBitGeneralTest, EmitExpression) {
     const auto assembly = SimplePreamble() + R"(
@@ -174,7 +174,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ShiftLeftLogical_Arg2Unsigned,
+    SpirvASTParserTest_ShiftLeftLogical_Arg2Unsigned,
     SpvBinaryBitTest,
     ::testing::Values(
         // uint uint -> uint
@@ -190,7 +190,7 @@
 
 INSTANTIATE_TEST_SUITE_P(
     // WGSL requires second operand to be unsigned, so insert bitcasts
-    SpvParserTest_ShiftLeftLogical_Arg2Signed,
+    SpirvASTParserTest_ShiftLeftLogical_Arg2Signed,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // int, int -> int
@@ -206,7 +206,7 @@
         BinaryDataGeneral{"v2int", "v2int_30_40", "OpShiftLeftLogical", "v2int_40_30", "vec2i",
                           "(vec2i(30i, 40i) << bitcast<vec2u>(vec2i(40i, 30i)))"}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_ShiftLeftLogical_BitcastResult,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_ShiftLeftLogical_BitcastResult,
                          SpvBinaryBitGeneralTest,
                          ::testing::Values(
                              // int, int -> uint
@@ -218,7 +218,7 @@
                                  "vec2u", "bitcast<vec2u>((vec2i(30i, 40i) << vec2u(20u, 10u)))"}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ShiftRightLogical_Arg2Unsigned,
+    SpirvASTParserTest_ShiftRightLogical_Arg2Unsigned,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // uint, uint -> uint
@@ -236,7 +236,7 @@
             R"(bitcast<vec2i>((bitcast<vec2u>(vec2i(30i, 40i)) >> vec2u(10u, 20u))))"}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ShiftRightLogical_Arg2Signed,
+    SpirvASTParserTest_ShiftRightLogical_Arg2Signed,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // uint, int -> uint
@@ -254,7 +254,7 @@
             R"(bitcast<vec2i>((bitcast<vec2u>(vec2i(40i, 30i)) >> bitcast<vec2u>(vec2i(30i, 40i)))))"}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ShiftRightLogical_BitcastResult,
+    SpirvASTParserTest_ShiftRightLogical_BitcastResult,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // uint, uint -> int
@@ -265,7 +265,7 @@
                           R"(bitcast<vec2i>((vec2u(10u, 20u) >> vec2u(20u, 10u))))"}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ShiftRightArithmetic_Arg2Unsigned,
+    SpirvASTParserTest_ShiftRightArithmetic_Arg2Unsigned,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // uint, uint -> uint
@@ -283,7 +283,7 @@
                           "(vec2i(40i, 30i) >> vec2u(20u, 10u))"}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ShiftRightArithmetic_Arg2Signed,
+    SpirvASTParserTest_ShiftRightArithmetic_Arg2Signed,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // uint, int -> uint
@@ -300,7 +300,7 @@
         BinaryDataGeneral{"v2int", "v2int_40_30", "OpShiftRightArithmetic", "v2int_30_40", "vec2i",
                           "(vec2i(40i, 30i) >> bitcast<vec2u>(vec2i(30i, 40i)))"}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_ShiftRightArithmetic_BitcastResult,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_ShiftRightArithmetic_BitcastResult,
                          SpvBinaryBitGeneralTest,
                          ::testing::Values(
                              // int, uint -> uint
@@ -312,7 +312,7 @@
                                  "vec2u", "bitcast<vec2u>((vec2i(30i, 40i) >> vec2u(20u, 10u)))"}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_BitwiseAnd,
+    SpirvASTParserTest_BitwiseAnd,
     SpvBinaryBitTest,
     ::testing::Values(
         // Both uint
@@ -328,7 +328,7 @@
                    AstFor("v2int_30_40"), "&", AstFor("v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_BitwiseAnd_MixedSignedness,
+    SpirvASTParserTest_BitwiseAnd_MixedSignedness,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // Mixed, uint <- int uint
@@ -352,7 +352,7 @@
             R"(bitcast<vec2i>((vec2u(10u, 20u) & bitcast<vec2u>(vec2i(40i, 30i)))))"}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_BitwiseOr,
+    SpirvASTParserTest_BitwiseOr,
     SpvBinaryBitTest,
     ::testing::Values(
         // Both uint
@@ -368,7 +368,7 @@
                    AstFor("v2int_30_40"), "|", AstFor("v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_BitwiseOr_MixedSignedness,
+    SpirvASTParserTest_BitwiseOr_MixedSignedness,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // Mixed, uint <- int uint
@@ -392,7 +392,7 @@
             R"(bitcast<vec2i>((vec2u(10u, 20u) | bitcast<vec2u>(vec2i(40i, 30i)))))"}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_BitwiseXor,
+    SpirvASTParserTest_BitwiseXor,
     SpvBinaryBitTest,
     ::testing::Values(
         // Both uint
@@ -408,7 +408,7 @@
                    AstFor("v2int_30_40"), "^", AstFor("v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_BitwiseXor_MixedSignedness,
+    SpirvASTParserTest_BitwiseXor_MixedSignedness,
     SpvBinaryBitGeneralTest,
     ::testing::Values(
         // Mixed, uint <- int uint
@@ -1067,4 +1067,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_call_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_call_test.cc
similarity index 92%
rename from src/tint/lang/spirv/reader/function_call_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_call_test.cc
index 0aa6366..10fa31e 100644
--- a/src/tint/lang/spirv/reader/function_call_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_call_test.cc
@@ -13,11 +13,11 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -68,7 +68,7 @@
   )";
 }
 
-TEST_F(SpvParserTest, EmitStatement_VoidCallNoParams) {
+TEST_F(SpirvASTParserTest, EmitStatement_VoidCallNoParams) {
     auto p = parser(test::Assemble(Preamble() + R"(
      %void = OpTypeVoid
      %voidfn = OpTypeFunction %void
@@ -103,7 +103,7 @@
     EXPECT_EQ(expect, got);
 }
 
-TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParams) {
+TEST_F(SpirvASTParserTest, EmitStatement_ScalarCallNoParams) {
     auto p = parser(test::Assemble(Preamble() + R"(
      %void = OpTypeVoid
      %voidfn = OpTypeFunction %void
@@ -140,7 +140,7 @@
     EXPECT_THAT(test::ToString(program, f50), HasSubstr("return 42u;"));
 }
 
-TEST_F(SpvParserTest, EmitStatement_ScalarCallNoParamsUsedTwice) {
+TEST_F(SpirvASTParserTest, EmitStatement_ScalarCallNoParamsUsedTwice) {
     auto p = parser(test::Assemble(Preamble() + R"(
      %void = OpTypeVoid
      %voidfn = OpTypeFunction %void
@@ -186,7 +186,7 @@
     EXPECT_THAT(test::ToString(program, f50), HasSubstr("return 42u;"));
 }
 
-TEST_F(SpvParserTest, EmitStatement_CallWithParams) {
+TEST_F(SpirvASTParserTest, EmitStatement_CallWithParams) {
     auto p = parser(test::Assemble(Preamble() + R"(
      %void = OpTypeVoid
      %voidfn = OpTypeFunction %void
@@ -266,7 +266,7 @@
      )";
 }
 
-TEST_F(SpvParserTest, Emit_FunctionCall_HandlePtrParams_Direct) {
+TEST_F(SpirvASTParserTest, Emit_FunctionCall_HandlePtrParams_Direct) {
     auto assembly = Preamble() + CommonHandleTypes() + HelperFunctionPtrHandle() + R"(
 
      %100 = OpFunction %void None %voidfn
@@ -288,7 +288,7 @@
     EXPECT_EQ(got, expect);
 }
 
-TEST_F(SpvParserTest, Emit_FunctionCall_HandlePtrParams_CopyObject) {
+TEST_F(SpirvASTParserTest, Emit_FunctionCall_HandlePtrParams_CopyObject) {
     auto assembly = Preamble() + CommonHandleTypes() + HelperFunctionPtrHandle() + R"(
 
      %100 = OpFunction %void None %voidfn
@@ -313,7 +313,7 @@
     EXPECT_EQ(got, expect);
 }
 
-TEST_F(SpvParserTest, Emit_FunctionCall_HandleParams_Load) {
+TEST_F(SpirvASTParserTest, Emit_FunctionCall_HandleParams_Load) {
     auto assembly = Preamble() + CommonHandleTypes() + HelperFunctionHandle() + R"(
 
      %100 = OpFunction %void None %voidfn
@@ -337,7 +337,7 @@
     EXPECT_EQ(got, expect);
 }
 
-TEST_F(SpvParserTest, Emit_FunctionCall_HandleParams_LoadsAndCopyObject) {
+TEST_F(SpirvASTParserTest, Emit_FunctionCall_HandleParams_LoadsAndCopyObject) {
     auto assembly = Preamble() + CommonHandleTypes() + HelperFunctionHandle() + R"(
 
      %100 = OpFunction %void None %voidfn
@@ -367,4 +367,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_cfg_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_cfg_test.cc
similarity index 99%
rename from src/tint/lang/spirv/reader/function_cfg_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_cfg_test.cc
index 814927c..073629a 100644
--- a/src/tint/lang/spirv/reader/function_cfg_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_cfg_test.cc
@@ -13,19 +13,19 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
 using ::testing::HasSubstr;
 
 // Make a local name so it's easier to triage errors.
-using SpvParserCFGTest = SpvParserTest;
+using SpvParserCFGTest = SpirvASTParserTest;
 
 std::string Dump(const std::vector<uint32_t>& v) {
     utils::StringStream o;
@@ -12087,4 +12087,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_composite_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_composite_test.cc
similarity index 90%
rename from src/tint/lang/spirv/reader/function_composite_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_composite_test.cc
index 93a0e7f..ae11225 100644
--- a/src/tint/lang/spirv/reader/function_composite_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_composite_test.cc
@@ -13,11 +13,11 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -78,9 +78,9 @@
     return Caps() + CommonTypes();
 }
 
-using SpvParserTest_Composite_Construct = SpvParserTest;
+using SpirvASTParserTest_Composite_Construct = SpirvASTParserTest;
 
-TEST_F(SpvParserTest_Composite_Construct, Vector) {
+TEST_F(SpirvASTParserTest_Composite_Construct, Vector) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -101,7 +101,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest_Composite_Construct, VectorSplat) {
+TEST_F(SpirvASTParserTest_Composite_Construct, VectorSplat) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -122,7 +122,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest_Composite_Construct, Matrix) {
+TEST_F(SpirvASTParserTest_Composite_Construct, Matrix) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -141,7 +141,7 @@
                                                                   "vec2f(70.0f));"));
 }
 
-TEST_F(SpvParserTest_Composite_Construct, Array) {
+TEST_F(SpirvASTParserTest_Composite_Construct, Array) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -158,7 +158,7 @@
                 HasSubstr("let x_1 = array<u32, 5u>(10u, 20u, 3u, 4u, 5u);"));
 }
 
-TEST_F(SpvParserTest_Composite_Construct, Struct) {
+TEST_F(SpirvASTParserTest_Composite_Construct, Struct) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -175,7 +175,7 @@
                 HasSubstr("let x_1 = S(vec2f(50.0f, 60.0f), 5u, 30i);"));
 }
 
-TEST_F(SpvParserTest_Composite_Construct, ConstantComposite_Struct_NoDeduplication) {
+TEST_F(SpirvASTParserTest_Composite_Construct, ConstantComposite_Struct_NoDeduplication) {
     const auto assembly = Preamble() + R"(
      %200 = OpTypeStruct %uint
      %300 = OpTypeStruct %uint ; isomorphic structures
@@ -204,9 +204,9 @@
     EXPECT_EQ(got, expected) << got;
 }
 
-using SpvParserTest_CompositeExtract = SpvParserTest;
+using SpirvASTParserTest_CompositeExtract = SpirvASTParserTest;
 
-TEST_F(SpvParserTest_CompositeExtract, Vector) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Vector) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -223,7 +223,7 @@
                 HasSubstr("let x_1 = vec2f(50.0f, 60.0f).y;"));
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Vector_IndexTooBigError) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Vector_IndexTooBigError) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -240,7 +240,7 @@
               "of 2 elements");
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Matrix) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Matrix) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %m3v2float
 
@@ -260,7 +260,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_2 = x_1[2u];"));
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Matrix_IndexTooBigError) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Matrix_IndexTooBigError) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %m3v2float
 
@@ -281,7 +281,7 @@
               "of 3 elements");
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Matrix_Vector) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Matrix_Vector) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %m3v2float
 
@@ -301,7 +301,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_2 = x_1[2u].y;"));
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Array) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Array) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %a_u_5
 
@@ -321,7 +321,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_2 = x_1[3u];"));
 }
 
-TEST_F(SpvParserTest_CompositeExtract, RuntimeArray_IsError) {
+TEST_F(SpirvASTParserTest_CompositeExtract, RuntimeArray_IsError) {
     const auto assembly = Preamble() + R"(
      %rtarr = OpTypeRuntimeArray %uint
      %ptr = OpTypePointer Function %rtarr
@@ -341,7 +341,7 @@
     EXPECT_THAT(p->error(), HasSubstr("can't do OpCompositeExtract on a runtime array: "));
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Struct) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Struct) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %s_v2f_u_i
 
@@ -361,7 +361,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_2 = x_1.field2;"));
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Struct_DifferOnlyInMemberName) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Struct_DifferOnlyInMemberName) {
     const std::string assembly = R"(
      OpCapability Shader
      OpMemoryModel Logical Simple
@@ -405,7 +405,7 @@
     p->SkipDumpingPending("crbug.com/tint/863");
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Struct_IndexTooBigError) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Struct_IndexTooBigError) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %s_v2f_u_i
 
@@ -426,7 +426,7 @@
               "structure %27 having 3 members");
 }
 
-TEST_F(SpvParserTest_CompositeExtract, Struct_Array_Matrix_Vector) {
+TEST_F(SpirvASTParserTest_CompositeExtract, Struct_Array_Matrix_Vector) {
     const auto assembly = Preamble() + R"(
      %a_mat = OpTypeArray %m3v2float %uint_3
      %s = OpTypeStruct %uint %a_mat
@@ -449,9 +449,9 @@
                 HasSubstr("let x_2 = x_1.field1[2u][0u].y;"));
 }
 
-using SpvParserTest_CompositeInsert = SpvParserTest;
+using SpirvASTParserTest_CompositeInsert = SpirvASTParserTest;
 
-TEST_F(SpvParserTest_CompositeInsert, Vector) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Vector) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -474,7 +474,7 @@
     EXPECT_EQ(got, expected);
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Vector_IndexTooBigError) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Vector_IndexTooBigError) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -491,7 +491,7 @@
               "of 2 elements");
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Matrix) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Matrix) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %m3v2float
 
@@ -515,7 +515,7 @@
 )")) << body_str;
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Matrix_IndexTooBigError) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Matrix_IndexTooBigError) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %m3v2float
 
@@ -536,7 +536,7 @@
               "3 elements");
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Matrix_Vector) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Matrix_Vector) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %m3v2float
 
@@ -561,7 +561,7 @@
 )")) << body_str;
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Array) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Array) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %a_u_5
 
@@ -585,7 +585,7 @@
 )")) << body_str;
 }
 
-TEST_F(SpvParserTest_CompositeInsert, RuntimeArray_IsError) {
+TEST_F(SpirvASTParserTest_CompositeInsert, RuntimeArray_IsError) {
     const auto assembly = Preamble() + R"(
      %rtarr = OpTypeRuntimeArray %uint
      %ptr = OpTypePointer Function %rtarr
@@ -605,7 +605,7 @@
     EXPECT_THAT(p->error(), HasSubstr("can't do OpCompositeInsert on a runtime array: "));
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Struct) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Struct) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %s_v2f_u_i
 
@@ -631,7 +631,7 @@
 )")) << body_str;
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Struct_DifferOnlyInMemberName) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Struct_DifferOnlyInMemberName) {
     const std::string assembly = R"(
      OpCapability Shader
      OpMemoryModel Logical Simple
@@ -687,7 +687,7 @@
     EXPECT_EQ(got, expected) << got;
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Struct_IndexTooBigError) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Struct_IndexTooBigError) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %s_v2f_u_i
 
@@ -708,7 +708,7 @@
               "structure %27 having 3 members");
 }
 
-TEST_F(SpvParserTest_CompositeInsert, Struct_Array_Matrix_Vector) {
+TEST_F(SpirvASTParserTest_CompositeInsert, Struct_Array_Matrix_Vector) {
     const auto assembly = Preamble() + R"(
      %a_mat = OpTypeArray %m3v2float %uint_3
      %s = OpTypeStruct %uint %a_mat
@@ -736,9 +736,9 @@
 )")) << body_str;
 }
 
-using SpvParserTest_CopyObject = SpvParserTest;
+using SpirvASTParserTest_CopyObject = SpirvASTParserTest;
 
-TEST_F(SpvParserTest_CopyObject, Scalar) {
+TEST_F(SpirvASTParserTest_CopyObject, Scalar) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -757,7 +757,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest_CopyObject, Pointer) {
+TEST_F(SpirvASTParserTest_CopyObject, Pointer) {
     const auto assembly = Preamble() + R"(
      %ptr = OpTypePointer Function %uint
 
@@ -780,9 +780,9 @@
 )"));
 }
 
-using SpvParserTest_VectorShuffle = SpvParserTest;
+using SpirvASTParserTest_VectorShuffle = SpirvASTParserTest;
 
-TEST_F(SpvParserTest_VectorShuffle, FunctionScopeOperands_UseBoth) {
+TEST_F(SpirvASTParserTest_VectorShuffle, FunctionScopeOperands_UseBoth) {
     // Note that variables are generated for the vector operands.
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
@@ -803,7 +803,7 @@
                 HasSubstr("let x_10 = vec4u(x_2.yx, x_1.yx);"));
 }
 
-TEST_F(SpvParserTest_VectorShuffle, FunctionScopeOperands_UseBoth_Swizzle) {
+TEST_F(SpirvASTParserTest_VectorShuffle, FunctionScopeOperands_UseBoth_Swizzle) {
     // Use the same vector for both source operands.
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
@@ -822,7 +822,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_10 = x_1.yxxy;"));
 }
 
-TEST_F(SpvParserTest_VectorShuffle, FunctionScopeOperands_UseOne_Swizzle) {
+TEST_F(SpirvASTParserTest_VectorShuffle, FunctionScopeOperands_UseOne_Swizzle) {
     // Only use the first vector operand.
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
@@ -842,7 +842,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_10 = x_1.yxxy;"));
 }
 
-TEST_F(SpvParserTest_VectorShuffle, ConstantOperands_UseBoth) {
+TEST_F(SpirvASTParserTest_VectorShuffle, ConstantOperands_UseBoth) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -860,7 +860,7 @@
                 HasSubstr("let x_10 = vec4u(vec2u(4u, 3u).yx, vec2u(3u, 4u).yx);"));
 }
 
-TEST_F(SpvParserTest_VectorShuffle, ConstantOperands_AllOnesMapToNull) {
+TEST_F(SpirvASTParserTest_VectorShuffle, ConstantOperands_AllOnesMapToNull) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -878,7 +878,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_10 = x_1.xy;"));
 }
 
-TEST_F(SpvParserTest_VectorShuffle, FunctionScopeOperands_MixedInputOperandSizes) {
+TEST_F(SpirvASTParserTest_VectorShuffle, FunctionScopeOperands_MixedInputOperandSizes) {
     // Note that variables are generated for the vector operands.
     const auto assembly = Preamble() + R"(
      %v3uint_3_4_5 = OpConstantComposite %v3uint %uint_3 %uint_4 %uint_5
@@ -900,7 +900,7 @@
                 HasSubstr("let x_10 = vec2u(x_1.y, x_3.z);"));
 }
 
-TEST_F(SpvParserTest_VectorShuffle, IndexTooBig_IsError) {
+TEST_F(SpirvASTParserTest_VectorShuffle, IndexTooBig_IsError) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -916,9 +916,9 @@
     EXPECT_THAT(p->error(), Eq("invalid vectorshuffle ID %10: index too large: 9"));
 }
 
-using SpvParserTest_VectorExtractDynamic = SpvParserTest;
+using SpirvASTParserTest_VectorExtractDynamic = SpirvASTParserTest;
 
-TEST_F(SpvParserTest_VectorExtractDynamic, SignedIndex) {
+TEST_F(SpirvASTParserTest_VectorExtractDynamic, SignedIndex) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -938,7 +938,7 @@
     EXPECT_THAT(got, HasSubstr("let x_10 = x_1[x_2];")) << got;
 }
 
-TEST_F(SpvParserTest_VectorExtractDynamic, UnsignedIndex) {
+TEST_F(SpirvASTParserTest_VectorExtractDynamic, UnsignedIndex) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -958,9 +958,9 @@
     EXPECT_THAT(got, HasSubstr("let x_10 = x_1[x_2];")) << got;
 }
 
-using SpvParserTest_VectorInsertDynamic = SpvParserTest;
+using SpirvASTParserTest_VectorInsertDynamic = SpirvASTParserTest;
 
-TEST_F(SpvParserTest_VectorInsertDynamic, Sample) {
+TEST_F(SpirvASTParserTest_VectorInsertDynamic, Sample) {
     const auto assembly = Preamble() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -985,7 +985,7 @@
      << assembly;
 }
 
-TEST_F(SpvParserTest, DISABLED_WorkgroupSize_Overridable) {
+TEST_F(SpirvASTParserTest, DISABLED_WorkgroupSize_Overridable) {
     // TODO(dneto): Support specializable workgroup size. crbug.com/tint/504
     const auto* assembly = R"(
   OpCapability Shader
@@ -1105,4 +1105,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_conversion_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_conversion_test.cc
similarity index 98%
rename from src/tint/lang/spirv/reader/function_conversion_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_conversion_test.cc
index 700449e..bbe0dc6 100644
--- a/src/tint/lang/spirv/reader/function_conversion_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_conversion_test.cc
@@ -13,11 +13,11 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -67,7 +67,7 @@
 )";
 }
 
-using SpvUnaryConversionTest = SpvParserTestBase<::testing::Test>;
+using SpvUnaryConversionTest = SpirvASTParserTestBase<::testing::Test>;
 
 TEST_F(SpvUnaryConversionTest, Bitcast_Scalar) {
     const auto assembly = Preamble() + R"(
@@ -615,4 +615,4 @@
 // TODO(dneto): OpSatConvertUToS // Kernel (OpenCL), not in WebGPU
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_decl_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_decl_test.cc
similarity index 90%
rename from src/tint/lang/spirv/reader/function_decl_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_decl_test.cc
index 6e7c5a4..ea17cb3 100644
--- a/src/tint/lang/spirv/reader/function_decl_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_decl_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::HasSubstr;
@@ -75,7 +75,7 @@
   )";
 }
 
-TEST_F(SpvParserTest, Emit_VoidFunctionWithoutParams) {
+TEST_F(SpirvASTParserTest, Emit_VoidFunctionWithoutParams) {
     auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -93,7 +93,7 @@
     EXPECT_EQ(got, expect);
 }
 
-TEST_F(SpvParserTest, Emit_NonVoidResultType) {
+TEST_F(SpirvASTParserTest, Emit_NonVoidResultType) {
     auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
      %fn_ret_float = OpTypeFunction %float
      %200 = OpFunction %float None %fn_ret_float
@@ -113,7 +113,7 @@
     EXPECT_THAT(got, HasSubstr(expect));
 }
 
-TEST_F(SpvParserTest, Emit_MixedParamTypes) {
+TEST_F(SpirvASTParserTest, Emit_MixedParamTypes) {
     auto p = parser(test::Assemble(Preamble() + Names({"a", "b", "c"}) + CommonTypes() + R"(
      %fn_mixed_params = OpTypeFunction %void %uint %float %int
 
@@ -137,7 +137,7 @@
     EXPECT_THAT(got, HasSubstr(expect));
 }
 
-TEST_F(SpvParserTest, Emit_GenerateParamNames) {
+TEST_F(SpirvASTParserTest, Emit_GenerateParamNames) {
     auto p = parser(test::Assemble(Preamble() + CommonTypes() + R"(
      %fn_mixed_params = OpTypeFunction %void %uint %float %int
 
@@ -161,7 +161,7 @@
     EXPECT_THAT(got, HasSubstr(expect));
 }
 
-TEST_F(SpvParserTest, Emit_FunctionDecl_ParamPtrTexture_ParamPtrSampler) {
+TEST_F(SpirvASTParserTest, Emit_FunctionDecl_ParamPtrTexture_ParamPtrSampler) {
     auto p = parser(test::Assemble(Preamble() + CommonHandleTypes() + R"(
 
      ; This is how Glslang generates functions that take texture and sampler arguments.
@@ -193,7 +193,7 @@
     EXPECT_EQ(got, expect);
 }
 
-TEST_F(SpvParserTest, Emit_FunctionDecl_ParamTexture_ParamSampler) {
+TEST_F(SpirvASTParserTest, Emit_FunctionDecl_ParamTexture_ParamSampler) {
     auto assembly = Preamble() + CommonHandleTypes() + R"(
 
      ; It is valid in SPIR-V to pass textures and samplers by value.
@@ -224,4 +224,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_glsl_std_450_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc
similarity index 88%
rename from src/tint/lang/spirv/reader/function_glsl_std_450_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc
index aa1dc67..8f571e2 100644
--- a/src/tint/lang/spirv/reader/function_glsl_std_450_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc
@@ -13,11 +13,11 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::HasSubstr;
@@ -158,37 +158,37 @@
 // Uint = scalar unsigned int
 // Uinting = scalar unsigned or vector-of-unsigned
 
-using SpvParserTest_GlslStd450_Float_Floating =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Float_FloatingFloating =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Floating_Floating =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Floating_FloatingFloating =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Floating_FloatingInting =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Float3_Float3Float3 =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Float_Floating =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Float_FloatingFloating =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Floating_Floating =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Floating_FloatingFloating =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Floating_FloatingFloatingFloating =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Floating_FloatingInting =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Float3_Float3Float3 =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
 
-using SpvParserTest_GlslStd450_Inting_Inting =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Inting_Inting_SignednessCoercing =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Inting_IntingInting =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Inting_IntingIntingInting =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Uinting_Uinting =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Uinting_UintingUinting =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
-using SpvParserTest_GlslStd450_Uinting_UintingUintingUinting =
-    SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Inting_Inting =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Inting_Inting_SignednessCoercing =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Inting_IntingInting =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Inting_IntingIntingInting =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Uinting_Uinting =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Uinting_UintingUinting =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
+using SpirvASTParserTest_GlslStd450_Uinting_UintingUintingUinting =
+    SpirvASTParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
 
-TEST_P(SpvParserTest_GlslStd450_Float_Floating, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Float_Floating, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl )" +
                           GetParam().opcode + R"( %f1
@@ -204,7 +204,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(f1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Float_Floating, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Float_Floating, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl )" +
                           GetParam().opcode + R"( %v2f1
@@ -220,7 +220,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2f1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Float_FloatingFloating, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Float_FloatingFloating, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl )" +
                           GetParam().opcode + R"( %f1 %f2
@@ -236,7 +236,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(f1, f2);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Float_FloatingFloating, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Float_FloatingFloating, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl )" +
                           GetParam().opcode + R"( %v2f1 %v2f2
@@ -252,7 +252,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2f1, v2f2);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Floating_Floating, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Floating_Floating, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl )" +
                           GetParam().opcode + R"( %f1
@@ -268,7 +268,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(f1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Floating_Floating, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Floating_Floating, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2float %glsl )" +
                           GetParam().opcode + R"( %v2f1
@@ -284,7 +284,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2f1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloating, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Floating_FloatingFloating, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl )" +
                           GetParam().opcode + R"( %f1 %f2
@@ -300,7 +300,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(f1, f2);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloating, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Floating_FloatingFloating, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2float %glsl )" +
                           GetParam().opcode + R"( %v2f1 %v2f2
@@ -316,7 +316,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2f1, v2f2);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Floating_FloatingFloatingFloating, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl )" +
                           GetParam().opcode + R"( %f1 %f2 %f3
@@ -332,7 +332,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(f1, f2, f3);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Floating_FloatingFloatingFloating, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2float %glsl )" +
                           GetParam().opcode +
@@ -350,7 +350,7 @@
         << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Floating_FloatingInting, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl )" +
                           GetParam().opcode + R"( %f1 %i1
@@ -366,7 +366,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(f1, i1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Floating_FloatingInting, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2float %glsl )" +
                           GetParam().opcode +
@@ -383,7 +383,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2f1, v2i1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Float3_Float3Float3, Samples) {
+TEST_P(SpirvASTParserTest_GlslStd450_Float3_Float3Float3, Samples) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v3float %glsl )" +
                           GetParam().opcode +
@@ -401,15 +401,15 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Float_Floating,
+                         SpirvASTParserTest_GlslStd450_Float_Floating,
                          ::testing::Values(GlslStd450Case{"Length", "length"}));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Float_FloatingFloating,
+                         SpirvASTParserTest_GlslStd450_Float_FloatingFloating,
                          ::testing::Values(GlslStd450Case{"Distance", "distance"}));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Floating_Floating,
+                         SpirvASTParserTest_GlslStd450_Floating_Floating,
                          ::testing::ValuesIn(std::vector<GlslStd450Case>{
                              {"Acos", "acos"},                //
                              {"Asin", "asin"},                //
@@ -439,7 +439,7 @@
                          }));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Floating_FloatingFloating,
+                         SpirvASTParserTest_GlslStd450_Floating_FloatingFloating,
                          ::testing::ValuesIn(std::vector<GlslStd450Case>{
                              {"Atan2", "atan2"},
                              {"NMax", "max"},
@@ -451,16 +451,16 @@
                          }));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Floating_FloatingInting,
+                         SpirvASTParserTest_GlslStd450_Floating_FloatingInting,
                          ::testing::Values(GlslStd450Case{"Ldexp", "ldexp"}));
 // For ldexp with unsigned second argument, see below.
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Float3_Float3Float3,
+                         SpirvASTParserTest_GlslStd450_Float3_Float3Float3,
                          ::testing::Values(GlslStd450Case{"Cross", "cross"}));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating,
+                         SpirvASTParserTest_GlslStd450_Floating_FloatingFloatingFloating,
                          ::testing::ValuesIn(std::vector<GlslStd450Case>{
                              {"NClamp", "clamp"},
                              {"FClamp", "clamp"},  // WGSL FClamp promises more for NaN
@@ -468,7 +468,7 @@
                              {"FMix", "mix"},
                              {"SmoothStep", "smoothstep"}}));
 
-TEST_P(SpvParserTest_GlslStd450_Inting_Inting, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_Inting, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %int %glsl )" +
                           GetParam().opcode +
@@ -485,7 +485,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(i1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_Inting_SignednessCoercing, Scalar_UnsignedArg) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_Inting_SignednessCoercing, Scalar_UnsignedArg) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %int %glsl )" +
                           GetParam().opcode +
@@ -503,7 +503,7 @@
         << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_Inting_SignednessCoercing, Scalar_UnsignedResult) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_Inting_SignednessCoercing, Scalar_UnsignedResult) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %uint %glsl )" +
                           GetParam().opcode +
@@ -521,7 +521,7 @@
         << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_Inting, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_Inting, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2int %glsl )" +
                           GetParam().opcode +
@@ -538,7 +538,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2i1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_Inting_SignednessCoercing, Vector_UnsignedArg) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_Inting_SignednessCoercing, Vector_UnsignedArg) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2int %glsl )" +
                           GetParam().opcode +
@@ -556,7 +556,7 @@
         << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_Inting_SignednessCoercing, Vector_UnsignedResult) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_Inting_SignednessCoercing, Vector_UnsignedResult) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2uint %glsl )" +
                           GetParam().opcode +
@@ -574,7 +574,7 @@
         << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_IntingInting, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %int %glsl )" +
                           GetParam().opcode +
@@ -591,7 +591,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(i1, i2);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_IntingInting, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_IntingInting, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2int %glsl )" +
                           GetParam().opcode +
@@ -608,7 +608,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2i1, v2i2);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_IntingIntingInting, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %int %glsl )" +
                           GetParam().opcode +
@@ -625,7 +625,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(i1, i2, i3);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Inting_IntingIntingInting, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Inting_IntingIntingInting, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2int %glsl )" +
                           GetParam().opcode +
@@ -644,26 +644,26 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Inting_Inting,
+                         SpirvASTParserTest_GlslStd450_Inting_Inting,
                          ::testing::Values(GlslStd450Case{"SAbs", "abs"},
                                            GlslStd450Case{"FindILsb", "firstTrailingBit"},
                                            GlslStd450Case{"FindSMsb", "firstLeadingBit"},
                                            GlslStd450Case{"SSign", "sign"}));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Inting_Inting_SignednessCoercing,
+                         SpirvASTParserTest_GlslStd450_Inting_Inting_SignednessCoercing,
                          ::testing::Values(GlslStd450Case{"SSign", "sign"}));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Inting_IntingInting,
+                         SpirvASTParserTest_GlslStd450_Inting_IntingInting,
                          ::testing::Values(GlslStd450Case{"SMax", "max"},
                                            GlslStd450Case{"SMin", "min"}));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Inting_IntingIntingInting,
+                         SpirvASTParserTest_GlslStd450_Inting_IntingIntingInting,
                          ::testing::Values(GlslStd450Case{"SClamp", "clamp"}));
 
-TEST_P(SpvParserTest_GlslStd450_Uinting_Uinting, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Uinting_Uinting, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %uint %glsl )" +
                           GetParam().opcode +
@@ -680,7 +680,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(u1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Uinting_Uinting, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Uinting_Uinting, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2uint %glsl )" +
                           GetParam().opcode +
@@ -697,7 +697,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2u1);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Uinting_UintingUinting, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %uint %glsl )" +
                           GetParam().opcode + R"( %u1 %u2
@@ -713,7 +713,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(u1, u2);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUinting, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Uinting_UintingUinting, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2uint %glsl )" +
                           GetParam().opcode +
@@ -730,7 +730,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(v2u1, v2u2);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Scalar) {
+TEST_P(SpirvASTParserTest_GlslStd450_Uinting_UintingUintingUinting, Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %uint %glsl )" +
                           GetParam().opcode + R"( %u1 %u2 %u3
@@ -746,7 +746,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = " + GetParam().wgsl_func + "(u1, u2, u3);")) << body;
 }
 
-TEST_P(SpvParserTest_GlslStd450_Uinting_UintingUintingUinting, Vector) {
+TEST_P(SpirvASTParserTest_GlslStd450_Uinting_UintingUintingUinting, Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2uint %glsl )" +
                           GetParam().opcode +
@@ -765,24 +765,24 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Uinting_Uinting,
+                         SpirvASTParserTest_GlslStd450_Uinting_Uinting,
                          ::testing::Values(GlslStd450Case{"FindILsb", "firstTrailingBit"},
                                            GlslStd450Case{"FindUMsb", "firstLeadingBit"}));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Uinting_UintingUinting,
+                         SpirvASTParserTest_GlslStd450_Uinting_UintingUinting,
                          ::testing::Values(GlslStd450Case{"UMax", "max"},
                                            GlslStd450Case{"UMin", "min"}));
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_Uinting_UintingUintingUinting,
+                         SpirvASTParserTest_GlslStd450_Uinting_UintingUintingUinting,
                          ::testing::Values(GlslStd450Case{"UClamp", "clamp"}));
 
 // Test Normalize.  WGSL does not have a scalar form of the normalize builtin.
 // So we have to test it separately, as it does not fit the patterns tested
 // above.
 
-TEST_F(SpvParserTest, Normalize_Scalar) {
+TEST_F(SpirvASTParserTest, Normalize_Scalar) {
     // Scalar normalize always results in 1.0
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl Normalize %f1
@@ -798,7 +798,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = 1.0f;")) << body;
 }
 
-TEST_F(SpvParserTest, Normalize_Vector2) {
+TEST_F(SpirvASTParserTest, Normalize_Vector2) {
     // Scalar normalize always results in 1.0
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2float %glsl Normalize %v2f1
@@ -814,7 +814,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = normalize(v2f1);")) << body;
 }
 
-TEST_F(SpvParserTest, Normalize_Vector3) {
+TEST_F(SpirvASTParserTest, Normalize_Vector3) {
     // Scalar normalize always results in 1.0
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v3float %glsl Normalize %v3f1
@@ -830,7 +830,7 @@
     EXPECT_THAT(body, HasSubstr("let x_1 = normalize(v3f1);")) << body;
 }
 
-TEST_F(SpvParserTest, Normalize_Vector4) {
+TEST_F(SpirvASTParserTest, Normalize_Vector4) {
     // Scalar normalize always results in 1.0
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v4float %glsl Normalize %v4f1
@@ -849,7 +849,7 @@
 // Check that we convert signedness of operands and result type.
 // This is needed for each of the integer-based extended instructions.
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_SAbs) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_SAbs) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %uint %glsl SAbs %u1
      %2 = OpExtInst %v2uint %glsl SAbs %v2u1
@@ -866,7 +866,7 @@
     EXPECT_THAT(body, HasSubstr(R"(let x_2 = bitcast<vec2u>(abs(bitcast<vec2i>(v2u1)));)")) << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_SMax) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_SMax) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %uint %glsl SMax %u1 %u2
      %2 = OpExtInst %v2uint %glsl SMax %v2u1 %v2u2
@@ -888,7 +888,7 @@
         << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_SMin) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_SMin) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %uint %glsl SMin %u1 %u2
      %2 = OpExtInst %v2uint %glsl SMin %v2u1 %v2u2
@@ -910,7 +910,7 @@
         << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_SClamp) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_SClamp) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %uint %glsl SClamp %u1 %i2 %u3
      %2 = OpExtInst %v2uint %glsl SClamp %v2u1 %v2i2 %v2u3
@@ -934,7 +934,7 @@
         << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_UMax) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_UMax) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %int %glsl UMax %i1 %i2
      %2 = OpExtInst %v2int %glsl UMax %v2i1 %v2i2
@@ -956,7 +956,7 @@
         << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_UMin) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_UMin) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %int %glsl UMin %i1 %i2
      %2 = OpExtInst %v2int %glsl UMin %v2i1 %v2i2
@@ -978,7 +978,7 @@
         << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_UClamp) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_UClamp) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %int %glsl UClamp %i1 %u2 %i3
      %2 = OpExtInst %v2int %glsl UClamp %v2i1 %v2u2 %v2i3
@@ -1002,7 +1002,7 @@
         << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_FindILsb) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_FindILsb) {
     // Check conversion of:
     //   signed results to unsigned result to match first arg.
     //   unsigned results to signed result to match first arg.
@@ -1030,7 +1030,7 @@
         << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_FindSMsb) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_FindSMsb) {
     // Check signedness conversion of arguments and results.
     //   SPIR-V signed arg -> keep it
     //      signed result -> keep it
@@ -1080,7 +1080,7 @@
 )")) << body;
 }
 
-TEST_F(SpvParserTest, RectifyOperandsAndResult_FindUMsb) {
+TEST_F(SpirvASTParserTest, RectifyOperandsAndResult_FindUMsb) {
     // Check signedness conversion of arguments and results.
     //   SPIR-V signed arg -> cast arg to unsigned
     //      signed result -> cast result to signed
@@ -1141,10 +1141,10 @@
     return out;
 }
 
-using SpvParserTest_GlslStd450_DataPacking =
-    SpvParserTestBase<::testing::TestWithParam<DataPackingCase>>;
+using SpirvASTParserTest_GlslStd450_DataPacking =
+    SpirvASTParserTestBase<::testing::TestWithParam<DataPackingCase>>;
 
-TEST_P(SpvParserTest_GlslStd450_DataPacking, Valid) {
+TEST_P(SpirvASTParserTest_GlslStd450_DataPacking, Valid) {
     auto param = GetParam();
     const auto assembly = Preamble() + R"(
   %1 = OpExtInst %uint %glsl )" +
@@ -1164,7 +1164,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_DataPacking,
+                         SpirvASTParserTest_GlslStd450_DataPacking,
                          ::testing::ValuesIn(std::vector<DataPackingCase>{
                              {"PackSnorm4x8", "pack4x8snorm", 4},
                              {"PackUnorm4x8", "pack4x8unorm", 4},
@@ -1172,10 +1172,10 @@
                              {"PackUnorm2x16", "pack2x16unorm", 2},
                              {"PackHalf2x16", "pack2x16float", 2}}));
 
-using SpvParserTest_GlslStd450_DataUnpacking =
-    SpvParserTestBase<::testing::TestWithParam<DataPackingCase>>;
+using SpirvASTParserTest_GlslStd450_DataUnpacking =
+    SpirvASTParserTestBase<::testing::TestWithParam<DataPackingCase>>;
 
-TEST_P(SpvParserTest_GlslStd450_DataUnpacking, Valid) {
+TEST_P(SpirvASTParserTest_GlslStd450_DataUnpacking, Valid) {
     auto param = GetParam();
     const auto assembly = Preamble() + R"(
   %1 = OpExtInst )" + (param.vec_size == 2 ? "%v2float" : "%v4float") +
@@ -1193,7 +1193,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(Samples,
-                         SpvParserTest_GlslStd450_DataUnpacking,
+                         SpirvASTParserTest_GlslStd450_DataUnpacking,
                          ::testing::ValuesIn(std::vector<DataPackingCase>{
                              {"UnpackSnorm4x8", "unpack4x8snorm", 4},
                              {"UnpackUnorm4x8", "unpack4x8unorm", 4},
@@ -1201,7 +1201,7 @@
                              {"UnpackUnorm2x16", "unpack2x16unorm", 2},
                              {"UnpackHalf2x16", "unpack2x16float", 2}}));
 
-TEST_F(SpvParserTest, GlslStd450_Refract_Scalar) {
+TEST_F(SpirvASTParserTest, GlslStd450_Refract_Scalar) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl Refract %f1 %f2 %f3
      OpReturn
@@ -1218,7 +1218,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_Refract_Vector) {
+TEST_F(SpirvASTParserTest, GlslStd450_Refract_Vector) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2float %glsl Refract %v2f1 %v2f2 %f3
      OpReturn
@@ -1235,7 +1235,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_FaceForward_Scalar) {
+TEST_F(SpirvASTParserTest, GlslStd450_FaceForward_Scalar) {
     const auto assembly = Preamble() + R"(
      %99 = OpFAdd %float %f1 %f1 ; normal operand has only one use
      %1 = OpExtInst %float %glsl FaceForward %99 %f2 %f3
@@ -1256,7 +1256,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_FaceForward_Vector) {
+TEST_F(SpirvASTParserTest, GlslStd450_FaceForward_Vector) {
     const auto assembly = Preamble() + R"(
      %99 = OpFAdd %v2float %v2f1 %v2f1
      %1 = OpExtInst %v2float %glsl FaceForward %v2f1 %v2f2 %v2f3
@@ -1274,7 +1274,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_Reflect_Scalar) {
+TEST_F(SpirvASTParserTest, GlslStd450_Reflect_Scalar) {
     const auto assembly = Preamble() + R"(
      %98 = OpFAdd %float %f1 %f1 ; has only one use
      %99 = OpFAdd %float %f2 %f2 ; has only one use
@@ -1296,7 +1296,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_Reflect_Vector) {
+TEST_F(SpirvASTParserTest, GlslStd450_Reflect_Vector) {
     const auto assembly = Preamble() + R"(
      %98 = OpFAdd %v2float %v2f1 %v2f1
      %99 = OpFAdd %v2float %v2f2 %v2f2
@@ -1320,7 +1320,7 @@
 }
 
 // For ldexp with signed second argument, see above.
-TEST_F(SpvParserTest, GlslStd450_Ldexp_Scalar_Float_Uint) {
+TEST_F(SpirvASTParserTest, GlslStd450_Ldexp_Scalar_Float_Uint) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl Ldexp %f1 %u1
      OpReturn
@@ -1337,7 +1337,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_Ldexp_Vector_Floatvec_Uintvec) {
+TEST_F(SpirvASTParserTest, GlslStd450_Ldexp_Vector_Floatvec_Uintvec) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %v2float %glsl Ldexp %v2f1 %v2u1
      OpReturn
@@ -1354,7 +1354,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-using GlslStd450_Determinant = SpvParserTestBase<::testing::TestWithParam<std::string>>;
+using GlslStd450_Determinant = SpirvASTParserTestBase<::testing::TestWithParam<std::string>>;
 TEST_P(GlslStd450_Determinant, Test) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %float %glsl Determinant %)" +
@@ -1376,7 +1376,7 @@
                          GlslStd450_Determinant,
                          ::testing::Values("m2x2f1", "m3x3f1", "m4x4f1"));
 
-TEST_F(SpvParserTest, GlslStd450_MatrixInverse_mat2x2) {
+TEST_F(SpirvASTParserTest, GlslStd450_MatrixInverse_mat2x2) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %mat2v2float %glsl MatrixInverse %m2x2f1
      OpReturn
@@ -1397,7 +1397,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_MatrixInverse_mat3x3) {
+TEST_F(SpirvASTParserTest, GlslStd450_MatrixInverse_mat3x3) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %mat3v3float %glsl MatrixInverse %m3x3f1
      OpReturn
@@ -1426,7 +1426,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_MatrixInverse_mat4x4) {
+TEST_F(SpirvASTParserTest, GlslStd450_MatrixInverse_mat4x4) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %mat4v4float %glsl MatrixInverse %m4x4f1
      OpReturn
@@ -1506,7 +1506,7 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 
-TEST_F(SpvParserTest, GlslStd450_MatrixInverse_MultipleInScope) {
+TEST_F(SpirvASTParserTest, GlslStd450_MatrixInverse_MultipleInScope) {
     const auto assembly = Preamble() + R"(
      %1 = OpExtInst %mat2v2float %glsl MatrixInverse %m2x2f1
      %2 = OpExtInst %mat2v2float %glsl MatrixInverse %m2x2f1
@@ -1531,4 +1531,4 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_logical_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_logical_test.cc
similarity index 96%
rename from src/tint/lang/spirv/reader/function_logical_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_logical_test.cc
index 91ee8f5..b79d803 100644
--- a/src/tint/lang/spirv/reader/function_logical_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_logical_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::HasSubstr;
@@ -121,7 +121,7 @@
     return "bad case";
 }
 
-using SpvUnaryLogicalTest = SpvParserTestBase<::testing::Test>;
+using SpvUnaryLogicalTest = SpirvASTParserTestBase<::testing::Test>;
 
 TEST_F(SpvUnaryLogicalTest, LogicalNot_Scalar) {
     const auto assembly = Preamble() + R"(
@@ -173,7 +173,7 @@
     return out;
 }
 
-using SpvBinaryLogicalTest = SpvParserTestBase<::testing::TestWithParam<BinaryData>>;
+using SpvBinaryLogicalTest = SpirvASTParserTestBase<::testing::TestWithParam<BinaryData>>;
 
 TEST_P(SpvBinaryLogicalTest, EmitExpression) {
     const auto assembly = Preamble() + R"(
@@ -197,7 +197,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_IEqual,
+    SpirvASTParserTest_IEqual,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // uint uint
@@ -217,7 +217,7 @@
         BinaryData{"v2bool", "v2int_30_40", "OpIEqual", "v2int_40_30", "vec2<bool>",
                    AstFor("v2int_30_40"), "==", AstFor("v2int_40_30")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdEqual,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FOrdEqual,
                          SpvBinaryLogicalTest,
                          ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdEqual", "float_60",
                                                       "bool", "50.0f", "==", "60.0f"},
@@ -227,7 +227,7 @@
                                                       "==", AstFor("v2float_60_50")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_INotEqual,
+    SpirvASTParserTest_INotEqual,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both uint
@@ -247,7 +247,7 @@
         BinaryData{"v2bool", "v2int_30_40", "OpINotEqual", "v2int_40_30", "vec2<bool>",
                    AstFor("v2int_30_40"), "!=", AstFor("v2int_40_30")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdNotEqual,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FOrdNotEqual,
                          SpvBinaryLogicalTest,
                          ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdNotEqual",
                                                       "float_60", "bool", "50.0f", "!=", "60.0f"},
@@ -256,7 +256,7 @@
                                                       AstFor("v2float_50_60"),
                                                       "!=", AstFor("v2float_60_50")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdLessThan,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FOrdLessThan,
                          SpvBinaryLogicalTest,
                          ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdLessThan",
                                                       "float_60", "bool", "50.0f", "<", "60.0f"},
@@ -265,7 +265,7 @@
                                                       AstFor("v2float_50_60"), "<",
                                                       AstFor("v2float_60_50")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdLessThanEqual,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FOrdLessThanEqual,
                          SpvBinaryLogicalTest,
                          ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdLessThanEqual",
                                                       "float_60", "bool", "50.0f", "<=", "60.0f"},
@@ -274,7 +274,7 @@
                                                       "vec2<bool>", AstFor("v2float_50_60"),
                                                       "<=", AstFor("v2float_60_50")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdGreaterThan,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FOrdGreaterThan,
                          SpvBinaryLogicalTest,
                          ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdGreaterThan",
                                                       "float_60", "bool", "50.0f", ">", "60.0f"},
@@ -283,7 +283,7 @@
                                                       "vec2<bool>", AstFor("v2float_50_60"), ">",
                                                       AstFor("v2float_60_50")}));
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_FOrdGreaterThanEqual,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_FOrdGreaterThanEqual,
                          SpvBinaryLogicalTest,
                          ::testing::Values(BinaryData{"bool", "float_50", "OpFOrdGreaterThanEqual",
                                                       "float_60", "bool", "50.0f", ">=", "60.0f"},
@@ -293,7 +293,7 @@
                                                       ">=", AstFor("v2float_60_50")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_LogicalAnd,
+    SpirvASTParserTest_LogicalAnd,
     SpvBinaryLogicalTest,
     ::testing::Values(BinaryData{"bool", "true", "OpLogicalAnd", "false", "bool", "true", "&",
                                  "false"},
@@ -301,7 +301,7 @@
                                  AstFor("v2bool_t_f"), "&", AstFor("v2bool_f_t")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_LogicalOr,
+    SpirvASTParserTest_LogicalOr,
     SpvBinaryLogicalTest,
     ::testing::Values(BinaryData{"bool", "true", "OpLogicalOr", "false", "bool", "true", "|",
                                  "false"},
@@ -309,7 +309,7 @@
                                  AstFor("v2bool_t_f"), "|", AstFor("v2bool_f_t")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_LogicalEqual,
+    SpirvASTParserTest_LogicalEqual,
     SpvBinaryLogicalTest,
     ::testing::Values(BinaryData{"bool", "true", "OpLogicalEqual", "false", "bool", "true",
                                  "==", "false"},
@@ -317,7 +317,7 @@
                                  "vec2<bool>", AstFor("v2bool_t_f"), "==", AstFor("v2bool_f_t")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_LogicalNotEqual,
+    SpirvASTParserTest_LogicalNotEqual,
     SpvBinaryLogicalTest,
     ::testing::Values(BinaryData{"bool", "true", "OpLogicalNotEqual", "false", "bool", "true",
                                  "!=", "false"},
@@ -325,7 +325,7 @@
                                  "vec2<bool>", AstFor("v2bool_t_f"), "!=", AstFor("v2bool_f_t")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_UGreaterThan,
+    SpirvASTParserTest_UGreaterThan,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both unsigned
@@ -347,7 +347,7 @@
                    AstFor("v2uint_10_20"), ">", AstFor("cast_v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_UGreaterThanEqual,
+    SpirvASTParserTest_UGreaterThanEqual,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both unsigned
@@ -369,7 +369,7 @@
                    AstFor("v2uint_10_20"), ">=", AstFor("cast_v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ULessThan,
+    SpirvASTParserTest_ULessThan,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both unsigned
@@ -391,7 +391,7 @@
                    AstFor("v2uint_10_20"), "<", AstFor("cast_v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_ULessThanEqual,
+    SpirvASTParserTest_ULessThanEqual,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both unsigned
@@ -413,7 +413,7 @@
                    AstFor("v2uint_10_20"), "<=", AstFor("cast_v2int_40_30")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_SGreaterThan,
+    SpirvASTParserTest_SGreaterThan,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both signed
@@ -435,7 +435,7 @@
                    AstFor("v2int_30_40"), ">", AstFor("cast_v2uint_20_10")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_SGreaterThanEqual,
+    SpirvASTParserTest_SGreaterThanEqual,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both signed
@@ -457,7 +457,7 @@
                    AstFor("v2int_30_40"), ">=", AstFor("cast_v2uint_20_10")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_SLessThan,
+    SpirvASTParserTest_SLessThan,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both signed
@@ -479,7 +479,7 @@
                    AstFor("v2int_30_40"), "<", AstFor("cast_v2uint_20_10")}));
 
 INSTANTIATE_TEST_SUITE_P(
-    SpvParserTest_SLessThanEqual,
+    SpirvASTParserTest_SLessThanEqual,
     SpvBinaryLogicalTest,
     ::testing::Values(
         // Both signed
@@ -500,7 +500,7 @@
         BinaryData{"v2bool", "v2int_30_40", "OpSLessThanEqual", "v2uint_20_10", "vec2<bool>",
                    AstFor("v2int_30_40"), "<=", AstFor("cast_v2uint_20_10")}));
 
-using SpvFUnordTest = SpvParserTestBase<::testing::Test>;
+using SpvFUnordTest = SpirvASTParserTestBase<::testing::Test>;
 
 TEST_F(SpvFUnordTest, FUnordEqual_Scalar) {
     const auto assembly = Preamble() + R"(
@@ -704,7 +704,7 @@
                 HasSubstr("let x_1 = !((vec2f(50.0f, 60.0f) < vec2f(60.0f, 50.0f)));"));
 }
 
-using SpvLogicalTest = SpvParserTestBase<::testing::Test>;
+using SpvLogicalTest = SpirvASTParserTestBase<::testing::Test>;
 
 TEST_F(SpvLogicalTest, Select_BoolCond_BoolParams) {
     const auto assembly = Preamble() + R"(
@@ -908,4 +908,4 @@
 // TODO(dneto): OpSelect over more general types, as in SPIR-V 1.4
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_memory_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_memory_test.cc
similarity index 99%
rename from src/tint/lang/spirv/reader/function_memory_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_memory_test.cc
index 01587c9..9cf96d4 100644
--- a/src/tint/lang/spirv/reader/function_memory_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_memory_test.cc
@@ -13,17 +13,17 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
 using ::testing::HasSubstr;
 
-using SpvParserMemoryTest = SpvParserTest;
+using SpvParserMemoryTest = SpirvASTParserTest;
 
 std::string Preamble() {
     return R"(
@@ -1395,4 +1395,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_misc_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_misc_test.cc
similarity index 89%
rename from src/tint/lang/spirv/reader/function_misc_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_misc_test.cc
index 17641df..167941a 100644
--- a/src/tint/lang/spirv/reader/function_misc_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_misc_test.cc
@@ -13,11 +13,11 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -49,9 +49,9 @@
 )";
 }
 
-using SpvParserTestMiscInstruction = SpvParserTest;
+using SpirvASTParserTestMiscInstruction = SpirvASTParserTest;
 
-TEST_F(SpvParserTestMiscInstruction, OpUndef_BeforeFunction_Scalar) {
+TEST_F(SpirvASTParserTestMiscInstruction, OpUndef_BeforeFunction_Scalar) {
     const auto assembly = Preamble() + CommonTypes() + R"(
      %1 = OpUndef %bool
      %2 = OpUndef %uint
@@ -80,7 +80,7 @@
 )"));
 }
 
-TEST_F(SpvParserTestMiscInstruction, OpUndef_BeforeFunction_Vector) {
+TEST_F(SpirvASTParserTestMiscInstruction, OpUndef_BeforeFunction_Vector) {
     const auto assembly = Preamble() + CommonTypes() + R"(
      %4 = OpUndef %v2bool
      %1 = OpUndef %v2uint
@@ -109,7 +109,7 @@
 )"));
 }
 
-TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Scalar) {
+TEST_F(SpirvASTParserTestMiscInstruction, OpUndef_InFunction_Scalar) {
     const auto assembly = Preamble() + CommonTypes() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -138,7 +138,7 @@
 )"));
 }
 
-TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Vector) {
+TEST_F(SpirvASTParserTestMiscInstruction, OpUndef_InFunction_Vector) {
     const auto assembly = Preamble() + CommonTypes() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -163,7 +163,7 @@
 )"));
 }
 
-TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Matrix) {
+TEST_F(SpirvASTParserTestMiscInstruction, OpUndef_InFunction_Matrix) {
     const auto assembly = Preamble() + CommonTypes() + R"(
      %mat = OpTypeMatrix %v2float 2
 
@@ -183,7 +183,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_11 = mat2x2f();"));
 }
 
-TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Array) {
+TEST_F(SpirvASTParserTestMiscInstruction, OpUndef_InFunction_Array) {
     const auto assembly = Preamble() + CommonTypes() + R"(
      %uint_2 = OpConstant %uint 2
      %arr = OpTypeArray %uint %uint_2
@@ -204,7 +204,7 @@
     EXPECT_THAT(test::ToString(p->program(), ast_body), HasSubstr("let x_11 = array<u32, 2u>();"));
 }
 
-TEST_F(SpvParserTestMiscInstruction, OpUndef_InFunction_Struct) {
+TEST_F(SpirvASTParserTestMiscInstruction, OpUndef_InFunction_Struct) {
     const auto assembly = Preamble() + CommonTypes() + R"(
      %strct = OpTypeStruct %bool %uint %int %float
 
@@ -225,7 +225,7 @@
                 HasSubstr("let x_11 = S(false, 0u, 0i, 0.0f);"));
 }
 
-TEST_F(SpvParserTestMiscInstruction, OpNop) {
+TEST_F(SpirvASTParserTestMiscInstruction, OpNop) {
     const auto assembly = Preamble() + CommonTypes() + R"(
      %100 = OpFunction %void None %voidfn
      %entry = OpLabel
@@ -248,7 +248,7 @@
     std::string expected_expr;
     std::string expected_error;
 };
-using SpvParserSwizzleTest = SpvParserTestBase<::testing::TestWithParam<SwizzleCase>>;
+using SpvParserSwizzleTest = SpirvASTParserTestBase<::testing::TestWithParam<SwizzleCase>>;
 
 TEST_P(SpvParserSwizzleTest, Sample) {
     // We need a function so we can get a FunctionEmitter.
@@ -289,4 +289,4 @@
 // TODO(dneto): OpSizeof : requires Kernel (OpenCL)
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/function_var_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_var_test.cc
similarity index 99%
rename from src/tint/lang/spirv/reader/function_var_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/function_var_test.cc
index 4485836..cc594ee 100644
--- a/src/tint/lang/spirv/reader/function_var_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_var_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -99,7 +99,7 @@
     return PreambleNames({});
 }
 
-using SpvParserFunctionVarTest = SpvParserTest;
+using SpvParserFunctionVarTest = SpirvASTParserTest;
 
 TEST_F(SpvParserFunctionVarTest, EmitFunctionVariables_AnonymousVars) {
     auto p = parser(test::Assemble(Preamble() + R"(
@@ -1877,4 +1877,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_get_decorations_test.cc b/src/tint/lang/spirv/reader/ast_parser/get_decorations_test.cc
similarity index 96%
rename from src/tint/lang/spirv/reader/parser_impl_get_decorations_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/get_decorations_test.cc
index d05fb93..1083750 100644
--- a/src/tint/lang/spirv/reader/parser_impl_get_decorations_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/get_decorations_test.cc
@@ -13,16 +13,16 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
 using ::testing::UnorderedElementsAre;
 
-using SpvParserGetDecorationsTest = SpvParserTest;
+using SpvParserGetDecorationsTest = SpirvASTParserTest;
 
 const char* kSkipReason = "This example is deliberately a SPIR-V fragment";
 
@@ -254,4 +254,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_handle_test.cc b/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
similarity index 99%
rename from src/tint/lang/spirv/reader/parser_impl_handle_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/handle_test.cc
index 01cf8cb..ebeb0ac 100644
--- a/src/tint/lang/spirv/reader/parser_impl_handle_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
@@ -15,12 +15,12 @@
 #include <ostream>
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -28,7 +28,7 @@
 using ::testing::Not;
 using ::testing::StartsWith;
 
-using SpvParserHandleTest = SpvParserTest;
+using SpvParserHandleTest = SpirvASTParserTest;
 
 std::string Preamble() {
     return R"(
@@ -868,7 +868,7 @@
 }
 
 using SpvParserHandleTest_RegisterHandleUsage_SampledImage =
-    SpvParserTestBase<::testing::TestWithParam<UsageImageAccessCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<UsageImageAccessCase>>;
 
 TEST_P(SpvParserHandleTest_RegisterHandleUsage_SampledImage, Variable) {
     const std::string inst = GetParam().inst;
@@ -1033,7 +1033,7 @@
 }
 
 using SpvParserHandleTest_RegisterHandleUsage_RawImage =
-    SpvParserTestBase<::testing::TestWithParam<UsageRawImageCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<UsageRawImageCase>>;
 
 TEST_P(SpvParserHandleTest_RegisterHandleUsage_RawImage, Variable) {
     const bool is_storage = GetParam().type.find("storage") != std::string::npos;
@@ -1173,7 +1173,7 @@
 }
 
 using SpvParserHandleTest_DeclUnderspecifiedHandle =
-    SpvParserTestBase<::testing::TestWithParam<DeclUnderspecifiedHandleCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<DeclUnderspecifiedHandleCase>>;
 
 TEST_P(SpvParserHandleTest_DeclUnderspecifiedHandle, Variable) {
     const auto assembly = Preamble() + R"(
@@ -1253,7 +1253,7 @@
 }
 
 using SpvParserHandleTest_ImageDeclTest =
-    SpvParserTestBase<::testing::TestWithParam<ImageDeclCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<ImageDeclCase>>;
 
 TEST_P(SpvParserHandleTest_ImageDeclTest, DeclareAndUseHandle) {
     // Only declare the sampled image type, and the associated variable
@@ -1382,7 +1382,7 @@
 }
 
 using SpvParserHandleTest_SampledImageAccessTest =
-    SpvParserTestBase<::testing::TestWithParam<ImageAccessCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<ImageAccessCase>>;
 
 TEST_P(SpvParserHandleTest_SampledImageAccessTest, Variable) {
     // Only declare the sampled image type, and the associated variable
@@ -2348,7 +2348,7 @@
 /////
 
 using SpvParserHandleTest_ImageAccessTest =
-    SpvParserTestBase<::testing::TestWithParam<ImageAccessCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<ImageAccessCase>>;
 
 TEST_P(SpvParserHandleTest_ImageAccessTest, Variable) {
     // In this test harness, we only create an image.
@@ -3079,7 +3079,7 @@
 }
 
 using SpvParserHandleTest_ImageCoordsTest =
-    SpvParserTestBase<::testing::TestWithParam<ImageCoordsCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<ImageCoordsCase>>;
 
 TEST_P(SpvParserHandleTest_ImageCoordsTest, MakeCoordinateOperandsForImageAccess) {
     // Only declare the sampled image type, and the associated variable
@@ -4282,4 +4282,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_import_test.cc b/src/tint/lang/spirv/reader/ast_parser/import_test.cc
similarity index 94%
rename from src/tint/lang/spirv/reader/parser_impl_import_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/import_test.cc
index 499003d..6dee3ef 100644
--- a/src/tint/lang/spirv/reader/parser_impl_import_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/import_test.cc
@@ -13,10 +13,10 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::ElementsAre;
@@ -25,7 +25,7 @@
 using ::testing::Not;
 using ::testing::UnorderedElementsAre;
 
-using SpvParserImportTest = SpvParserTest;
+using SpvParserImportTest = SpirvASTParserTest;
 
 TEST_F(SpvParserImportTest, Import_NoImport) {
     auto p = parser(test::Assemble("%1 = OpTypeVoid"));
@@ -127,4 +127,4 @@
 // imports.
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_function_decl_test.cc b/src/tint/lang/spirv/reader/ast_parser/module_function_decl_test.cc
similarity index 90%
rename from src/tint/lang/spirv/reader/parser_impl_function_decl_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/module_function_decl_test.cc
index bbfc6ff..ca1f50a 100644
--- a/src/tint/lang/spirv/reader/parser_impl_function_decl_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/module_function_decl_test.cc
@@ -13,11 +13,11 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::HasSubstr;
@@ -78,7 +78,7 @@
 )";
 }
 
-TEST_F(SpvParserTest, EmitFunctions_NoFunctions) {
+TEST_F(SpirvASTParserTest, EmitFunctions_NoFunctions) {
     auto p = parser(test::Assemble(
         R"(
      OpCapability Shader
@@ -92,7 +92,7 @@
     p->SkipDumpingPending("Not valid for Vulkan: needs an entry point");
 }
 
-TEST_F(SpvParserTest, EmitFunctions_FunctionWithoutBody) {
+TEST_F(SpirvASTParserTest, EmitFunctions_FunctionWithoutBody) {
     auto p = parser(test::Assemble(Preamble() + Names({"main"}) + CommonTypes() + R"(
      %main = OpFunction %void None %voidfn
      OpFunctionEnd
@@ -105,7 +105,7 @@
     p->SkipDumpingPending("Missing an entry point body requires Linkage");
 }
 
-TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_Vertex) {
+TEST_F(SpirvASTParserTest, EmitFunctions_Function_EntryPoint_Vertex) {
     std::string input = Caps() + R"(OpEntryPoint Vertex %main "main" %position )" +
                         Names({"main"}) + BuiltinPosition() + R"(
 
@@ -132,7 +132,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_Fragment) {
+TEST_F(SpirvASTParserTest, EmitFunctions_Function_EntryPoint_Fragment) {
     std::string input = Caps() + R"(
      OpEntryPoint Fragment %main "main"
      OpExecutionMode %main OriginUpperLeft
@@ -150,7 +150,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_GLCompute) {
+TEST_F(SpirvASTParserTest, EmitFunctions_Function_EntryPoint_GLCompute) {
     std::string input = Caps() + R"(
       OpEntryPoint GLCompute %main "main"
       OpExecutionMode %main LocalSize 1 1 1
@@ -168,7 +168,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_MultipleEntryPoints) {
+TEST_F(SpirvASTParserTest, EmitFunctions_Function_EntryPoint_MultipleEntryPoints) {
     std::string input = Caps() +
                         R"(
 OpEntryPoint Fragment %main "first_shader"
@@ -192,7 +192,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_GLCompute_LocalSize_Only) {
+TEST_F(SpirvASTParserTest, EmitFunctions_Function_EntryPoint_GLCompute_LocalSize_Only) {
     std::string input = Caps() + R"(
 OpEntryPoint GLCompute %main "comp_main"
 OpExecutionMode %main LocalSize 2 4 8
@@ -214,7 +214,7 @@
 )")) << program_ast;
 }
 
-TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_WorkgroupSizeBuiltin_Constant_Only) {
+TEST_F(SpirvASTParserTest, EmitFunctions_Function_EntryPoint_WorkgroupSizeBuiltin_Constant_Only) {
     std::string input = Caps() + R"(OpEntryPoint GLCompute %main "comp_main"
 OpDecorate %wgsize BuiltIn WorkgroupSize
 )" + CommonTypes() + R"(
@@ -239,7 +239,8 @@
 )")) << program_ast;
 }
 
-TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_WorkgroupSizeBuiltin_SpecConstant_Only) {
+TEST_F(SpirvASTParserTest,
+       EmitFunctions_Function_EntryPoint_WorkgroupSizeBuiltin_SpecConstant_Only) {
     std::string input = Caps() +
                         R"(OpEntryPoint GLCompute %main "comp_main"
 OpDecorate %wgsize BuiltIn WorkgroupSize
@@ -268,7 +269,8 @@
 )")) << program_ast;
 }
 
-TEST_F(SpvParserTest, EmitFunctions_Function_EntryPoint_WorkgroupSize_MixedConstantSpecConstant) {
+TEST_F(SpirvASTParserTest,
+       EmitFunctions_Function_EntryPoint_WorkgroupSize_MixedConstantSpecConstant) {
     std::string input = Caps() +
                         R"(OpEntryPoint GLCompute %main "comp_main"
 OpDecorate %wgsize BuiltIn WorkgroupSize
@@ -296,7 +298,7 @@
 )")) << program_ast;
 }
 
-TEST_F(SpvParserTest,
+TEST_F(SpirvASTParserTest,
        // I had to shorten the name to pass the linter.
        EmitFunctions_Function_EntryPoint_LocalSize_And_WGSBuiltin_SpecConstant) {
     // WorkgroupSize builtin wins.
@@ -329,7 +331,7 @@
 )")) << program_ast;
 }
 
-TEST_F(SpvParserTest, EmitFunctions_VoidFunctionWithoutParams) {
+TEST_F(SpirvASTParserTest, EmitFunctions_VoidFunctionWithoutParams) {
     auto p = parser(test::Assemble(Preamble() + Names({"another_function"}) + CommonTypes() + R"(
     %another_function = OpFunction %void None %voidfn
     %entry = OpLabel
@@ -344,7 +346,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest, EmitFunctions_CalleePrecedesCaller) {
+TEST_F(SpirvASTParserTest, EmitFunctions_CalleePrecedesCaller) {
     auto p = parser(test::Assemble(
         Preamble() + Names({"root", "branch", "leaf", "leaf_result", "branch_result"}) +
         CommonTypes() + R"(
@@ -388,7 +390,7 @@
 )")) << program_ast;
 }
 
-TEST_F(SpvParserTest, EmitFunctions_NonVoidResultType) {
+TEST_F(SpirvASTParserTest, EmitFunctions_NonVoidResultType) {
     auto p = parser(test::Assemble(Preamble() + Names({"ret_float"}) + CommonTypes() + R"(
      %float_0 = OpConstant %float 0.0
      %fn_ret_float = OpTypeFunction %float
@@ -417,7 +419,7 @@
 )")) << program_ast;
 }
 
-TEST_F(SpvParserTest, EmitFunctions_MixedParamTypes) {
+TEST_F(SpirvASTParserTest, EmitFunctions_MixedParamTypes) {
     auto p = parser(
         test::Assemble(Preamble() + Names({"mixed_params", "a", "b", "c"}) + CommonTypes() + R"(
      %fn_mixed_params = OpTypeFunction %void %uint %float %int
@@ -440,7 +442,7 @@
 )"));
 }
 
-TEST_F(SpvParserTest, EmitFunctions_GenerateParamNames) {
+TEST_F(SpirvASTParserTest, EmitFunctions_GenerateParamNames) {
     auto p = parser(test::Assemble(Preamble() + Names({"mixed_params"}) + CommonTypes() + R"(
      %fn_mixed_params = OpTypeFunction %void %uint %float %int
 
@@ -463,4 +465,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_module_var_test.cc b/src/tint/lang/spirv/reader/ast_parser/module_var_test.cc
similarity index 99%
rename from src/tint/lang/spirv/reader/parser_impl_module_var_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/module_var_test.cc
index 2273c29..610ba06 100644
--- a/src/tint/lang/spirv/reader/parser_impl_module_var_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/module_var_test.cc
@@ -13,15 +13,15 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
-using SpvModuleScopeVarParserTest = SpvParserTest;
+using SpvModuleScopeVarParserTest = SpirvASTParserTest;
 
 using ::testing::ElementsAre;
 using ::testing::Eq;
@@ -128,7 +128,7 @@
     %voidfn = OpTypeFunction %void
   )" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
-    // Normally we should run ParserImpl::RegisterTypes before emitting
+    // Normally we should run ASTParser::RegisterTypes before emitting
     // variables. But defensive coding in EmitModuleScopeVariables lets
     // us catch this error.
     EXPECT_FALSE(p->EmitModuleScopeVariables()) << p->error();
@@ -144,7 +144,7 @@
     %voidfn = OpTypeFunction %void
   )" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
-    // Normally we should run ParserImpl::RegisterTypes before emitting
+    // Normally we should run ASTParser::RegisterTypes before emitting
     // variables. But defensive coding in EmitModuleScopeVariables lets
     // us catch this error.
     EXPECT_FALSE(p->EmitModuleScopeVariables()) << p->error();
@@ -162,7 +162,7 @@
     %voidfn = OpTypeFunction %void
   )" + MainBody()));
     EXPECT_TRUE(p->BuildInternalModule());
-    // Normally we should run ParserImpl::RegisterTypes before emitting
+    // Normally we should run ASTParser::RegisterTypes before emitting
     // variables. But defensive coding in EmitModuleScopeVariables lets
     // us catch this error.
     EXPECT_FALSE(p->EmitModuleScopeVariables());
@@ -3204,7 +3204,7 @@
 }
 
 using SpvModuleScopeVarParserTest_ComputeBuiltin =
-    SpvParserTestBase<::testing::TestWithParam<ComputeBuiltinInputCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<ComputeBuiltinInputCase>>;
 
 TEST_P(SpvModuleScopeVarParserTest_ComputeBuiltin, Load_Direct) {
     const auto wgsl_type = WgslType(GetParam().spirv_store_type);
@@ -3368,7 +3368,7 @@
 }
 
 using SpvModuleScopeVarParserTest_ComputeBuiltinVector =
-    SpvParserTestBase<::testing::TestWithParam<ComputeBuiltinInputVectorCase>>;
+    SpirvASTParserTestBase<::testing::TestWithParam<ComputeBuiltinInputVectorCase>>;
 
 TEST_P(SpvModuleScopeVarParserTest_ComputeBuiltinVector, Load_Component_Direct) {
     const auto wgsl_type = WgslType(GetParam().spirv_store_type);
@@ -5360,4 +5360,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_named_types_test.cc b/src/tint/lang/spirv/reader/ast_parser/named_types_test.cc
similarity index 85%
rename from src/tint/lang/spirv/reader/parser_impl_named_types_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/named_types_test.cc
index e0ec06b..5ef9040 100644
--- a/src/tint/lang/spirv/reader/parser_impl_named_types_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/named_types_test.cc
@@ -13,15 +13,15 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::HasSubstr;
 
-TEST_F(SpvParserTest, NamedTypes_AnonStruct) {
+TEST_F(SpirvASTParserTest, NamedTypes_AnonStruct) {
     auto p = parser(test::Assemble(R"(
     %uint = OpTypeInt 32 0
     %s = OpTypeStruct %uint %uint
@@ -32,7 +32,7 @@
     p->DeliberatelyInvalidSpirv();
 }
 
-TEST_F(SpvParserTest, NamedTypes_NamedStruct) {
+TEST_F(SpirvASTParserTest, NamedTypes_NamedStruct) {
     auto p = parser(test::Assemble(R"(
     OpName %s "mystruct"
     %uint = OpTypeInt 32 0
@@ -44,7 +44,7 @@
     p->DeliberatelyInvalidSpirv();
 }
 
-TEST_F(SpvParserTest, NamedTypes_Dup_EmitBoth) {
+TEST_F(SpirvASTParserTest, NamedTypes_Dup_EmitBoth) {
     auto p = parser(test::Assemble(R"(
     %uint = OpTypeInt 32 0
     %s = OpTypeStruct %uint %uint
@@ -67,7 +67,7 @@
 // TODO(dneto): Should we make an alias for an un-decoratrd array with
 // an OpName?
 
-TEST_F(SpvParserTest, NamedTypes_AnonRTArrayWithDecoration) {
+TEST_F(SpirvASTParserTest, NamedTypes_AnonRTArrayWithDecoration) {
     // Runtime arrays are always in SSBO, and those are always laid out.
     auto p = parser(test::Assemble(R"(
     OpDecorate %arr ArrayStride 8
@@ -80,7 +80,7 @@
     p->DeliberatelyInvalidSpirv();
 }
 
-TEST_F(SpvParserTest, NamedTypes_AnonRTArray_Dup_EmitBoth) {
+TEST_F(SpirvASTParserTest, NamedTypes_AnonRTArray_Dup_EmitBoth) {
     auto p = parser(test::Assemble(R"(
     OpDecorate %arr ArrayStride 8
     OpDecorate %arr2 ArrayStride 8
@@ -97,7 +97,7 @@
     p->DeliberatelyInvalidSpirv();
 }
 
-TEST_F(SpvParserTest, NamedTypes_NamedRTArray) {
+TEST_F(SpirvASTParserTest, NamedTypes_NamedRTArray) {
     auto p = parser(test::Assemble(R"(
     OpName %arr "myrtarr"
     OpDecorate %arr ArrayStride 8
@@ -110,7 +110,7 @@
     p->DeliberatelyInvalidSpirv();
 }
 
-TEST_F(SpvParserTest, NamedTypes_NamedArray) {
+TEST_F(SpirvASTParserTest, NamedTypes_NamedArray) {
     auto p = parser(test::Assemble(R"(
     OpName %arr "myarr"
     OpDecorate %arr ArrayStride 8
@@ -125,7 +125,7 @@
     p->DeliberatelyInvalidSpirv();
 }
 
-TEST_F(SpvParserTest, NamedTypes_AnonArray_Dup_EmitBoth) {
+TEST_F(SpirvASTParserTest, NamedTypes_AnonArray_Dup_EmitBoth) {
     auto p = parser(test::Assemble(R"(
     OpDecorate %arr ArrayStride 8
     OpDecorate %arr2 ArrayStride 8
@@ -147,4 +147,4 @@
 // Blocked by crbug.com/tint/32
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/namer.cc b/src/tint/lang/spirv/reader/ast_parser/namer.cc
similarity index 98%
rename from src/tint/lang/spirv/reader/namer.cc
rename to src/tint/lang/spirv/reader/ast_parser/namer.cc
index 2179f81..96a193a 100644
--- a/src/tint/lang/spirv/reader/namer.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/namer.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/namer.h"
+#include "src/tint/lang/spirv/reader/ast_parser/namer.h"
 
 #include <algorithm>
 #include <unordered_set>
@@ -21,7 +21,7 @@
 #include "src/tint/utils/debug/debug.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 namespace {
 
@@ -345,4 +345,4 @@
     }
 }
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/namer.h b/src/tint/lang/spirv/reader/ast_parser/namer.h
similarity index 95%
rename from src/tint/lang/spirv/reader/namer.h
rename to src/tint/lang/spirv/reader/ast_parser/namer.h
index 5674118..fe7d479 100644
--- a/src/tint/lang/spirv/reader/namer.h
+++ b/src/tint/lang/spirv/reader/ast_parser/namer.h
@@ -12,16 +12,16 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_NAMER_H_
-#define SRC_TINT_LANG_SPIRV_READER_NAMER_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_NAMER_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_NAMER_H_
 
 #include <string>
 #include <unordered_map>
 #include <vector>
 
-#include "src/tint/lang/spirv/reader/fail_stream.h"
+#include "src/tint/lang/spirv/reader/ast_parser/fail_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// A Namer maps SPIR-V IDs to strings.
 ///
@@ -152,6 +152,6 @@
     std::unordered_map<std::string, uint32_t> next_unusued_derived_name_id_;
 };
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_NAMER_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_NAMER_H_
diff --git a/src/tint/lang/spirv/reader/namer_test.cc b/src/tint/lang/spirv/reader/ast_parser/namer_test.cc
similarity index 98%
rename from src/tint/lang/spirv/reader/namer_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/namer_test.cc
index 65f7646..ed36693 100644
--- a/src/tint/lang/spirv/reader/namer_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/namer_test.cc
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/namer.h"
+#include "src/tint/lang/spirv/reader/ast_parser/namer.h"
 
 #include "gmock/gmock.h"
 #include "src/tint/lang/core/builtin/function.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
@@ -361,7 +361,7 @@
     EXPECT_THAT(namer.FindUnusedDerivedName(reserved), Eq(reserved + "_1"));
 }
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_ReservedWords,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_ReservedWords,
                          SpvNamerReservedWordTest,
                          ::testing::ValuesIn(std::vector<std::string>{
                              // Please keep this list sorted.
@@ -406,9 +406,9 @@
     EXPECT_THAT(namer.FindUnusedDerivedName(builtin_fn), Eq(builtin_fn + "_1"));
 }
 
-INSTANTIATE_TEST_SUITE_P(SpvParserTest_BuiltinFunctions,
+INSTANTIATE_TEST_SUITE_P(SpirvASTParserTest_BuiltinFunctions,
                          SpvNamerBuiltinFunctionTest,
                          ::testing::ValuesIn(builtin::kFunctionStrings));
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_test.cc b/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
similarity index 93%
rename from src/tint/lang/spirv/reader/parser_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/parser_test.cc
index a54e5d7..fb89ec5 100644
--- a/src/tint/lang/spirv/reader/parser_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/parser.h"
+#include "src/tint/lang/spirv/reader/reader.h"
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ParserTest = testing::Test;
@@ -82,4 +82,4 @@
 // TODO(dneto): uint32 vec, invalid SPIR-V
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/spirv_tools_helpers_test.cc b/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc
similarity index 92%
rename from src/tint/lang/spirv/reader/spirv_tools_helpers_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc
index 2c3985d..1c06054 100644
--- a/src/tint/lang/spirv/reader/spirv_tools_helpers_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
 #include "gtest/gtest.h"
 #include "spirv-tools/libspirv.hpp"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv::test {
+namespace tint::spirv::reader::test {
 
 std::vector<uint32_t> Assemble(const std::string& spirv_assembly) {
     // TODO(dneto): Use ScopedTrace?
@@ -55,4 +55,4 @@
     return result;
 }
 
-}  // namespace tint::reader::spirv::test
+}  // namespace tint::spirv::reader::test
diff --git a/src/tint/lang/spirv/reader/spirv_tools_helpers_test.h b/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h
similarity index 76%
rename from src/tint/lang/spirv/reader/spirv_tools_helpers_test.h
rename to src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h
index ff639f6..456ceb2 100644
--- a/src/tint/lang/spirv/reader/spirv_tools_helpers_test.h
+++ b/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_SPIRV_TOOLS_HELPERS_TEST_H_
-#define SRC_TINT_LANG_SPIRV_READER_SPIRV_TOOLS_HELPERS_TEST_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_SPIRV_TOOLS_HELPERS_TEST_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_SPIRV_TOOLS_HELPERS_TEST_H_
 
 #include <string>
 #include <vector>
 
-namespace tint::reader::spirv::test {
+namespace tint::spirv::reader::test {
 
 /// @param spirv_assembly SPIR-V assembly text
 /// @returns the SPIR-V module assembled from the given text.  Numeric IDs
@@ -29,6 +29,6 @@
 /// @returns the disassembled module
 std::string Disassemble(const std::vector<uint32_t>& spirv_module);
 
-}  // namespace tint::reader::spirv::test
+}  // namespace tint::spirv::reader::test
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_SPIRV_TOOLS_HELPERS_TEST_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_SPIRV_TOOLS_HELPERS_TEST_H_
diff --git a/src/tint/lang/spirv/reader/parser_impl_test_helper.cc b/src/tint/lang/spirv/reader/ast_parser/test_helper.cc
similarity index 87%
rename from src/tint/lang/spirv/reader/parser_impl_test_helper.cc
rename to src/tint/lang/spirv/reader/ast_parser/test_helper.cc
index 18e8567..ada184a 100644
--- a/src/tint/lang/spirv/reader/parser_impl_test_helper.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/test_helper.cc
@@ -12,22 +12,22 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/lang/wgsl/writer/ast_printer/ast_printer.h"
 #include "src/tint/utils/rtti/switch.h"
 #include "src/tint/utils/text/string_stream.h"
 
 #include "gmock/gmock.h"
 
-namespace tint::reader::spirv::test {
+namespace tint::spirv::reader::test {
 
 // Default to not dumping the SPIR-V assembly.
-bool ParserImplWrapperForTest::dump_successfully_converted_spirv_ = false;
+bool ASTParserWrapperForTest::dump_successfully_converted_spirv_ = false;
 
-ParserImplWrapperForTest::ParserImplWrapperForTest(const std::vector<uint32_t>& input)
+ASTParserWrapperForTest::ASTParserWrapperForTest(const std::vector<uint32_t>& input)
     : impl_(input) {}
 
-ParserImplWrapperForTest::~ParserImplWrapperForTest() {
+ASTParserWrapperForTest::~ASTParserWrapperForTest() {
     if (dump_successfully_converted_spirv_ && !skip_dumping_spirv_ && !impl_.spv_binary().empty() &&
         impl_.success()) {
         std::string disassembly = Disassemble(impl_.spv_binary());
@@ -81,4 +81,4 @@
         });
 }
 
-}  // namespace tint::reader::spirv::test
+}  // namespace tint::spirv::reader::test
diff --git a/src/tint/lang/spirv/reader/parser_impl_test_helper.h b/src/tint/lang/spirv/reader/ast_parser/test_helper.h
similarity index 89%
rename from src/tint/lang/spirv/reader/parser_impl_test_helper.h
rename to src/tint/lang/spirv/reader/ast_parser/test_helper.h
index 027cb64..3cdce29 100644
--- a/src/tint/lang/spirv/reader/parser_impl_test_helper.h
+++ b/src/tint/lang/spirv/reader/ast_parser/test_helper.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_PARSER_IMPL_TEST_HELPER_H_
-#define SRC_TINT_LANG_SPIRV_READER_PARSER_IMPL_TEST_HELPER_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_TEST_HELPER_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_TEST_HELPER_H_
 
 #include <memory>
 #include <string>
@@ -34,24 +34,24 @@
 TINT_END_DISABLE_WARNING(NEWLINE_EOF);
 
 #include "gtest/gtest.h"
-#include "src/tint/lang/spirv/reader/fail_stream.h"
-#include "src/tint/lang/spirv/reader/function.h"
-#include "src/tint/lang/spirv/reader/namer.h"
-#include "src/tint/lang/spirv/reader/parser_impl.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
-#include "src/tint/lang/spirv/reader/usage.h"
+#include "src/tint/lang/spirv/reader/ast_parser/ast_parser.h"
+#include "src/tint/lang/spirv/reader/ast_parser/fail_stream.h"
+#include "src/tint/lang/spirv/reader/ast_parser/function.h"
+#include "src/tint/lang/spirv/reader/ast_parser/namer.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/usage.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace test {
 
 /// A test class that wraps ParseImpl
-class ParserImplWrapperForTest {
+class ASTParserWrapperForTest {
   public:
     /// Constructor
     /// @param input the input data to parse
-    explicit ParserImplWrapperForTest(const std::vector<uint32_t>& input);
+    explicit ASTParserWrapperForTest(const std::vector<uint32_t>& input);
     /// Dumps SPIR-V if the conversion succeeded, then destroys the wrapper.
-    ~ParserImplWrapperForTest();
+    ~ASTParserWrapperForTest();
 
     /// Sets global state to force dumping of the assembly text of succesfully
     /// SPIR-V.
@@ -63,7 +63,7 @@
     void SkipDumpingPending(std::string) { skip_dumping_spirv_ = true; }
 
     /// @returns a new function emitter for the given function ID.
-    /// Assumes ParserImpl::BuildInternalRepresentation has been run and
+    /// Assumes ASTParser::BuildInternalRepresentation has been run and
     /// succeeded.
     /// @param function_id the SPIR-V identifier of the function
     FunctionEmitter function_emitter(uint32_t function_id) {
@@ -236,7 +236,7 @@
     }
 
     /// @returns info about the gl_Position builtin variable.
-    const ParserImpl::BuiltInPositionInfo& GetBuiltInPositionInfo() {
+    const ASTParser::BuiltInPositionInfo& GetBuiltInPositionInfo() {
         return impl_.GetBuiltInPositionInfo();
     }
 
@@ -249,7 +249,7 @@
     }
 
   private:
-    ParserImpl impl_;
+    ASTParser impl_;
     /// When true, indicates the input SPIR-V module should not be emitted.
     /// It's either deliberately invalid, or not supported for some pending
     /// reason.
@@ -260,7 +260,7 @@
 // Sets global state to force dumping of the assembly text of succesfully
 // SPIR-V.
 inline void DumpSuccessfullyConvertedSpirv() {
-    ParserImplWrapperForTest::DumpSuccessfullyConvertedSpirv();
+    ASTParserWrapperForTest::DumpSuccessfullyConvertedSpirv();
 }
 
 /// Returns the WGSL printed string of a program.
@@ -284,16 +284,16 @@
 
 /// SPIR-V Parser test class
 template <typename T>
-class SpvParserTestBase : public T {
+class SpirvASTParserTestBase : public T {
   public:
-    SpvParserTestBase() = default;
-    ~SpvParserTestBase() override = default;
+    SpirvASTParserTestBase() = default;
+    ~SpirvASTParserTestBase() override = default;
 
     /// Retrieves the parser from the helper
     /// @param input the SPIR-V binary to parse
     /// @returns a parser for the given binary
-    std::unique_ptr<test::ParserImplWrapperForTest> parser(const std::vector<uint32_t>& input) {
-        auto parser = std::make_unique<test::ParserImplWrapperForTest>(input);
+    std::unique_ptr<test::ASTParserWrapperForTest> parser(const std::vector<uint32_t>& input) {
+        auto parser = std::make_unique<test::ASTParserWrapperForTest>(input);
 
         // Don't run the Resolver when building the program.
         // We're not interested in type information with these tests.
@@ -302,10 +302,10 @@
     }
 };
 
-/// SpvParserTest the the base class for SPIR-V reader unit tests.
+/// SpirvASTParserTest the the base class for SPIR-V reader unit tests.
 /// Use this form when you don't need to template any further.
-using SpvParserTest = SpvParserTestBase<::testing::Test>;
+using SpirvASTParserTest = SpirvASTParserTestBase<::testing::Test>;
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_PARSER_IMPL_TEST_HELPER_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_TEST_HELPER_H_
diff --git a/src/tint/lang/spirv/reader/parser_type.cc b/src/tint/lang/spirv/reader/ast_parser/type.cc
similarity index 75%
rename from src/tint/lang/spirv/reader/parser_type.cc
rename to src/tint/lang/spirv/reader/ast_parser/type.cc
index fd8a0c6..18dc52c 100644
--- a/src/tint/lang/spirv/reader/parser_type.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/type.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/parser_type.h"
+#include "src/tint/lang/spirv/reader/ast_parser/type.h"
 
 #include <sstream>
 #include <string>
@@ -28,29 +28,29 @@
 #include "src/tint/utils/text/string.h"
 #include "src/tint/utils/text/string_stream.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Type);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Void);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Bool);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::U32);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::F32);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::I32);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Pointer);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Reference);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Vector);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Matrix);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Array);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Sampler);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Texture);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::DepthTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::DepthMultisampledTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::MultisampledTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::SampledTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::StorageTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Named);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Alias);
-TINT_INSTANTIATE_TYPEINFO(tint::reader::spirv::Struct);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Type);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Void);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Bool);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::U32);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::F32);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::I32);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Pointer);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Reference);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Vector);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Matrix);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Array);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Sampler);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Texture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::DepthTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::DepthMultisampledTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::MultisampledTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::SampledTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::StorageTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Named);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Alias);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Struct);
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 namespace {
 struct PointerHasher {
@@ -315,43 +315,43 @@
     /// The allocator of primitive types
     utils::BlockAllocator<Type> allocator_;
     /// The lazily-created Void type
-    spirv::Void const* void_ = nullptr;
+    reader::Void const* void_ = nullptr;
     /// The lazily-created Bool type
-    spirv::Bool const* bool_ = nullptr;
+    reader::Bool const* bool_ = nullptr;
     /// The lazily-created U32 type
-    spirv::U32 const* u32_ = nullptr;
+    reader::U32 const* u32_ = nullptr;
     /// The lazily-created F32 type
-    spirv::F32 const* f32_ = nullptr;
+    reader::F32 const* f32_ = nullptr;
     /// The lazily-created I32 type
-    spirv::I32 const* i32_ = nullptr;
+    reader::I32 const* i32_ = nullptr;
     /// Unique Pointer instances
-    utils::UniqueAllocator<spirv::Pointer, PointerHasher> pointers_;
+    utils::UniqueAllocator<reader::Pointer, PointerHasher> pointers_;
     /// Unique Reference instances
-    utils::UniqueAllocator<spirv::Reference, ReferenceHasher> references_;
+    utils::UniqueAllocator<reader::Reference, ReferenceHasher> references_;
     /// Unique Vector instances
-    utils::UniqueAllocator<spirv::Vector, VectorHasher> vectors_;
+    utils::UniqueAllocator<reader::Vector, VectorHasher> vectors_;
     /// Unique Matrix instances
-    utils::UniqueAllocator<spirv::Matrix, MatrixHasher> matrices_;
+    utils::UniqueAllocator<reader::Matrix, MatrixHasher> matrices_;
     /// Unique Array instances
-    utils::UniqueAllocator<spirv::Array, ArrayHasher> arrays_;
+    utils::UniqueAllocator<reader::Array, ArrayHasher> arrays_;
     /// Unique Alias instances
-    utils::UniqueAllocator<spirv::Alias, AliasHasher> aliases_;
+    utils::UniqueAllocator<reader::Alias, AliasHasher> aliases_;
     /// Unique Struct instances
-    utils::UniqueAllocator<spirv::Struct, StructHasher> structs_;
+    utils::UniqueAllocator<reader::Struct, StructHasher> structs_;
     /// Unique Sampler instances
-    utils::UniqueAllocator<spirv::Sampler, SamplerHasher> samplers_;
+    utils::UniqueAllocator<reader::Sampler, SamplerHasher> samplers_;
     /// Unique DepthTexture instances
-    utils::UniqueAllocator<spirv::DepthTexture, DepthTextureHasher> depth_textures_;
+    utils::UniqueAllocator<reader::DepthTexture, DepthTextureHasher> depth_textures_;
     /// Unique DepthMultisampledTexture instances
-    utils::UniqueAllocator<spirv::DepthMultisampledTexture, DepthMultisampledTextureHasher>
+    utils::UniqueAllocator<reader::DepthMultisampledTexture, DepthMultisampledTextureHasher>
         depth_multisampled_textures_;
     /// Unique MultisampledTexture instances
-    utils::UniqueAllocator<spirv::MultisampledTexture, MultisampledTextureHasher>
+    utils::UniqueAllocator<reader::MultisampledTexture, MultisampledTextureHasher>
         multisampled_textures_;
     /// Unique SampledTexture instances
-    utils::UniqueAllocator<spirv::SampledTexture, SampledTextureHasher> sampled_textures_;
+    utils::UniqueAllocator<reader::SampledTexture, SampledTextureHasher> sampled_textures_;
     /// Unique StorageTexture instances
-    utils::UniqueAllocator<spirv::StorageTexture, StorageTextureHasher> storage_textures_;
+    utils::UniqueAllocator<reader::StorageTexture, StorageTextureHasher> storage_textures_;
 };
 
 const Type* Type::UnwrapPtr() const {
@@ -438,113 +438,113 @@
 
 TypeManager::~TypeManager() = default;
 
-const spirv::Void* TypeManager::Void() {
+const reader::Void* TypeManager::Void() {
     if (!state->void_) {
-        state->void_ = state->allocator_.Create<spirv::Void>();
+        state->void_ = state->allocator_.Create<reader::Void>();
     }
     return state->void_;
 }
 
-const spirv::Bool* TypeManager::Bool() {
+const reader::Bool* TypeManager::Bool() {
     if (!state->bool_) {
-        state->bool_ = state->allocator_.Create<spirv::Bool>();
+        state->bool_ = state->allocator_.Create<reader::Bool>();
     }
     return state->bool_;
 }
 
-const spirv::U32* TypeManager::U32() {
+const reader::U32* TypeManager::U32() {
     if (!state->u32_) {
-        state->u32_ = state->allocator_.Create<spirv::U32>();
+        state->u32_ = state->allocator_.Create<reader::U32>();
     }
     return state->u32_;
 }
 
-const spirv::F32* TypeManager::F32() {
+const reader::F32* TypeManager::F32() {
     if (!state->f32_) {
-        state->f32_ = state->allocator_.Create<spirv::F32>();
+        state->f32_ = state->allocator_.Create<reader::F32>();
     }
     return state->f32_;
 }
 
-const spirv::I32* TypeManager::I32() {
+const reader::I32* TypeManager::I32() {
     if (!state->i32_) {
-        state->i32_ = state->allocator_.Create<spirv::I32>();
+        state->i32_ = state->allocator_.Create<reader::I32>();
     }
     return state->i32_;
 }
 
 const Type* TypeManager::AsUnsigned(const Type* ty) {
     return Switch(
-        ty,                                        //
-        [&](const spirv::I32*) { return U32(); },  //
-        [&](const spirv::U32*) { return ty; },     //
-        [&](const spirv::Vector* vec) {
+        ty,                                         //
+        [&](const reader::I32*) { return U32(); },  //
+        [&](const reader::U32*) { return ty; },     //
+        [&](const reader::Vector* vec) {
             return Switch(
-                vec->type,                                                    //
-                [&](const spirv::I32*) { return Vector(U32(), vec->size); },  //
-                [&](const spirv::U32*) { return ty; }                         //
+                vec->type,                                                     //
+                [&](const reader::I32*) { return Vector(U32(), vec->size); },  //
+                [&](const reader::U32*) { return ty; }                         //
             );
         });
 }
 
-const spirv::Pointer* TypeManager::Pointer(builtin::AddressSpace address_space,
-                                           const Type* el,
-                                           builtin::Access access) {
+const reader::Pointer* TypeManager::Pointer(builtin::AddressSpace address_space,
+                                            const Type* el,
+                                            builtin::Access access) {
     return state->pointers_.Get(address_space, el, access);
 }
 
-const spirv::Reference* TypeManager::Reference(builtin::AddressSpace address_space,
-                                               const Type* el,
-                                               builtin::Access access) {
+const reader::Reference* TypeManager::Reference(builtin::AddressSpace address_space,
+                                                const Type* el,
+                                                builtin::Access access) {
     return state->references_.Get(address_space, el, access);
 }
 
-const spirv::Vector* TypeManager::Vector(const Type* el, uint32_t size) {
+const reader::Vector* TypeManager::Vector(const Type* el, uint32_t size) {
     return state->vectors_.Get(el, size);
 }
 
-const spirv::Matrix* TypeManager::Matrix(const Type* el, uint32_t columns, uint32_t rows) {
+const reader::Matrix* TypeManager::Matrix(const Type* el, uint32_t columns, uint32_t rows) {
     return state->matrices_.Get(el, columns, rows);
 }
 
-const spirv::Array* TypeManager::Array(const Type* el, uint32_t size, uint32_t stride) {
+const reader::Array* TypeManager::Array(const Type* el, uint32_t size, uint32_t stride) {
     return state->arrays_.Get(el, size, stride);
 }
 
-const spirv::Alias* TypeManager::Alias(Symbol name, const Type* ty) {
+const reader::Alias* TypeManager::Alias(Symbol name, const Type* ty) {
     return state->aliases_.Get(name, ty);
 }
 
-const spirv::Struct* TypeManager::Struct(Symbol name, TypeList members) {
+const reader::Struct* TypeManager::Struct(Symbol name, TypeList members) {
     return state->structs_.Get(name, std::move(members));
 }
 
-const spirv::Sampler* TypeManager::Sampler(type::SamplerKind kind) {
+const reader::Sampler* TypeManager::Sampler(type::SamplerKind kind) {
     return state->samplers_.Get(kind);
 }
 
-const spirv::DepthTexture* TypeManager::DepthTexture(type::TextureDimension dims) {
+const reader::DepthTexture* TypeManager::DepthTexture(type::TextureDimension dims) {
     return state->depth_textures_.Get(dims);
 }
 
-const spirv::DepthMultisampledTexture* TypeManager::DepthMultisampledTexture(
+const reader::DepthMultisampledTexture* TypeManager::DepthMultisampledTexture(
     type::TextureDimension dims) {
     return state->depth_multisampled_textures_.Get(dims);
 }
 
-const spirv::MultisampledTexture* TypeManager::MultisampledTexture(type::TextureDimension dims,
-                                                                   const Type* ty) {
+const reader::MultisampledTexture* TypeManager::MultisampledTexture(type::TextureDimension dims,
+                                                                    const Type* ty) {
     return state->multisampled_textures_.Get(dims, ty);
 }
 
-const spirv::SampledTexture* TypeManager::SampledTexture(type::TextureDimension dims,
-                                                         const Type* ty) {
+const reader::SampledTexture* TypeManager::SampledTexture(type::TextureDimension dims,
+                                                          const Type* ty) {
     return state->sampled_textures_.Get(dims, ty);
 }
 
-const spirv::StorageTexture* TypeManager::StorageTexture(type::TextureDimension dims,
-                                                         builtin::TexelFormat fmt,
-                                                         builtin::Access access) {
+const reader::StorageTexture* TypeManager::StorageTexture(type::TextureDimension dims,
+                                                          builtin::TexelFormat fmt,
+                                                          builtin::Access access) {
     return state->storage_textures_.Get(dims, fmt, access);
 }
 
@@ -645,4 +645,4 @@
 }
 #endif  // NDEBUG
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_type.h b/src/tint/lang/spirv/reader/ast_parser/type.h
similarity index 91%
rename from src/tint/lang/spirv/reader/parser_type.h
rename to src/tint/lang/spirv/reader/ast_parser/type.h
index a15eda7..5339018 100644
--- a/src/tint/lang/spirv/reader/parser_type.h
+++ b/src/tint/lang/spirv/reader/ast_parser/type.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_PARSER_TYPE_H_
-#define SRC_TINT_LANG_SPIRV_READER_PARSER_TYPE_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_TYPE_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_TYPE_H_
 
 #include <memory>
 #include <string>
@@ -34,7 +34,7 @@
 class ProgramBuilder;
 }  // namespace tint
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// Type is the base class for all types
 class Type : public utils::Castable<Type> {
@@ -529,15 +529,15 @@
     ~TypeManager();
 
     /// @return a Void type. Repeated calls will return the same pointer.
-    const spirv::Void* Void();
+    const reader::Void* Void();
     /// @return a Bool type. Repeated calls will return the same pointer.
-    const spirv::Bool* Bool();
+    const reader::Bool* Bool();
     /// @return a U32 type. Repeated calls will return the same pointer.
-    const spirv::U32* U32();
+    const reader::U32* U32();
     /// @return a F32 type. Repeated calls will return the same pointer.
-    const spirv::F32* F32();
+    const reader::F32* F32();
     /// @return a I32 type. Repeated calls will return the same pointer.
-    const spirv::I32* I32();
+    const reader::I32* I32();
     /// @param ty the input type.
     /// @returns the equivalent unsigned integer scalar or vector if @p ty is a scalar or vector,
     /// otherwise nullptr.
@@ -548,81 +548,81 @@
     /// @param access the declared access mode
     /// @return a Pointer type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const spirv::Pointer* Pointer(builtin::AddressSpace address_space,
-                                  const Type* ty,
-                                  builtin::Access access = builtin::Access::kUndefined);
+    const reader::Pointer* Pointer(builtin::AddressSpace address_space,
+                                   const Type* ty,
+                                   builtin::Access access = builtin::Access::kUndefined);
     /// @param address_space the reference address space
     /// @param ty the referenced type
     /// @param access the declared access mode
     /// @return a Reference type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const spirv::Reference* Reference(builtin::AddressSpace address_space,
-                                      const Type* ty,
-                                      builtin::Access access = builtin::Access::kUndefined);
+    const reader::Reference* Reference(builtin::AddressSpace address_space,
+                                       const Type* ty,
+                                       builtin::Access access = builtin::Access::kUndefined);
     /// @param ty the element type
     /// @param sz the number of elements in the vector
     /// @return a Vector type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const spirv::Vector* Vector(const Type* ty, uint32_t sz);
+    const reader::Vector* Vector(const Type* ty, uint32_t sz);
     /// @param ty the matrix element type
     /// @param c the number of columns in the matrix
     /// @param r the number of rows in the matrix
     /// @return a Matrix type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const spirv::Matrix* Matrix(const Type* ty, uint32_t c, uint32_t r);
+    const reader::Matrix* Matrix(const Type* ty, uint32_t c, uint32_t r);
     /// @param el the element type
     /// @param sz the number of elements in the array. 0 represents runtime-sized
     /// array.
     /// @param st the byte stride of the array
     /// @return a Array type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const spirv::Array* Array(const Type* el, uint32_t sz, uint32_t st);
+    const reader::Array* Array(const Type* el, uint32_t sz, uint32_t st);
     /// @param n the alias name
     /// @param t the aliased type
     /// @return a Alias type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const spirv::Alias* Alias(Symbol n, const Type* t);
+    const reader::Alias* Alias(Symbol n, const Type* t);
     /// @param n the struct name
     /// @param m the member types
     /// @return a Struct type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const spirv::Struct* Struct(Symbol n, TypeList m);
+    const reader::Struct* Struct(Symbol n, TypeList m);
     /// @param k the sampler kind
     /// @return a Sampler type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const spirv::Sampler* Sampler(type::SamplerKind k);
+    const reader::Sampler* Sampler(type::SamplerKind k);
     /// @param d the texture dimensions
     /// @return a DepthTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const spirv::DepthTexture* DepthTexture(type::TextureDimension d);
+    const reader::DepthTexture* DepthTexture(type::TextureDimension d);
     /// @param d the texture dimensions
     /// @return a DepthMultisampledTexture type. Repeated calls with the same
     /// arguments will return the same pointer.
-    const spirv::DepthMultisampledTexture* DepthMultisampledTexture(type::TextureDimension d);
+    const reader::DepthMultisampledTexture* DepthMultisampledTexture(type::TextureDimension d);
     /// @param d the texture dimensions
     /// @param t the multisampled texture type
     /// @return a MultisampledTexture type. Repeated calls with the same arguments
     /// will return the same pointer.
-    const spirv::MultisampledTexture* MultisampledTexture(type::TextureDimension d, const Type* t);
+    const reader::MultisampledTexture* MultisampledTexture(type::TextureDimension d, const Type* t);
     /// @param d the texture dimensions
     /// @param t the sampled texture type
     /// @return a SampledTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const spirv::SampledTexture* SampledTexture(type::TextureDimension d, const Type* t);
+    const reader::SampledTexture* SampledTexture(type::TextureDimension d, const Type* t);
     /// @param d the texture dimensions
     /// @param f the storage image format
     /// @param a the access control
     /// @return a StorageTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const spirv::StorageTexture* StorageTexture(type::TextureDimension d,
-                                                builtin::TexelFormat f,
-                                                builtin::Access a);
+    const reader::StorageTexture* StorageTexture(type::TextureDimension d,
+                                                 builtin::TexelFormat f,
+                                                 builtin::Access a);
 
   private:
     struct State;
     std::unique_ptr<State> state;
 };
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_PARSER_TYPE_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_TYPE_H_
diff --git a/src/tint/lang/spirv/reader/parser_type_test.cc b/src/tint/lang/spirv/reader/ast_parser/type_test.cc
similarity index 94%
rename from src/tint/lang/spirv/reader/parser_type_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/type_test.cc
index 6d33c49..ccef49c 100644
--- a/src/tint/lang/spirv/reader/parser_type_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/type_test.cc
@@ -15,12 +15,12 @@
 #include "gtest/gtest.h"
 
 #include "src/tint/lang/core/type/texture_dimension.h"
-#include "src/tint/lang/spirv/reader/parser_type.h"
+#include "src/tint/lang/spirv/reader/ast_parser/type.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
-TEST(SpvParserTypeTest, SameArgumentsGivesSamePointer) {
+TEST(SpirvASTParserTypeTest, SameArgumentsGivesSamePointer) {
     Symbol sym(Symbol(1, {}, "1"));
 
     TypeManager ty;
@@ -49,7 +49,7 @@
                                 builtin::Access::kRead));
 }
 
-TEST(SpvParserTypeTest, DifferentArgumentsGivesDifferentPointer) {
+TEST(SpirvASTParserTypeTest, DifferentArgumentsGivesDifferentPointer) {
     Symbol sym_a(Symbol(1, {}, "1"));
     Symbol sym_b(Symbol(2, {}, "2"));
 
@@ -95,4 +95,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/usage.cc b/src/tint/lang/spirv/reader/ast_parser/usage.cc
similarity index 97%
rename from src/tint/lang/spirv/reader/usage.cc
rename to src/tint/lang/spirv/reader/ast_parser/usage.cc
index 7139832..90d8bb2 100644
--- a/src/tint/lang/spirv/reader/usage.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/usage.cc
@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/usage.h"
+#include "src/tint/lang/spirv/reader/ast_parser/usage.h"
 
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 Usage::Usage() {}
 Usage::Usage(const Usage& other) = default;
@@ -184,4 +184,4 @@
     return ss.str();
 }
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/usage.h b/src/tint/lang/spirv/reader/ast_parser/usage.h
similarity index 95%
rename from src/tint/lang/spirv/reader/usage.h
rename to src/tint/lang/spirv/reader/ast_parser/usage.h
index 2184785..4111ee6 100644
--- a/src/tint/lang/spirv/reader/usage.h
+++ b/src/tint/lang/spirv/reader/ast_parser/usage.h
@@ -12,14 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_USAGE_H_
-#define SRC_TINT_LANG_SPIRV_READER_USAGE_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_USAGE_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_USAGE_H_
 
 #include <string>
 
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 /// Records the properties of a sampler or texture based on how it's used
 /// by image instructions inside function bodies.
@@ -132,6 +132,6 @@
     return u.operator<<(out);
 }
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_USAGE_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_USAGE_H_
diff --git a/src/tint/lang/spirv/reader/usage_test.cc b/src/tint/lang/spirv/reader/ast_parser/usage_test.cc
similarity index 90%
rename from src/tint/lang/spirv/reader/usage_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/usage_test.cc
index 8571d23..e9da7e3 100644
--- a/src/tint/lang/spirv/reader/usage_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/usage_test.cc
@@ -16,15 +16,15 @@
 #include <vector>
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
 
-TEST_F(SpvParserTest, Usage_Trivial_Properties) {
+TEST_F(SpirvASTParserTest, Usage_Trivial_Properties) {
     Usage u;
     EXPECT_TRUE(u.IsValid());
     EXPECT_FALSE(u.IsComplete());
@@ -38,14 +38,14 @@
     EXPECT_FALSE(u.IsStorageWriteTexture());
 }
 
-TEST_F(SpvParserTest, Usage_Trivial_Output) {
+TEST_F(SpirvASTParserTest, Usage_Trivial_Output) {
     utils::StringStream ss;
     Usage u;
     ss << u;
     EXPECT_THAT(ss.str(), Eq("Usage()"));
 }
 
-TEST_F(SpvParserTest, Usage_Equality_OneDifference) {
+TEST_F(SpirvASTParserTest, Usage_Equality_OneDifference) {
     const size_t num_usages = 9u;
     std::vector<Usage> usages(num_usages);
     usages[1].AddSampler();
@@ -69,7 +69,7 @@
     }
 }
 
-TEST_F(SpvParserTest, Usage_Add) {
+TEST_F(SpirvASTParserTest, Usage_Add) {
     // Mix two nontrivial usages.
     Usage a;
     a.AddStorageReadTexture();
@@ -95,7 +95,7 @@
     EXPECT_THAT(ss.str(), Eq("Usage(Sampler( comparison )Texture( read ))"));
 }
 
-TEST_F(SpvParserTest, Usage_AddSampler) {
+TEST_F(SpirvASTParserTest, Usage_AddSampler) {
     utils::StringStream ss;
     Usage u;
     u.AddSampler();
@@ -120,7 +120,7 @@
     EXPECT_TRUE(u == copy);
 }
 
-TEST_F(SpvParserTest, Usage_AddComparisonSampler) {
+TEST_F(SpirvASTParserTest, Usage_AddComparisonSampler) {
     utils::StringStream ss;
     Usage u;
     u.AddComparisonSampler();
@@ -144,7 +144,7 @@
     EXPECT_TRUE(u == copy);
 }
 
-TEST_F(SpvParserTest, Usage_AddTexture) {
+TEST_F(SpirvASTParserTest, Usage_AddTexture) {
     utils::StringStream ss;
     Usage u;
     u.AddTexture();
@@ -168,7 +168,7 @@
     EXPECT_TRUE(u == copy);
 }
 
-TEST_F(SpvParserTest, Usage_AddSampledTexture) {
+TEST_F(SpirvASTParserTest, Usage_AddSampledTexture) {
     utils::StringStream ss;
     Usage u;
     u.AddSampledTexture();
@@ -192,7 +192,7 @@
     EXPECT_TRUE(u == copy);
 }
 
-TEST_F(SpvParserTest, Usage_AddMultisampledTexture) {
+TEST_F(SpirvASTParserTest, Usage_AddMultisampledTexture) {
     utils::StringStream ss;
     Usage u;
     u.AddMultisampledTexture();
@@ -216,7 +216,7 @@
     EXPECT_TRUE(u == copy);
 }
 
-TEST_F(SpvParserTest, Usage_AddDepthTexture) {
+TEST_F(SpirvASTParserTest, Usage_AddDepthTexture) {
     utils::StringStream ss;
     Usage u;
     u.AddDepthTexture();
@@ -240,7 +240,7 @@
     EXPECT_TRUE(u == copy);
 }
 
-TEST_F(SpvParserTest, Usage_AddStorageReadTexture) {
+TEST_F(SpirvASTParserTest, Usage_AddStorageReadTexture) {
     utils::StringStream ss;
     Usage u;
     u.AddStorageReadTexture();
@@ -264,7 +264,7 @@
     EXPECT_TRUE(u == copy);
 }
 
-TEST_F(SpvParserTest, Usage_AddStorageWriteTexture) {
+TEST_F(SpirvASTParserTest, Usage_AddStorageWriteTexture) {
     utils::StringStream ss;
     Usage u;
     u.AddStorageWriteTexture();
@@ -289,4 +289,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser_impl_user_name_test.cc b/src/tint/lang/spirv/reader/ast_parser/user_name_test.cc
similarity index 95%
rename from src/tint/lang/spirv/reader/parser_impl_user_name_test.cc
rename to src/tint/lang/spirv/reader/ast_parser/user_name_test.cc
index 97a5c91..187ea27 100644
--- a/src/tint/lang/spirv/reader/parser_impl_user_name_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/user_name_test.cc
@@ -13,15 +13,15 @@
 // limitations under the License.
 
 #include "gmock/gmock.h"
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
-#include "src/tint/lang/spirv/reader/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 namespace {
 
 using ::testing::Eq;
 
-using SpvParserUserNameTest = SpvParserTest;
+using SpvParserUserNameTest = SpirvASTParserTest;
 
 TEST_F(SpvParserUserNameTest, UserName_RespectOpName) {
     auto p = parser(test::Assemble(R"(
@@ -208,4 +208,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/options.h b/src/tint/lang/spirv/reader/options.h
new file mode 100644
index 0000000..fe74e15
--- /dev/null
+++ b/src/tint/lang/spirv/reader/options.h
@@ -0,0 +1,28 @@
+// 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.
+
+#ifndef SRC_TINT_LANG_SPIRV_READER_OPTIONS_H_
+#define SRC_TINT_LANG_SPIRV_READER_OPTIONS_H_
+
+namespace tint::spirv::reader {
+
+/// Options that control how the SPIR-V parser should behave.
+struct Options {
+    /// Set to `true` to allow calls to derivative builtins in non-uniform control flow.
+    bool allow_non_uniform_derivatives = false;
+};
+
+}  // namespace tint::spirv::reader
+
+#endif  // SRC_TINT_LANG_SPIRV_READER_OPTIONS_H_
diff --git a/src/tint/lang/spirv/reader/parser.cc b/src/tint/lang/spirv/reader/reader.cc
similarity index 90%
rename from src/tint/lang/spirv/reader/parser.cc
rename to src/tint/lang/spirv/reader/reader.cc
index b6efafa..8604ff3 100644
--- a/src/tint/lang/spirv/reader/parser.cc
+++ b/src/tint/lang/spirv/reader/reader.cc
@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/parser.h"
+#include "src/tint/lang/spirv/reader/reader.h"
 
 #include <utility>
 
-#include "src/tint/lang/spirv/reader/parser_impl.h"
+#include "src/tint/lang/spirv/reader/ast_parser/ast_parser.h"
 #include "src/tint/lang/wgsl/ast/transform/decompose_strided_array.h"
 #include "src/tint/lang/wgsl/ast/transform/decompose_strided_matrix.h"
 #include "src/tint/lang/wgsl/ast/transform/fold_trivial_lets.h"
@@ -26,15 +26,15 @@
 #include "src/tint/lang/wgsl/ast/transform/spirv_atomic.h"
 #include "src/tint/lang/wgsl/ast/transform/unshadow.h"
 
-namespace tint::reader::spirv {
+namespace tint::spirv::reader {
 
 Program Parse(const std::vector<uint32_t>& input, const Options& options) {
-    ParserImpl parser(input);
+    ASTParser parser(input);
     bool parsed = parser.Parse();
 
     ProgramBuilder& builder = parser.builder();
     if (!parsed) {
-        // TODO(bclayton): Migrate spirv::ParserImpl to using diagnostics.
+        // TODO(bclayton): Migrate ASTParser to using diagnostics.
         builder.Diagnostics().add_error(diag::System::Reader, parser.error());
         return Program(std::move(builder));
     }
@@ -69,4 +69,4 @@
     return manager.Run(&program, {}, outputs);
 }
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser.h b/src/tint/lang/spirv/reader/reader.h
similarity index 71%
rename from src/tint/lang/spirv/reader/parser.h
rename to src/tint/lang/spirv/reader/reader.h
index b77b161..5840ac4 100644
--- a/src/tint/lang/spirv/reader/parser.h
+++ b/src/tint/lang/spirv/reader/reader.h
@@ -12,20 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_PARSER_H_
-#define SRC_TINT_LANG_SPIRV_READER_PARSER_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_READER_H_
+#define SRC_TINT_LANG_SPIRV_READER_READER_H_
 
 #include <vector>
 
+#include "src/tint/lang/spirv/reader/options.h"
 #include "src/tint/lang/wgsl/program/program.h"
 
-namespace tint::reader::spirv {
-
-/// Options that control how the SPIR-V parser should behave.
-struct Options {
-    /// Set to `true` to allow calls to derivative builtins in non-uniform control flow.
-    bool allow_non_uniform_derivatives = false;
-};
+namespace tint::spirv::reader {
 
 /// Parses the SPIR-V source data, returning the parsed program.
 /// If the source data fails to parse then the returned
@@ -36,6 +31,6 @@
 /// @returns the parsed program
 Program Parse(const std::vector<uint32_t>& input, const Options& options = {});
 
-}  // namespace tint::reader::spirv
+}  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_PARSER_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_READER_H_
diff --git a/src/tint/test_main.cc b/src/tint/test_main.cc
index 198613a..1c75902 100644
--- a/src/tint/test_main.cc
+++ b/src/tint/test_main.cc
@@ -17,7 +17,7 @@
 #include "tint/tint.h"
 
 #if TINT_BUILD_SPV_READER
-#include "src/tint/lang/spirv/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/spirv/reader/ast_parser/test_helper.h"
 #endif
 
 namespace {
@@ -60,7 +60,7 @@
 
 #if TINT_BUILD_SPV_READER
     if (flags.spirv_reader_dump_converted) {
-        tint::reader::spirv::test::DumpSuccessfullyConvertedSpirv();
+        tint::spirv::reader::test::DumpSuccessfullyConvertedSpirv();
     }
 #endif  // TINT_BUILD_SPV_READER