Rename StorageClass to AddressSpace.

This CL updates the internals to use AddressSpace instead of the old
StorageClass name.

Bug: tint:1404
Change-Id: Iecc208e839453437f4d630f65e0152206a52db7e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/104420
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Auto-Submit: Dan Sinclair <dsinclair@chromium.org>
diff --git a/docs/tint/diagnostics_guide.md b/docs/tint/diagnostics_guide.md
index fc8fa22..72e5d4c 100644
--- a/docs/tint/diagnostics_guide.md
+++ b/docs/tint/diagnostics_guide.md
@@ -63,7 +63,7 @@
 **Don't:**
 
 ```
-shader.wgsl:5:11 error: type cannot be used in storage class 'storage' as it is non-host-shareable
+shader.wgsl:5:11 error: type cannot be used in address space 'storage' as it is non-host-shareable
 
     cond : bool;
            ^^^^
@@ -72,7 +72,7 @@
 **Do:**
 
 ```
-shader.wgsl:5:11 error: type cannot be used in storage class 'storage' as it is non-host-shareable
+shader.wgsl:5:11 error: type cannot be used in address space 'storage' as it is non-host-shareable
 
     cond : bool;
            ^^^^
diff --git a/docs/tint/extensions/chromium_experimental_push_constant.md b/docs/tint/extensions/chromium_experimental_push_constant.md
index d10e1ee..6f23c1a 100644
--- a/docs/tint/extensions/chromium_experimental_push_constant.md
+++ b/docs/tint/extensions/chromium_experimental_push_constant.md
@@ -12,7 +12,7 @@
 
 ## Pseudo-specification
 
-This extension adds a new `push_constant` storage class that's only allowed on global variable declarations.
+This extension adds a new `push_constant` address space that's only allowed on global variable declarations.
 Push constant variables must only contain 32bit data types (or aggregates of such types).
 Push constant variable declarations must not have an initializer.
 It is an error for a entry point to statically use more than one `push_constant` variable.
diff --git a/docs/tint/spirv-input-output-variables.md b/docs/tint/spirv-input-output-variables.md
index 0ba4ae4..c9d6932 100644
--- a/docs/tint/spirv-input-output-variables.md
+++ b/docs/tint/spirv-input-output-variables.md
@@ -15,7 +15,7 @@
 ## Vulkan SPIR-V today
 
 SPIR-V for Vulkan models inputs and outputs as module-scope variables in
-the Input and Output storage classes, respectively.
+the Input and Output address spaces, respectively.
 
 The `OpEntryPoint` instruction has a list of module-scope variables that must
 be a superset of all the input and output variables that are statically
diff --git a/docs/tint/translations.md b/docs/tint/translations.md
index 83370b6..e7f7576 100644
--- a/docs/tint/translations.md
+++ b/docs/tint/translations.md
@@ -141,7 +141,7 @@
 ## SPIR-V
 TODO(dsinclair): Nested if's
 
-# Storage classes
+# Address spaces
 TODO(dsinclair): do ...
 
 # Storage buffers
@@ -155,7 +155,7 @@
 ## MSL
 TODO(dsinclair): Rewrite with bools
 
-# Input / Output storage class
+# Input / Output address spaces
 ## HLSL
 TODO(dsinclair): Structs and params
 
diff --git a/src/dawn/native/ComputePassEncoder.cpp b/src/dawn/native/ComputePassEncoder.cpp
index 1d3c2b3..4c8d9ca 100644
--- a/src/dawn/native/ComputePassEncoder.cpp
+++ b/src/dawn/native/ComputePassEncoder.cpp
@@ -42,7 +42,7 @@
 
     // TODO(https://crbug.com/dawn/1108): Propagate validation feedback from this
     // shader in various failure modes.
-    // Type 'bool' cannot be used in storage class 'uniform' as it is non-host-shareable.
+    // Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable.
     Ref<ShaderModuleBase> shaderModule;
     DAWN_TRY_ASSIGN(shaderModule, utils::CreateShaderModule(device, R"(
                 struct UniformParams {
@@ -258,7 +258,7 @@
         kDispatchIndirectSize + clientOffsetFromAlignedBoundary;
 
     // Neither 'enableValidation' nor 'duplicateNumWorkgroups' can be declared as 'bool' as
-    // currently in WGSL type 'bool' cannot be used in storage class 'uniform' as 'it is
+    // currently in WGSL type 'bool' cannot be used in address space 'uniform' as 'it is
     // non-host-shareable'.
     struct UniformParams {
         uint32_t maxComputeWorkgroupsPerDimension;
diff --git a/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp b/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp
index 6808574..0ceca8d 100644
--- a/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp
+++ b/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp
@@ -34,18 +34,18 @@
     return str;
 }
 
-// StorageClass is an enumerator of storage classes used by ComputeLayoutMemoryBufferTests.Fields
-enum class StorageClass {
+// AddressSpace is an enumerator of address spaces used by ComputeLayoutMemoryBufferTests.Fields
+enum class AddressSpace {
     Uniform,
     Storage,
 };
 
-std::ostream& operator<<(std::ostream& o, StorageClass storageClass) {
-    switch (storageClass) {
-        case StorageClass::Uniform:
+std::ostream& operator<<(std::ostream& o, AddressSpace addressSpace) {
+    switch (addressSpace) {
+        case AddressSpace::Uniform:
             o << "uniform";
             break;
-        case StorageClass::Storage:
+        case AddressSpace::Storage:
             o << "storage";
             break;
     }
@@ -441,7 +441,7 @@
     queue.Submit(1, &commands);
 }
 
-DAWN_TEST_PARAM_STRUCT(ComputeLayoutMemoryBufferTestParams, StorageClass, Field);
+DAWN_TEST_PARAM_STRUCT(ComputeLayoutMemoryBufferTestParams, AddressSpace, Field);
 
 class ComputeLayoutMemoryBufferTests
     : public DawnTestWithParams<ComputeLayoutMemoryBufferTestParams> {
@@ -472,7 +472,7 @@
 
     const Field& field = GetParam().mField;
 
-    const bool isUniform = GetParam().mStorageClass == StorageClass::Uniform;
+    const bool isUniform = GetParam().mAddressSpace == AddressSpace::Uniform;
 
     std::string shader = R"(
 struct Data {
@@ -619,7 +619,7 @@
         return;
     }
 
-    const bool isUniform = GetParam().mStorageClass == StorageClass::Uniform;
+    const bool isUniform = GetParam().mAddressSpace == AddressSpace::Uniform;
 
     std::string shader = R"(
 @group(0) @binding(0) var<{input_qualifiers}> input : {field_type};
@@ -685,7 +685,7 @@
             OpenGLBackend(),
             OpenGLESBackend(),
         },
-        {StorageClass::Storage, StorageClass::Uniform},
+        {AddressSpace::Storage, AddressSpace::Uniform},
         {
             // See https://www.w3.org/TR/WGSL/#alignment-and-size
             // Scalar types with no custom alignment or size
@@ -851,7 +851,7 @@
 
     std::vector<ComputeLayoutMemoryBufferTestParams> filtered;
     for (auto param : params) {
-        if (param.mStorageClass != StorageClass::Storage && param.mField.IsStorageBufferOnly()) {
+        if (param.mAddressSpace != AddressSpace::Storage && param.mField.IsStorageBufferOnly()) {
             continue;
         }
         filtered.emplace_back(param);
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 7fcc8c1..07c5350 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -180,6 +180,8 @@
   sources = [
     "ast/access.cc",
     "ast/access.h",
+    "ast/address_space.cc",
+    "ast/address_space.h",
     "ast/alias.cc",
     "ast/alias.h",
     "ast/array.cc",
@@ -312,8 +314,6 @@
     "ast/statement.h",
     "ast/static_assert.cc",
     "ast/static_assert.h",
-    "ast/storage_class.cc",
-    "ast/storage_class.h",
     "ast/storage_texture.cc",
     "ast/storage_texture.h",
     "ast/stride_attribute.cc",
@@ -998,6 +998,7 @@
 
   tint_unittests_source_set("tint_unittests_ast_src") {
     sources = [
+      "ast/address_space_test.cc",
       "ast/alias_test.cc",
       "ast/array_test.cc",
       "ast/assignment_statement_test.cc",
@@ -1054,7 +1055,6 @@
       "ast/sampler_test.cc",
       "ast/stage_attribute_test.cc",
       "ast/static_assert_test.cc",
-      "ast/storage_class_test.cc",
       "ast/storage_texture_test.cc",
       "ast/stride_attribute_test.cc",
       "ast/struct_member_align_attribute_test.cc",
@@ -1097,6 +1097,8 @@
 
   tint_unittests_source_set("tint_unittests_resolver_src") {
     sources = [
+      "resolver/address_space_layout_validation_test.cc",
+      "resolver/address_space_validation_test.cc",
       "resolver/array_accessor_test.cc",
       "resolver/assignment_validation_test.cc",
       "resolver/atomics_test.cc",
@@ -1133,11 +1135,9 @@
       "resolver/side_effects_test.cc",
       "resolver/source_variable_test.cc",
       "resolver/static_assert_test.cc",
-      "resolver/storage_class_layout_validation_test.cc",
-      "resolver/storage_class_validation_test.cc",
+      "resolver/struct_address_space_use_test.cc",
       "resolver/struct_layout_test.cc",
       "resolver/struct_pipeline_stage_use_test.cc",
-      "resolver/struct_storage_class_use_test.cc",
       "resolver/type_constructor_validation_test.cc",
       "resolver/type_validation_test.cc",
       "resolver/uniformity_test.cc",
@@ -1354,6 +1354,7 @@
     sources = [
       "reader/wgsl/lexer_test.cc",
       "reader/wgsl/parser_impl_additive_expression_test.cc",
+      "reader/wgsl/parser_impl_address_space_test.cc",
       "reader/wgsl/parser_impl_argument_expression_list_test.cc",
       "reader/wgsl/parser_impl_assignment_stmt_test.cc",
       "reader/wgsl/parser_impl_bitwise_expression_test.cc",
@@ -1400,7 +1401,6 @@
       "reader/wgsl/parser_impl_singular_expression_test.cc",
       "reader/wgsl/parser_impl_statement_test.cc",
       "reader/wgsl/parser_impl_statements_test.cc",
-      "reader/wgsl/parser_impl_storage_class_test.cc",
       "reader/wgsl/parser_impl_storage_texture_test.cc",
       "reader/wgsl/parser_impl_struct_attribute_decl_test.cc",
       "reader/wgsl/parser_impl_struct_body_decl_test.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index bcb4d4d..10b0686 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -182,8 +182,8 @@
   ast/statement.h
   ast/static_assert.cc
   ast/static_assert.h
-  ast/storage_class.cc
-  ast/storage_class.h
+  ast/address_space.cc
+  ast/address_space.h
   ast/storage_texture.cc
   ast/storage_texture.h
   ast/stride_attribute.cc
@@ -747,7 +747,7 @@
     ast/sampler_test.cc
     ast/stage_attribute_test.cc
     ast/static_assert_test.cc
-    ast/storage_class_test.cc
+    ast/address_space_test.cc
     ast/storage_texture_test.cc
     ast/stride_attribute_test.cc
     ast/struct_member_align_attribute_test.cc
@@ -814,11 +814,11 @@
     resolver/side_effects_test.cc
     resolver/static_assert_test.cc
     resolver/source_variable_test.cc
-    resolver/storage_class_layout_validation_test.cc
-    resolver/storage_class_validation_test.cc
+    resolver/address_space_layout_validation_test.cc
+    resolver/address_space_validation_test.cc
     resolver/struct_layout_test.cc
     resolver/struct_pipeline_stage_use_test.cc
-    resolver/struct_storage_class_use_test.cc
+    resolver/struct_address_space_use_test.cc
     resolver/type_constructor_validation_test.cc
     resolver/type_validation_test.cc
     resolver/validation_test.cc
@@ -992,7 +992,7 @@
       reader/wgsl/parser_impl_singular_expression_test.cc
       reader/wgsl/parser_impl_statement_test.cc
       reader/wgsl/parser_impl_statements_test.cc
-      reader/wgsl/parser_impl_storage_class_test.cc
+      reader/wgsl/parser_impl_address_space_test.cc
       reader/wgsl/parser_impl_storage_texture_test.cc
       reader/wgsl/parser_impl_struct_body_decl_test.cc
       reader/wgsl/parser_impl_struct_decl_test.cc
@@ -1300,7 +1300,7 @@
   set(TINT_BENCHMARK_SRC
     "castable_bench.cc"
     "ast/extension_bench.cc"
-    "ast/storage_class_bench.cc"
+    "ast/address_space_bench.cc"
     "ast/texel_format_bench.cc"
     "bench/benchmark.cc"
     "reader/wgsl/parser_bench.cc"
diff --git a/src/tint/ast/storage_class.cc b/src/tint/ast/address_space.cc
similarity index 62%
rename from src/tint/ast/storage_class.cc
rename to src/tint/ast/address_space.cc
index 450067b..a55fb87 100644
--- a/src/tint/ast/storage_class.cc
+++ b/src/tint/ast/address_space.cc
@@ -15,63 +15,63 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/storage_class.cc.tmpl
+//   src/tint/ast/address_space.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 
 namespace tint::ast {
 
-/// ParseStorageClass parses a StorageClass from a string.
+/// ParseAddressSpace parses a AddressSpace from a string.
 /// @param str the string to parse
-/// @returns the parsed enum, or StorageClass::kInvalid if the string could not be parsed.
-StorageClass ParseStorageClass(std::string_view str) {
+/// @returns the parsed enum, or AddressSpace::kInvalid if the string could not be parsed.
+AddressSpace ParseAddressSpace(std::string_view str) {
     if (str == "function") {
-        return StorageClass::kFunction;
+        return AddressSpace::kFunction;
     }
     if (str == "private") {
-        return StorageClass::kPrivate;
+        return AddressSpace::kPrivate;
     }
     if (str == "workgroup") {
-        return StorageClass::kWorkgroup;
+        return AddressSpace::kWorkgroup;
     }
     if (str == "uniform") {
-        return StorageClass::kUniform;
+        return AddressSpace::kUniform;
     }
     if (str == "storage") {
-        return StorageClass::kStorage;
+        return AddressSpace::kStorage;
     }
     if (str == "push_constant") {
-        return StorageClass::kPushConstant;
+        return AddressSpace::kPushConstant;
     }
-    return StorageClass::kInvalid;
+    return AddressSpace::kInvalid;
 }
 
-std::ostream& operator<<(std::ostream& out, StorageClass value) {
+std::ostream& operator<<(std::ostream& out, AddressSpace value) {
     switch (value) {
-        case StorageClass::kInvalid:
+        case AddressSpace::kInvalid:
             return out << "invalid";
-        case StorageClass::kNone:
+        case AddressSpace::kNone:
             return out << "none";
-        case StorageClass::kFunction:
+        case AddressSpace::kFunction:
             return out << "function";
-        case StorageClass::kPrivate:
+        case AddressSpace::kPrivate:
             return out << "private";
-        case StorageClass::kWorkgroup:
+        case AddressSpace::kWorkgroup:
             return out << "workgroup";
-        case StorageClass::kUniform:
+        case AddressSpace::kUniform:
             return out << "uniform";
-        case StorageClass::kStorage:
+        case AddressSpace::kStorage:
             return out << "storage";
-        case StorageClass::kPushConstant:
+        case AddressSpace::kPushConstant:
             return out << "push_constant";
-        case StorageClass::kHandle:
+        case AddressSpace::kHandle:
             return out << "handle";
-        case StorageClass::kIn:
+        case AddressSpace::kIn:
             return out << "in";
-        case StorageClass::kOut:
+        case AddressSpace::kOut:
             return out << "out";
     }
     return out << "<unknown>";
diff --git a/src/tint/ast/storage_class.cc.tmpl b/src/tint/ast/address_space.cc.tmpl
similarity index 77%
rename from src/tint/ast/storage_class.cc.tmpl
rename to src/tint/ast/address_space.cc.tmpl
index e2903b7..7295f14 100644
--- a/src/tint/ast/storage_class.cc.tmpl
+++ b/src/tint/ast/address_space.cc.tmpl
@@ -1,6 +1,6 @@
 {{- /*
 --------------------------------------------------------------------------------
-Template file for use with tools/src/cmd/gen to generate storage_class.cc
+Template file for use with tools/src/cmd/gen to generate address_space.cc
 
 To update the generated file, run:
     ./tools/run gen
@@ -12,9 +12,9 @@
 */ -}}
 
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
-{{- $enum := (Sem.Enum "storage_class") -}}
+{{- $enum := (Sem.Enum "address_space") -}}
 
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 
 namespace tint::ast {
 
diff --git a/src/tint/ast/storage_class.h b/src/tint/ast/address_space.h
similarity index 63%
rename from src/tint/ast/storage_class.h
rename to src/tint/ast/address_space.h
index 43e41e1..210dc7f 100644
--- a/src/tint/ast/storage_class.h
+++ b/src/tint/ast/address_space.h
@@ -15,20 +15,20 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/storage_class.h.tmpl
+//   src/tint/ast/address_space.h.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#ifndef SRC_TINT_AST_STORAGE_CLASS_H_
-#define SRC_TINT_AST_STORAGE_CLASS_H_
+#ifndef SRC_TINT_AST_ADDRESS_SPACE_H_
+#define SRC_TINT_AST_ADDRESS_SPACE_H_
 
 #include <ostream>
 
 namespace tint::ast {
 
-/// Storage class of a given pointer.
-enum class StorageClass {
+/// Address space of a given pointer.
+enum class AddressSpace {
     kInvalid,
     kNone,  // Tint-internal enum entry - not parsed
     kFunction,
@@ -43,23 +43,24 @@
 };
 
 /// @param out the std::ostream to write to
-/// @param value the StorageClass
+/// @param value the AddressSpace
 /// @returns `out` so calls can be chained
-std::ostream& operator<<(std::ostream& out, StorageClass value);
+std::ostream& operator<<(std::ostream& out, AddressSpace value);
 
-/// ParseStorageClass parses a StorageClass from a string.
+/// ParseAddressSpace parses a AddressSpace from a string.
 /// @param str the string to parse
-/// @returns the parsed enum, or StorageClass::kInvalid if the string could not be parsed.
-StorageClass ParseStorageClass(std::string_view str);
+/// @returns the parsed enum, or AddressSpace::kInvalid if the string could not be parsed.
+AddressSpace ParseAddressSpace(std::string_view str);
 
-/// @returns true if the StorageClass is host-shareable
-/// @param sc the StorageClass
+/// @returns true if the AddressSpace is host-shareable
+/// @param address_space the AddressSpace
 /// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
-inline bool IsHostShareable(StorageClass sc) {
-    return sc == ast::StorageClass::kUniform || sc == ast::StorageClass::kStorage ||
-           sc == ast::StorageClass::kPushConstant;
+inline bool IsHostShareable(AddressSpace address_space) {
+    return address_space == ast::AddressSpace::kUniform ||
+           address_space == ast::AddressSpace::kStorage ||
+           address_space == ast::AddressSpace::kPushConstant;
 }
 
 }  // namespace tint::ast
 
-#endif  // SRC_TINT_AST_STORAGE_CLASS_H_
+#endif  // SRC_TINT_AST_ADDRESS_SPACE_H_
diff --git a/src/tint/ast/address_space.h.tmpl b/src/tint/ast/address_space.h.tmpl
new file mode 100644
index 0000000..0726ef3
--- /dev/null
+++ b/src/tint/ast/address_space.h.tmpl
@@ -0,0 +1,37 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate address_space.h
+
+To update the generated file, run:
+    ./tools/run gen
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "address_space") -}}
+
+#ifndef SRC_TINT_AST_ADDRESS_SPACE_H_
+#define SRC_TINT_AST_ADDRESS_SPACE_H_
+
+#include <ostream>
+
+namespace tint::ast {
+
+/// Address space of a given pointer.
+{{ Eval "DeclareEnum" $enum}}
+
+/// @returns true if the AddressSpace is host-shareable
+/// @param address_space the AddressSpace
+/// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
+inline bool IsHostShareable(AddressSpace address_space) {
+    return address_space == ast::AddressSpace::kUniform || address_space == ast::AddressSpace::kStorage ||
+           address_space == ast::AddressSpace::kPushConstant;
+}
+
+}  // namespace tint::ast
+
+#endif  // SRC_TINT_AST_ADDRESS_SPACE_H_
diff --git a/src/tint/ast/storage_class_bench.cc b/src/tint/ast/address_space_bench.cc
similarity index 89%
rename from src/tint/ast/storage_class_bench.cc
rename to src/tint/ast/address_space_bench.cc
index 00095c2..364d015 100644
--- a/src/tint/ast/storage_class_bench.cc
+++ b/src/tint/ast/address_space_bench.cc
@@ -15,12 +15,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 // File generated by tools/src/cmd/gen
 // using the template:
-//   src/tint/ast/storage_class_bench.cc.tmpl
+//   src/tint/ast/address_space_bench.cc.tmpl
 //
 // Do not modify this file directly
 ////////////////////////////////////////////////////////////////////////////////
 
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 
 #include <array>
 
@@ -29,7 +29,7 @@
 namespace tint::ast {
 namespace {
 
-void StorageClassParser(::benchmark::State& state) {
+void AddressSpaceParser(::benchmark::State& state) {
     std::array kStrings{
         "fccnctin",
         "ucti3",
@@ -76,13 +76,13 @@
     };
     for (auto _ : state) {
         for (auto& str : kStrings) {
-            auto result = ParseStorageClass(str);
+            auto result = ParseAddressSpace(str);
             benchmark::DoNotOptimize(result);
         }
     }
 }
 
-BENCHMARK(StorageClassParser);
+BENCHMARK(AddressSpaceParser);
 
 }  // namespace
 }  // namespace tint::ast
diff --git a/src/tint/ast/storage_class_bench.cc.tmpl b/src/tint/ast/address_space_bench.cc.tmpl
similarity index 78%
rename from src/tint/ast/storage_class_bench.cc.tmpl
rename to src/tint/ast/address_space_bench.cc.tmpl
index d9ea8cb..4644944 100644
--- a/src/tint/ast/storage_class_bench.cc.tmpl
+++ b/src/tint/ast/address_space_bench.cc.tmpl
@@ -1,6 +1,6 @@
 {{- /*
 --------------------------------------------------------------------------------
-Template file for use with tools/src/cmd/gen to generate storage_class_bench.cc
+Template file for use with tools/src/cmd/gen to generate address_space_bench.cc
 
 To update the generated file, run:
     ./tools/run gen
@@ -12,9 +12,9 @@
 */ -}}
 
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
-{{- $enum := (Sem.Enum "storage_class") -}}
+{{- $enum := (Sem.Enum "address_space") -}}
 
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 
 #include <array>
 
diff --git a/src/tint/ast/address_space_test.cc b/src/tint/ast/address_space_test.cc
new file mode 100644
index 0000000..86a8e40
--- /dev/null
+++ b/src/tint/ast/address_space_test.cc
@@ -0,0 +1,86 @@
+// Copyright 2022 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.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+//   src/tint/ast/address_space_test.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/ast/address_space.h"
+
+#include <string>
+
+#include "src/tint/ast/test_helper.h"
+#include "src/tint/utils/string.h"
+
+namespace tint::ast {
+namespace {
+
+namespace parse_print_tests {
+
+struct Case {
+    const char* string;
+    AddressSpace value;
+};
+
+inline std::ostream& operator<<(std::ostream& out, Case c) {
+    return out << "'" << std::string(c.string) << "'";
+}
+
+static constexpr Case kValidCases[] = {
+    {"function", AddressSpace::kFunction},   {"private", AddressSpace::kPrivate},
+    {"workgroup", AddressSpace::kWorkgroup}, {"uniform", AddressSpace::kUniform},
+    {"storage", AddressSpace::kStorage},     {"push_constant", AddressSpace::kPushConstant},
+};
+
+static constexpr Case kInvalidCases[] = {
+    {"fccnctin", AddressSpace::kInvalid},       {"ucti3", AddressSpace::kInvalid},
+    {"functVon", AddressSpace::kInvalid},       {"priv1te", AddressSpace::kInvalid},
+    {"pqiJate", AddressSpace::kInvalid},        {"privat7ll", AddressSpace::kInvalid},
+    {"workroppqHH", AddressSpace::kInvalid},    {"workru", AddressSpace::kInvalid},
+    {"wbkgGoup", AddressSpace::kInvalid},       {"unifiivm", AddressSpace::kInvalid},
+    {"8WWiform", AddressSpace::kInvalid},       {"uxxform", AddressSpace::kInvalid},
+    {"sXraggg", AddressSpace::kInvalid},        {"traXe", AddressSpace::kInvalid},
+    {"stor3ge", AddressSpace::kInvalid},        {"push_constanE", AddressSpace::kInvalid},
+    {"push_TTPnstant", AddressSpace::kInvalid}, {"puxxdh_constan", AddressSpace::kInvalid},
+};
+
+using AddressSpaceParseTest = testing::TestWithParam<Case>;
+
+TEST_P(AddressSpaceParseTest, Parse) {
+    const char* string = GetParam().string;
+    AddressSpace expect = GetParam().value;
+    EXPECT_EQ(expect, ParseAddressSpace(string));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, AddressSpaceParseTest, testing::ValuesIn(kValidCases));
+INSTANTIATE_TEST_SUITE_P(InvalidCases, AddressSpaceParseTest, testing::ValuesIn(kInvalidCases));
+
+using AddressSpacePrintTest = testing::TestWithParam<Case>;
+
+TEST_P(AddressSpacePrintTest, Print) {
+    AddressSpace value = GetParam().value;
+    const char* expect = GetParam().string;
+    EXPECT_EQ(expect, utils::ToString(value));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, AddressSpacePrintTest, testing::ValuesIn(kValidCases));
+
+}  // namespace parse_print_tests
+
+}  // namespace
+}  // namespace tint::ast
diff --git a/src/tint/ast/storage_class_test.cc.tmpl b/src/tint/ast/address_space_test.cc.tmpl
similarity index 79%
rename from src/tint/ast/storage_class_test.cc.tmpl
rename to src/tint/ast/address_space_test.cc.tmpl
index 3696aab..2967f73 100644
--- a/src/tint/ast/storage_class_test.cc.tmpl
+++ b/src/tint/ast/address_space_test.cc.tmpl
@@ -1,6 +1,6 @@
 {{- /*
 --------------------------------------------------------------------------------
-Template file for use with tools/src/cmd/gen to generate storage_class_test.cc
+Template file for use with tools/src/cmd/gen to generate address_space_test.cc
 
 To update the generated file, run:
     ./tools/run gen
@@ -12,9 +12,9 @@
 */ -}}
 
 {{- Import "src/tint/templates/enums.tmpl.inc" -}}
-{{- $enum := (Sem.Enum "storage_class") -}}
+{{- $enum := (Sem.Enum "address_space") -}}
 
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 
 #include <string>
 
diff --git a/src/tint/ast/disable_validation_attribute.cc b/src/tint/ast/disable_validation_attribute.cc
index 1f58799..2ae8c16 100644
--- a/src/tint/ast/disable_validation_attribute.cc
+++ b/src/tint/ast/disable_validation_attribute.cc
@@ -33,8 +33,8 @@
             return "disable_validation__function_has_no_body";
         case DisabledValidation::kBindingPointCollision:
             return "disable_validation__binding_point_collision";
-        case DisabledValidation::kIgnoreStorageClass:
-            return "disable_validation__ignore_storage_class";
+        case DisabledValidation::kIgnoreAddressSpace:
+            return "disable_validation__ignore_address_space";
         case DisabledValidation::kEntryPointParameter:
             return "disable_validation__entry_point_parameter";
         case DisabledValidation::kFunctionParameter:
diff --git a/src/tint/ast/disable_validation_attribute.h b/src/tint/ast/disable_validation_attribute.h
index a109d18..d4c7455 100644
--- a/src/tint/ast/disable_validation_attribute.h
+++ b/src/tint/ast/disable_validation_attribute.h
@@ -29,9 +29,9 @@
     /// When applied to a module-scoped variable, the validator will not complain if two resource
     /// variables have the same binding points.
     kBindingPointCollision,
-    /// When applied to a variable, the validator will not complain about the declared storage
-    /// class.
-    kIgnoreStorageClass,
+    /// When applied to a variable, the validator will not complain about the declared address
+    /// space.
+    kIgnoreAddressSpace,
     /// When applied to an entry-point function parameter, the validator will not check for entry IO
     /// attributes.
     kEntryPointParameter,
diff --git a/src/tint/ast/module_test.cc b/src/tint/ast/module_test.cc
index 3093a16..c34805e 100644
--- a/src/tint/ast/module_test.cc
+++ b/src/tint/ast/module_test.cc
@@ -72,7 +72,7 @@
         {
             ProgramBuilder b1;
             ProgramBuilder b2;
-            b1.AST().AddGlobalVariable(b2.Var("var", b2.ty.i32(), ast::StorageClass::kPrivate));
+            b1.AST().AddGlobalVariable(b2.Var("var", b2.ty.i32(), ast::AddressSpace::kPrivate));
         },
         "internal compiler error");
 }
@@ -92,7 +92,7 @@
         ProgramBuilder b;
         b.Func("F", {}, b.ty.void_(), {});
         b.Alias("A", b.ty.u32());
-        b.GlobalVar("V", b.ty.i32(), ast::StorageClass::kPrivate);
+        b.GlobalVar("V", b.ty.i32(), ast::AddressSpace::kPrivate);
         return Program(std::move(b));
     }();
 
diff --git a/src/tint/ast/pointer.cc b/src/tint/ast/pointer.cc
index 796fe85..71b7004 100644
--- a/src/tint/ast/pointer.cc
+++ b/src/tint/ast/pointer.cc
@@ -24,15 +24,15 @@
                  NodeID nid,
                  const Source& src,
                  const Type* const subtype,
-                 ast::StorageClass sc,
+                 ast::AddressSpace addr_space,
                  ast::Access ac)
-    : Base(pid, nid, src), type(subtype), storage_class(sc), access(ac) {}
+    : Base(pid, nid, src), type(subtype), address_space(addr_space), access(ac) {}
 
 std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
     std::ostringstream out;
     out << "ptr<";
-    if (storage_class != ast::StorageClass::kNone) {
-        out << storage_class << ", ";
+    if (address_space != ast::AddressSpace::kNone) {
+        out << address_space << ", ";
     }
     out << type->FriendlyName(symbols);
     if (access != ast::Access::kUndefined) {
@@ -50,7 +50,7 @@
     // Clone arguments outside of create() call to have deterministic ordering
     auto src = ctx->Clone(source);
     auto* ty = ctx->Clone(type);
-    return ctx->dst->create<Pointer>(src, ty, storage_class, access);
+    return ctx->dst->create<Pointer>(src, ty, address_space, access);
 }
 
 }  // namespace tint::ast
diff --git a/src/tint/ast/pointer.h b/src/tint/ast/pointer.h
index 61eff88..0e1e090 100644
--- a/src/tint/ast/pointer.h
+++ b/src/tint/ast/pointer.h
@@ -18,7 +18,7 @@
 #include <string>
 
 #include "src/tint/ast/access.h"
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/type.h"
 
 namespace tint::ast {
@@ -31,13 +31,13 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param subtype the pointee type
-    /// @param storage_class the storage class of the pointer
+    /// @param address_space the address space of the pointer
     /// @param access the access control of the pointer
     Pointer(ProgramID pid,
             NodeID nid,
             const Source& src,
             const Type* const subtype,
-            ast::StorageClass storage_class,
+            ast::AddressSpace address_space,
             ast::Access access);
     /// Move constructor
     Pointer(Pointer&&);
@@ -56,8 +56,8 @@
     /// The pointee type
     const Type* const type;
 
-    /// The storage class of the pointer
-    ast::StorageClass const storage_class;
+    /// The address space of the pointer
+    ast::AddressSpace const address_space;
 
     /// The access control of the pointer
     ast::Access const access;
diff --git a/src/tint/ast/pointer_test.cc b/src/tint/ast/pointer_test.cc
index dbfd3b0..aea260a 100644
--- a/src/tint/ast/pointer_test.cc
+++ b/src/tint/ast/pointer_test.cc
@@ -24,21 +24,21 @@
 
 TEST_F(AstPointerTest, Creation) {
     auto* i32 = create<I32>();
-    auto* p = create<Pointer>(i32, ast::StorageClass::kStorage, Access::kRead);
+    auto* p = create<Pointer>(i32, ast::AddressSpace::kStorage, Access::kRead);
     EXPECT_EQ(p->type, i32);
-    EXPECT_EQ(p->storage_class, ast::StorageClass::kStorage);
+    EXPECT_EQ(p->address_space, ast::AddressSpace::kStorage);
     EXPECT_EQ(p->access, Access::kRead);
 }
 
 TEST_F(AstPointerTest, FriendlyName) {
     auto* i32 = create<I32>();
-    auto* p = create<Pointer>(i32, ast::StorageClass::kWorkgroup, Access::kUndefined);
+    auto* p = create<Pointer>(i32, ast::AddressSpace::kWorkgroup, Access::kUndefined);
     EXPECT_EQ(p->FriendlyName(Symbols()), "ptr<workgroup, i32>");
 }
 
 TEST_F(AstPointerTest, FriendlyNameWithAccess) {
     auto* i32 = create<I32>();
-    auto* p = create<Pointer>(i32, ast::StorageClass::kStorage, Access::kReadWrite);
+    auto* p = create<Pointer>(i32, ast::AddressSpace::kStorage, Access::kReadWrite);
     EXPECT_EQ(p->FriendlyName(Symbols()), "ptr<storage, i32, read_write>");
 }
 
diff --git a/src/tint/ast/storage_class.h.tmpl b/src/tint/ast/storage_class.h.tmpl
deleted file mode 100644
index c21d6f6..0000000
--- a/src/tint/ast/storage_class.h.tmpl
+++ /dev/null
@@ -1,37 +0,0 @@
-{{- /*
---------------------------------------------------------------------------------
-Template file for use with tools/src/cmd/gen to generate storage_class.h
-
-To update the generated file, run:
-    ./tools/run gen
-
-See:
-* tools/src/cmd/gen for structures used by this template
-* https://golang.org/pkg/text/template/ for documentation on the template syntax
---------------------------------------------------------------------------------
-*/ -}}
-
-{{- Import "src/tint/templates/enums.tmpl.inc" -}}
-{{- $enum := (Sem.Enum "storage_class") -}}
-
-#ifndef SRC_TINT_AST_STORAGE_CLASS_H_
-#define SRC_TINT_AST_STORAGE_CLASS_H_
-
-#include <ostream>
-
-namespace tint::ast {
-
-/// Storage class of a given pointer.
-{{ Eval "DeclareEnum" $enum}}
-
-/// @returns true if the StorageClass is host-shareable
-/// @param sc the StorageClass
-/// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
-inline bool IsHostShareable(StorageClass sc) {
-    return sc == ast::StorageClass::kUniform || sc == ast::StorageClass::kStorage ||
-           sc == ast::StorageClass::kPushConstant;
-}
-
-}  // namespace tint::ast
-
-#endif  // SRC_TINT_AST_STORAGE_CLASS_H_
diff --git a/src/tint/ast/storage_class_test.cc b/src/tint/ast/storage_class_test.cc
deleted file mode 100644
index 1d12d45..0000000
--- a/src/tint/ast/storage_class_test.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2022 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.
-
-////////////////////////////////////////////////////////////////////////////////
-// File generated by tools/src/cmd/gen
-// using the template:
-//   src/tint/ast/storage_class_test.cc.tmpl
-//
-// Do not modify this file directly
-////////////////////////////////////////////////////////////////////////////////
-
-#include "src/tint/ast/storage_class.h"
-
-#include <string>
-
-#include "src/tint/ast/test_helper.h"
-#include "src/tint/utils/string.h"
-
-namespace tint::ast {
-namespace {
-
-namespace parse_print_tests {
-
-struct Case {
-    const char* string;
-    StorageClass value;
-};
-
-inline std::ostream& operator<<(std::ostream& out, Case c) {
-    return out << "'" << std::string(c.string) << "'";
-}
-
-static constexpr Case kValidCases[] = {
-    {"function", StorageClass::kFunction},   {"private", StorageClass::kPrivate},
-    {"workgroup", StorageClass::kWorkgroup}, {"uniform", StorageClass::kUniform},
-    {"storage", StorageClass::kStorage},     {"push_constant", StorageClass::kPushConstant},
-};
-
-static constexpr Case kInvalidCases[] = {
-    {"fccnctin", StorageClass::kInvalid},       {"ucti3", StorageClass::kInvalid},
-    {"functVon", StorageClass::kInvalid},       {"priv1te", StorageClass::kInvalid},
-    {"pqiJate", StorageClass::kInvalid},        {"privat7ll", StorageClass::kInvalid},
-    {"workroppqHH", StorageClass::kInvalid},    {"workru", StorageClass::kInvalid},
-    {"wbkgGoup", StorageClass::kInvalid},       {"unifiivm", StorageClass::kInvalid},
-    {"8WWiform", StorageClass::kInvalid},       {"uxxform", StorageClass::kInvalid},
-    {"sXraggg", StorageClass::kInvalid},        {"traXe", StorageClass::kInvalid},
-    {"stor3ge", StorageClass::kInvalid},        {"push_constanE", StorageClass::kInvalid},
-    {"push_TTPnstant", StorageClass::kInvalid}, {"puxxdh_constan", StorageClass::kInvalid},
-};
-
-using StorageClassParseTest = testing::TestWithParam<Case>;
-
-TEST_P(StorageClassParseTest, Parse) {
-    const char* string = GetParam().string;
-    StorageClass expect = GetParam().value;
-    EXPECT_EQ(expect, ParseStorageClass(string));
-}
-
-INSTANTIATE_TEST_SUITE_P(ValidCases, StorageClassParseTest, testing::ValuesIn(kValidCases));
-INSTANTIATE_TEST_SUITE_P(InvalidCases, StorageClassParseTest, testing::ValuesIn(kInvalidCases));
-
-using StorageClassPrintTest = testing::TestWithParam<Case>;
-
-TEST_P(StorageClassPrintTest, Print) {
-    StorageClass value = GetParam().value;
-    const char* expect = GetParam().string;
-    EXPECT_EQ(expect, utils::ToString(value));
-}
-
-INSTANTIATE_TEST_SUITE_P(ValidCases, StorageClassPrintTest, testing::ValuesIn(kValidCases));
-
-}  // namespace parse_print_tests
-
-}  // namespace
-}  // namespace tint::ast
diff --git a/src/tint/ast/var.cc b/src/tint/ast/var.cc
index 474cff2..26c23f6 100644
--- a/src/tint/ast/var.cc
+++ b/src/tint/ast/var.cc
@@ -25,12 +25,12 @@
          const Source& src,
          const Symbol& sym,
          const ast::Type* ty,
-         StorageClass storage_class,
+         AddressSpace address_space,
          Access access,
          const Expression* ctor,
          utils::VectorRef<const Attribute*> attrs)
     : Base(pid, nid, src, sym, ty, ctor, std::move(attrs)),
-      declared_storage_class(storage_class),
+      declared_address_space(address_space),
       declared_access(access) {}
 
 Var::Var(Var&&) = default;
@@ -47,7 +47,7 @@
     auto* ty = ctx->Clone(type);
     auto* ctor = ctx->Clone(constructor);
     auto attrs = ctx->Clone(attributes);
-    return ctx->dst->create<Var>(src, sym, ty, declared_storage_class, declared_access, ctor,
+    return ctx->dst->create<Var>(src, sym, ty, declared_address_space, declared_access, ctor,
                                  std::move(attrs));
 }
 
diff --git a/src/tint/ast/var.h b/src/tint/ast/var.h
index 908a9b3..5234165 100644
--- a/src/tint/ast/var.h
+++ b/src/tint/ast/var.h
@@ -28,11 +28,11 @@
 ///
 /// ```
 ///  // Declared outside a function, i.e. at module scope, requires
-///  // a storage class.
+///  // a address space.
 ///  var<workgroup> width : i32;     // no initializer
 ///  var<private> height : i32 = 3;  // with initializer
 ///
-///  // A variable declared inside a function doesn't take a storage class,
+///  // A variable declared inside a function doesn't take a address space,
 ///  // and maps to SPIR-V Function storage.
 ///  var computed_depth : i32;
 ///  var area : i32 = compute_area(width, height);
@@ -47,7 +47,7 @@
     /// @param source the variable source
     /// @param sym the variable symbol
     /// @param type the declared variable type
-    /// @param declared_storage_class the declared storage class
+    /// @param declared_address_space the declared address space
     /// @param declared_access the declared access control
     /// @param constructor the constructor expression
     /// @param attributes the variable attributes
@@ -56,7 +56,7 @@
         const Source& source,
         const Symbol& sym,
         const ast::Type* type,
-        StorageClass declared_storage_class,
+        AddressSpace declared_address_space,
         Access declared_access,
         const Expression* constructor,
         utils::VectorRef<const Attribute*> attributes);
@@ -76,8 +76,8 @@
     /// @return the newly cloned node
     const Var* Clone(CloneContext* ctx) const override;
 
-    /// The declared storage class
-    const StorageClass declared_storage_class;
+    /// The declared address space
+    const AddressSpace declared_address_space;
 
     /// The declared access control
     const Access declared_access;
diff --git a/src/tint/ast/variable.h b/src/tint/ast/variable.h
index 8772f5b..ea0ff99 100644
--- a/src/tint/ast/variable.h
+++ b/src/tint/ast/variable.h
@@ -19,11 +19,11 @@
 #include <vector>
 
 #include "src/tint/ast/access.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/attribute.h"
 #include "src/tint/ast/binding_attribute.h"
 #include "src/tint/ast/expression.h"
 #include "src/tint/ast/group_attribute.h"
-#include "src/tint/ast/storage_class.h"
 
 // Forward declarations
 namespace tint::ast {
diff --git a/src/tint/ast/variable_test.cc b/src/tint/ast/variable_test.cc
index 2fed042..01f3d8e99 100644
--- a/src/tint/ast/variable_test.cc
+++ b/src/tint/ast/variable_test.cc
@@ -25,10 +25,10 @@
 using VariableTest = TestHelper;
 
 TEST_F(VariableTest, Creation) {
-    auto* v = Var("my_var", ty.i32(), StorageClass::kFunction);
+    auto* v = Var("my_var", ty.i32(), AddressSpace::kFunction);
 
     EXPECT_EQ(v->symbol, Symbol(1, ID()));
-    EXPECT_EQ(v->declared_storage_class, StorageClass::kFunction);
+    EXPECT_EQ(v->declared_address_space, AddressSpace::kFunction);
     EXPECT_TRUE(v->type->Is<ast::I32>());
     EXPECT_EQ(v->source.range.begin.line, 0u);
     EXPECT_EQ(v->source.range.begin.column, 0u);
@@ -38,10 +38,10 @@
 
 TEST_F(VariableTest, CreationWithSource) {
     auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 5}}}, "i",
-                  ty.f32(), StorageClass::kPrivate, utils::Empty);
+                  ty.f32(), AddressSpace::kPrivate, utils::Empty);
 
     EXPECT_EQ(v->symbol, Symbol(1, ID()));
-    EXPECT_EQ(v->declared_storage_class, StorageClass::kPrivate);
+    EXPECT_EQ(v->declared_address_space, AddressSpace::kPrivate);
     EXPECT_TRUE(v->type->Is<ast::F32>());
     EXPECT_EQ(v->source.range.begin.line, 27u);
     EXPECT_EQ(v->source.range.begin.column, 4u);
@@ -51,10 +51,10 @@
 
 TEST_F(VariableTest, CreationEmpty) {
     auto* v = Var(Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 7}}}, "a_var",
-                  ty.i32(), StorageClass::kWorkgroup, utils::Empty);
+                  ty.i32(), AddressSpace::kWorkgroup, utils::Empty);
 
     EXPECT_EQ(v->symbol, Symbol(1, ID()));
-    EXPECT_EQ(v->declared_storage_class, StorageClass::kWorkgroup);
+    EXPECT_EQ(v->declared_address_space, AddressSpace::kWorkgroup);
     EXPECT_TRUE(v->type->Is<ast::I32>());
     EXPECT_EQ(v->source.range.begin.line, 27u);
     EXPECT_EQ(v->source.range.begin.column, 4u);
@@ -92,7 +92,7 @@
 }
 
 TEST_F(VariableTest, WithAttributes) {
-    auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, Location(1_u),
+    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, Location(1_u),
                     Builtin(BuiltinValue::kPosition), Id(1200_u));
 
     auto& attributes = var->attributes;
@@ -107,22 +107,22 @@
 }
 
 TEST_F(VariableTest, HasBindingPoint_BothProvided) {
-    auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, Binding(2_a), Group(1_a));
+    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, Binding(2_a), Group(1_a));
     EXPECT_TRUE(var->HasBindingPoint());
 }
 
 TEST_F(VariableTest, HasBindingPoint_NeitherProvided) {
-    auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, utils::Empty);
+    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, utils::Empty);
     EXPECT_FALSE(var->HasBindingPoint());
 }
 
 TEST_F(VariableTest, HasBindingPoint_MissingGroupAttribute) {
-    auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, Binding(2_a));
+    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, Binding(2_a));
     EXPECT_FALSE(var->HasBindingPoint());
 }
 
 TEST_F(VariableTest, HasBindingPoint_MissingBindingAttribute) {
-    auto* var = Var("my_var", ty.i32(), StorageClass::kFunction, Group(1_a));
+    auto* var = Var("my_var", ty.i32(), AddressSpace::kFunction, Group(1_a));
     EXPECT_FALSE(var->HasBindingPoint());
 }
 
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
index f201047..93466d8 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
@@ -272,7 +272,7 @@
 
 TEST(ReplaceIdentifierTest, NotApplicable5) {
     // Can't replace `a` with `b` since the latter has a wrong access mode
-    // (`read` for uniform storage class).
+    // (`read` for uniform address space).
     std::string shader = R"(
 struct S {
   a: i32
@@ -343,7 +343,7 @@
 
 TEST(ReplaceIdentifierTest, NotApplicable8) {
     // Can't replace `ptr_b` with `c` since the latter has a wrong access mode and
-    // storage class.
+    // address space.
     std::string shader = R"(
 struct S {
   a: i32
@@ -451,7 +451,7 @@
 }
 
 TEST(ReplaceIdentifierTest, Applicable1) {
-    // Can replace `a` with `b` (same storage class).
+    // Can replace `a` with `b` (same address space).
     std::string shader = R"(
 fn f() {
   var b : vec2<u32>;
@@ -611,7 +611,7 @@
 
 TEST(ReplaceIdentifierTest, NotApplicable14) {
     // Can't replace `ptr_a` with `ptr_b` (both are pointers with different
-    // storage class).
+    // address space).
     std::string shader = R"(
 var<private> b: vec2<u32>;
 fn f() {
diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc
index d32ef6f..3520ae3 100644
--- a/src/tint/inspector/inspector.cc
+++ b/src/tint/inspector/inspector.cc
@@ -565,7 +565,7 @@
     uint32_t total_size = 0;
     auto* func_sem = program_->Sem().Get(func);
     for (const sem::Variable* var : func_sem->TransitivelyReferencedGlobals()) {
-        if (var->StorageClass() == ast::StorageClass::kWorkgroup) {
+        if (var->AddressSpace() == ast::AddressSpace::kWorkgroup) {
             auto* ty = var->Type()->UnwrapRef();
             uint32_t align = ty->Align();
             uint32_t size = ty->Size();
diff --git a/src/tint/inspector/test_inspector_builder.cc b/src/tint/inspector/test_inspector_builder.cc
index ce341a6..79122dc 100644
--- a/src/tint/inspector/test_inspector_builder.cc
+++ b/src/tint/inspector/test_inspector_builder.cc
@@ -126,11 +126,11 @@
                                         const ast::Type* type,
                                         uint32_t group,
                                         uint32_t binding) {
-    GlobalVar(name, type, ast::StorageClass::kUniform, Binding(AInt(binding)), Group(AInt(group)));
+    GlobalVar(name, type, ast::AddressSpace::kUniform, Binding(AInt(binding)), Group(AInt(group)));
 }
 
 void InspectorBuilder::AddWorkgroupStorage(const std::string& name, const ast::Type* type) {
-    GlobalVar(name, type, ast::StorageClass::kWorkgroup);
+    GlobalVar(name, type, ast::AddressSpace::kWorkgroup);
 }
 
 void InspectorBuilder::AddStorageBuffer(const std::string& name,
@@ -138,7 +138,7 @@
                                         ast::Access access,
                                         uint32_t group,
                                         uint32_t binding) {
-    GlobalVar(name, type, ast::StorageClass::kStorage, access, Binding(AInt(binding)),
+    GlobalVar(name, type, ast::AddressSpace::kStorage, access, Binding(AInt(binding)),
               Group(AInt(group)));
 }
 
@@ -188,7 +188,7 @@
 }
 
 void InspectorBuilder::AddGlobalVariable(const std::string& name, const ast::Type* type) {
-    GlobalVar(name, type, ast::StorageClass::kPrivate);
+    GlobalVar(name, type, ast::AddressSpace::kPrivate);
 }
 
 const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index b88ff59..5864fb0 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -54,7 +54,7 @@
 }
 
 // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
-enum storage_class {
+enum address_space {
   @internal none
   function
   private
@@ -125,7 +125,7 @@
 type mat4x4<T>
 @display("vec{N}<{T}>")     type vec<N: num, T>
 @display("mat{N}x{M}<{T}>") type mat<N: num, M: num, T>
-type ptr<S: storage_class, T, A: access>
+type ptr<S: address_space, T, A: access>
 type atomic<T>
 type array<T>
 type sampler
@@ -214,14 +214,14 @@
 match read_write: access.read_write
 
 match function_private_workgroup
-  : storage_class.function
-  | storage_class.private
-  | storage_class.workgroup
+  : address_space.function
+  | address_space.private
+  | address_space.workgroup
 match workgroup_or_storage
-  : storage_class.workgroup
-  | storage_class.storage
+  : address_space.workgroup
+  | address_space.storage
 match storage
-  : storage_class.storage
+  : address_space.storage
 
 ////////////////////////////////////////////////////////////////////////////////
 // Builtin Functions                                                          //
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index e8296a5..116660f 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -172,14 +172,14 @@
         ~VarOptions();
 
         const ast::Type* type = nullptr;
-        ast::StorageClass storage = ast::StorageClass::kNone;
+        ast::AddressSpace address_space = ast::AddressSpace::kNone;
         ast::Access access = ast::Access::kUndefined;
         const ast::Expression* constructor = nullptr;
         utils::Vector<const ast::Attribute*, 4> attributes;
 
       private:
         void Set(const ast::Type* t) { type = t; }
-        void Set(ast::StorageClass sc) { storage = sc; }
+        void Set(ast::AddressSpace addr_space) { address_space = addr_space; }
         void Set(ast::Access ac) { access = ac; }
         void Set(const ast::Expression* c) { constructor = c; }
         void Set(utils::VectorRef<const ast::Attribute*> l) { attributes = std::move(l); }
@@ -902,45 +902,45 @@
         }
 
         /// @param type the type of the pointer
-        /// @param storage_class the storage class of the pointer
+        /// @param address_space the address space of the pointer
         /// @param access the optional access control of the pointer
-        /// @return the pointer to `type` with the given ast::StorageClass
+        /// @return the pointer to `type` with the given ast::AddressSpace
         const ast::Pointer* pointer(const ast::Type* type,
-                                    ast::StorageClass storage_class,
+                                    ast::AddressSpace address_space,
                                     ast::Access access = ast::Access::kUndefined) const {
-            return builder->create<ast::Pointer>(type, storage_class, access);
+            return builder->create<ast::Pointer>(type, address_space, access);
         }
 
         /// @param source the Source of the node
         /// @param type the type of the pointer
-        /// @param storage_class the storage class of the pointer
+        /// @param address_space the address space of the pointer
         /// @param access the optional access control of the pointer
-        /// @return the pointer to `type` with the given ast::StorageClass
+        /// @return the pointer to `type` with the given ast::AddressSpace
         const ast::Pointer* pointer(const Source& source,
                                     const ast::Type* type,
-                                    ast::StorageClass storage_class,
+                                    ast::AddressSpace address_space,
                                     ast::Access access = ast::Access::kUndefined) const {
-            return builder->create<ast::Pointer>(source, type, storage_class, access);
+            return builder->create<ast::Pointer>(source, type, address_space, access);
         }
 
-        /// @param storage_class the storage class of the pointer
+        /// @param address_space the address space of the pointer
         /// @param access the optional access control of the pointer
-        /// @return the pointer to type `T` with the given ast::StorageClass.
+        /// @return the pointer to type `T` with the given ast::AddressSpace.
         template <typename T>
-        const ast::Pointer* pointer(ast::StorageClass storage_class,
+        const ast::Pointer* pointer(ast::AddressSpace address_space,
                                     ast::Access access = ast::Access::kUndefined) const {
-            return pointer(Of<T>(), storage_class, access);
+            return pointer(Of<T>(), address_space, access);
         }
 
         /// @param source the Source of the node
-        /// @param storage_class the storage class of the pointer
+        /// @param address_space the address space of the pointer
         /// @param access the optional access control of the pointer
-        /// @return the pointer to type `T` with the given ast::StorageClass.
+        /// @return the pointer to type `T` with the given ast::AddressSpace.
         template <typename T>
         const ast::Pointer* pointer(const Source& source,
-                                    ast::StorageClass storage_class,
+                                    ast::AddressSpace address_space,
                                     ast::Access access = ast::Access::kUndefined) const {
-            return pointer(source, Of<T>(), storage_class, access);
+            return pointer(source, Of<T>(), address_space, access);
         }
 
         /// @param source the Source of the node
@@ -1651,7 +1651,7 @@
     /// @param options the extra options passed to the ast::Var constructor
     /// Can be any of the following, in any order:
     ///   * ast::Type*          - specifies the variable type
-    ///   * ast::StorageClass   - specifies the variable storage class
+    ///   * ast::AddressSpace   - specifies the variable address space
     ///   * ast::Access         - specifies the variable's access control
     ///   * ast::Expression*    - specifies the variable's initializer expression
     ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
@@ -1661,8 +1661,8 @@
     template <typename NAME, typename... OPTIONS, typename = DisableIfSource<NAME>>
     const ast::Var* Var(NAME&& name, OPTIONS&&... options) {
         VarOptions opts(std::forward<OPTIONS>(options)...);
-        return create<ast::Var>(Sym(std::forward<NAME>(name)), opts.type, opts.storage, opts.access,
-                                opts.constructor, std::move(opts.attributes));
+        return create<ast::Var>(Sym(std::forward<NAME>(name)), opts.type, opts.address_space,
+                                opts.access, opts.constructor, std::move(opts.attributes));
     }
 
     /// @param source the variable source
@@ -1670,17 +1670,18 @@
     /// @param options the extra options passed to the ast::Var constructor
     /// Can be any of the following, in any order:
     ///   * ast::Type*          - specifies the variable type
-    ///   * ast::StorageClass   - specifies the variable storage class
+    ///   * ast::AddressSpace   - specifies the variable address space
     ///   * ast::Access         - specifies the variable's access control
     ///   * ast::Expression*    - specifies the variable's initializer expression
     ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
     /// Note that non-repeatable arguments of the same type will use the last argument's value.
-    /// @returns a `ast::Var` with the given name, storage and type
+    /// @returns a `ast::Var` with the given name, address_space and type
     template <typename NAME, typename... OPTIONS>
     const ast::Var* Var(const Source& source, NAME&& name, OPTIONS&&... options) {
         VarOptions opts(std::forward<OPTIONS>(options)...);
-        return create<ast::Var>(source, Sym(std::forward<NAME>(name)), opts.type, opts.storage,
-                                opts.access, opts.constructor, std::move(opts.attributes));
+        return create<ast::Var>(source, Sym(std::forward<NAME>(name)), opts.type,
+                                opts.address_space, opts.access, opts.constructor,
+                                std::move(opts.attributes));
     }
 
     /// @param name the variable name
@@ -1773,7 +1774,7 @@
     /// @param options the extra options passed to the ast::Var constructor
     /// Can be any of the following, in any order:
     ///   * ast::Type*          - specifies the variable type
-    ///   * ast::StorageClass   - specifies the variable storage class
+    ///   * ast::AddressSpace   - specifies the variable address space
     ///   * ast::Access         - specifies the variable's access control
     ///   * ast::Expression*    - specifies the variable's initializer expression
     ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
@@ -1792,7 +1793,7 @@
     /// @param options the extra options passed to the ast::Var constructor
     /// Can be any of the following, in any order:
     ///   * ast::Type*          - specifies the variable type
-    ///   * ast::StorageClass   - specifies the variable storage class
+    ///   * ast::AddressSpace   - specifies the variable address space
     ///   * ast::Access         - specifies the variable's access control
     ///   * ast::Expression*    - specifies the variable's initializer expression
     ///   * ast::Attribute*    - specifies the variable's attributes (repeatable, or vector)
diff --git a/src/tint/program_test.cc b/src/tint/program_test.cc
index 39d7c07..d2f1673 100644
--- a/src/tint/program_test.cc
+++ b/src/tint/program_test.cc
@@ -46,7 +46,7 @@
 }
 
 TEST_F(ProgramTest, Assert_GlobalVariable) {
-    GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
 
     Program program(std::move(*this));
     EXPECT_TRUE(program.IsValid());
diff --git a/src/tint/reader/spirv/enum_converter.cc b/src/tint/reader/spirv/enum_converter.cc
index 8791670..bc899d7 100644
--- a/src/tint/reader/spirv/enum_converter.cc
+++ b/src/tint/reader/spirv/enum_converter.cc
@@ -36,30 +36,30 @@
     return ast::PipelineStage::kNone;
 }
 
-ast::StorageClass EnumConverter::ToStorageClass(const SpvStorageClass sc) {
+ast::AddressSpace EnumConverter::ToAddressSpace(const SpvStorageClass sc) {
     switch (sc) {
         case SpvStorageClassInput:
-            return ast::StorageClass::kIn;
+            return ast::AddressSpace::kIn;
         case SpvStorageClassOutput:
-            return ast::StorageClass::kOut;
+            return ast::AddressSpace::kOut;
         case SpvStorageClassUniform:
-            return ast::StorageClass::kUniform;
+            return ast::AddressSpace::kUniform;
         case SpvStorageClassWorkgroup:
-            return ast::StorageClass::kWorkgroup;
+            return ast::AddressSpace::kWorkgroup;
         case SpvStorageClassUniformConstant:
-            return ast::StorageClass::kNone;
+            return ast::AddressSpace::kNone;
         case SpvStorageClassStorageBuffer:
-            return ast::StorageClass::kStorage;
+            return ast::AddressSpace::kStorage;
         case SpvStorageClassPrivate:
-            return ast::StorageClass::kPrivate;
+            return ast::AddressSpace::kPrivate;
         case SpvStorageClassFunction:
-            return ast::StorageClass::kFunction;
+            return ast::AddressSpace::kFunction;
         default:
             break;
     }
 
     Fail() << "unknown SPIR-V storage class: " << uint32_t(sc);
-    return ast::StorageClass::kInvalid;
+    return ast::AddressSpace::kInvalid;
 }
 
 ast::BuiltinValue EnumConverter::ToBuiltin(SpvBuiltIn b) {
diff --git a/src/tint/reader/spirv/enum_converter.h b/src/tint/reader/spirv/enum_converter.h
index fc3ad83..1ebea36 100644
--- a/src/tint/reader/spirv/enum_converter.h
+++ b/src/tint/reader/spirv/enum_converter.h
@@ -16,9 +16,9 @@
 #define SRC_TINT_READER_SPIRV_ENUM_CONVERTER_H_
 
 #include "spirv/unified1/spirv.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/builtin_value.h"
 #include "src/tint/ast/pipeline_stage.h"
-#include "src/tint/ast/storage_class.h"
 #include "src/tint/reader/spirv/fail_stream.h"
 #include "src/tint/sem/storage_texture.h"
 
@@ -39,11 +39,11 @@
     /// @returns a Tint AST pipeline stage
     ast::PipelineStage ToPipelineStage(SpvExecutionModel model);
 
-    /// Converts a SPIR-V storage class to a Tint storage class.
+    /// Converts a SPIR-V storage class to a Tint address space.
     /// On failure, logs an error and returns kNone
     /// @param sc the SPIR-V storage class
-    /// @returns a Tint AST storage class
-    ast::StorageClass ToStorageClass(const SpvStorageClass sc);
+    /// @returns a Tint AST address space
+    ast::AddressSpace ToAddressSpace(const SpvStorageClass sc);
 
     /// Converts a SPIR-V Builtin value a Tint Builtin.
     /// On failure, logs an error and returns kNone
diff --git a/src/tint/reader/spirv/enum_converter_test.cc b/src/tint/reader/spirv/enum_converter_test.cc
index 95a6264..623f6ea 100644
--- a/src/tint/reader/spirv/enum_converter_test.cc
+++ b/src/tint/reader/spirv/enum_converter_test.cc
@@ -84,7 +84,7 @@
 struct StorageClassCase {
     SpvStorageClass sc;
     bool expect_success;
-    ast::StorageClass expected;
+    ast::AddressSpace expected;
 };
 inline std::ostream& operator<<(std::ostream& out, StorageClassCase scc) {
     out << "StorageClassCase{ SpvStorageClass:" << int(scc.sc)
@@ -110,7 +110,7 @@
 TEST_P(SpvStorageClassTest, Samples) {
     const auto params = GetParam();
 
-    const auto result = converter_.ToStorageClass(params.sc);
+    const auto result = converter_.ToAddressSpace(params.sc);
     EXPECT_EQ(success_, params.expect_success);
     if (params.expect_success) {
         EXPECT_EQ(result, params.expected);
@@ -125,19 +125,19 @@
     EnumConverterGood,
     SpvStorageClassTest,
     testing::Values(
-        StorageClassCase{SpvStorageClassInput, true, ast::StorageClass::kIn},
-        StorageClassCase{SpvStorageClassOutput, true, ast::StorageClass::kOut},
-        StorageClassCase{SpvStorageClassUniform, true, ast::StorageClass::kUniform},
-        StorageClassCase{SpvStorageClassWorkgroup, true, ast::StorageClass::kWorkgroup},
-        StorageClassCase{SpvStorageClassUniformConstant, true, ast::StorageClass::kNone},
-        StorageClassCase{SpvStorageClassStorageBuffer, true, ast::StorageClass::kStorage},
-        StorageClassCase{SpvStorageClassPrivate, true, ast::StorageClass::kPrivate},
-        StorageClassCase{SpvStorageClassFunction, true, ast::StorageClass::kFunction}));
+        StorageClassCase{SpvStorageClassInput, true, ast::AddressSpace::kIn},
+        StorageClassCase{SpvStorageClassOutput, true, ast::AddressSpace::kOut},
+        StorageClassCase{SpvStorageClassUniform, true, ast::AddressSpace::kUniform},
+        StorageClassCase{SpvStorageClassWorkgroup, true, ast::AddressSpace::kWorkgroup},
+        StorageClassCase{SpvStorageClassUniformConstant, true, ast::AddressSpace::kNone},
+        StorageClassCase{SpvStorageClassStorageBuffer, true, ast::AddressSpace::kStorage},
+        StorageClassCase{SpvStorageClassPrivate, true, ast::AddressSpace::kPrivate},
+        StorageClassCase{SpvStorageClassFunction, true, ast::AddressSpace::kFunction}));
 
 INSTANTIATE_TEST_SUITE_P(EnumConverterBad,
                          SpvStorageClassTest,
                          testing::Values(StorageClassCase{static_cast<SpvStorageClass>(9999), false,
-                                                          ast::StorageClass::kInvalid}));
+                                                          ast::AddressSpace::kInvalid}));
 
 // Builtin
 
diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc
index 00b49d9..7d4181d 100644
--- a/src/tint/reader/spirv/function.cc
+++ b/src/tint/reader/spirv/function.cc
@@ -2500,11 +2500,11 @@
                 return false;
             }
         }
-        auto* var = parser_impl_.MakeVar(inst.result_id(), ast::StorageClass::kNone, var_store_type,
+        auto* var = parser_impl_.MakeVar(inst.result_id(), ast::AddressSpace::kNone, var_store_type,
                                          constructor, AttributeList{});
         auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var);
         AddStatement(var_decl_stmt);
-        auto* var_type = ty_.Reference(var_store_type, ast::StorageClass::kNone);
+        auto* var_type = ty_.Reference(var_store_type, ast::AddressSpace::kNone);
         identifier_types_.emplace(inst.result_id(), var_type);
     }
     return success();
@@ -3356,11 +3356,11 @@
     for (auto id : sorted_by_index(block_info.hoisted_ids)) {
         const auto* def_inst = def_use_mgr_->GetDef(id);
         TINT_ASSERT(Reader, def_inst);
-        auto* storage_type = RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
+        auto* storage_type = RemapAddressSpace(parser_impl_.ConvertType(def_inst->type_id()), id);
         AddStatement(create<ast::VariableDeclStatement>(
-            Source{}, parser_impl_.MakeVar(id, ast::StorageClass::kNone, storage_type, nullptr,
+            Source{}, parser_impl_.MakeVar(id, ast::AddressSpace::kNone, storage_type, nullptr,
                                            AttributeList{})));
-        auto* type = ty_.Reference(storage_type, ast::StorageClass::kNone);
+        auto* type = ty_.Reference(storage_type, ast::AddressSpace::kNone);
         identifier_types_.emplace(id, type);
     }
 
@@ -3720,7 +3720,7 @@
             if (!expr) {
                 return false;
             }
-            expr.type = RemapStorageClass(expr.type, result_id);
+            expr.type = RemapAddressSpace(expr.type, result_id);
             return EmitConstDefOrWriteToHoistedVar(inst, expr);
         }
 
@@ -3777,15 +3777,15 @@
     return parser_impl_.RectifyOperandSignedness(inst, std::move(expr));
 }
 
-TypedExpression FunctionEmitter::InferFunctionStorageClass(TypedExpression expr) {
+TypedExpression FunctionEmitter::InferFunctionAddressSpace(TypedExpression expr) {
     TypedExpression result(expr);
     if (const auto* ref = expr.type->UnwrapAlias()->As<Reference>()) {
-        if (ref->storage_class == ast::StorageClass::kNone) {
-            expr.type = ty_.Reference(ref->type, ast::StorageClass::kFunction);
+        if (ref->address_space == ast::AddressSpace::kNone) {
+            expr.type = ty_.Reference(ref->type, ast::AddressSpace::kFunction);
         }
     } else if (const auto* ptr = expr.type->UnwrapAlias()->As<Pointer>()) {
-        if (ptr->storage_class == ast::StorageClass::kNone) {
-            expr.type = ty_.Pointer(ptr->type, ast::StorageClass::kFunction);
+        if (ptr->address_space == ast::AddressSpace::kNone) {
+            expr.type = ty_.Pointer(ptr->type, ast::AddressSpace::kFunction);
         }
     }
     return expr;
@@ -4418,7 +4418,7 @@
     // ever-deeper nested indexing expressions. Start off with an expression
     // for the base, and then bury that inside nested indexing expressions.
     if (!current_expr) {
-        current_expr = InferFunctionStorageClass(MakeOperand(inst, 0));
+        current_expr = InferFunctionAddressSpace(MakeOperand(inst, 0));
         if (current_expr.type->Is<Pointer>()) {
             current_expr = Dereference(current_expr);
         }
@@ -4430,7 +4430,7 @@
         Fail() << "Access chain %" << inst.result_id() << " base pointer is not of pointer type";
         return {};
     }
-    SpvStorageClass storage_class =
+    SpvStorageClass address_space =
         static_cast<SpvStorageClass>(ptr_type_inst->GetSingleWordInOperand(0));
     uint32_t pointee_type_id = ptr_type_inst->GetSingleWordInOperand(1);
 
@@ -4521,7 +4521,7 @@
                        << ": " << pointee_type_inst->PrettyPrint();
                 return {};
         }
-        const auto pointer_type_id = type_mgr_->FindPointerToType(pointee_type_id, storage_class);
+        const auto pointer_type_id = type_mgr_->FindPointerToType(pointee_type_id, address_space);
         auto* type = parser_impl_.ConvertType(pointer_type_id, PtrAs::Ref);
         TINT_ASSERT(Reader, type && type->Is<Reference>());
         current_expr = TypedExpression{type, next_expr};
@@ -4799,8 +4799,8 @@
             ++index;
             auto& info = def_info_[result_id];
 
-            // Determine storage class for pointer values. Do this in order because
-            // we might rely on the storage class for a previously-visited definition.
+            // Determine address space for pointer values. Do this in order because
+            // we might rely on the address space for a previously-visited definition.
             // Logical pointers can't be transmitted through OpPhi, so remaining
             // pointer definitions are SSA values, and their definitions must be
             // visited before their uses.
@@ -4809,7 +4809,7 @@
                 if (type->AsPointer()) {
                     if (auto* ast_type = parser_impl_.ConvertType(inst.type_id())) {
                         if (auto* ptr = ast_type->As<Pointer>()) {
-                            info->storage_class = ptr->storage_class;
+                            info->address_space = ptr->address_space;
                         }
                     }
                     switch (inst.opcode()) {
@@ -4823,8 +4823,8 @@
                         case SpvOpCopyObject:
                             // Inherit from the first operand. We need this so we can pick up
                             // a remapped storage buffer.
-                            info->storage_class =
-                                GetStorageClassForPointerValue(inst.GetSingleWordInOperand(0));
+                            info->address_space =
+                                GetAddressSpaceForPointerValue(inst.GetSingleWordInOperand(0));
                             break;
                         default:
                             return Fail() << "pointer defined in function from unknown opcode: "
@@ -4846,11 +4846,11 @@
     return true;
 }
 
-ast::StorageClass FunctionEmitter::GetStorageClassForPointerValue(uint32_t id) {
+ast::AddressSpace FunctionEmitter::GetAddressSpaceForPointerValue(uint32_t id) {
     auto where = def_info_.find(id);
     if (where != def_info_.end()) {
-        auto candidate = where->second.get()->storage_class;
-        if (candidate != ast::StorageClass::kInvalid) {
+        auto candidate = where->second.get()->address_space;
+        if (candidate != ast::AddressSpace::kInvalid) {
             return candidate;
         }
     }
@@ -4858,19 +4858,19 @@
     if (type_id) {
         auto* ast_type = parser_impl_.ConvertType(type_id);
         if (auto* ptr = As<Pointer>(ast_type)) {
-            return ptr->storage_class;
+            return ptr->address_space;
         }
     }
-    return ast::StorageClass::kInvalid;
+    return ast::AddressSpace::kInvalid;
 }
 
-const Type* FunctionEmitter::RemapStorageClass(const Type* type, uint32_t result_id) {
+const Type* FunctionEmitter::RemapAddressSpace(const Type* type, uint32_t result_id) {
     if (auto* ast_ptr_type = As<Pointer>(type)) {
         // Remap an old-style storage buffer pointer to a new-style storage
         // buffer pointer.
-        const auto sc = GetStorageClassForPointerValue(result_id);
-        if (ast_ptr_type->storage_class != sc) {
-            return ty_.Pointer(ast_ptr_type->type, sc);
+        const auto addr_space = GetAddressSpaceForPointerValue(result_id);
+        if (ast_ptr_type->address_space != addr_space) {
+            return ty_.Pointer(ast_ptr_type->type, addr_space);
         }
     }
     return type;
@@ -5053,7 +5053,7 @@
             // Avoid moving combinatorial values across constructs.  This is a
             // simple heuristic to avoid changing the cost of an operation
             // by moving it into or out of a loop, for example.
-            if ((def_info->storage_class == ast::StorageClass::kInvalid) &&
+            if ((def_info->address_space == ast::AddressSpace::kInvalid) &&
                 local_def.used_in_another_construct) {
                 should_hoist_to_let = true;
             }
@@ -6170,7 +6170,7 @@
         // API in parser_impl_.
         var_name = namer_.MakeDerivedName(original_value_name);
 
-        auto* temp_var = builder_.Var(var_name, type->Build(builder_), ast::StorageClass::kNone,
+        auto* temp_var = builder_.Var(var_name, type->Build(builder_), ast::AddressSpace::kNone,
                                       src_vector.expr);
 
         AddStatement(builder_.Decl({}, temp_var));
@@ -6240,7 +6240,7 @@
         // It doesn't correspond to a SPIR-V ID, so we don't use the ordinary
         // API in parser_impl_.
         var_name = namer_.MakeDerivedName(original_value_name);
-        auto* temp_var = builder_.Var(var_name, type->Build(builder_), ast::StorageClass::kNone,
+        auto* temp_var = builder_.Var(var_name, type->Build(builder_), ast::AddressSpace::kNone,
                                       src_composite.expr);
         AddStatement(builder_.Decl({}, temp_var));
     }
@@ -6271,7 +6271,7 @@
         return {};
     }
     return {
-        ty_.Pointer(ref->type, ref->storage_class),
+        ty_.Pointer(ref->type, ref->address_space),
         create<ast::UnaryOpExpression>(Source{}, ast::UnaryOp::kAddressOf, expr.expr),
     };
 }
diff --git a/src/tint/reader/spirv/function.h b/src/tint/reader/spirv/function.h
index 53c983c..3295551 100644
--- a/src/tint/reader/spirv/function.h
+++ b/src/tint/reader/spirv/function.h
@@ -325,12 +325,12 @@
     /// example, pointers. crbug.com/tint/98
     bool requires_hoisted_var_def = false;
 
-    /// The storage class to use for this value, if it is of pointer type.
-    /// This is required to carry a storage class override from a storage
-    /// buffer expressed in the old style (with Uniform storage class)
-    /// that needs to be remapped to StorageBuffer storage class.
+    /// The address space to use for this value, if it is of pointer type.
+    /// This is required to carry an address space override from a storage
+    /// buffer expressed in the old style (with Uniform address space)
+    /// that needs to be remapped to StorageBuffer address space.
     /// This is kInvalid for non-pointers.
-    ast::StorageClass storage_class = ast::StorageClass::kInvalid;
+    ast::AddressSpace address_space = ast::AddressSpace::kInvalid;
 
     /// The expression to use when sinking pointers into their use.
     /// When encountering a use of this instruction, we will emit this expression
@@ -360,8 +360,8 @@
     }
     o << " requires_named_let_def: " << (di.requires_named_let_def ? "true" : "false")
       << " requires_hoisted_var_def: " << (di.requires_hoisted_var_def ? "true" : "false");
-    if (di.storage_class != ast::StorageClass::kNone) {
-        o << " sc:" << int(di.storage_class);
+    if (di.address_space != ast::AddressSpace::kNone) {
+        o << " sc:" << int(di.address_space);
     }
     switch (di.skip) {
         case SkipReason::kDontSkip:
@@ -470,7 +470,7 @@
     /// by the `index_prefix`, which successively indexes into the variable.
     /// Also generates the assignment statements that copy the input parameter
     /// to the corresponding part of the variable.  Assumes the variable
-    /// has already been created in the Private storage class.
+    /// has already been created in the Private address space.
     /// @param var_name The name of the variable
     /// @param var_type The store type of the variable
     /// @param decos The variable's decorations
@@ -496,8 +496,7 @@
     /// expressions that compute the value they contribute to the entry point
     /// return value.  The part of the output variable is specfied
     /// by the `index_prefix`, which successively indexes into the variable.
-    /// Assumes the variable has already been created in the Private storage
-    /// class.
+    /// Assumes the variable has already been created in the Private address space
     /// @param var_name The name of the variable
     /// @param var_type The store type of the variable
     /// @param decos The variable's decorations
@@ -612,19 +611,19 @@
     /// @returns false on failure
     bool RegisterLocallyDefinedValues();
 
-    /// Returns the Tint storage class for the given SPIR-V ID that is a
+    /// Returns the Tint address space for the given SPIR-V ID that is a
     /// pointer value.
     /// @param id a SPIR-V ID for a pointer value
-    /// @returns the storage class
-    ast::StorageClass GetStorageClassForPointerValue(uint32_t id);
+    /// @returns the address space
+    ast::AddressSpace GetAddressSpaceForPointerValue(uint32_t id);
 
-    /// Remaps the storage class for the type of a locally-defined value,
-    /// if necessary. If it's not a pointer type, or if its storage class
+    /// Remaps the address space for the type of a locally-defined value,
+    /// if necessary. If it's not a pointer type, or if its address space
     /// already matches, then the result is a copy of the `type` argument.
     /// @param type the AST type
     /// @param result_id the SPIR-V ID for the locally defined value
     /// @returns an possibly updated type
-    const Type* RemapStorageClass(const Type* type, uint32_t result_id);
+    const Type* RemapAddressSpace(const Type* type, uint32_t result_id);
 
     /// Marks locally defined values when they should get a 'let'
     /// definition in WGSL, or a 'var' definition at an outer scope.
@@ -1005,11 +1004,11 @@
     TypedExpression MakeOperand(const spvtools::opt::Instruction& inst, uint32_t operand_index);
 
     /// Copies a typed expression to the result, but when the type is a pointer
-    /// or reference type, ensures the storage class is not defaulted.  That is,
-    /// it changes a storage class of "none" to "function".
+    /// or reference type, ensures the address space is not defaulted.  That is,
+    /// it changes a address space of "none" to "function".
     /// @param expr a typed expression
     /// @results a copy of the expression, with possibly updated type
-    TypedExpression InferFunctionStorageClass(TypedExpression expr);
+    TypedExpression InferFunctionAddressSpace(TypedExpression expr);
 
     /// Returns an expression for a SPIR-V OpFMod instruction.
     /// @param inst the SPIR-V instruction
diff --git a/src/tint/reader/spirv/function_memory_test.cc b/src/tint/reader/spirv/function_memory_test.cc
index 2bb98e3..4470d3d 100644
--- a/src/tint/reader/spirv/function_memory_test.cc
+++ b/src/tint/reader/spirv/function_memory_test.cc
@@ -818,11 +818,11 @@
     EXPECT_EQ(got, expected) << got;
 }
 
-TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_InferFunctionStorageClass) {
+TEST_F(SpvParserMemoryTest, EmitStatement_AccessChain_InferFunctionAddressSpace) {
     // An access chain can have no indices. When the base is a Function variable,
-    // the reference type has no explicit storage class in the AST representation.
+    // the reference type has no explicit address space in the AST representation.
     // But the pointer type for the let declaration must have an explicit
-    // 'function' storage class. From crbug.com/tint/807
+    // 'function' address space. From crbug.com/tint/807
     const std::string assembly = R"(
 OpCapability Shader
 OpMemoryModel Logical Simple
@@ -993,7 +993,7 @@
 
 TEST_F(SpvParserMemoryTest, RemapStorageBuffer_ThroughCopyObject_WithoutHoisting) {
     // Generates a const declaration directly.
-    // We have to do a bunch of storage class tracking for locally
+    // We have to do a bunch of address space tracking for locally
     // defined values in order to get the right pointer-to-storage-buffer
     // value type for the const declration.
     const auto assembly = OldStorageBufferPreamble() + R"(
diff --git a/src/tint/reader/spirv/parser_impl.cc b/src/tint/reader/spirv/parser_impl.cc
index 683dd59..3c64c5b 100644
--- a/src/tint/reader/spirv/parser_impl.cc
+++ b/src/tint/reader/spirv/parser_impl.cc
@@ -1205,28 +1205,28 @@
         return nullptr;
     }
 
-    auto ast_storage_class = enum_converter_.ToStorageClass(storage_class);
-    if (ast_storage_class == ast::StorageClass::kInvalid) {
+    auto ast_address_space = enum_converter_.ToAddressSpace(storage_class);
+    if (ast_address_space == ast::AddressSpace::kInvalid) {
         Fail() << "SPIR-V pointer type with ID " << type_id << " has invalid storage class "
                << static_cast<uint32_t>(storage_class);
         return nullptr;
     }
-    if (ast_storage_class == ast::StorageClass::kUniform &&
+    if (ast_address_space == ast::AddressSpace::kUniform &&
         remap_buffer_block_type_.count(pointee_type_id)) {
-        ast_storage_class = ast::StorageClass::kStorage;
+        ast_address_space = ast::AddressSpace::kStorage;
         remap_buffer_block_type_.insert(type_id);
     }
 
     // Pipeline input and output variables map to private variables.
-    if (ast_storage_class == ast::StorageClass::kIn ||
-        ast_storage_class == ast::StorageClass::kOut) {
-        ast_storage_class = ast::StorageClass::kPrivate;
+    if (ast_address_space == ast::AddressSpace::kIn ||
+        ast_address_space == ast::AddressSpace::kOut) {
+        ast_address_space = ast::AddressSpace::kPrivate;
     }
     switch (ptr_as) {
         case PtrAs::Ref:
-            return ty_.Reference(ast_elem_ty, ast_storage_class);
+            return ty_.Reference(ast_elem_ty, ast_address_space);
         case PtrAs::Ptr:
-            return ty_.Pointer(ast_elem_ty, ast_storage_class);
+            return ty_.Pointer(ast_elem_ty, ast_address_space);
     }
     Fail() << "invalid value for ptr_as: " << static_cast<int>(ptr_as);
     return nullptr;
@@ -1443,15 +1443,15 @@
                 var.NumInOperands() > 1 ? var.GetSingleWordInOperand(1) : 0u;
             continue;
         }
-        switch (enum_converter_.ToStorageClass(spirv_storage_class)) {
-            case ast::StorageClass::kNone:
-            case ast::StorageClass::kIn:
-            case ast::StorageClass::kOut:
-            case ast::StorageClass::kUniform:
-            case ast::StorageClass::kHandle:
-            case ast::StorageClass::kStorage:
-            case ast::StorageClass::kWorkgroup:
-            case ast::StorageClass::kPrivate:
+        switch (enum_converter_.ToAddressSpace(spirv_storage_class)) {
+            case ast::AddressSpace::kNone:
+            case ast::AddressSpace::kIn:
+            case ast::AddressSpace::kOut:
+            case ast::AddressSpace::kUniform:
+            case ast::AddressSpace::kHandle:
+            case ast::AddressSpace::kStorage:
+            case ast::AddressSpace::kWorkgroup:
+            case ast::AddressSpace::kPrivate:
                 break;
             default:
                 return Fail() << "invalid SPIR-V storage class " << int(spirv_storage_class)
@@ -1481,7 +1481,7 @@
         }
 
         auto* ast_store_type = ast_type->As<Pointer>()->type;
-        auto ast_storage_class = ast_type->As<Pointer>()->storage_class;
+        auto ast_address_space = ast_type->As<Pointer>()->address_space;
         const ast::Expression* ast_constructor = nullptr;
         if (var.NumInOperands() > 1) {
             // SPIR-V initializers are always constants.
@@ -1489,7 +1489,7 @@
             // here.)
             ast_constructor = MakeConstantExpression(var.GetSingleWordInOperand(1)).expr;
         }
-        auto* ast_var = MakeVar(var.result_id(), ast_storage_class, ast_store_type, ast_constructor,
+        auto* ast_var = MakeVar(var.result_id(), ast_address_space, ast_store_type, ast_constructor,
                                 utils::Empty);
         // TODO(dneto): initializers (a.k.a. constructor expression)
         if (ast_var) {
@@ -1522,7 +1522,7 @@
         }
         auto* ast_var =
             MakeVar(builtin_position_.per_vertex_var_id,
-                    enum_converter_.ToStorageClass(builtin_position_.storage_class),
+                    enum_converter_.ToAddressSpace(builtin_position_.storage_class),
                     ConvertType(builtin_position_.position_member_type_id), ast_constructor, {});
 
         builder_.AST().AddGlobalVariable(ast_var);
@@ -1554,7 +1554,7 @@
 }
 
 ast::Var* ParserImpl::MakeVar(uint32_t id,
-                              ast::StorageClass sc,
+                              ast::AddressSpace address_space,
                               const Type* storage_type,
                               const ast::Expression* constructor,
                               AttributeList decorations) {
@@ -1564,7 +1564,7 @@
     }
 
     ast::Access access = ast::Access::kUndefined;
-    if (sc == ast::StorageClass::kStorage) {
+    if (address_space == ast::AddressSpace::kStorage) {
         bool read_only = false;
         if (auto* tn = storage_type->As<Named>()) {
             read_only = read_only_struct_types_.count(tn->name) > 0;
@@ -1575,19 +1575,19 @@
     }
 
     // Handle variables (textures and samplers) are always in the handle
-    // storage class, so we don't mention the storage class.
-    if (sc == ast::StorageClass::kHandle) {
-        sc = ast::StorageClass::kNone;
+    // address space, so we don't mention the address space.
+    if (address_space == ast::AddressSpace::kHandle) {
+        address_space = ast::AddressSpace::kNone;
     }
 
     if (!ConvertDecorationsForVariable(id, &storage_type, &decorations,
-                                       sc != ast::StorageClass::kPrivate)) {
+                                       address_space != ast::AddressSpace::kPrivate)) {
         return nullptr;
     }
 
     auto sym = builder_.Symbols().Register(namer_.Name(id));
-    return create<ast::Var>(Source{}, sym, storage_type->Build(builder_), sc, access, constructor,
-                            decorations);
+    return create<ast::Var>(Source{}, sym, storage_type->Build(builder_), address_space, access,
+                            constructor, decorations);
 }
 
 ast::Let* ParserImpl::MakeLet(uint32_t id, const Type* type, const ast::Expression* constructor) {
@@ -2486,7 +2486,7 @@
     }
 
     // Form the pointer type.
-    auto* result = ty_.Pointer(ast_store_type, ast::StorageClass::kHandle);
+    auto* result = ty_.Pointer(ast_store_type, ast::AddressSpace::kHandle);
     // Remember it for later.
     handle_type_[&var] = result;
     return result;
diff --git a/src/tint/reader/spirv/parser_impl.h b/src/tint/reader/spirv/parser_impl.h
index 948a9a8..11cbe7c 100644
--- a/src/tint/reader/spirv/parser_impl.h
+++ b/src/tint/reader/spirv/parser_impl.h
@@ -50,7 +50,7 @@
 ///
 /// A WGSL "handle" is an opaque object used for accessing a resource via
 /// special builtins.  In SPIR-V, a handle is stored a variable in the
-/// UniformConstant storage class.  The handles supported by SPIR-V are:
+/// UniformConstant address space.  The handles supported by SPIR-V are:
 ///   - images, both sampled texture and storage image
 ///   - samplers
 ///   - combined image+sampler
@@ -424,14 +424,14 @@
     /// Creates an AST 'var' node for a SPIR-V ID, including any attached decorations, unless it's
     /// an ignorable builtin variable.
     /// @param id the SPIR-V result ID
-    /// @param sc the storage class, which cannot be ast::StorageClass::kNone
+    /// @param address_space the address space, which cannot be ast::AddressSpace::kNone
     /// @param storage_type the storage type of the variable
     /// @param constructor the variable constructor
     /// @param decorations the variable decorations
     /// @returns a new Variable node, or null in the ignorable variable case and
     /// in the error case
     ast::Var* MakeVar(uint32_t id,
-                      ast::StorageClass sc,
+                      ast::AddressSpace address_space,
                       const Type* storage_type,
                       const ast::Expression* constructor,
                       AttributeList decorations);
@@ -583,7 +583,7 @@
         /// The ID of the type of a pointer to the struct in the Output storage
         /// class class.
         uint32_t pointer_type_id = 0;
-        /// The SPIR-V storage class.
+        /// The SPIR-V address space.
         SpvStorageClass storage_class = SpvStorageClassOutput;
         /// The ID of the type of a pointer to the Position member.
         uint32_t position_member_pointer_type_id = 0;
@@ -640,8 +640,8 @@
     Usage GetHandleUsage(uint32_t id) const;
 
     /// Returns the SPIR-V type for the sampler or image type for the given
-    /// variable in UniformConstant storage class, or function parameter pointing
-    /// into the UniformConstant storage class .  Returns null and emits an
+    /// variable in UniformConstant address space, or function parameter pointing
+    /// into the UniformConstant address space .  Returns null and emits an
     /// error on failure.
     /// @param var the OpVariable instruction or OpFunctionParameter
     /// @returns the Tint AST type for the sampler or texture, or null on error
@@ -649,7 +649,7 @@
         const spvtools::opt::Instruction& var);
 
     /// Returns the AST type for the pointer-to-sampler or pointer-to-texture type
-    /// for the given variable in UniformConstant storage class.  Returns null and
+    /// for the given variable in UniformConstant address space.  Returns null and
     /// emits an error on failure.
     /// @param var the OpVariable instruction
     /// @returns the Tint AST type for the poiner-to-{sampler|texture} or null on
@@ -841,8 +841,8 @@
     // - an array, runtime array containing one of these
     // - a pointer type to one of these
     // These are the types "enclosing" a buffer block with the old style
-    // representation: using Uniform storage class and BufferBlock decoration
-    // on the struct.  The new style is to use the StorageBuffer storage class
+    // representation: using Uniform address space and BufferBlock decoration
+    // on the struct.  The new style is to use the StorageBuffer address space
     // and Block decoration.
     std::unordered_set<uint32_t> remap_buffer_block_type_;
 
diff --git a/src/tint/reader/spirv/parser_impl_convert_type_test.cc b/src/tint/reader/spirv/parser_impl_convert_type_test.cc
index 6cedddb..3b8fa62 100644
--- a/src/tint/reader/spirv/parser_impl_convert_type_test.cc
+++ b/src/tint/reader/spirv/parser_impl_convert_type_test.cc
@@ -709,11 +709,11 @@
     EXPECT_THAT(p->error(), Eq("SPIR-V pointer type with ID 3 has invalid pointee type 42"));
 }
 
-TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidStorageClass) {
-    // Disallow invalid storage class
+TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidAddressSpace) {
+    // Disallow invalid address space
     auto p = parser(test::Assemble(Preamble() + R"(
   %1 = OpTypeFloat 32
-  %3 = OpTypePointer !999 %1   ; Special syntax to inject 999 as the storage class
+  %3 = OpTypePointer !999 %1   ; Special syntax to inject 999 as the address space
   )" + MainBody()));
     // TODO(dneto): I can't get it past module building.
     EXPECT_FALSE(p->BuildInternalModule()) << p->error();
@@ -731,7 +731,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kPrivate);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kPrivate);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -747,7 +747,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kPrivate);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kPrivate);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -763,7 +763,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kUniform);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kUniform);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -779,7 +779,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kWorkgroup);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kWorkgroup);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -795,7 +795,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kNone);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kNone);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -811,7 +811,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kStorage);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kStorage);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -827,7 +827,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kPrivate);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kPrivate);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -843,7 +843,7 @@
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
     EXPECT_TRUE(ptr_ty->type->Is<F32>());
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kFunction);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kFunction);
     EXPECT_TRUE(p->error().empty());
 }
 
@@ -862,12 +862,12 @@
 
     auto* ptr_ty = type->As<Pointer>();
     EXPECT_NE(ptr_ty, nullptr);
-    EXPECT_EQ(ptr_ty->storage_class, ast::StorageClass::kPrivate);
+    EXPECT_EQ(ptr_ty->address_space, ast::AddressSpace::kPrivate);
     EXPECT_TRUE(ptr_ty->type->Is<Pointer>());
 
     auto* ptr_ptr_ty = ptr_ty->type->As<Pointer>();
     EXPECT_NE(ptr_ptr_ty, nullptr);
-    EXPECT_EQ(ptr_ptr_ty->storage_class, ast::StorageClass::kPrivate);
+    EXPECT_EQ(ptr_ptr_ty->address_space, ast::AddressSpace::kPrivate);
     EXPECT_TRUE(ptr_ptr_ty->type->Is<F32>());
 
     EXPECT_TRUE(p->error().empty());
diff --git a/src/tint/reader/spirv/parser_impl_module_var_test.cc b/src/tint/reader/spirv/parser_impl_module_var_test.cc
index 6e8b4fc..44fc4b3 100644
--- a/src/tint/reader/spirv/parser_impl_module_var_test.cc
+++ b/src/tint/reader/spirv/parser_impl_module_var_test.cc
@@ -119,7 +119,7 @@
     EXPECT_THAT(module_ast, Not(HasSubstr("Variable"))) << module_ast;
 }
 
-TEST_F(SpvModuleScopeVarParserTest, BadStorageClass_NotAWebGPUStorageClass) {
+TEST_F(SpvModuleScopeVarParserTest, BadAddressSpace_NotAWebGPUAddressSpace) {
     auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
     %float = OpTypeFloat 32
     %ptr = OpTypePointer CrossWorkgroup %float
@@ -135,7 +135,7 @@
     EXPECT_THAT(p->error(), HasSubstr("unknown SPIR-V storage class: 5"));
 }
 
-TEST_F(SpvModuleScopeVarParserTest, BadStorageClass_Function) {
+TEST_F(SpvModuleScopeVarParserTest, BadAddressSpace_Function) {
     auto p = parser(test::Assemble(Preamble() + FragMain() + R"(
     %float = OpTypeFloat 32
     %ptr = OpTypePointer Function %float
diff --git a/src/tint/reader/spirv/parser_type.cc b/src/tint/reader/spirv/parser_type.cc
index 5de62f6..256444a 100644
--- a/src/tint/reader/spirv/parser_type.cc
+++ b/src/tint/reader/spirv/parser_type.cc
@@ -50,11 +50,11 @@
 
 namespace {
 struct PointerHasher {
-    size_t operator()(const Pointer& t) const { return utils::Hash(t.type, t.storage_class); }
+    size_t operator()(const Pointer& t) const { return utils::Hash(t.type, t.address_space); }
 };
 
 struct ReferenceHasher {
-    size_t operator()(const Reference& t) const { return utils::Hash(t.type, t.storage_class); }
+    size_t operator()(const Reference& t) const { return utils::Hash(t.type, t.address_space); }
 };
 
 struct VectorHasher {
@@ -107,10 +107,10 @@
 // Equality operators
 //! @cond Doxygen_Suppress
 static bool operator==(const Pointer& a, const Pointer& b) {
-    return a.type == b.type && a.storage_class == b.storage_class;
+    return a.type == b.type && a.address_space == b.address_space;
 }
 static bool operator==(const Reference& a, const Reference& b) {
-    return a.type == b.type && a.storage_class == b.storage_class;
+    return a.type == b.type && a.address_space == b.address_space;
 }
 static bool operator==(const Vector& a, const Vector& b) {
     return a.type == b.type && a.size == b.size;
@@ -170,14 +170,14 @@
 
 Texture::~Texture() = default;
 
-Pointer::Pointer(const Type* t, ast::StorageClass s) : type(t), storage_class(s) {}
+Pointer::Pointer(const Type* t, ast::AddressSpace s) : type(t), address_space(s) {}
 Pointer::Pointer(const Pointer&) = default;
 
 const ast::Type* Pointer::Build(ProgramBuilder& b) const {
-    return b.ty.pointer(type->Build(b), storage_class);
+    return b.ty.pointer(type->Build(b), address_space);
 }
 
-Reference::Reference(const Type* t, ast::StorageClass s) : type(t), storage_class(s) {}
+Reference::Reference(const Type* t, ast::AddressSpace s) : type(t), address_space(s) {}
 Reference::Reference(const Reference&) = default;
 
 const ast::Type* Reference::Build(ProgramBuilder& b) const {
@@ -438,12 +438,12 @@
     return state->i32_;
 }
 
-const spirv::Pointer* TypeManager::Pointer(const Type* el, ast::StorageClass sc) {
-    return state->pointers_.Get(el, sc);
+const spirv::Pointer* TypeManager::Pointer(const Type* el, ast::AddressSpace address_space) {
+    return state->pointers_.Get(el, address_space);
 }
 
-const spirv::Reference* TypeManager::Reference(const Type* el, ast::StorageClass sc) {
-    return state->references_.Get(el, sc);
+const spirv::Reference* TypeManager::Reference(const Type* el, ast::AddressSpace address_space) {
+    return state->references_.Get(el, address_space);
 }
 
 const spirv::Vector* TypeManager::Vector(const Type* el, uint32_t size) {
@@ -519,13 +519,13 @@
 
 std::string Pointer::String() const {
     std::stringstream ss;
-    ss << "ptr<" << utils::ToString(storage_class) << ", " << type->String() + ">";
+    ss << "ptr<" << utils::ToString(address_space) << ", " << type->String() + ">";
     return ss.str();
 }
 
 std::string Reference::String() const {
     std::stringstream ss;
-    ss << "ref<" + utils::ToString(storage_class) << ", " << type->String() << ">";
+    ss << "ref<" + utils::ToString(address_space) << ", " << type->String() << ">";
     return ss.str();
 }
 
diff --git a/src/tint/reader/spirv/parser_type.h b/src/tint/reader/spirv/parser_type.h
index 9543b51..4c67f7a 100644
--- a/src/tint/reader/spirv/parser_type.h
+++ b/src/tint/reader/spirv/parser_type.h
@@ -20,8 +20,8 @@
 #include <vector>
 
 #include "src/tint/ast/access.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/sampler.h"
-#include "src/tint/ast/storage_class.h"
 #include "src/tint/ast/storage_texture.h"
 #include "src/tint/ast/texture.h"
 #include "src/tint/castable.h"
@@ -161,8 +161,8 @@
 struct Pointer final : public Castable<Pointer, Type> {
     /// Constructor
     /// @param ty the store type
-    /// @param sc the pointer storage class
-    Pointer(const Type* ty, ast::StorageClass sc);
+    /// @param sc the pointer address space
+    Pointer(const Type* ty, ast::AddressSpace sc);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -179,8 +179,8 @@
 
     /// the store type
     Type const* const type;
-    /// the pointer storage class
-    ast::StorageClass const storage_class;
+    /// the pointer address space
+    ast::AddressSpace const address_space;
 };
 
 /// `ref<SC, T>` type
@@ -189,8 +189,8 @@
 struct Reference final : public Castable<Reference, Type> {
     /// Constructor
     /// @param ty the referenced type
-    /// @param sc the reference storage class
-    Reference(const Type* ty, ast::StorageClass sc);
+    /// @param sc the reference address space
+    Reference(const Type* ty, ast::AddressSpace sc);
 
     /// Copy constructor
     /// @param other the other type to copy
@@ -207,8 +207,8 @@
 
     /// the store type
     Type const* const type;
-    /// the pointer storage class
-    ast::StorageClass const storage_class;
+    /// the pointer address space
+    ast::AddressSpace const address_space;
 };
 
 /// `vecN<T>` type
@@ -534,15 +534,15 @@
     /// @return a I32 type. Repeated calls will return the same pointer.
     const spirv::I32* I32();
     /// @param ty the store type
-    /// @param sc the pointer storage class
+    /// @param address_space the pointer address space
     /// @return a Pointer type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const spirv::Pointer* Pointer(const Type* ty, ast::StorageClass sc);
+    const spirv::Pointer* Pointer(const Type* ty, ast::AddressSpace address_space);
     /// @param ty the referenced type
-    /// @param sc the reference storage class
+    /// @param address_space the reference address space
     /// @return a Reference type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const spirv::Reference* Reference(const Type* ty, ast::StorageClass sc);
+    const spirv::Reference* Reference(const Type* ty, ast::AddressSpace address_space);
     /// @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
diff --git a/src/tint/reader/spirv/parser_type_test.cc b/src/tint/reader/spirv/parser_type_test.cc
index 37ac113..90a8da2 100644
--- a/src/tint/reader/spirv/parser_type_test.cc
+++ b/src/tint/reader/spirv/parser_type_test.cc
@@ -28,8 +28,8 @@
     EXPECT_EQ(ty.U32(), ty.U32());
     EXPECT_EQ(ty.F32(), ty.F32());
     EXPECT_EQ(ty.I32(), ty.I32());
-    EXPECT_EQ(ty.Pointer(ty.I32(), ast::StorageClass::kNone),
-              ty.Pointer(ty.I32(), ast::StorageClass::kNone));
+    EXPECT_EQ(ty.Pointer(ty.I32(), ast::AddressSpace::kNone),
+              ty.Pointer(ty.I32(), ast::AddressSpace::kNone));
     EXPECT_EQ(ty.Vector(ty.I32(), 3), ty.Vector(ty.I32(), 3));
     EXPECT_EQ(ty.Matrix(ty.I32(), 3, 2), ty.Matrix(ty.I32(), 3, 2));
     EXPECT_EQ(ty.Array(ty.I32(), 3, 2), ty.Array(ty.I32(), 3, 2));
@@ -53,10 +53,10 @@
     Symbol sym_b(Symbol(2, {}));
 
     TypeManager ty;
-    EXPECT_NE(ty.Pointer(ty.I32(), ast::StorageClass::kNone),
-              ty.Pointer(ty.U32(), ast::StorageClass::kNone));
-    EXPECT_NE(ty.Pointer(ty.I32(), ast::StorageClass::kNone),
-              ty.Pointer(ty.I32(), ast::StorageClass::kIn));
+    EXPECT_NE(ty.Pointer(ty.I32(), ast::AddressSpace::kNone),
+              ty.Pointer(ty.U32(), ast::AddressSpace::kNone));
+    EXPECT_NE(ty.Pointer(ty.I32(), ast::AddressSpace::kNone),
+              ty.Pointer(ty.I32(), ast::AddressSpace::kIn));
     EXPECT_NE(ty.Vector(ty.I32(), 3), ty.Vector(ty.U32(), 3));
     EXPECT_NE(ty.Vector(ty.I32(), 3), ty.Vector(ty.I32(), 2));
     EXPECT_NE(ty.Matrix(ty.I32(), 3, 2), ty.Matrix(ty.U32(), 3, 2));
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index cb7cb6a..edf90d3 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -206,12 +206,12 @@
 
 ParserImpl::VarDeclInfo::VarDeclInfo(Source source_in,
                                      std::string name_in,
-                                     ast::StorageClass storage_class_in,
+                                     ast::AddressSpace address_space_in,
                                      ast::Access access_in,
                                      const ast::Type* type_in)
     : source(std::move(source_in)),
       name(std::move(name_in)),
-      storage_class(storage_class_in),
+      address_space(address_space_in),
       access(access_in),
       type(type_in) {}
 
@@ -594,7 +594,7 @@
     return create<ast::Var>(decl->source,                             // source
                             builder_.Symbols().Register(decl->name),  // symbol
                             decl->type,                               // type
-                            decl->storage_class,                      // storage class
+                            decl->address_space,                      // address space
                             decl->access,                             // access control
                             initializer,                              // initializer
                             std::move(attrs));                        // attributes
@@ -697,7 +697,7 @@
         return Failure::kErrored;
     }
 
-    return VarDeclInfo{decl->source, decl->name, vq.storage_class, vq.access, decl->type};
+    return VarDeclInfo{decl->source, decl->name, vq.address_space, vq.access, decl->type};
 }
 
 // texture_and_sampler_types
@@ -1208,7 +1208,7 @@
 Expect<const ast::Type*> ParserImpl::expect_type_decl_pointer(const Source& s) {
     const char* use = "ptr declaration";
 
-    auto storage_class = ast::StorageClass::kNone;
+    auto address_space = ast::AddressSpace::kNone;
     auto access = ast::Access::kUndefined;
 
     auto subtype = expect_lt_gt_block(use, [&]() -> Expect<const ast::Type*> {
@@ -1216,7 +1216,7 @@
         if (sc.errored) {
             return Failure::kErrored;
         }
-        storage_class = sc.value;
+        address_space = sc.value;
 
         if (!expect(use, Token::Type::kComma)) {
             return Failure::kErrored;
@@ -1242,7 +1242,7 @@
         return Failure::kErrored;
     }
 
-    return builder_.ty.pointer(make_source_range_from(s), subtype.value, storage_class, access);
+    return builder_.ty.pointer(make_source_range_from(s), subtype.value, address_space, access);
 }
 
 // LESS_THAN type_decl GREATER_THAN
@@ -1329,19 +1329,19 @@
 //   | 'storage'
 //
 // Note, we also parse `push_constant` from the experimental extension
-Expect<ast::StorageClass> ParserImpl::expect_address_space(std::string_view use) {
+Expect<ast::AddressSpace> ParserImpl::expect_address_space(std::string_view use) {
     auto& t = peek();
-    auto ident = expect_ident("storage class");
+    auto ident = expect_ident("address space");
     if (ident.errored) {
         return Failure::kErrored;
     }
 
-    auto storage_class = ast::ParseStorageClass(ident.value);
-    if (storage_class == ast::StorageClass::kInvalid) {
-        return add_error(t.source(), "invalid storage class", use);
+    auto address_space = ast::ParseAddressSpace(ident.value);
+    if (address_space == ast::AddressSpace::kInvalid) {
+        return add_error(t.source(), "invalid address space", use);
     }
 
-    return {storage_class, t.source()};
+    return {address_space, t.source()};
 }
 
 // struct_decl
@@ -1988,7 +1988,7 @@
     auto* var = create<ast::Var>(decl->source,                             // source
                                  builder_.Symbols().Register(decl->name),  // symbol
                                  decl->type,                               // type
-                                 decl->storage_class,                      // storage class
+                                 decl->address_space,                      // address space
                                  decl->access,                             // access control
                                  initializer,                              // initializer
                                  utils::Empty);                            // attributes
diff --git a/src/tint/reader/wgsl/parser_impl.h b/src/tint/reader/wgsl/parser_impl.h
index cc0cd2b..4d338c2 100644
--- a/src/tint/reader/wgsl/parser_impl.h
+++ b/src/tint/reader/wgsl/parser_impl.h
@@ -278,12 +278,12 @@
         /// Constructor
         /// @param source_in variable declaration source
         /// @param name_in variable name
-        /// @param storage_class_in variable storage class
+        /// @param address_space_in variable address space
         /// @param access_in variable access control
         /// @param type_in variable type
         VarDeclInfo(Source source_in,
                     std::string name_in,
-                    ast::StorageClass storage_class_in,
+                    ast::AddressSpace address_space_in,
                     ast::Access access_in,
                     const ast::Type* type_in);
         /// Destructor
@@ -293,8 +293,8 @@
         Source source;
         /// Variable name
         std::string name;
-        /// Variable storage class
-        ast::StorageClass storage_class = ast::StorageClass::kNone;
+        /// Variable address space
+        ast::AddressSpace address_space = ast::AddressSpace::kNone;
         /// Variable access control
         ast::Access access = ast::Access::kUndefined;
         /// Variable type
@@ -303,8 +303,8 @@
 
     /// VariableQualifier contains the parsed information for a variable qualifier
     struct VariableQualifier {
-        /// The variable's storage class
-        ast::StorageClass storage_class = ast::StorageClass::kNone;
+        /// The variable's address space
+        ast::AddressSpace address_space = ast::AddressSpace::kNone;
         /// The variable's access control
         ast::Access access = ast::Access::kUndefined;
     };
@@ -460,8 +460,8 @@
     Maybe<const ast::Type*> type_decl();
     /// Parses an `address_space` grammar element, erroring on parse failure.
     /// @param use a description of what was being parsed if an error was raised.
-    /// @returns the address space or StorageClass::kNone if none matched
-    Expect<ast::StorageClass> expect_address_space(std::string_view use);
+    /// @returns the address space or ast::AddressSpace::kNone if none matched
+    Expect<ast::AddressSpace> expect_address_space(std::string_view use);
     /// Parses a `struct_decl` grammar element.
     /// @returns the struct type or nullptr on error
     Maybe<const ast::Struct*> struct_decl();
diff --git a/src/tint/reader/wgsl/parser_impl_storage_class_test.cc b/src/tint/reader/wgsl/parser_impl_address_space_test.cc
similarity index 60%
rename from src/tint/reader/wgsl/parser_impl_storage_class_test.cc
rename to src/tint/reader/wgsl/parser_impl_address_space_test.cc
index c6ef7eb..d9d6d5e 100644
--- a/src/tint/reader/wgsl/parser_impl_storage_class_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_address_space_test.cc
@@ -17,18 +17,18 @@
 namespace tint::reader::wgsl {
 namespace {
 
-struct StorageClassData {
+struct AddressSpaceData {
     const char* input;
-    ast::StorageClass result;
+    ast::AddressSpace result;
 };
-inline std::ostream& operator<<(std::ostream& out, StorageClassData data) {
+inline std::ostream& operator<<(std::ostream& out, AddressSpaceData data) {
     out << std::string(data.input);
     return out;
 }
 
-class ParserStorageClassTest : public ParserImplTestWithParam<StorageClassData> {};
+class ParserAddressSpaceTest : public ParserImplTestWithParam<AddressSpaceData> {};
 
-TEST_P(ParserStorageClassTest, Parses) {
+TEST_P(ParserAddressSpaceTest, Parses) {
     auto params = GetParam();
     auto p = parser(params.input);
 
@@ -42,19 +42,19 @@
 }
 INSTANTIATE_TEST_SUITE_P(
     ParserImplTest,
-    ParserStorageClassTest,
-    testing::Values(StorageClassData{"uniform", ast::StorageClass::kUniform},
-                    StorageClassData{"workgroup", ast::StorageClass::kWorkgroup},
-                    StorageClassData{"storage", ast::StorageClass::kStorage},
-                    StorageClassData{"private", ast::StorageClass::kPrivate},
-                    StorageClassData{"function", ast::StorageClass::kFunction}));
+    ParserAddressSpaceTest,
+    testing::Values(AddressSpaceData{"uniform", ast::AddressSpace::kUniform},
+                    AddressSpaceData{"workgroup", ast::AddressSpace::kWorkgroup},
+                    AddressSpaceData{"storage", ast::AddressSpace::kStorage},
+                    AddressSpaceData{"private", ast::AddressSpace::kPrivate},
+                    AddressSpaceData{"function", ast::AddressSpace::kFunction}));
 
-TEST_F(ParserImplTest, StorageClass_NoMatch) {
-    auto p = parser("not-a-storage-class");
+TEST_F(ParserImplTest, AddressSpace_NoMatch) {
+    auto p = parser("not-a-address-space");
     auto sc = p->expect_address_space("test");
     EXPECT_EQ(sc.errored, true);
     EXPECT_TRUE(p->has_error());
-    EXPECT_EQ(p->error(), "1:1: invalid storage class for test");
+    EXPECT_EQ(p->error(), "1:1: invalid address space for test");
 }
 
 }  // namespace
diff --git a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
index 9fad55c..7ea5aaa 100644
--- a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
@@ -1105,9 +1105,9 @@
 )");
 }
 
-TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingStorageClass) {
+TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingAddressSpace) {
     EXPECT("var i : ptr<meow, u32>;",
-           R"(test.wgsl:1:13 error: invalid storage class for ptr declaration
+           R"(test.wgsl:1:13 error: invalid address space for ptr declaration
 var i : ptr<meow, u32>;
             ^^^^
 )");
@@ -1139,7 +1139,7 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarStorageDeclInvalidClass) {
     EXPECT("var<fish> i : i32",
-           R"(test.wgsl:1:5 error: invalid storage class for variable declaration
+           R"(test.wgsl:1:5 error: invalid address space for variable declaration
 var<fish> i : i32
     ^^^^
 )");
diff --git a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
index 85f4702..d6e475a 100644
--- a/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc
@@ -31,7 +31,7 @@
 
     EXPECT_EQ(var->symbol, p->builder().Symbols().Get("a"));
     EXPECT_TRUE(var->type->Is<ast::F32>());
-    EXPECT_EQ(var->declared_storage_class, ast::StorageClass::kPrivate);
+    EXPECT_EQ(var->declared_address_space, ast::AddressSpace::kPrivate);
 
     EXPECT_EQ(var->source.range.begin.line, 1u);
     EXPECT_EQ(var->source.range.begin.column, 14u);
@@ -55,7 +55,7 @@
 
     EXPECT_EQ(var->symbol, p->builder().Symbols().Get("a"));
     EXPECT_TRUE(var->type->Is<ast::F32>());
-    EXPECT_EQ(var->declared_storage_class, ast::StorageClass::kPrivate);
+    EXPECT_EQ(var->declared_address_space, ast::AddressSpace::kPrivate);
 
     EXPECT_EQ(var->source.range.begin.line, 1u);
     EXPECT_EQ(var->source.range.begin.column, 14u);
@@ -81,7 +81,7 @@
     EXPECT_EQ(var->symbol, p->builder().Symbols().Get("a"));
     ASSERT_NE(var->type, nullptr);
     EXPECT_TRUE(var->type->Is<ast::F32>());
-    EXPECT_EQ(var->declared_storage_class, ast::StorageClass::kUniform);
+    EXPECT_EQ(var->declared_address_space, ast::AddressSpace::kUniform);
 
     EXPECT_EQ(var->source.range.begin.line, 1u);
     EXPECT_EQ(var->source.range.begin.column, 36u);
@@ -112,7 +112,7 @@
     EXPECT_EQ(var->symbol, p->builder().Symbols().Get("a"));
     ASSERT_NE(var->type, nullptr);
     EXPECT_TRUE(var->type->Is<ast::F32>());
-    EXPECT_EQ(var->declared_storage_class, ast::StorageClass::kUniform);
+    EXPECT_EQ(var->declared_address_space, ast::AddressSpace::kUniform);
 
     EXPECT_EQ(var->source.range.begin.line, 1u);
     EXPECT_EQ(var->source.range.begin.column, 36u);
@@ -165,7 +165,7 @@
     EXPECT_TRUE(e.errored);
     EXPECT_FALSE(e.matched);
     EXPECT_EQ(e.value, nullptr);
-    EXPECT_EQ(p->error(), "1:5: invalid storage class for variable declaration");
+    EXPECT_EQ(p->error(), "1:5: invalid address space for variable declaration");
 }
 
 }  // namespace
diff --git a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
index 926f7c7..ba8339e 100644
--- a/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_decl_test.cc
@@ -176,7 +176,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::F32>());
-    ASSERT_EQ(ptr->storage_class, ast::StorageClass::kFunction);
+    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
 }
 
@@ -191,7 +191,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::F32>());
-    ASSERT_EQ(ptr->storage_class, ast::StorageClass::kFunction);
+    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
     ASSERT_EQ(ptr->access, ast::Access::kRead);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
 }
@@ -207,7 +207,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::Vector>());
-    ASSERT_EQ(ptr->storage_class, ast::StorageClass::kFunction);
+    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
 
     auto* vec = ptr->type->As<ast::Vector>();
     ASSERT_EQ(vec->width, 2u);
@@ -245,7 +245,7 @@
     ASSERT_EQ(p->error(), "1:24: expected '>' for ptr declaration");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterStorageClass) {
+TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAddressSpace) {
     auto p = parser("ptr<function f32>");
     auto t = p->type_decl();
     EXPECT_TRUE(t.errored);
@@ -265,14 +265,14 @@
     ASSERT_EQ(p->error(), "1:19: expected '>' for ptr declaration");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_MissingStorageClass) {
+TEST_F(ParserImplTest, TypeDecl_Ptr_MissingAddressSpace) {
     auto p = parser("ptr<, f32>");
     auto t = p->type_decl();
     EXPECT_TRUE(t.errored);
     EXPECT_FALSE(t.matched);
     ASSERT_EQ(t.value, nullptr);
     ASSERT_TRUE(p->has_error());
-    ASSERT_EQ(p->error(), "1:5: expected identifier for storage class");
+    ASSERT_EQ(p->error(), "1:5: expected identifier for address space");
 }
 
 TEST_F(ParserImplTest, TypeDecl_Ptr_MissingType) {
@@ -302,17 +302,17 @@
     EXPECT_FALSE(t.matched);
     ASSERT_EQ(t.value, nullptr);
     ASSERT_TRUE(p->has_error());
-    ASSERT_EQ(p->error(), "1:5: expected identifier for storage class");
+    ASSERT_EQ(p->error(), "1:5: expected identifier for address space");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_BadStorageClass) {
+TEST_F(ParserImplTest, TypeDecl_Ptr_BadAddressSpace) {
     auto p = parser("ptr<unknown, f32>");
     auto t = p->type_decl();
     EXPECT_TRUE(t.errored);
     EXPECT_FALSE(t.matched);
     ASSERT_EQ(t.value, nullptr);
     ASSERT_TRUE(p->has_error());
-    ASSERT_EQ(p->error(), "1:5: invalid storage class for ptr declaration");
+    ASSERT_EQ(p->error(), "1:5: invalid address space for ptr declaration");
 }
 
 TEST_F(ParserImplTest, TypeDecl_Ptr_BadAccess) {
diff --git a/src/tint/reader/wgsl/parser_impl_type_decl_without_ident_test.cc b/src/tint/reader/wgsl/parser_impl_type_decl_without_ident_test.cc
index ec23f2f..541687e 100644
--- a/src/tint/reader/wgsl/parser_impl_type_decl_without_ident_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_type_decl_without_ident_test.cc
@@ -167,7 +167,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::F32>());
-    ASSERT_EQ(ptr->storage_class, ast::StorageClass::kFunction);
+    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
 }
 
@@ -182,7 +182,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::F32>());
-    ASSERT_EQ(ptr->storage_class, ast::StorageClass::kFunction);
+    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
     ASSERT_EQ(ptr->access, ast::Access::kRead);
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
 }
@@ -198,7 +198,7 @@
 
     auto* ptr = t.value->As<ast::Pointer>();
     ASSERT_TRUE(ptr->type->Is<ast::Vector>());
-    ASSERT_EQ(ptr->storage_class, ast::StorageClass::kFunction);
+    ASSERT_EQ(ptr->address_space, ast::AddressSpace::kFunction);
 
     auto* vec = ptr->type->As<ast::Vector>();
     ASSERT_EQ(vec->width, 2u);
@@ -236,7 +236,7 @@
     ASSERT_EQ(p->error(), "1:24: expected '>' for ptr declaration");
 }
 
-TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingCommaAfterStorageClass) {
+TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingCommaAfterAddressSpace) {
     auto p = parser("ptr<function f32>");
     auto t = p->type_decl_without_ident();
     EXPECT_TRUE(t.errored);
@@ -256,14 +256,14 @@
     ASSERT_EQ(p->error(), "1:19: expected '>' for ptr declaration");
 }
 
-TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingStorageClass) {
+TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingAddressSpace) {
     auto p = parser("ptr<, f32>");
     auto t = p->type_decl_without_ident();
     EXPECT_TRUE(t.errored);
     EXPECT_FALSE(t.matched);
     ASSERT_EQ(t.value, nullptr);
     ASSERT_TRUE(p->has_error());
-    ASSERT_EQ(p->error(), "1:5: expected identifier for storage class");
+    ASSERT_EQ(p->error(), "1:5: expected identifier for address space");
 }
 
 TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_MissingType) {
@@ -293,17 +293,17 @@
     EXPECT_FALSE(t.matched);
     ASSERT_EQ(t.value, nullptr);
     ASSERT_TRUE(p->has_error());
-    ASSERT_EQ(p->error(), "1:5: expected identifier for storage class");
+    ASSERT_EQ(p->error(), "1:5: expected identifier for address space");
 }
 
-TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_BadStorageClass) {
+TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_BadAddressSpace) {
     auto p = parser("ptr<unknown, f32>");
     auto t = p->type_decl_without_ident();
     EXPECT_TRUE(t.errored);
     EXPECT_FALSE(t.matched);
     ASSERT_EQ(t.value, nullptr);
     ASSERT_TRUE(p->has_error());
-    ASSERT_EQ(p->error(), "1:5: invalid storage class for ptr declaration");
+    ASSERT_EQ(p->error(), "1:5: invalid address space for ptr declaration");
 }
 
 TEST_F(ParserImplTest, TypeDeclWithoutIdent_Ptr_BadAccess) {
diff --git a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
index 2fee83c..8427c6e 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_decl_test.cc
@@ -72,7 +72,7 @@
     ASSERT_TRUE(t.IsIdentifier());
 }
 
-TEST_F(ParserImplTest, VariableDecl_WithStorageClass) {
+TEST_F(ParserImplTest, VariableDecl_WithAddressSpace) {
     auto p = parser("var<private> my_var : f32");
     auto v = p->variable_decl();
     EXPECT_TRUE(v.matched);
@@ -80,7 +80,7 @@
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(v->name, "my_var");
     EXPECT_TRUE(v->type->Is<ast::F32>());
-    EXPECT_EQ(v->storage_class, ast::StorageClass::kPrivate);
+    EXPECT_EQ(v->address_space, ast::AddressSpace::kPrivate);
 
     EXPECT_EQ(v->source.range.begin.line, 1u);
     EXPECT_EQ(v->source.range.begin.column, 14u);
@@ -96,16 +96,16 @@
     EXPECT_FALSE(p->has_error());
     EXPECT_EQ(v->name, "my_var");
     EXPECT_TRUE(v->type->Is<ast::F32>());
-    EXPECT_EQ(v->storage_class, ast::StorageClass::kPushConstant);
+    EXPECT_EQ(v->address_space, ast::AddressSpace::kPushConstant);
 }
 
-TEST_F(ParserImplTest, VariableDecl_InvalidStorageClass) {
+TEST_F(ParserImplTest, VariableDecl_InvalidAddressSpace) {
     auto p = parser("var<unknown> my_var : f32");
     auto v = p->variable_decl();
     EXPECT_FALSE(v.matched);
     EXPECT_TRUE(v.errored);
     EXPECT_TRUE(p->has_error());
-    EXPECT_EQ(p->error(), "1:5: invalid storage class for variable declaration");
+    EXPECT_EQ(p->error(), "1:5: invalid address space for variable declaration");
 }
 
 }  // namespace
diff --git a/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc b/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
index 5362d38..9f8663d 100644
--- a/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_variable_qualifier_test.cc
@@ -19,7 +19,7 @@
 
 struct VariableStorageData {
     const char* input;
-    ast::StorageClass storage_class;
+    ast::AddressSpace address_space;
     ast::Access access;
 };
 inline std::ostream& operator<<(std::ostream& out, VariableStorageData data) {
@@ -29,7 +29,7 @@
 
 class VariableQualifierTest : public ParserImplTestWithParam<VariableStorageData> {};
 
-TEST_P(VariableQualifierTest, ParsesStorageClass) {
+TEST_P(VariableQualifierTest, ParsesAddressSpace) {
     auto params = GetParam();
     auto p = parser(std::string("<") + params.input + ">");
 
@@ -37,7 +37,7 @@
     EXPECT_FALSE(p->has_error());
     EXPECT_FALSE(sc.errored);
     EXPECT_TRUE(sc.matched);
-    EXPECT_EQ(sc->storage_class, params.storage_class);
+    EXPECT_EQ(sc->address_space, params.address_space);
     EXPECT_EQ(sc->access, params.access);
 
     auto& t = p->next();
@@ -47,14 +47,14 @@
     ParserImplTest,
     VariableQualifierTest,
     testing::Values(
-        VariableStorageData{"uniform", ast::StorageClass::kUniform, ast::Access::kUndefined},
-        VariableStorageData{"workgroup", ast::StorageClass::kWorkgroup, ast::Access::kUndefined},
-        VariableStorageData{"storage", ast::StorageClass::kStorage, ast::Access::kUndefined},
-        VariableStorageData{"private", ast::StorageClass::kPrivate, ast::Access::kUndefined},
-        VariableStorageData{"function", ast::StorageClass::kFunction, ast::Access::kUndefined},
-        VariableStorageData{"storage, read", ast::StorageClass::kStorage, ast::Access::kRead},
-        VariableStorageData{"storage, write", ast::StorageClass::kStorage, ast::Access::kWrite},
-        VariableStorageData{"storage, read_write", ast::StorageClass::kStorage,
+        VariableStorageData{"uniform", ast::AddressSpace::kUniform, ast::Access::kUndefined},
+        VariableStorageData{"workgroup", ast::AddressSpace::kWorkgroup, ast::Access::kUndefined},
+        VariableStorageData{"storage", ast::AddressSpace::kStorage, ast::Access::kUndefined},
+        VariableStorageData{"private", ast::AddressSpace::kPrivate, ast::Access::kUndefined},
+        VariableStorageData{"function", ast::AddressSpace::kFunction, ast::Access::kUndefined},
+        VariableStorageData{"storage, read", ast::AddressSpace::kStorage, ast::Access::kRead},
+        VariableStorageData{"storage, write", ast::AddressSpace::kStorage, ast::Access::kWrite},
+        VariableStorageData{"storage, read_write", ast::AddressSpace::kStorage,
                             ast::Access::kReadWrite}));
 
 TEST_F(ParserImplTest, VariableQualifier_NoMatch) {
@@ -63,7 +63,7 @@
     EXPECT_TRUE(p->has_error());
     EXPECT_TRUE(sc.errored);
     EXPECT_FALSE(sc.matched);
-    EXPECT_EQ(p->error(), "1:2: invalid storage class for variable declaration");
+    EXPECT_EQ(p->error(), "1:2: invalid address space for variable declaration");
 }
 
 TEST_F(ParserImplTest, VariableQualifier_Empty) {
@@ -72,7 +72,7 @@
     EXPECT_TRUE(p->has_error());
     EXPECT_TRUE(sc.errored);
     EXPECT_FALSE(sc.matched);
-    EXPECT_EQ(p->error(), "1:2: expected identifier for storage class");
+    EXPECT_EQ(p->error(), "1:2: expected identifier for address space");
 }
 
 TEST_F(ParserImplTest, VariableQualifier_MissingLessThan) {
diff --git a/src/tint/resolver/storage_class_layout_validation_test.cc b/src/tint/resolver/address_space_layout_validation_test.cc
similarity index 89%
rename from src/tint/resolver/storage_class_layout_validation_test.cc
rename to src/tint/resolver/address_space_layout_validation_test.cc
index 818a7d0..82da573 100644
--- a/src/tint/resolver/storage_class_layout_validation_test.cc
+++ b/src/tint/resolver/address_space_layout_validation_test.cc
@@ -22,10 +22,10 @@
 namespace tint::resolver {
 namespace {
 
-using ResolverStorageClassLayoutValidationTest = ResolverTest;
+using ResolverAddressSpaceLayoutValidationTest = ResolverTest;
 
 // Detect unaligned member for storage buffers
-TEST_F(ResolverStorageClassLayoutValidationTest, StorageBuffer_UnalignedMember) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, StorageBuffer_UnalignedMember) {
     // struct S {
     //     @size(5) a : f32;
     //     @align(1) b : f32;
@@ -39,13 +39,13 @@
                   Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(1_i)}),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kStorage, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::AddressSpace::kStorage, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
-        R"(34:56 error: the offset of a struct member of type 'f32' in storage class 'storage' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting @align(4) on this member
+        R"(34:56 error: the offset of a struct member of type 'f32' in address space 'storage' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting @align(4) on this member
 12:34 note: see layout of struct:
 /*           align(4) size(12) */ struct S {
 /* offset(0) align(4) size( 5) */   a : f32;
@@ -55,7 +55,7 @@
 78:90 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest, StorageBuffer_UnalignedMember_SuggestedFix) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, StorageBuffer_UnalignedMember_SuggestedFix) {
     // struct S {
     //     @size(5) a : f32;
     //     @align(4) b : f32;
@@ -69,14 +69,14 @@
                   Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(4_i)}),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kStorage, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::AddressSpace::kStorage, Group(0_a),
               Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 // Detect unaligned struct member for uniform buffers
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_UnalignedMember_Struct) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_UnalignedMember_Struct) {
     // struct Inner {
     //   scalar : i32;
     // };
@@ -100,13 +100,13 @@
                   Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: the offset of a struct member of type 'Inner' in storage class 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting @align(16) on this member
+        R"(56:78 error: the offset of a struct member of type 'Inner' in address space 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting @align(16) on this member
 34:56 note: see layout of struct:
 /*           align(4) size(8) */ struct Outer {
 /* offset(0) align(4) size(4) */   scalar : f32;
@@ -119,7 +119,7 @@
 78:90 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest,
+TEST_F(ResolverAddressSpaceLayoutValidationTest,
        UniformBuffer_UnalignedMember_Struct_SuggestedFix) {
     // struct Inner {
     //   scalar : i32;
@@ -145,14 +145,14 @@
                          utils::Vector{MemberAlign(16_i)}),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 // Detect unaligned array member for uniform buffers
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_UnalignedMember_Array) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_UnalignedMember_Array) {
     // type Inner = @stride(16) array<f32, 10u>;
     //
     // struct Outer {
@@ -170,13 +170,13 @@
                   Member(Source{{56, 78}}, "inner", ty.type_name("Inner")),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: the offset of a struct member of type '@stride(16) array<f32, 10>' in storage class 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting @align(16) on this member
+        R"(56:78 error: the offset of a struct member of type '@stride(16) array<f32, 10>' in address space 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting @align(16) on this member
 12:34 note: see layout of struct:
 /*             align(4) size(164) */ struct Outer {
 /* offset(  0) align(4) size(  4) */   scalar : f32;
@@ -185,7 +185,7 @@
 78:90 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_UnalignedMember_Array_SuggestedFix) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_UnalignedMember_Array_SuggestedFix) {
     // type Inner = @stride(16) array<f32, 10u>;
     //
     // struct Outer {
@@ -204,7 +204,7 @@
                          utils::Vector{MemberAlign(16_i)}),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -212,7 +212,7 @@
 
 // Detect uniform buffers with byte offset between 2 members that is not a
 // multiple of 16 bytes
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_MembersOffsetNotMultipleOf16) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_MembersOffsetNotMultipleOf16) {
     // struct Inner {
     //   @align(1) @size(5) scalar : i32;
     // };
@@ -236,7 +236,7 @@
                   Member(Source{{78, 90}}, "scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -257,7 +257,7 @@
 }
 
 // See https://crbug.com/tint/1344
-TEST_F(ResolverStorageClassLayoutValidationTest,
+TEST_F(ResolverAddressSpaceLayoutValidationTest,
        UniformBuffer_MembersOffsetNotMultipleOf16_InnerMoreMembersThanOuter) {
     // struct Inner {
     //   a : i32;
@@ -288,7 +288,7 @@
                   Member(Source{{78, 90}}, "scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{22, 24}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -311,7 +311,7 @@
 22:24 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest,
+TEST_F(ResolverAddressSpaceLayoutValidationTest,
        UniformBuffer_MembersOffsetNotMultipleOf16_SuggestedFix) {
     // struct Inner {
     //   @align(1) @size(5) scalar : i32;
@@ -336,7 +336,7 @@
                   Member(Source{{78, 90}}, "scalar", ty.i32(), utils::Vector{MemberAlign(16_i)}),
               });
 
-    GlobalVar(Source{{22, 34}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{22, 34}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -344,7 +344,7 @@
 
 // Make sure that this doesn't fail validation because vec3's align is 16, but
 // size is 12. 's' should be at offset 12, which is okay here.
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_Vec3MemberOffset_NoFail) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_Vec3MemberOffset_NoFail) {
     // struct ScalarPackedAtEndOfVec3 {
     //     v : vec3<f32>;
     //     s : f32;
@@ -358,13 +358,13 @@
                                          });
 
     GlobalVar(Source{{78, 90}}, "a", ty.type_name("ScalarPackedAtEndOfVec3"),
-              ast::StorageClass::kUniform, Group(0_a), Binding(0_a));
+              ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 // Detect array stride must be a multiple of 16 bytes for uniform buffers
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_Scalar) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_Scalar) {
     // type Inner = array<f32, 10u>;
     //
     // struct Outer {
@@ -383,7 +383,7 @@
                   Member("scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -398,7 +398,7 @@
 78:90 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_Vector) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_Vector) {
     // type Inner = array<vec2<f32>, 10u>;
     //
     // struct Outer {
@@ -417,7 +417,7 @@
                   Member("scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -433,7 +433,7 @@
 78:90 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_Struct) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_Struct) {
     // struct ArrayElem {
     //   a : f32;
     //   b : i32;
@@ -460,7 +460,7 @@
                   Member("scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -475,11 +475,11 @@
 78:90 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_TopLevelArray) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_TopLevelArray) {
     // @group(0) @binding(0)
     // var<uniform> a : array<f32, 4u>;
     GlobalVar(Source{{78, 90}}, "a", ty.array(Source{{34, 56}}, ty.f32(), 4_u),
-              ast::StorageClass::kUniform, Group(0_a), Binding(0_a));
+              ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
@@ -487,7 +487,7 @@
         R"(34:56 error: uniform storage requires that array elements be aligned to 16 bytes, but array element alignment is currently 4. Consider using a vector or struct as the element type instead.)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_NestedArray) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_NestedArray) {
     // struct Outer {
     //   inner : array<array<f32, 4u>, 4u>
     // };
@@ -500,7 +500,7 @@
                   Member("inner", ty.array(Source{{34, 56}}, ty.array(ty.f32(), 4_u), 4_u)),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -514,7 +514,7 @@
 78:90 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest, UniformBuffer_InvalidArrayStride_SuggestedFix) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_SuggestedFix) {
     // type Inner = @stride(16) array<f32, 10u>;
     //
     // struct Outer {
@@ -533,14 +533,14 @@
                   Member("scalar", ty.i32()),
               });
 
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::StorageClass::kUniform, Group(0_a),
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("Outer"), ast::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
 // Detect unaligned member for push constants buffers
-TEST_F(ResolverStorageClassLayoutValidationTest, PushConstant_UnalignedMember) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, PushConstant_UnalignedMember) {
     // enable chromium_experimental_push_constant;
     // struct S {
     //     @size(5) a : f32;
@@ -552,12 +552,12 @@
         Source{{12, 34}}, "S",
         utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5_a)}),
                       Member(Source{{34, 56}}, "b", ty.f32(), utils::Vector{MemberAlign(1_i)})});
-    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::StorageClass::kPushConstant);
+    GlobalVar(Source{{78, 90}}, "a", ty.type_name("S"), ast::AddressSpace::kPushConstant);
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
-        R"(34:56 error: the offset of a struct member of type 'f32' in storage class 'push_constant' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting @align(4) on this member
+        R"(34:56 error: the offset of a struct member of type 'f32' in address space 'push_constant' must be a multiple of 4 bytes, but 'b' is currently at offset 5. Consider setting @align(4) on this member
 12:34 note: see layout of struct:
 /*           align(4) size(12) */ struct S {
 /* offset(0) align(4) size( 5) */   a : f32;
@@ -567,7 +567,7 @@
 78:90 note: see declaration of variable)");
 }
 
-TEST_F(ResolverStorageClassLayoutValidationTest, PushConstant_Aligned) {
+TEST_F(ResolverAddressSpaceLayoutValidationTest, PushConstant_Aligned) {
     // enable chromium_experimental_push_constant;
     // struct S {
     //     @size(5) a : f32;
@@ -577,7 +577,7 @@
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
     Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(5_a)}),
                                  Member("b", ty.f32(), utils::Vector{MemberAlign(4_i)})});
-    GlobalVar("a", ty.type_name("S"), ast::StorageClass::kPushConstant);
+    GlobalVar("a", ty.type_name("S"), ast::AddressSpace::kPushConstant);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
diff --git a/src/tint/resolver/storage_class_validation_test.cc b/src/tint/resolver/address_space_validation_test.cc
similarity index 61%
rename from src/tint/resolver/storage_class_validation_test.cc
rename to src/tint/resolver/address_space_validation_test.cc
index cff20c0..ae68013 100644
--- a/src/tint/resolver/storage_class_validation_test.cc
+++ b/src/tint/resolver/address_space_validation_test.cc
@@ -25,169 +25,169 @@
 
 using ::testing::HasSubstr;
 
-using ResolverStorageClassValidationTest = ResolverTest;
+using ResolverAddressSpaceValidationTest = ResolverTest;
 
-TEST_F(ResolverStorageClassValidationTest, GlobalVariableNoStorageClass_Fail) {
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariableNoAddressSpace_Fail) {
     // var g : f32;
     GlobalVar(Source{{12, 34}}, "g", ty.f32());
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: module-scope 'var' declaration must have a storage class");
+              "12:34 error: module-scope 'var' declaration must have a address space");
 }
 
-TEST_F(ResolverStorageClassValidationTest, GlobalVariableFunctionStorageClass_Fail) {
+TEST_F(ResolverAddressSpaceValidationTest, GlobalVariableFunctionAddressSpace_Fail) {
     // var<function> g : f32;
-    GlobalVar(Source{{12, 34}}, "g", ty.f32(), ast::StorageClass::kFunction);
+    GlobalVar(Source{{12, 34}}, "g", ty.f32(), ast::AddressSpace::kFunction);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: module-scope 'var' must not use storage class 'function'");
+              "12:34 error: module-scope 'var' must not use address space 'function'");
 }
 
-TEST_F(ResolverStorageClassValidationTest, Private_RuntimeArray) {
-    GlobalVar(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::StorageClass::kPrivate);
+TEST_F(ResolverAddressSpaceValidationTest, Private_RuntimeArray) {
+    GlobalVar(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
 12:34 note: while instantiating 'var' v)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, Private_RuntimeArrayInStruct) {
+TEST_F(ResolverAddressSpaceValidationTest, Private_RuntimeArrayInStruct) {
     auto* s = Structure("S", utils::Vector{Member("m", ty.array(ty.i32()))});
-    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
 note: while analysing structure member S.m
 12:34 note: while instantiating 'var' v)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, Workgroup_RuntimeArray) {
-    GlobalVar(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::StorageClass::kWorkgroup);
+TEST_F(ResolverAddressSpaceValidationTest, Workgroup_RuntimeArray) {
+    GlobalVar(Source{{12, 34}}, "v", ty.array(ty.i32()), ast::AddressSpace::kWorkgroup);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
 12:34 note: while instantiating 'var' v)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, Workgroup_RuntimeArrayInStruct) {
+TEST_F(ResolverAddressSpaceValidationTest, Workgroup_RuntimeArrayInStruct) {
     auto* s = Structure("S", utils::Vector{Member("m", ty.array(ty.i32()))});
-    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kWorkgroup);
+    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::AddressSpace::kWorkgroup);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
 note: while analysing structure member S.m
 12:34 note: while instantiating 'var' v)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferBool) {
     // var<storage> g : bool;
-    GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kStorage, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::AddressSpace::kStorage, Binding(0_a),
               Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
+        R"(56:78 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
 56:78 note: while instantiating 'var' g)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferBoolAlias) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferBoolAlias) {
     // type a = bool;
     // var<storage, read> g : a;
     auto* a = Alias("a", ty.bool_());
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::StorageClass::kStorage, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::AddressSpace::kStorage, Binding(0_a),
               Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
+        R"(56:78 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
 56:78 note: while instantiating 'var' g)");
 }
 
 // F16 types in storage and uniform buffer is not implemented yet.
 // TODO(tint:1473, tint:1502): make these testcases valid after f16 is supported.
-TEST_F(ResolverStorageClassValidationTest, StorageBufferF16_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferF16_TemporallyBan) {
     // var<storage> g : f16;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("g", ty.f16(Source{{56, 78}}), ast::StorageClass::kStorage, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.f16(Source{{56, 78}}), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              "56:78 error: using f16 types in 'storage' storage class is not "
+              "56:78 error: using f16 types in 'storage' address space is not "
               "implemented yet");
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferF16Alias_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferF16Alias_TemporallyBan) {
     // type a = f16;
     // var<storage, read> g : a;
     Enable(ast::Extension::kF16);
 
     auto* a = Alias("a", ty.f16());
-    GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::StorageClass::kStorage,
+    GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::AddressSpace::kStorage,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              "56:78 error: using f16 types in 'storage' storage class is not "
+              "56:78 error: using f16 types in 'storage' address space is not "
               "implemented yet");
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferVectorF16_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferVectorF16_TemporallyBan) {
     // var<storage> g : vec4<f16>;
     Enable(ast::Extension::kF16);
-    GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of<f16>(), 4u), ast::StorageClass::kStorage,
+    GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of<f16>(), 4u), ast::AddressSpace::kStorage,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              "56:78 error: using f16 types in 'storage' storage class is not "
+              "56:78 error: using f16 types in 'storage' address space is not "
               "implemented yet");
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferArrayF16_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferArrayF16_TemporallyBan) {
     // struct S { a : f16 };
     // var<storage, read> g : array<S, 3u>;
     Enable(ast::Extension::kF16);
 
     auto* s = Structure("S", utils::Vector{Member("a", ty.f16(Source{{56, 78}}))});
     auto* a = ty.array(ty.Of(s), 3_u);
-    GlobalVar("g", a, ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a), Group(0_a));
+    GlobalVar("g", a, ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
-    EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'storage' storage "
-                                        "class is not implemented yet"));
+    EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'storage' address "
+                                        "space is not implemented yet"));
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferStructF16_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructF16_TemporallyBan) {
     // struct S { x : f16 };
     // var<storage, read> g : S;
     Enable(ast::Extension::kF16);
 
     auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))});
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
-    EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'storage' storage "
-                                        "class is not implemented yet"));
+    EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'storage' address "
+                                        "space is not implemented yet"));
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferNoErrorStructF16Aliases_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferNoErrorStructF16Aliases_TemporallyBan) {
     // struct S { x : f16 };
     // type a1 = S;
     // var<storage, read> g : a1;
@@ -196,84 +196,84 @@
     auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))});
     auto* a1 = Alias("a1", ty.Of(s));
     auto* a2 = Alias("a2", ty.Of(a1));
-    GlobalVar("g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
-    EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'storage' storage "
-                                        "class is not implemented yet"));
+    EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'storage' address "
+                                        "space is not implemented yet"));
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferPointer) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferPointer) {
     // var<storage> g : ptr<private, f32>;
-    GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
-              ast::StorageClass::kStorage, Binding(0_a), Group(0_a));
+    GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate),
+              ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in storage class 'storage' as it is non-host-shareable
+        R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in address space 'storage' as it is non-host-shareable
 56:78 note: while instantiating 'var' g)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferIntScalar) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferIntScalar) {
     // var<storage> g : i32;
-    GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kStorage, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kStorage, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferVectorF32) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferVectorF32) {
     // var<storage> g : vec4<f32>;
-    GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kStorage, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::AddressSpace::kStorage, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferArrayF32) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferArrayF32) {
     // var<storage, read> g : array<S, 3u>;
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* a = ty.array(ty.Of(s), 3_u);
-    GlobalVar(Source{{56, 78}}, "g", a, ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", a, ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, NotStorage_AccessMode) {
+TEST_F(ResolverAddressSpaceValidationTest, NotStorage_AccessMode) {
     // var<private, read> g : a;
-    GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kPrivate, ast::Access::kRead);
+    GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kPrivate, ast::Access::kRead);
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: only variables in <storage> storage class may declare an access mode)");
+        R"(56:78 error: only variables in <storage> address space may declare an access mode)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, Storage_ReadAccessMode) {
+TEST_F(ResolverAddressSpaceValidationTest, Storage_ReadAccessMode) {
     // @group(0) @binding(0) var<storage, read> a : i32;
-    GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead,
               Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, Storage_ReadWriteAccessMode) {
+TEST_F(ResolverAddressSpaceValidationTest, Storage_ReadWriteAccessMode) {
     // @group(0) @binding(0) var<storage, read_write> a : i32;
-    GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+    GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
               Group(0_a), Binding(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, Storage_WriteAccessMode) {
+TEST_F(ResolverAddressSpaceValidationTest, Storage_WriteAccessMode) {
     // @group(0) @binding(0) var<storage, read_write> a : i32;
-    GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kWrite,
+    GlobalVar(Source{{56, 78}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kWrite,
               Group(0_a), Binding(0_a));
 
     ASSERT_FALSE(r()->Resolve());
@@ -282,117 +282,117 @@
               R"(56:78 error: access mode 'write' is not valid for the 'storage' address space)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferStructI32) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferStructI32) {
     // struct S { x : i32 };
     // var<storage, read> g : S;
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve());
 }
 
-TEST_F(ResolverStorageClassValidationTest, StorageBufferNoErrorStructI32Aliases) {
+TEST_F(ResolverAddressSpaceValidationTest, StorageBufferNoErrorStructI32Aliases) {
     // struct S { x : i32 };
     // type a1 = S;
     // var<storage, read> g : a1;
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
     auto* a1 = Alias("a1", ty.Of(s));
     auto* a2 = Alias("a2", ty.Of(a1));
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve());
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBuffer_Struct_Runtime) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBuffer_Struct_Runtime) {
     // struct S { m:  array<f32>; };
     // @group(0) @binding(0) var<uniform, > svar : S;
 
     auto* s = Structure(Source{{12, 34}}, "S", utils::Vector{Member("m", ty.array<i32>())});
 
-    GlobalVar(Source{{56, 78}}, "svar", ty.Of(s), ast::StorageClass::kUniform, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "svar", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              R"(56:78 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(56:78 error: runtime-sized arrays can only be used in the <storage> address space
 note: while analysing structure member S.m
 56:78 note: while instantiating 'var' svar)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferBool) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferBool) {
     // var<uniform> g : bool;
-    GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kUniform, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'bool' cannot be used in storage class 'uniform' as it is non-host-shareable
+        R"(56:78 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
 56:78 note: while instantiating 'var' g)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferBoolAlias) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferBoolAlias) {
     // type a = bool;
     // var<uniform> g : a;
     auto* a = Alias("a", ty.bool_());
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::StorageClass::kUniform, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(a), ast::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'bool' cannot be used in storage class 'uniform' as it is non-host-shareable
+        R"(56:78 error: Type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable
 56:78 note: while instantiating 'var' g)");
 }
 
 // F16 types in storage and uniform buffer is not implemented yet.
 // TODO(tint:1473, tint:1502): make these testcases valid after f16 is supported.
-TEST_F(ResolverStorageClassValidationTest, UniformBufferF16_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferF16_TemporallyBan) {
     // var<uniform> g : f16;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("g", ty.f16(Source{{56, 78}}), ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.f16(Source{{56, 78}}), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              "56:78 error: using f16 types in 'uniform' storage class is not "
+              "56:78 error: using f16 types in 'uniform' address space is not "
               "implemented yet");
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferF16Alias_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferF16Alias_TemporallyBan) {
     // type a = f16;
     // var<uniform> g : a;
     Enable(ast::Extension::kF16);
 
     auto* a = Alias("a", ty.f16());
-    GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::StorageClass::kUniform,
+    GlobalVar("g", ty.type_name(Source{{56, 78}}, a->name), ast::AddressSpace::kUniform,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              "56:78 error: using f16 types in 'uniform' storage class is not "
+              "56:78 error: using f16 types in 'uniform' address space is not "
               "implemented yet");
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferVectorF16_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferVectorF16_TemporallyBan) {
     // var<uniform> g : vec4<f16>;
     Enable(ast::Extension::kF16);
-    GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of<f16>(), 4u), ast::StorageClass::kUniform,
+    GlobalVar("g", ty.vec(Source{{56, 78}}, ty.Of<f16>(), 4u), ast::AddressSpace::kUniform,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
-    EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'uniform' storage "
-                                        "class is not implemented yet"));
+    EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'uniform' address "
+                                        "space is not implemented yet"));
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferArrayF16_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferArrayF16_TemporallyBan) {
     // struct S {
     //   @size(16) f : f16;
     // }
@@ -402,29 +402,29 @@
     auto* s = Structure(
         "S", utils::Vector{Member("a", ty.f16(Source{{56, 78}}), utils::Vector{MemberSize(16_a)})});
     auto* a = ty.array(ty.Of(s), 3_u);
-    GlobalVar("g", a, ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", a, ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
-    EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'uniform' storage "
-                                        "class is not implemented yet"));
+    EXPECT_THAT(r()->error(), HasSubstr("56:78 error: using f16 types in 'uniform' address "
+                                        "space is not implemented yet"));
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferStructF16_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructF16_TemporallyBan) {
     // struct S { x : f16 };
     // var<uniform> g :  S;
     Enable(ast::Extension::kF16);
 
     auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))});
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
-    EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'uniform' storage "
-                                        "class is not implemented yet"));
+    EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'uniform' address "
+                                        "space is not implemented yet"));
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferStructF16Aliases_TemporallyBan) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructF16Aliases_TemporallyBan) {
     // struct S { x : f16 };
     // type a1 = S;
     // var<uniform> g : a1;
@@ -432,159 +432,159 @@
 
     auto* s = Structure("S", utils::Vector{Member("x", ty.f16(Source{{12, 34}}))});
     auto* a1 = Alias("a1", ty.Of(s));
-    GlobalVar("g", ty.Of(a1), ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("g", ty.Of(a1), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
-    EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'uniform' storage "
-                                        "class is not implemented yet"));
+    EXPECT_THAT(r()->error(), HasSubstr("12:34 error: using f16 types in 'uniform' address "
+                                        "space is not implemented yet"));
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferPointer) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferPointer) {
     // var<uniform> g : ptr<private, f32>;
-    GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
-              ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate),
+              ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in storage class 'uniform' as it is non-host-shareable
+        R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in address space 'uniform' as it is non-host-shareable
 56:78 note: while instantiating 'var' g)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferIntScalar) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferIntScalar) {
     // var<uniform> g : i32;
-    GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::StorageClass::kUniform, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.i32(), ast::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferVectorF32) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferVectorF32) {
     // var<uniform> g : vec4<f32>;
-    GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::StorageClass::kUniform, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.vec4<f32>(), ast::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferArrayF32) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferArrayF32) {
     // struct S {
     //   @size(16) f : f32;
     // }
     // var<uniform> g : array<S, 3u>;
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32(), utils::Vector{MemberSize(16_a)})});
     auto* a = ty.array(ty.Of(s), 3_u);
-    GlobalVar(Source{{56, 78}}, "g", a, ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar(Source{{56, 78}}, "g", a, ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferStructI32) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructI32) {
     // struct S { x : i32 };
     // var<uniform> g :  S;
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kUniform, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, UniformBufferStructI32Aliases) {
+TEST_F(ResolverAddressSpaceValidationTest, UniformBufferStructI32Aliases) {
     // struct S { x : i32 };
     // type a1 = S;
     // var<uniform> g : a1;
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
     auto* a1 = Alias("a1", ty.Of(s));
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(a1), ast::StorageClass::kUniform, Binding(0_a),
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(a1), ast::AddressSpace::kUniform, Binding(0_a),
               Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, PushConstantBool) {
+TEST_F(ResolverAddressSpaceValidationTest, PushConstantBool) {
     // enable chromium_experimental_push_constant;
     // var<push_constant> g : bool;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::StorageClass::kPushConstant);
+    GlobalVar(Source{{56, 78}}, "g", ty.bool_(), ast::AddressSpace::kPushConstant);
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'bool' cannot be used in storage class 'push_constant' as it is non-host-shareable
+        R"(56:78 error: Type 'bool' cannot be used in address space 'push_constant' as it is non-host-shareable
 56:78 note: while instantiating 'var' g)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, PushConstantF16) {
+TEST_F(ResolverAddressSpaceValidationTest, PushConstantF16) {
     // enable chromium_experimental_push_constant;
     // enable f16;
     // var<push_constant> g : f16;
     Enable(ast::Extension::kF16);
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("g", ty.f16(Source{{56, 78}}), ast::StorageClass::kPushConstant);
+    GlobalVar("g", ty.f16(Source{{56, 78}}), ast::AddressSpace::kPushConstant);
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "56:78 error: using f16 types in 'push_constant' storage class is not "
+              "56:78 error: using f16 types in 'push_constant' address space is not "
               "implemented yet");
 }
 
-TEST_F(ResolverStorageClassValidationTest, PushConstantPointer) {
+TEST_F(ResolverAddressSpaceValidationTest, PushConstantPointer) {
     // enable chromium_experimental_push_constant;
     // var<push_constant> g : ptr<private, f32>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::StorageClass::kPrivate),
-              ast::StorageClass::kPushConstant);
+    GlobalVar(Source{{56, 78}}, "g", ty.pointer(ty.f32(), ast::AddressSpace::kPrivate),
+              ast::AddressSpace::kPushConstant);
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in storage class 'push_constant' as it is non-host-shareable
+        R"(56:78 error: Type 'ptr<private, f32, read_write>' cannot be used in address space 'push_constant' as it is non-host-shareable
 56:78 note: while instantiating 'var' g)");
 }
 
-TEST_F(ResolverStorageClassValidationTest, PushConstantIntScalar) {
+TEST_F(ResolverAddressSpaceValidationTest, PushConstantIntScalar) {
     // enable chromium_experimental_push_constant;
     // var<push_constant> g : i32;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("g", ty.i32(), ast::StorageClass::kPushConstant);
+    GlobalVar("g", ty.i32(), ast::AddressSpace::kPushConstant);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, PushConstantVectorF32) {
+TEST_F(ResolverAddressSpaceValidationTest, PushConstantVectorF32) {
     // enable chromium_experimental_push_constant;
     // var<push_constant> g : vec4<f32>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPushConstant);
+    GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPushConstant);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, PushConstantArrayF32) {
+TEST_F(ResolverAddressSpaceValidationTest, PushConstantArrayF32) {
     // enable chromium_experimental_push_constant;
     // struct S { a : f32}
     // var<push_constant> g : array<S, 3u>;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* a = ty.array(ty.Of(s), 3_u);
-    GlobalVar("g", a, ast::StorageClass::kPushConstant);
+    GlobalVar("g", a, ast::AddressSpace::kPushConstant);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverStorageClassValidationTest, PushConstantWithInitializer) {
+TEST_F(ResolverAddressSpaceValidationTest, PushConstantWithInitializer) {
     // enable chromium_experimental_push_constant;
     // var<push_constant> a : u32 = 0u;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), ast::StorageClass::kPushConstant,
+    GlobalVar(Source{{1u, 2u}}, "a", ty.u32(), ast::AddressSpace::kPushConstant,
               Expr(Source{{3u, 4u}}, u32(0)));
 
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
-        R"(1:2 error: var of storage class 'push_constant' cannot have an initializer. var initializers are only supported for the storage classes 'private' and 'function')");
+        R"(1:2 error: var of address space 'push_constant' cannot have an initializer. var initializers are only supported for the address spacees 'private' and 'function')");
 }
 
 }  // namespace
diff --git a/src/tint/resolver/array_accessor_test.cc b/src/tint/resolver/array_accessor_test.cc
index f63bb1f..d7327de 100644
--- a/src/tint/resolver/array_accessor_test.cc
+++ b/src/tint/resolver/array_accessor_test.cc
@@ -27,7 +27,7 @@
 using ResolverIndexAccessorTest = ResolverTest;
 
 TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_F32) {
-    GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 1_f));
     WrapInFunction(acc);
 
@@ -36,7 +36,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_Dynamic_Ref) {
-    GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
     auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
     auto* acc = IndexAccessor("my_var", idx);
     WrapInFunction(Decl(idx), acc);
@@ -50,7 +50,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions_Dynamic_Ref) {
-    GlobalVar("my_var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.mat4x4<f32>(), ast::AddressSpace::kPrivate);
     auto* idx = Var("idx", ty.u32(), Expr(3_u));
     auto* idy = Var("idy", ty.u32(), Expr(2_u));
     auto* acc = IndexAccessor(IndexAccessor("my_var", idx), idy);
@@ -100,7 +100,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix) {
-    GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* acc = IndexAccessor("my_var", 1_i);
     WrapInFunction(acc);
@@ -121,7 +121,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Matrix_BothDimensions) {
-    GlobalVar("my_var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* acc = IndexAccessor(IndexAccessor("my_var", 0_i), 1_i);
     WrapInFunction(acc);
@@ -141,7 +141,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector_F32) {
-    GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", Expr(Source{{12, 34}}, 2_f));
     WrapInFunction(acc);
 
@@ -150,7 +150,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector_Dynamic_Ref) {
-    GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
     auto* idx = Var("idx", ty.i32(), Expr(2_i));
     auto* acc = IndexAccessor("my_var", idx);
     WrapInFunction(Decl(idx), acc);
@@ -173,7 +173,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Vector) {
-    GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
@@ -193,7 +193,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_i32) {
-    GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.array<f32, 3>(), ast::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -209,7 +209,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_u32) {
-    GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.array<f32, 3>(), ast::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", 2_u);
     WrapInFunction(acc);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -225,7 +225,7 @@
 }
 
 TEST_F(ResolverIndexAccessorTest, Array_Literal_AInt) {
-    GlobalVar("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.array<f32, 3>(), ast::AddressSpace::kPrivate);
     auto* acc = IndexAccessor("my_var", 2_a);
     WrapInFunction(acc);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -243,7 +243,7 @@
 TEST_F(ResolverIndexAccessorTest, Alias_Array) {
     auto* aary = Alias("myarrty", ty.array<f32, 3>());
 
-    GlobalVar("my_var", ty.Of(aary), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.Of(aary), ast::AddressSpace::kPrivate);
 
     auto* acc = IndexAccessor("my_var", 2_i);
     WrapInFunction(acc);
@@ -337,7 +337,7 @@
     //     let x: f32 = (*p)[idx];
     //     return x;
     // }
-    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction));
+    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction));
     auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
     auto* star_p = Deref(p);
     auto* acc = IndexAccessor(Source{{12, 34}}, star_p, idx);
@@ -358,7 +358,7 @@
     //     let x: f32 = *p[idx];
     //     return x;
     // }
-    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction));
+    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction));
     auto* idx = Let("idx", ty.u32(), Construct(ty.u32()));
     auto* accessor_expr = IndexAccessor(Source{{12, 34}}, p, idx);
     auto* star_p = Deref(accessor_expr);
diff --git a/src/tint/resolver/assignment_validation_test.cc b/src/tint/resolver/assignment_validation_test.cc
index 36ce0cb..02a6191 100644
--- a/src/tint/resolver/assignment_validation_test.cc
+++ b/src/tint/resolver/assignment_validation_test.cc
@@ -32,7 +32,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("m", ty.i32()),
                              });
-    GlobalVar(Source{{12, 34}}, "a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{12, 34}}, "a", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("a", "m"), 1_i));
@@ -192,7 +192,7 @@
     // var a : i32;
     // let b : ptr<function,i32> = &a;
     // *b = 2i;
-    const auto func = ast::StorageClass::kFunction;
+    const auto func = ast::AddressSpace::kFunction;
     WrapInFunction(Var("a", ty.i32(), func, Expr(2_i)),                    //
                    Let("b", ty.pointer<i32>(func), AddressOf(Expr("a"))),  //
                    Assign(Deref("b"), 2_i));
@@ -204,7 +204,7 @@
     // var a : i32;
     // let b : ptr<function,i32> = &a;
     // *b = 2;
-    const auto func = ast::StorageClass::kFunction;
+    const auto func = ast::AddressSpace::kFunction;
     auto* var_a = Var("a", ty.i32(), func, Expr(2_i));
     auto* var_b = Let("b", ty.pointer<i32>(func), AddressOf(Expr("a")));
     WrapInFunction(var_a, var_b, Assign(Deref("b"), 2_a));
@@ -251,7 +251,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("a", ty.atomic(ty.i32())),
                              });
-    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
               Binding(0_a), Group(0_a));
 
     WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("v", "a"), MemberAccessor("v", "a")));
@@ -268,7 +268,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("a", ty.array(ty.f32())),
                              });
-    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+    GlobalVar(Source{{12, 34}}, "v", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
               Binding(0_a), Group(0_a));
 
     WrapInFunction(Assign(Source{{56, 78}}, MemberAccessor("v", "a"), MemberAccessor("v", "a")));
@@ -288,7 +288,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("arr", ty.array<i32>()),
                              });
-    GlobalVar("s", ty.Of(s), ast::StorageClass::kStorage, Group(0_a), Binding(0_a));
+    GlobalVar("s", ty.Of(s), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
 
     WrapInFunction(Assign(Phony(), Expr(Source{{12, 34}}, "s")));
 
@@ -310,7 +310,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("arr", ty.array<i32>()),
                              });
-    GlobalVar("s", ty.Of(s), ast::StorageClass::kStorage, Group(0_a), Binding(0_a));
+    GlobalVar("s", ty.Of(s), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
 
     WrapInFunction(Assign(Phony(), MemberAccessor(Source{{12, 34}}, "s", "arr")));
 
@@ -363,9 +363,9 @@
     GlobalVar("tex", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(0_a),
               Binding(0_a));
     GlobalVar("smp", ty.sampler(ast::SamplerKind::kSampler), Group(0_a), Binding(1_a));
-    GlobalVar("u", ty.Of(U), ast::StorageClass::kUniform, Group(0_a), Binding(2_a));
-    GlobalVar("s", ty.Of(S), ast::StorageClass::kStorage, Group(0_a), Binding(3_a));
-    GlobalVar("wg", ty.array<f32, 10>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("u", ty.Of(U), ast::AddressSpace::kUniform, Group(0_a), Binding(2_a));
+    GlobalVar("s", ty.Of(S), ast::AddressSpace::kStorage, Group(0_a), Binding(3_a));
+    GlobalVar("wg", ty.array<f32, 10>(), ast::AddressSpace::kWorkgroup);
 
     WrapInFunction(Assign(Phony(), 1_i),                                    //
                    Assign(Phony(), 2_u),                                    //
diff --git a/src/tint/resolver/atomics_test.cc b/src/tint/resolver/atomics_test.cc
index a22977e..bb08e83 100644
--- a/src/tint/resolver/atomics_test.cc
+++ b/src/tint/resolver/atomics_test.cc
@@ -27,7 +27,7 @@
 struct ResolverAtomicTest : public resolver::TestHelper, public testing::Test {};
 
 TEST_F(ResolverAtomicTest, GlobalWorkgroupI32) {
-    auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kWorkgroup);
+    auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
     ASSERT_TRUE(TypeOf(g)->Is<sem::Reference>());
@@ -37,7 +37,7 @@
 }
 
 TEST_F(ResolverAtomicTest, GlobalWorkgroupU32) {
-    auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.u32()), ast::StorageClass::kWorkgroup);
+    auto* g = GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.u32()), ast::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
     ASSERT_TRUE(TypeOf(g)->Is<sem::Reference>());
@@ -48,7 +48,7 @@
 
 TEST_F(ResolverAtomicTest, GlobalStorageStruct) {
     auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
-    auto* g = GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+    auto* g = GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
                         Binding(0_a), Group(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/atomics_validation_test.cc b/src/tint/resolver/atomics_validation_test.cc
index aa4c1c2..08bdf13 100644
--- a/src/tint/resolver/atomics_validation_test.cc
+++ b/src/tint/resolver/atomics_validation_test.cc
@@ -26,64 +26,64 @@
 
 struct ResolverAtomicValidationTest : public resolver::TestHelper, public testing::Test {};
 
-TEST_F(ResolverAtomicValidationTest, StorageClass_WorkGroup) {
-    GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kWorkgroup);
+TEST_F(ResolverAtomicValidationTest, AddressSpace_WorkGroup) {
+    GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve());
 }
 
-TEST_F(ResolverAtomicValidationTest, StorageClass_Storage) {
-    GlobalVar("g", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kStorage,
+TEST_F(ResolverAtomicValidationTest, AddressSpace_Storage) {
+    GlobalVar("g", ty.atomic(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kStorage,
               ast::Access::kReadWrite, Group(0_a), Binding(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverAtomicValidationTest, StorageClass_Storage_Struct) {
+TEST_F(ResolverAtomicValidationTest, AddressSpace_Storage_Struct) {
     auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverAtomicValidationTest, InvalidType) {
-    GlobalVar("a", ty.atomic(ty.f32(Source{{12, 34}})), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.atomic(ty.f32(Source{{12, 34}})), ast::AddressSpace::kWorkgroup);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: atomic only supports i32 or u32 types");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Simple) {
-    GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kPrivate);
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Simple) {
+    GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: atomic variables must have <storage> or <workgroup> "
-              "storage class");
+              "address space");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Array) {
-    GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::StorageClass::kPrivate);
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Array) {
+    GlobalVar("a", ty.atomic(Source{{12, 34}}, ty.i32()), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: atomic variables must have <storage> or <workgroup> "
-              "storage class");
+              "address space");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Struct) {
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Struct) {
     auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "error: atomic variables must have <storage> or <workgroup> "
-              "storage class\n"
+              "address space\n"
               "note: atomic sub-type of 's' is declared here");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_StructOfStruct) {
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_StructOfStruct) {
     // struct Inner { m : atomic<i32>; };
     // struct Outer { m : array<Inner, 4>; };
     // var<private> g : Outer;
@@ -91,16 +91,16 @@
     auto* Inner =
         Structure("Inner", utils::Vector{Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
     auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
-    GlobalVar("g", ty.Of(Outer), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(Outer), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "error: atomic variables must have <storage> or <workgroup> "
-              "storage class\n"
+              "address space\n"
               "note: atomic sub-type of 'Outer' is declared here");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_StructOfStructOfArray) {
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_StructOfStructOfArray) {
     // struct Inner { m : array<atomic<i32>, 4>; };
     // struct Outer { m : array<Inner, 4>; };
     // var<private> g : Outer;
@@ -108,46 +108,46 @@
     auto* Inner =
         Structure("Inner", utils::Vector{Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
     auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
-    GlobalVar("g", ty.Of(Outer), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(Outer), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "error: atomic variables must have <storage> or <workgroup> "
-              "storage class\n"
+              "address space\n"
               "12:34 note: atomic sub-type of 'Outer' is declared here");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_ArrayOfArray) {
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_ArrayOfArray) {
     // type AtomicArray = array<atomic<i32>, 5>;
     // var<private> v: array<s, 5>;
 
     auto* atomic_array =
         Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
-    GlobalVar(Source{{56, 78}}, "v", ty.Of(atomic_array), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{56, 78}}, "v", ty.Of(atomic_array), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "error: atomic variables must have <storage> or <workgroup> "
-              "storage class");
+              "address space");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_ArrayOfStruct) {
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_ArrayOfStruct) {
     // struct S{
     //   m: atomic<u32>;
     // };
     // var<private> v: array<S, 5u>;
 
     auto* s = Structure("S", utils::Vector{Member("m", ty.atomic<u32>())});
-    GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "error: atomic variables must have <storage> or <workgroup> "
-              "storage class\n"
+              "address space\n"
               "note: atomic sub-type of 'array<S, 5>' is declared here");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_ArrayOfStructOfArray) {
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_ArrayOfStructOfArray) {
     // type AtomicArray = array<atomic<i32>, 5u>;
     // struct S{
     //   m: AtomicArray;
@@ -157,16 +157,16 @@
     auto* atomic_array =
         Alias(Source{{12, 34}}, "AtomicArray", ty.atomic(Source{{12, 34}}, ty.i32()));
     auto* s = Structure("S", utils::Vector{Member("m", ty.Of(atomic_array))});
-    GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{56, 78}}, "v", ty.array(ty.Of(s), 5_u), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "error: atomic variables must have <storage> or <workgroup> "
-              "storage class\n"
+              "address space\n"
               "note: atomic sub-type of 'array<S, 5>' is declared here");
 }
 
-TEST_F(ResolverAtomicValidationTest, InvalidStorageClass_Complex) {
+TEST_F(ResolverAtomicValidationTest, InvalidAddressSpace_Complex) {
     // type AtomicArray = array<atomic<i32>, 5u>;
     // struct S6 { x: array<i32, 4>; };
     // struct S5 { x: S6;
@@ -198,35 +198,35 @@
     auto* s2 = Structure("S2", utils::Vector{Member("x", ty.Of(s3))});
     auto* s1 = Structure("S1", utils::Vector{Member("x", ty.Of(s2))});
     auto* s0 = Structure("S0", utils::Vector{Member("x", ty.Of(s1))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "error: atomic variables must have <storage> or <workgroup> "
-              "storage class\n"
+              "address space\n"
               "note: atomic sub-type of 'S0' is declared here");
 }
 
 TEST_F(ResolverAtomicValidationTest, Struct_AccessMode_Read) {
     auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
               Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "error: atomic variables in <storage> storage class must have read_write "
+              "error: atomic variables in <storage> address space must have read_write "
               "access mode\n"
               "note: atomic sub-type of 's' is declared here");
 }
 
 TEST_F(ResolverAtomicValidationTest, InvalidAccessMode_Struct) {
     auto* s = Structure("s", utils::Vector{Member("a", ty.atomic(Source{{12, 34}}, ty.i32()))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
               Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "error: atomic variables in <storage> storage class must have read_write "
+              "error: atomic variables in <storage> address space must have read_write "
               "access mode\n"
               "note: atomic sub-type of 's' is declared here");
 }
@@ -239,12 +239,12 @@
     auto* Inner =
         Structure("Inner", utils::Vector{Member("m", ty.atomic(Source{{12, 34}}, ty.i32()))});
     auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::AddressSpace::kStorage, ast::Access::kRead,
               Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "error: atomic variables in <storage> storage class must have read_write "
+              "error: atomic variables in <storage> address space must have read_write "
               "access mode\n"
               "note: atomic sub-type of 'Outer' is declared here");
 }
@@ -257,12 +257,12 @@
     auto* Inner =
         Structure("Inner", utils::Vector{Member(Source{{12, 34}}, "m", ty.atomic(ty.i32()))});
     auto* Outer = Structure("Outer", utils::Vector{Member("m", ty.Of(Inner))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(Outer), ast::AddressSpace::kStorage, ast::Access::kRead,
               Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "error: atomic variables in <storage> storage class must have "
+              "error: atomic variables in <storage> address space must have "
               "read_write access mode\n"
               "12:34 note: atomic sub-type of 'Outer' is declared here");
 }
@@ -299,12 +299,12 @@
     auto* s2 = Structure("S2", utils::Vector{Member("x", ty.Of(s3))});
     auto* s1 = Structure("S1", utils::Vector{Member("x", ty.Of(s2))});
     auto* s0 = Structure("S0", utils::Vector{Member("x", ty.Of(s1))});
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s0), ast::AddressSpace::kStorage, ast::Access::kRead,
               Group(0_a), Binding(0_a));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "error: atomic variables in <storage> storage class must have "
+              "error: atomic variables in <storage> address space must have "
               "read_write access mode\n"
               "note: atomic sub-type of 'S0' is declared here");
 }
diff --git a/src/tint/resolver/attribute_validation_test.cc b/src/tint/resolver/attribute_validation_test.cc
index bae34df..796487b 100644
--- a/src/tint/resolver/attribute_validation_test.cc
+++ b/src/tint/resolver/attribute_validation_test.cc
@@ -721,7 +721,7 @@
 }
 
 TEST_F(StructMemberAttributeTest, Align_Attribute_Var) {
-    GlobalVar(Source{{1, 2}}, "val", ty.f32(), ast::StorageClass::kPrivate, ast::Access::kUndefined,
+    GlobalVar(Source{{1, 2}}, "val", ty.f32(), ast::AddressSpace::kPrivate, ast::Access::kUndefined,
               Expr(1.23_f));
 
     Structure(Source{{6, 4}}, "mystruct",
@@ -785,7 +785,7 @@
     if (IsBindingAttribute(params.kind)) {
         GlobalVar("a", ty.sampler(ast::SamplerKind::kSampler), attrs);
     } else {
-        GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate, attrs);
+        GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate, attrs);
     }
 
     if (params.should_pass) {
@@ -956,7 +956,7 @@
                              create<ast::StrideAttribute>(Source{{12, 34}}, params.stride),
                          });
 
-    GlobalVar("myarray", arr, ast::StorageClass::kPrivate);
+    GlobalVar("myarray", arr, ast::AddressSpace::kPrivate);
 
     if (params.should_pass) {
         EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1039,7 +1039,7 @@
                              create<ast::StrideAttribute>(Source{{56, 78}}, 4u),
                          });
 
-    GlobalVar("myarray", arr, ast::StorageClass::kPrivate);
+    GlobalVar("myarray", arr, ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1058,7 +1058,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("x", ty.i32()),
                              });
-    GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::StorageClass::kUniform);
+    GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::AddressSpace::kUniform);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1069,7 +1069,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("x", ty.i32()),
                              });
-    GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead);
+    GlobalVar(Source{{12, 34}}, "G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -1155,7 +1155,7 @@
 }
 
 TEST_F(ResourceAttributeTest, BindingPointOnNonResource) {
-    GlobalVar(Source{{12, 34}}, "G", ty.f32(), ast::StorageClass::kPrivate, Binding(1_a),
+    GlobalVar(Source{{12, 34}}, "G", ty.f32(), ast::AddressSpace::kPrivate, Binding(1_a),
               Group(2_a));
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc
index b1d1e35..69a42f8 100644
--- a/src/tint/resolver/builtin_test.cc
+++ b/src/tint/resolver/builtin_test.cc
@@ -78,7 +78,7 @@
 TEST_P(ResolverBuiltinTest_BoolMethod, Scalar) {
     auto name = GetParam();
 
-    GlobalVar("my_var", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call(name, "my_var");
     WrapInFunction(expr);
@@ -91,7 +91,7 @@
 TEST_P(ResolverBuiltinTest_BoolMethod, Vector) {
     auto name = GetParam();
 
-    GlobalVar("my_var", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call(name, "my_var");
     WrapInFunction(expr);
@@ -106,9 +106,9 @@
                          testing::Values("any", "all"));
 
 TEST_F(ResolverBuiltinTest, Select) {
-    GlobalVar("my_var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
-    GlobalVar("bool_var", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+    GlobalVar("bool_var", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call("select", "my_var", "my_var", "bool_var");
     WrapInFunction(expr);
@@ -212,7 +212,7 @@
 TEST_F(ResolverBuiltinArrayTest, ArrayLength_Vector) {
     auto* ary = ty.array<i32>();
     auto* str = Structure("S", utils::Vector{Member("x", ary)});
-    GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("a", ty.Of(str), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     auto* call = Call("arrayLength", AddressOf(MemberAccessor("a", "x")));
@@ -225,7 +225,7 @@
 }
 
 TEST_F(ResolverBuiltinArrayTest, ArrayLength_Error_ArraySized) {
-    GlobalVar("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate);
+    GlobalVar("arr", ty.array<i32, 4>(), ast::AddressSpace::kPrivate);
     auto* call = Call("arrayLength", AddressOf("arr"));
     WrapInFunction(call);
 
@@ -1029,7 +1029,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Frexp_Error_FirstParamInt) {
-    GlobalVar("v", ty.i32(), ast::StorageClass::kWorkgroup);
+    GlobalVar("v", ty.i32(), ast::AddressSpace::kWorkgroup);
     auto* call = Call("frexp", 1_i, AddressOf("v"));
     WrapInFunction(call);
 
@@ -1045,7 +1045,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Frexp_Error_SecondParamFloatPtr) {
-    GlobalVar("v", ty.f32(), ast::StorageClass::kWorkgroup);
+    GlobalVar("v", ty.f32(), ast::AddressSpace::kWorkgroup);
     auto* call = Call("frexp", 1_f, AddressOf("v"));
     WrapInFunction(call);
 
@@ -1075,7 +1075,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Frexp_Error_VectorSizesDontMatch) {
-    GlobalVar("v", ty.vec4<i32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("v", ty.vec4<i32>(), ast::AddressSpace::kWorkgroup);
     auto* call = Call("frexp", vec2<f32>(1_f, 2_f), AddressOf("v"));
     WrapInFunction(call);
 
@@ -1324,7 +1324,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Modf_Error_FirstParamInt) {
-    GlobalVar("whole", ty.f32(), ast::StorageClass::kWorkgroup);
+    GlobalVar("whole", ty.f32(), ast::AddressSpace::kWorkgroup);
     auto* call = Call("modf", 1_i, AddressOf("whole"));
     WrapInFunction(call);
 
@@ -1340,7 +1340,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Modf_Error_SecondParamIntPtr) {
-    GlobalVar("whole", ty.i32(), ast::StorageClass::kWorkgroup);
+    GlobalVar("whole", ty.i32(), ast::AddressSpace::kWorkgroup);
     auto* call = Call("modf", 1_f, AddressOf("whole"));
     WrapInFunction(call);
 
@@ -1370,7 +1370,7 @@
 }
 
 TEST_F(ResolverBuiltinFloatTest, Modf_Error_VectorSizesDontMatch) {
-    GlobalVar("whole", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("whole", ty.vec4<f32>(), ast::AddressSpace::kWorkgroup);
     auto* call = Call("modf", vec2<f32>(1_f, 2_f), AddressOf("whole"));
     WrapInFunction(call);
 
@@ -1850,7 +1850,7 @@
 namespace matrix_builtin_tests {
 
 TEST_F(ResolverBuiltinTest, Determinant_2x2_f32) {
-    GlobalVar("var", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat2x2<f32>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1864,7 +1864,7 @@
 TEST_F(ResolverBuiltinTest, Determinant_2x2_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("var", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat2x2<f16>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1876,7 +1876,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Determinant_3x3_f32) {
-    GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1890,7 +1890,7 @@
 TEST_F(ResolverBuiltinTest, Determinant_3x3_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("var", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1902,7 +1902,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Determinant_4x4_f32) {
-    GlobalVar("var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat4x4<f32>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1916,7 +1916,7 @@
 TEST_F(ResolverBuiltinTest, Determinant_4x4_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("var", ty.mat4x4<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat4x4<f16>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1928,7 +1928,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Determinant_NotSquare) {
-    GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1943,7 +1943,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Determinant_NotMatrix) {
-    GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("determinant", "var");
     WrapInFunction(call);
@@ -1963,7 +1963,7 @@
 namespace vector_builtin_tests {
 
 TEST_F(ResolverBuiltinTest, Dot_Vec2_f32) {
-    GlobalVar("my_var", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call("dot", "my_var", "my_var");
     WrapInFunction(expr);
@@ -1977,7 +1977,7 @@
 TEST_F(ResolverBuiltinTest, Dot_Vec2_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("my_var", ty.vec2<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call("dot", "my_var", "my_var");
     WrapInFunction(expr);
@@ -1989,7 +1989,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Dot_Vec3_i32) {
-    GlobalVar("my_var", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call("dot", "my_var", "my_var");
     WrapInFunction(expr);
@@ -2001,7 +2001,7 @@
 }
 
 TEST_F(ResolverBuiltinTest, Dot_Vec4_u32) {
-    GlobalVar("my_var", ty.vec4<u32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_var", ty.vec4<u32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call("dot", "my_var", "my_var");
     WrapInFunction(expr);
@@ -2036,7 +2036,7 @@
 TEST_P(ResolverBuiltinDerivativeTest, Scalar) {
     auto name = GetParam();
 
-    GlobalVar("ident", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("ident", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call(name, "ident");
     Func("func", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
@@ -2050,7 +2050,7 @@
 
 TEST_P(ResolverBuiltinDerivativeTest, Vector) {
     auto name = GetParam();
-    GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("ident", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call(name, "ident");
     Func("func", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
@@ -2146,7 +2146,7 @@
             GlobalVar(name, type, Binding(0_a), Group(0_a));
 
         } else {
-            GlobalVar(name, type, ast::StorageClass::kPrivate);
+            GlobalVar(name, type, ast::AddressSpace::kPrivate);
         }
 
         call_params->Push(Expr(name));
diff --git a/src/tint/resolver/builtin_validation_test.cc b/src/tint/resolver/builtin_validation_test.cc
index 63f3ccb..6ba48de 100644
--- a/src/tint/resolver/builtin_validation_test.cc
+++ b/src/tint/resolver/builtin_validation_test.cc
@@ -113,7 +113,7 @@
 }
 
 TEST_F(ResolverBuiltinValidationTest, BuiltinRedeclaredAsGlobalVar) {
-    GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{12, 34}}, "mix", ty.i32(), Expr(1_i), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(
diff --git a/src/tint/resolver/builtins_validation_test.cc b/src/tint/resolver/builtins_validation_test.cc
index a27052c..f2bf191 100644
--- a/src/tint/resolver/builtins_validation_test.cc
+++ b/src/tint/resolver/builtins_validation_test.cc
@@ -100,7 +100,7 @@
 TEST_P(ResolverBuiltinsStageTest, All_input) {
     const Params& params = GetParam();
 
-    auto* p = GlobalVar("p", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    auto* p = GlobalVar("p", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     auto* input = Param("input", params.type(*this),
                         utils::Vector{Builtin(Source{{12, 34}}, params.builtin)});
     switch (params.stage) {
diff --git a/src/tint/resolver/call_validation_test.cc b/src/tint/resolver/call_validation_test.cc
index 3fa71b8..6c64fad 100644
--- a/src/tint/resolver/call_validation_test.cc
+++ b/src/tint/resolver/call_validation_test.cc
@@ -103,7 +103,7 @@
     //   var z: i32 = 1i;
     //   foo(&z);
     // }
-    auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -120,7 +120,7 @@
     //   let z: i32 = 1i;
     //   foo(&z);
     // }
-    auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -142,7 +142,7 @@
     auto* S = Structure("S", utils::Vector{
                                  Member("m", ty.i32()),
                              });
-    auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -166,7 +166,7 @@
     auto* S = Structure("S", utils::Vector{
                                  Member("m", ty.i32()),
                              });
-    auto* param = Param("p", ty.pointer<i32>(ast::StorageClass::kFunction));
+    auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
     Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -185,12 +185,12 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("bar",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -212,12 +212,12 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     Func("bar",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
          },
          ty.void_(),
          utils::Vector{
@@ -245,11 +245,11 @@
     // }
     Func("x",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::StorageClass::kFunction)),
+             Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
          },
          ty.void_(), utils::Empty);
     auto* v = Var("v", ty.i32());
-    auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kFunction), AddressOf(v));
+    auto* p = Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kFunction), AddressOf(v));
     auto* c = Var("c", ty.i32(), Call("x", Expr(Source{{12, 34}}, p)));
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -276,11 +276,11 @@
     // }
     Func("foo",
          utils::Vector{
-             Param("p", ty.pointer<i32>(ast::StorageClass::kPrivate)),
+             Param("p", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
          },
          ty.void_(), utils::Empty);
-    auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kPrivate), AddressOf(v));
+    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* p = Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kPrivate), AddressOf(v));
     auto* c = Var("c", ty.i32(), Call("foo", Expr(Source{{12, 34}}, p)));
     Func("main", utils::Empty, ty.void_(),
          utils::Vector{
@@ -301,7 +301,7 @@
     // fn f() {
     //   v();
     // }
-    GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              CallStmt(Call(Source{{12, 34}}, "v")),
diff --git a/src/tint/resolver/compound_assignment_validation_test.cc b/src/tint/resolver/compound_assignment_validation_test.cc
index 9112fa0..dfb6926 100644
--- a/src/tint/resolver/compound_assignment_validation_test.cc
+++ b/src/tint/resolver/compound_assignment_validation_test.cc
@@ -51,7 +51,7 @@
     // var a : i32;
     // let b : ptr<function,i32> = &a;
     // *b += 2;
-    const auto func = ast::StorageClass::kFunction;
+    const auto func = ast::AddressSpace::kFunction;
     auto* var_a = Var("a", ty.i32(), func, Expr(2_i));
     auto* var_b = Let("b", ty.pointer<i32>(func), AddressOf(Expr("a")));
     WrapInFunction(var_a, var_b,
@@ -233,7 +233,7 @@
     // {
     //   a += 1i;
     // }
-    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead,
               Group(0_a), Binding(0_a));
     WrapInFunction(CompoundAssign(Source{{56, 78}}, "a", 1_i, ast::BinaryOp::kAdd));
 
@@ -264,7 +264,7 @@
 TEST_F(ResolverCompoundAssignmentValidationTest, LhsAtomic) {
     // var<workgroup> a : atomic<i32>;
     // a += a;
-    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
+    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::AddressSpace::kWorkgroup);
     WrapInFunction(CompoundAssign(Source{{56, 78}}, "a", "a", ast::BinaryOp::kAdd));
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/const_eval_test.cc b/src/tint/resolver/const_eval_test.cc
index 5f5b486..11a7315 100644
--- a/src/tint/resolver/const_eval_test.cc
+++ b/src/tint/resolver/const_eval_test.cc
@@ -2666,7 +2666,7 @@
 
 TEST_F(ResolverConstEvalTest, RuntimeArray_vec3_f32_Index_OOB_Low) {
     auto* sb = GlobalVar("sb", ty.array(ty.vec3<f32>()), Group(0_a), Binding(0_a),
-                         ast::StorageClass::kStorage);
+                         ast::AddressSpace::kStorage);
     auto* expr = IndexAccessor(sb, Expr(Source{{12, 34}}, -2_i));
     WrapInFunction(expr);
 
diff --git a/src/tint/resolver/dependency_graph_test.cc b/src/tint/resolver/dependency_graph_test.cc
index c9ffc91..614873e 100644
--- a/src/tint/resolver/dependency_graph_test.cc
+++ b/src/tint/resolver/dependency_graph_test.cc
@@ -425,7 +425,7 @@
     auto& b = *builder;
     switch (kind) {
         case SymbolDeclKind::GlobalVar:
-            return b.GlobalVar(source, symbol, b.ty.i32(), ast::StorageClass::kPrivate);
+            return b.GlobalVar(source, symbol, b.ty.i32(), ast::AddressSpace::kPrivate);
         case SymbolDeclKind::GlobalConst:
             return b.GlobalConst(source, symbol, b.ty.i32(), b.Expr(1_i));
         case SymbolDeclKind::Alias:
@@ -468,27 +468,27 @@
     switch (kind) {
         case SymbolUseKind::GlobalVarType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), node, ast::StorageClass::kPrivate);
+            b.GlobalVar(b.Sym(), node, ast::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarArrayElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.array(node, 4_i), ast::StorageClass::kPrivate);
+            b.GlobalVar(b.Sym(), b.ty.array(node, 4_i), ast::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarArraySizeValue: {
             auto* node = b.Expr(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.array(b.ty.i32(), node), ast::StorageClass::kPrivate);
+            b.GlobalVar(b.Sym(), b.ty.array(b.ty.i32(), node), ast::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarVectorElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.vec3(node), ast::StorageClass::kPrivate);
+            b.GlobalVar(b.Sym(), b.ty.vec3(node), ast::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarMatrixElemType: {
             auto* node = b.ty.type_name(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.mat3x4(node), ast::StorageClass::kPrivate);
+            b.GlobalVar(b.Sym(), b.ty.mat3x4(node), ast::AddressSpace::kPrivate);
             return node;
         }
         case SymbolUseKind::GlobalVarSampledTexElemType: {
@@ -503,7 +503,7 @@
         }
         case SymbolUseKind::GlobalVarValue: {
             auto* node = b.Expr(source, symbol);
-            b.GlobalVar(b.Sym(), b.ty.i32(), ast::StorageClass::kPrivate, node);
+            b.GlobalVar(b.Sym(), b.ty.i32(), ast::AddressSpace::kPrivate, node);
             return node;
         }
         case SymbolUseKind::GlobalConstType: {
@@ -724,7 +724,7 @@
              Block(Assign(Expr(Source{{12, 34}}, "G"), 3.14_f)),
          });
 
-    GlobalVar(Source{{56, 78}}, "G", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
+    GlobalVar(Source{{56, 78}}, "G", ty.f32(), ast::AddressSpace::kPrivate, Expr(2.1_f));
 
     Build();
 }
@@ -1207,7 +1207,7 @@
     const auto type_sym = Sym("TYPE");
     const auto func_sym = Sym("FUNC");
 
-    const auto* value_decl = GlobalVar(value_sym, ty.i32(), ast::StorageClass::kPrivate);
+    const auto* value_decl = GlobalVar(value_sym, ty.i32(), ast::AddressSpace::kPrivate);
     const auto* type_decl = Alias(type_sym, ty.i32());
     const auto* func_decl = Func(func_sym, utils::Empty, ty.void_(), utils::Empty);
 
@@ -1278,7 +1278,7 @@
     GlobalVar(Sym(), ty.array(T, V, 4));
     GlobalVar(Sym(), ty.vec3(T));
     GlobalVar(Sym(), ty.mat3x2(T));
-    GlobalVar(Sym(), ty.pointer(T, ast::StorageClass::kPrivate));
+    GlobalVar(Sym(), ty.pointer(T, ast::AddressSpace::kPrivate));
     GlobalVar(Sym(), ty.sampled_texture(ast::TextureDimension::k2d, T));
     GlobalVar(Sym(), ty.depth_texture(ast::TextureDimension::k2d));
     GlobalVar(Sym(), ty.depth_multisampled_texture(ast::TextureDimension::k2d));
diff --git a/src/tint/resolver/entry_point_validation_test.cc b/src/tint/resolver/entry_point_validation_test.cc
index 2179f68..2a9f25b 100644
--- a/src/tint/resolver/entry_point_validation_test.cc
+++ b/src/tint/resolver/entry_point_validation_test.cc
@@ -453,25 +453,25 @@
     // enable chromium_experimental_push_constant;
     // var<push_constant> a : u32;
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("a", ty.u32(), ast::StorageClass::kPushConstant);
+    GlobalVar("a", ty.u32(), ast::AddressSpace::kPushConstant);
 
     EXPECT_TRUE(r()->Resolve());
 }
 
 TEST_F(ResolverEntryPointValidationTest, PushConstantDisallowedWithoutEnable) {
     // var<push_constant> a : u32;
-    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::StorageClass::kPushConstant);
+    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::AddressSpace::kPushConstant);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "1:2 error: use of variable storage class 'push_constant' requires enabling "
+              "1:2 error: use of variable address space 'push_constant' requires enabling "
               "extension 'chromium_experimental_push_constant'");
 }
 
-TEST_F(ResolverEntryPointValidationTest, PushConstantAllowedWithIgnoreStorageClassAttribute) {
-    // var<push_constant> a : u32; // With ast::DisabledValidation::kIgnoreStorageClass
-    GlobalVar("a", ty.u32(), ast::StorageClass::kPushConstant,
-              utils::Vector{Disable(ast::DisabledValidation::kIgnoreStorageClass)});
+TEST_F(ResolverEntryPointValidationTest, PushConstantAllowedWithIgnoreAddressSpaceAttribute) {
+    // var<push_constant> a : u32; // With ast::DisabledValidation::kIgnoreAddressSpace
+    GlobalVar("a", ty.u32(), ast::AddressSpace::kPushConstant,
+              utils::Vector{Disable(ast::DisabledValidation::kIgnoreAddressSpace)});
 
     EXPECT_TRUE(r()->Resolve());
 }
@@ -483,7 +483,7 @@
     //   _ = a;
     // }
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("a", ty.u32(), ast::StorageClass::kPushConstant);
+    GlobalVar("a", ty.u32(), ast::AddressSpace::kPushConstant);
 
     Func("main", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")},
          utils::Vector{Stage(ast::PipelineStage::kCompute),
@@ -501,8 +501,8 @@
     //   _ = b;
     // }
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::StorageClass::kPushConstant);
-    GlobalVar(Source{{3, 4}}, "b", ty.u32(), ast::StorageClass::kPushConstant);
+    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar(Source{{3, 4}}, "b", ty.u32(), ast::AddressSpace::kPushConstant);
 
     Func(Source{{5, 6}}, "main", {}, ty.void_(),
          utils::Vector{Assign(Phony(), "a"), Assign(Phony(), "b")},
@@ -532,8 +532,8 @@
     //   uses_b();
     // }
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::StorageClass::kPushConstant);
-    GlobalVar(Source{{3, 4}}, "b", ty.u32(), ast::StorageClass::kPushConstant);
+    GlobalVar(Source{{1, 2}}, "a", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar(Source{{3, 4}}, "b", ty.u32(), ast::AddressSpace::kPushConstant);
 
     Func(Source{{5, 6}}, "uses_a", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")});
     Func(Source{{7, 8}}, "uses_b", {}, ty.void_(), utils::Vector{Assign(Phony(), "b")});
@@ -565,8 +565,8 @@
     //   _ = a;
     // }
     Enable(ast::Extension::kChromiumExperimentalPushConstant);
-    GlobalVar("a", ty.u32(), ast::StorageClass::kPushConstant);
-    GlobalVar("b", ty.u32(), ast::StorageClass::kPushConstant);
+    GlobalVar("a", ty.u32(), ast::AddressSpace::kPushConstant);
+    GlobalVar("b", ty.u32(), ast::AddressSpace::kPushConstant);
 
     Func("uses_a", {}, ty.void_(), utils::Vector{Assign(Phony(), "a")},
          utils::Vector{Stage(ast::PipelineStage::kCompute),
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index 5d88258..2fddc09 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -39,7 +39,7 @@
 TEST_F(ResolverFunctionValidationTest, ParameterMayShadowGlobal) {
     // var<private> common_name : f32;
     // fn func(common_name : f32) { }
-    GlobalVar("common_name", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("common_name", ty.f32(), ast::AddressSpace::kPrivate);
     Func("func", utils::Vector{Param("common_name", ty.f32())}, ty.void_(), utils::Empty);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -388,7 +388,7 @@
          utils::Vector{
              Return(1_i),
          });
-    GlobalVar("x", Call(Source{{12, 34}}, "F"), ast::StorageClass::kPrivate);
+    GlobalVar("x", Call(Source{{12, 34}}, "F"), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(12:34 error: functions cannot be called at module-scope)");
@@ -771,7 +771,7 @@
     // var<private> x = 64i;
     // @compute @workgroup_size(x)
     // fn main() {}
-    GlobalVar("x", ty.i32(), ast::StorageClass::kPrivate, Expr(64_i));
+    GlobalVar("x", ty.i32(), ast::AddressSpace::kPrivate, Expr(64_i));
     Func("main", utils::Empty, ty.void_(), utils::Empty,
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -830,7 +830,7 @@
 }
 
 TEST_F(ResolverFunctionValidationTest, ReturnIsConstructible_NonPlain) {
-    auto* ret_type = ty.pointer(Source{{12, 34}}, ty.i32(), ast::StorageClass::kFunction);
+    auto* ret_type = ty.pointer(Source{{12, 34}}, ty.i32(), ast::AddressSpace::kFunction);
     Func("f", utils::Empty, ret_type, utils::Empty);
 
     EXPECT_FALSE(r()->Resolve());
@@ -939,16 +939,16 @@
 }
 
 struct TestParams {
-    ast::StorageClass storage_class;
+    ast::AddressSpace address_space;
     bool should_pass;
 };
 
 struct TestWithParams : ResolverTestWithParam<TestParams> {};
 
 using ResolverFunctionParameterValidationTest = TestWithParams;
-TEST_P(ResolverFunctionParameterValidationTest, StorageClass) {
+TEST_P(ResolverFunctionParameterValidationTest, AddressSpace) {
     auto& param = GetParam();
-    auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.storage_class);
+    auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.address_space);
     auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
     Func("f", utils::Vector{arg}, ty.void_(), utils::Empty);
 
@@ -956,23 +956,23 @@
         ASSERT_TRUE(r()->Resolve()) << r()->error();
     } else {
         std::stringstream ss;
-        ss << param.storage_class;
+        ss << param.address_space;
         EXPECT_FALSE(r()->Resolve());
         EXPECT_EQ(r()->error(), "12:34 error: function parameter of pointer type cannot be in '" +
-                                    ss.str() + "' storage class");
+                                    ss.str() + "' address space");
     }
 }
 INSTANTIATE_TEST_SUITE_P(ResolverTest,
                          ResolverFunctionParameterValidationTest,
-                         testing::Values(TestParams{ast::StorageClass::kNone, false},
-                                         TestParams{ast::StorageClass::kIn, false},
-                                         TestParams{ast::StorageClass::kOut, false},
-                                         TestParams{ast::StorageClass::kUniform, false},
-                                         TestParams{ast::StorageClass::kWorkgroup, true},
-                                         TestParams{ast::StorageClass::kHandle, false},
-                                         TestParams{ast::StorageClass::kStorage, false},
-                                         TestParams{ast::StorageClass::kPrivate, true},
-                                         TestParams{ast::StorageClass::kFunction, true}));
+                         testing::Values(TestParams{ast::AddressSpace::kNone, false},
+                                         TestParams{ast::AddressSpace::kIn, false},
+                                         TestParams{ast::AddressSpace::kOut, false},
+                                         TestParams{ast::AddressSpace::kUniform, false},
+                                         TestParams{ast::AddressSpace::kWorkgroup, true},
+                                         TestParams{ast::AddressSpace::kHandle, false},
+                                         TestParams{ast::AddressSpace::kStorage, false},
+                                         TestParams{ast::AddressSpace::kPrivate, true},
+                                         TestParams{ast::AddressSpace::kFunction, true}));
 
 }  // namespace
 }  // namespace tint::resolver
diff --git a/src/tint/resolver/host_shareable_validation_test.cc b/src/tint/resolver/host_shareable_validation_test.cc
index bba156b..bd8f3ca 100644
--- a/src/tint/resolver/host_shareable_validation_test.cc
+++ b/src/tint/resolver/host_shareable_validation_test.cc
@@ -28,14 +28,14 @@
 TEST_F(ResolverHostShareableValidationTest, BoolMember) {
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.bool_())});
 
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
+        R"(56:78 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
 12:34 note: while analysing structure member S.x
 56:78 note: while instantiating 'var' g)");
 }
@@ -43,14 +43,14 @@
 TEST_F(ResolverHostShareableValidationTest, BoolVectorMember) {
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.vec3<bool>())});
 
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'vec3<bool>' cannot be used in storage class 'storage' as it is non-host-shareable
+        R"(56:78 error: Type 'vec3<bool>' cannot be used in address space 'storage' as it is non-host-shareable
 12:34 note: while analysing structure member S.x
 56:78 note: while instantiating 'var' g)");
 }
@@ -59,14 +59,14 @@
     auto* a1 = Alias("a1", ty.bool_());
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.Of(a1))});
     auto* a2 = Alias("a2", ty.Of(s));
-    GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{56, 78}}, "g", ty.Of(a2), ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
+        R"(56:78 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
 12:34 note: while analysing structure member S.x
 56:78 note: while instantiating 'var' g)");
 }
@@ -78,14 +78,14 @@
 
     auto* s = Structure("S", utils::Vector{Member(Source{{7, 8}}, "m", ty.Of(i3))});
 
-    GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(
         r()->error(),
-        R"(9:10 error: Type 'bool' cannot be used in storage class 'storage' as it is non-host-shareable
+        R"(9:10 error: Type 'bool' cannot be used in address space 'storage' as it is non-host-shareable
 1:2 note: while analysing structure member I1.x
 3:4 note: while analysing structure member I2.y
 5:6 note: while analysing structure member I3.z
@@ -117,7 +117,7 @@
 
     auto* s = Structure("S", utils::Vector{Member(Source{{7, 8}}, "m", ty.Of(i3))});
 
-    GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{9, 10}}, "g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
               Binding(0_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/increment_decrement_validation_test.cc b/src/tint/resolver/increment_decrement_validation_test.cc
index 7368b6d..e822de3 100644
--- a/src/tint/resolver/increment_decrement_validation_test.cc
+++ b/src/tint/resolver/increment_decrement_validation_test.cc
@@ -64,8 +64,8 @@
     // var a : i32;
     // let b : ptr<function,i32> = &a;
     // *b++;
-    auto* var_a = Var("a", ty.i32(), ast::StorageClass::kFunction);
-    auto* var_b = Let("b", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(Expr("a")));
+    auto* var_a = Var("a", ty.i32(), ast::AddressSpace::kFunction);
+    auto* var_b = Let("b", ty.pointer<i32>(ast::AddressSpace::kFunction), AddressOf(Expr("a")));
     WrapInFunction(var_a, var_b, Increment(Source{{12, 34}}, Deref("b")));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -127,7 +127,7 @@
 TEST_F(ResolverIncrementDecrementValidationTest, Atomic) {
     // var<workgroup> a : atomic<i32>;
     // a++;
-    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
+    GlobalVar(Source{{12, 34}}, "a", ty.atomic(ty.i32()), ast::AddressSpace::kWorkgroup);
     WrapInFunction(Increment(Expr(Source{{56, 78}}, "a")));
 
     EXPECT_FALSE(r()->Resolve());
@@ -193,7 +193,7 @@
     // {
     //   a++;
     // }
-    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
+    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead,
               Group(0_a), Binding(0_a));
     WrapInFunction(Increment(Source{{56, 78}}, "a"));
 
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index 2521959..3d03c1a 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -97,7 +97,7 @@
 
     // var a = <type constructor>;
     auto* ctor_expr = params.create_value(*this, 0);
-    auto* var = GlobalVar("a", ast::StorageClass::kPrivate, ctor_expr);
+    auto* var = GlobalVar("a", ast::AddressSpace::kPrivate, ctor_expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
     EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
@@ -124,7 +124,7 @@
 
     // var a = <type constructor>;
     auto* ctor_expr = params.create_value(*this, 0);
-    auto* var = Var("a", ast::StorageClass::kFunction, ctor_expr);
+    auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
     WrapInFunction(var);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -139,7 +139,7 @@
         create<sem::Array>(create<sem::U32>(), sem::ConstantArrayCount{10u}, 4u, 4u * 10u, 4u, 4u);
 
     auto* ctor_expr = Construct(type);
-    auto* var = Var("a", ast::StorageClass::kFunction, ctor_expr);
+    auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
     WrapInFunction(var);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -158,7 +158,7 @@
 
     auto* ctor_expr = Construct(ty.Of(str));
 
-    auto* var = Var("a", ast::StorageClass::kFunction, ctor_expr);
+    auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
     WrapInFunction(var);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index 8533940..ad6a837 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -321,7 +321,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 using TexelFormat = ast::TexelFormat;
 using Access = ast::Access;
-using StorageClass = ast::StorageClass;
+using AddressSpace = ast::AddressSpace;
 using ParameterUsage = sem::ParameterUsage;
 using PipelineStage = ast::PipelineStage;
 
@@ -539,7 +539,7 @@
     }
 
     if (auto* p = ty->As<sem::Pointer>()) {
-        S = Number(static_cast<uint32_t>(p->StorageClass()));
+        S = Number(static_cast<uint32_t>(p->AddressSpace()));
         T = p->StoreType();
         A = Number(static_cast<uint32_t>(p->Access()));
         return true;
@@ -548,7 +548,7 @@
 }
 
 const sem::Pointer* build_ptr(MatchState& state, Number S, const sem::Type* T, Number& A) {
-    return state.builder.create<sem::Pointer>(T, static_cast<ast::StorageClass>(S.Value()),
+    return state.builder.create<sem::Pointer>(T, static_cast<ast::AddressSpace>(S.Value()),
                                               static_cast<ast::Access>(A.Value()));
 }
 
@@ -1158,7 +1158,7 @@
         params.Reserve(match.parameters.Length());
         for (auto& p : match.parameters) {
             params.Push(builder.create<sem::Parameter>(
-                nullptr, static_cast<uint32_t>(params.Length()), p.type, ast::StorageClass::kNone,
+                nullptr, static_cast<uint32_t>(params.Length()), p.type, ast::AddressSpace::kNone,
                 ast::Access::kUndefined, p.usage));
         }
         sem::PipelineStageSet supported_stages;
@@ -1356,7 +1356,7 @@
         params.Reserve(match.parameters.Length());
         for (auto& p : match.parameters) {
             params.Push(builder.create<sem::Parameter>(
-                nullptr, static_cast<uint32_t>(params.Length()), p.type, ast::StorageClass::kNone,
+                nullptr, static_cast<uint32_t>(params.Length()), p.type, ast::AddressSpace::kNone,
                 ast::Access::kUndefined, p.usage));
         }
         auto eval_stage = match.overload->const_eval_fn ? sem::EvaluationStage::kConstant
@@ -1371,7 +1371,7 @@
     // Conversion.
     auto* target = utils::GetOrCreate(converters, match, [&]() {
         auto param = builder.create<sem::Parameter>(
-            nullptr, 0u, match.parameters[0].type, ast::StorageClass::kNone,
+            nullptr, 0u, match.parameters[0].type, ast::AddressSpace::kNone,
             ast::Access::kUndefined, match.parameters[0].usage);
         auto eval_stage = match.overload->const_eval_fn ? sem::EvaluationStage::kConstant
                                                         : sem::EvaluationStage::kRuntime;
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index dfe2574..fcc651c 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -2457,10 +2457,10 @@
 };
 
 Number FunctionPrivateWorkgroup::Match(MatchState&, Number number) const {
-  switch (static_cast<StorageClass>(number.Value())) {
-    case StorageClass::kFunction:
-    case StorageClass::kPrivate:
-    case StorageClass::kWorkgroup:
+  switch (static_cast<AddressSpace>(number.Value())) {
+    case AddressSpace::kFunction:
+    case AddressSpace::kPrivate:
+    case AddressSpace::kWorkgroup:
       return number;
     default:
       return Number::invalid;
@@ -2486,9 +2486,9 @@
 };
 
 Number WorkgroupOrStorage::Match(MatchState&, Number number) const {
-  switch (static_cast<StorageClass>(number.Value())) {
-    case StorageClass::kWorkgroup:
-    case StorageClass::kStorage:
+  switch (static_cast<AddressSpace>(number.Value())) {
+    case AddressSpace::kWorkgroup:
+    case AddressSpace::kStorage:
       return number;
     default:
       return Number::invalid;
@@ -2514,8 +2514,8 @@
 };
 
 Number Storage::Match(MatchState&, Number number) const {
-  if (number.IsAny() || number.Value() == static_cast<uint32_t>(StorageClass::kStorage)) {
-    return Number(static_cast<uint32_t>(StorageClass::kStorage));
+  if (number.IsAny() || number.Value() == static_cast<uint32_t>(AddressSpace::kStorage)) {
+    return Number(static_cast<uint32_t>(AddressSpace::kStorage));
   }
   return Number::invalid;
 }
diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc
index b8f5629..1397d11 100644
--- a/src/tint/resolver/intrinsic_table_test.cc
+++ b/src/tint/resolver/intrinsic_table_test.cc
@@ -216,7 +216,7 @@
     auto* i32 = create<sem::I32>();
     auto* atomicI32 = create<sem::Atomic>(i32);
     auto* ptr =
-        create<sem::Pointer>(atomicI32, ast::StorageClass::kWorkgroup, ast::Access::kReadWrite);
+        create<sem::Pointer>(atomicI32, ast::AddressSpace::kWorkgroup, ast::Access::kReadWrite);
     auto result = table->Lookup(BuiltinType::kAtomicLoad, utils::Vector{ptr}, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
     ASSERT_EQ(Diagnostics().str(), "");
@@ -236,7 +236,7 @@
 
 TEST_F(IntrinsicTableTest, MatchArray) {
     auto* arr = create<sem::Array>(create<sem::U32>(), sem::RuntimeArrayCount{}, 4u, 4u, 4u, 4u);
-    auto* arr_ptr = create<sem::Pointer>(arr, ast::StorageClass::kStorage, ast::Access::kReadWrite);
+    auto* arr_ptr = create<sem::Pointer>(arr, ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto result = table->Lookup(BuiltinType::kArrayLength, utils::Vector{arr_ptr}, Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
     ASSERT_EQ(Diagnostics().str(), "");
@@ -424,7 +424,7 @@
     auto result = table->Lookup(
         BuiltinType::kCos,
         utils::Vector{
-            create<sem::Reference>(f32, ast::StorageClass::kFunction, ast::Access::kReadWrite),
+            create<sem::Reference>(f32, ast::AddressSpace::kFunction, ast::Access::kReadWrite),
         },
         Source{});
     ASSERT_NE(result.sem, nullptr) << Diagnostics().str();
diff --git a/src/tint/resolver/is_host_shareable_test.cc b/src/tint/resolver/is_host_shareable_test.cc
index 04f9b89..ab969fa 100644
--- a/src/tint/resolver/is_host_shareable_test.cc
+++ b/src/tint/resolver/is_host_shareable_test.cc
@@ -95,7 +95,7 @@
 }
 
 TEST_F(ResolverIsHostShareable, Pointer) {
-    auto* ptr = create<sem::Pointer>(create<sem::I32>(), ast::StorageClass::kPrivate,
+    auto* ptr = create<sem::Pointer>(create<sem::I32>(), ast::AddressSpace::kPrivate,
                                      ast::Access::kReadWrite);
     EXPECT_FALSE(r()->IsHostShareable(ptr));
 }
diff --git a/src/tint/resolver/is_storeable_test.cc b/src/tint/resolver/is_storeable_test.cc
index 3662f38..61cf33b 100644
--- a/src/tint/resolver/is_storeable_test.cc
+++ b/src/tint/resolver/is_storeable_test.cc
@@ -78,7 +78,7 @@
 }
 
 TEST_F(ResolverIsStorableTest, Pointer) {
-    auto* ptr = create<sem::Pointer>(create<sem::I32>(), ast::StorageClass::kPrivate,
+    auto* ptr = create<sem::Pointer>(create<sem::I32>(), ast::AddressSpace::kPrivate,
                                      ast::Access::kReadWrite);
     EXPECT_FALSE(r()->IsStorable(ptr));
 }
@@ -111,7 +111,7 @@
 TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) {
     Structure("S", utils::Vector{
                        Member("a", ty.i32()),
-                       Member("b", ty.pointer<i32>(ast::StorageClass::kPrivate)),
+                       Member("b", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
                    });
 
     EXPECT_FALSE(r()->Resolve());
@@ -137,7 +137,7 @@
     auto* non_storable =
         Structure("nonstorable", utils::Vector{
                                      Member("a", ty.i32()),
-                                     Member("b", ty.pointer<i32>(ast::StorageClass::kPrivate)),
+                                     Member("b", ty.pointer<i32>(ast::AddressSpace::kPrivate)),
                                  });
     Structure("S", utils::Vector{
                        Member("a", ty.i32()),
diff --git a/src/tint/resolver/materialize_test.cc b/src/tint/resolver/materialize_test.cc
index dd200bc..e8a1de5 100644
--- a/src/tint/resolver/materialize_test.cc
+++ b/src/tint/resolver/materialize_test.cc
@@ -902,7 +902,7 @@
                 utils::Vector{WorkgroupSize(abstract_expr()), Stage(ast::PipelineStage::kCompute)});
             break;
         case Method::kIndex:
-            GlobalVar("arr", ty.array<i32, 4>(), ast::StorageClass::kPrivate);
+            GlobalVar("arr", ty.array<i32, 4>(), ast::AddressSpace::kPrivate);
             WrapInFunction(IndexAccessor("arr", abstract_expr()));
             break;
         case Method::kRuntimeIndex:
diff --git a/src/tint/resolver/ptr_ref_test.cc b/src/tint/resolver/ptr_ref_test.cc
index 129263a..a42d554 100644
--- a/src/tint/resolver/ptr_ref_test.cc
+++ b/src/tint/resolver/ptr_ref_test.cc
@@ -38,7 +38,7 @@
 
     ASSERT_TRUE(TypeOf(expr)->Is<sem::Pointer>());
     EXPECT_TRUE(TypeOf(expr)->As<sem::Pointer>()->StoreType()->Is<sem::I32>());
-    EXPECT_EQ(TypeOf(expr)->As<sem::Pointer>()->StorageClass(), ast::StorageClass::kFunction);
+    EXPECT_EQ(TypeOf(expr)->As<sem::Pointer>()->AddressSpace(), ast::AddressSpace::kFunction);
 }
 
 TEST_F(ResolverPtrRefTest, AddressOfThenDeref) {
@@ -56,28 +56,28 @@
     EXPECT_TRUE(TypeOf(expr)->As<sem::Reference>()->StoreType()->Is<sem::I32>());
 }
 
-TEST_F(ResolverPtrRefTest, DefaultPtrStorageClass) {
+TEST_F(ResolverPtrRefTest, DefaultPtrAddressSpace) {
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
 
     auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
     auto* function = Var("f", ty.i32());
-    auto* private_ = GlobalVar("p", ty.i32(), ast::StorageClass::kPrivate);
-    auto* workgroup = GlobalVar("w", ty.i32(), ast::StorageClass::kWorkgroup);
+    auto* private_ = GlobalVar("p", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* workgroup = GlobalVar("w", ty.i32(), ast::AddressSpace::kWorkgroup);
     auto* uniform =
-        GlobalVar("ub", ty.Of(buf), ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
+        GlobalVar("ub", ty.Of(buf), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
     auto* storage =
-        GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage, Binding(1_a), Group(0_a));
+        GlobalVar("sb", ty.Of(buf), ast::AddressSpace::kStorage, Binding(1_a), Group(0_a));
 
     auto* function_ptr =
-        Let("f_ptr", ty.pointer(ty.i32(), ast::StorageClass::kFunction), AddressOf(function));
+        Let("f_ptr", ty.pointer(ty.i32(), ast::AddressSpace::kFunction), AddressOf(function));
     auto* private_ptr =
-        Let("p_ptr", ty.pointer(ty.i32(), ast::StorageClass::kPrivate), AddressOf(private_));
+        Let("p_ptr", ty.pointer(ty.i32(), ast::AddressSpace::kPrivate), AddressOf(private_));
     auto* workgroup_ptr =
-        Let("w_ptr", ty.pointer(ty.i32(), ast::StorageClass::kWorkgroup), AddressOf(workgroup));
+        Let("w_ptr", ty.pointer(ty.i32(), ast::AddressSpace::kWorkgroup), AddressOf(workgroup));
     auto* uniform_ptr =
-        Let("ub_ptr", ty.pointer(ty.Of(buf), ast::StorageClass::kUniform), AddressOf(uniform));
+        Let("ub_ptr", ty.pointer(ty.Of(buf), ast::AddressSpace::kUniform), AddressOf(uniform));
     auto* storage_ptr =
-        Let("sb_ptr", ty.pointer(ty.Of(buf), ast::StorageClass::kStorage), AddressOf(storage));
+        Let("sb_ptr", ty.pointer(ty.Of(buf), ast::AddressSpace::kStorage), AddressOf(storage));
 
     WrapInFunction(function, function_ptr, private_ptr, workgroup_ptr, uniform_ptr, storage_ptr);
 
diff --git a/src/tint/resolver/ptr_ref_validation_test.cc b/src/tint/resolver/ptr_ref_validation_test.cc
index f850f2a..176a836 100644
--- a/src/tint/resolver/ptr_ref_validation_test.cc
+++ b/src/tint/resolver/ptr_ref_validation_test.cc
@@ -62,7 +62,7 @@
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: cannot take the address of expression in handle "
-              "storage class");
+              "address space");
 }
 
 TEST_F(ResolverPtrRefValidationTest, AddressOfVectorComponent_MemberAccessor) {
@@ -102,7 +102,7 @@
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: cannot take the address of expression in handle "
-              "storage class");
+              "address space");
 }
 
 TEST_F(ResolverPtrRefValidationTest, DerefOfLiteral) {
@@ -143,12 +143,12 @@
     // }
     auto* inner = Structure("Inner", utils::Vector{Member("arr", ty.array<i32, 4>())});
     auto* buf = Structure("S", utils::Vector{Member("inner", ty.Of(inner))});
-    auto* storage = GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+    auto* storage = GlobalVar("s", ty.Of(buf), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
                               Binding(0_a), Group(0_a));
 
     auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
     auto* ptr =
-        Let(Source{{12, 34}}, "p", ty.pointer<i32>(ast::StorageClass::kStorage), AddressOf(expr));
+        Let(Source{{12, 34}}, "p", ty.pointer<i32>(ast::AddressSpace::kStorage), AddressOf(expr));
 
     WrapInFunction(ptr);
 
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index cbc71e6..d79d6a0 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -247,9 +247,9 @@
             if (auto* el = Type(t->type)) {
                 auto access = t->access;
                 if (access == ast::kUndefined) {
-                    access = DefaultAccessForStorageClass(t->storage_class);
+                    access = DefaultAccessForAddressSpace(t->address_space);
                 }
-                return builder_->create<sem::Pointer>(el, t->storage_class, access);
+                return builder_->create<sem::Pointer>(el, t->address_space, access);
             }
             return nullptr;
         },
@@ -368,11 +368,11 @@
         ty = rhs->Type()->UnwrapRef();  // Implicit load of RHS
     }
 
-    if (rhs && !validator_.VariableInitializer(v, ast::StorageClass::kNone, ty, rhs)) {
+    if (rhs && !validator_.VariableInitializer(v, ast::AddressSpace::kNone, ty, rhs)) {
         return nullptr;
     }
 
-    if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, const_cast<sem::Type*>(ty),
+    if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<sem::Type*>(ty),
                                       v->source)) {
         AddNote("while instantiating 'let' " + builder_->Symbols().NameFor(v->symbol), v->source);
         return nullptr;
@@ -381,12 +381,12 @@
     sem::Variable* sem = nullptr;
     if (is_global) {
         sem = builder_->create<sem::GlobalVariable>(
-            v, ty, sem::EvaluationStage::kRuntime, ast::StorageClass::kNone,
+            v, ty, sem::EvaluationStage::kRuntime, ast::AddressSpace::kNone,
             ast::Access::kUndefined, /* constant_value */ nullptr, sem::BindingPoint{},
             std::nullopt);
     } else {
         sem = builder_->create<sem::LocalVariable>(v, ty, sem::EvaluationStage::kRuntime,
-                                                   ast::StorageClass::kNone,
+                                                   ast::AddressSpace::kNone,
                                                    ast::Access::kUndefined, current_statement_,
                                                    /* constant_value */ nullptr);
     }
@@ -425,11 +425,11 @@
         return nullptr;
     }
 
-    if (rhs && !validator_.VariableInitializer(v, ast::StorageClass::kNone, ty, rhs)) {
+    if (rhs && !validator_.VariableInitializer(v, ast::AddressSpace::kNone, ty, rhs)) {
         return nullptr;
     }
 
-    if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, const_cast<sem::Type*>(ty),
+    if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<sem::Type*>(ty),
                                       v->source)) {
         AddNote("while instantiating 'override' " + builder_->Symbols().NameFor(v->symbol),
                 v->source);
@@ -437,7 +437,7 @@
     }
 
     auto* sem = builder_->create<sem::GlobalVariable>(
-        v, ty, sem::EvaluationStage::kOverride, ast::StorageClass::kNone, ast::Access::kUndefined,
+        v, ty, sem::EvaluationStage::kOverride, ast::AddressSpace::kNone, ast::Access::kUndefined,
         /* constant_value */ nullptr, sem::BindingPoint{}, std::nullopt);
     sem->SetConstructor(rhs);
 
@@ -510,21 +510,21 @@
         return nullptr;
     }
 
-    if (!validator_.VariableInitializer(c, ast::StorageClass::kNone, ty, rhs)) {
+    if (!validator_.VariableInitializer(c, ast::AddressSpace::kNone, ty, rhs)) {
         return nullptr;
     }
 
-    if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, const_cast<sem::Type*>(ty),
+    if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, const_cast<sem::Type*>(ty),
                                       c->source)) {
         AddNote("while instantiating 'const' " + builder_->Symbols().NameFor(c->symbol), c->source);
         return nullptr;
     }
 
     auto* sem = is_global ? static_cast<sem::Variable*>(builder_->create<sem::GlobalVariable>(
-                                c, ty, sem::EvaluationStage::kConstant, ast::StorageClass::kNone,
+                                c, ty, sem::EvaluationStage::kConstant, ast::AddressSpace::kNone,
                                 ast::Access::kUndefined, value, sem::BindingPoint{}, std::nullopt))
                           : static_cast<sem::Variable*>(builder_->create<sem::LocalVariable>(
-                                c, ty, sem::EvaluationStage::kConstant, ast::StorageClass::kNone,
+                                c, ty, sem::EvaluationStage::kConstant, ast::AddressSpace::kNone,
                                 ast::Access::kUndefined, current_statement_, value));
 
     sem->SetConstructor(rhs);
@@ -562,39 +562,39 @@
         return nullptr;
     }
 
-    auto storage_class = var->declared_storage_class;
-    if (storage_class == ast::StorageClass::kNone) {
-        // No declared storage class. Infer from usage / type.
+    auto address_space = var->declared_address_space;
+    if (address_space == ast::AddressSpace::kNone) {
+        // No declared address space. Infer from usage / type.
         if (!is_global) {
-            storage_class = ast::StorageClass::kFunction;
+            address_space = ast::AddressSpace::kFunction;
         } else if (storage_ty->UnwrapRef()->is_handle()) {
             // https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
             // If the store type is a texture type or a sampler type, then the
-            // variable declaration must not have a storage class attribute. The
-            // storage class will always be handle.
-            storage_class = ast::StorageClass::kHandle;
+            // variable declaration must not have a address space attribute. The
+            // address space will always be handle.
+            address_space = ast::AddressSpace::kHandle;
         }
     }
 
-    if (!is_global && storage_class != ast::StorageClass::kFunction &&
+    if (!is_global && address_space != ast::AddressSpace::kFunction &&
         validator_.IsValidationEnabled(var->attributes,
-                                       ast::DisabledValidation::kIgnoreStorageClass)) {
-        AddError("function-scope 'var' declaration must use 'function' storage class", var->source);
+                                       ast::DisabledValidation::kIgnoreAddressSpace)) {
+        AddError("function-scope 'var' declaration must use 'function' address space", var->source);
         return nullptr;
     }
 
     auto access = var->declared_access;
     if (access == ast::Access::kUndefined) {
-        access = DefaultAccessForStorageClass(storage_class);
+        access = DefaultAccessForAddressSpace(address_space);
     }
 
-    if (rhs && !validator_.VariableInitializer(var, storage_class, storage_ty, rhs)) {
+    if (rhs && !validator_.VariableInitializer(var, address_space, storage_ty, rhs)) {
         return nullptr;
     }
 
-    auto* var_ty = builder_->create<sem::Reference>(storage_ty, storage_class, access);
+    auto* var_ty = builder_->create<sem::Reference>(storage_ty, address_space, access);
 
-    if (!ApplyStorageClassUsageToType(storage_class, var_ty, var->source)) {
+    if (!ApplyAddressSpaceUsageToType(address_space, var_ty, var->source)) {
         AddNote("while instantiating 'var' " + builder_->Symbols().NameFor(var->symbol),
                 var->source);
         return nullptr;
@@ -654,12 +654,12 @@
         }
 
         sem = builder_->create<sem::GlobalVariable>(
-            var, var_ty, sem::EvaluationStage::kRuntime, storage_class, access,
+            var, var_ty, sem::EvaluationStage::kRuntime, address_space, access,
             /* constant_value */ nullptr, binding_point, location);
 
     } else {
         sem = builder_->create<sem::LocalVariable>(var, var_ty, sem::EvaluationStage::kRuntime,
-                                                   storage_class, access, current_statement_,
+                                                   address_space, access, current_statement_,
                                                    /* constant_value */ nullptr);
     }
 
@@ -686,7 +686,7 @@
         return nullptr;
     }
 
-    if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, ty, param->source)) {
+    if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, ty, param->source)) {
         add_note();
         return nullptr;
     }
@@ -694,8 +694,8 @@
     if (auto* ptr = ty->As<sem::Pointer>()) {
         // For MSL, we push module-scope variables into the entry point as pointer
         // parameters, so we also need to handle their store type.
-        if (!ApplyStorageClassUsageToType(
-                ptr->StorageClass(), const_cast<sem::Type*>(ptr->StoreType()), param->source)) {
+        if (!ApplyAddressSpaceUsageToType(
+                ptr->AddressSpace(), const_cast<sem::Type*>(ptr->StoreType()), param->source)) {
             add_note();
             return nullptr;
         }
@@ -749,18 +749,18 @@
     }
 
     auto* sem = builder_->create<sem::Parameter>(
-        param, index, ty, ast::StorageClass::kNone, ast::Access::kUndefined,
+        param, index, ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
         sem::ParameterUsage::kNone, binding_point, location);
     builder_->Sem().Add(param, sem);
     return sem;
 }
 
-ast::Access Resolver::DefaultAccessForStorageClass(ast::StorageClass storage_class) {
+ast::Access Resolver::DefaultAccessForAddressSpace(ast::AddressSpace address_space) {
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
-    switch (storage_class) {
-        case ast::StorageClass::kStorage:
-        case ast::StorageClass::kUniform:
-        case ast::StorageClass::kHandle:
+    switch (address_space) {
+        case ast::AddressSpace::kStorage:
+        case ast::AddressSpace::kUniform:
+        case ast::AddressSpace::kHandle:
             return ast::Access::kRead;
         default:
             break;
@@ -845,7 +845,7 @@
 
     // TODO(bclayton): Call this at the end of resolve on all uniform and storage
     // referenced structs
-    if (!validator_.StorageClassLayout(sem, enabled_extensions_, valid_type_storage_layouts_)) {
+    if (!validator_.AddressSpaceLayout(sem, enabled_extensions_, valid_type_storage_layouts_)) {
         return nullptr;
     }
 
@@ -962,7 +962,7 @@
     }
 
     if (auto* str = return_type->As<sem::Struct>()) {
-        if (!ApplyStorageClassUsageToType(ast::StorageClass::kNone, str, decl->source)) {
+        if (!ApplyAddressSpaceUsageToType(ast::AddressSpace::kNone, str, decl->source)) {
             AddNote(
                 "while instantiating return type for " + builder_->Symbols().NameFor(decl->symbol),
                 decl->source);
@@ -1625,7 +1625,7 @@
 
     // If we're extracting from a reference, we return a reference.
     if (auto* ref = obj_raw_ty->As<sem::Reference>()) {
-        ty = builder_->create<sem::Reference>(ty, ref->StorageClass(), ref->Access());
+        ty = builder_->create<sem::Reference>(ty, ref->AddressSpace(), ref->Access());
     }
 
     auto stage = sem::EarliestStage(obj->Stage(), idx->Stage());
@@ -1783,7 +1783,7 @@
                                 nullptr,                   // declaration
                                 static_cast<uint32_t>(i),  // index
                                 arr->ElemType(),           // type
-                                ast::StorageClass::kNone,  // storage_class
+                                ast::AddressSpace::kNone,  // address_space
                                 ast::Access::kUndefined);
                         });
                         return builder_->create<sem::TypeConstructor>(arr, std::move(params),
@@ -1812,7 +1812,7 @@
                                 nullptr,                    // declaration
                                 static_cast<uint32_t>(i),   // index
                                 str->Members()[i]->Type(),  // type
-                                ast::StorageClass::kNone,   // storage_class
+                                ast::AddressSpace::kNone,   // address_space
                                 ast::Access::kUndefined);   // access
                         }
                         return builder_->create<sem::TypeConstructor>(str, std::move(params),
@@ -2321,7 +2321,7 @@
 
             // If we're extracting from a reference, we return a reference.
             if (auto* ref = structure->As<sem::Reference>()) {
-                ty = builder_->create<sem::Reference>(ty, ref->StorageClass(), ref->Access());
+                ty = builder_->create<sem::Reference>(ty, ref->AddressSpace(), ref->Access());
             }
 
             auto val = const_eval_.MemberAccess(object, member);
@@ -2390,7 +2390,7 @@
                 ty = vec->type();
                 // If we're extracting from a reference, we return a reference.
                 if (auto* ref = structure->As<sem::Reference>()) {
-                    ty = builder_->create<sem::Reference>(ty, ref->StorageClass(), ref->Access());
+                    ty = builder_->create<sem::Reference>(ty, ref->AddressSpace(), ref->Access());
                 }
             } else {
                 // The vector will have a number of components equal to the length of
@@ -2483,7 +2483,7 @@
         case ast::UnaryOp::kAddressOf:
             if (auto* ref = expr_ty->As<sem::Reference>()) {
                 if (ref->StoreType()->UnwrapRef()->is_handle()) {
-                    AddError("cannot take the address of expression in handle storage class",
+                    AddError("cannot take the address of expression in handle address space",
                              unary->expr->source);
                     return nullptr;
                 }
@@ -2496,7 +2496,7 @@
                     return nullptr;
                 }
 
-                ty = builder_->create<sem::Pointer>(ref->StoreType(), ref->StorageClass(),
+                ty = builder_->create<sem::Pointer>(ref->StoreType(), ref->AddressSpace(),
                                                     ref->Access());
 
                 source_var = expr->SourceVariable();
@@ -2508,7 +2508,7 @@
 
         case ast::UnaryOp::kIndirection:
             if (auto* ptr = expr_ty->As<sem::Pointer>()) {
-                ty = builder_->create<sem::Reference>(ptr->StoreType(), ptr->StorageClass(),
+                ty = builder_->create<sem::Reference>(ptr->StoreType(), ptr->AddressSpace(),
                                                       ptr->Access());
                 source_var = expr->SourceVariable();
             } else {
@@ -3205,20 +3205,20 @@
     });
 }
 
-bool Resolver::ApplyStorageClassUsageToType(ast::StorageClass sc,
+bool Resolver::ApplyAddressSpaceUsageToType(ast::AddressSpace sc,
                                             sem::Type* ty,
                                             const Source& usage) {
     ty = const_cast<sem::Type*>(ty->UnwrapRef());
 
     if (auto* str = ty->As<sem::Struct>()) {
-        if (str->StorageClassUsage().count(sc)) {
+        if (str->AddressSpaceUsage().count(sc)) {
             return true;  // Already applied
         }
 
         str->AddUsage(sc);
 
         for (auto* member : str->Members()) {
-            if (!ApplyStorageClassUsageToType(sc, const_cast<sem::Type*>(member->Type()), usage)) {
+            if (!ApplyAddressSpaceUsageToType(sc, const_cast<sem::Type*>(member->Type()), usage)) {
                 std::stringstream err;
                 err << "while analysing structure member " << sem_.TypeNameOf(str) << "."
                     << builder_->Symbols().NameFor(member->Declaration()->symbol);
@@ -3230,20 +3230,20 @@
     }
 
     if (auto* arr = ty->As<sem::Array>()) {
-        if (arr->IsRuntimeSized() && sc != ast::StorageClass::kStorage) {
+        if (arr->IsRuntimeSized() && sc != ast::AddressSpace::kStorage) {
             AddError(
-                "runtime-sized arrays can only be used in the <storage> storage "
-                "class",
+                "runtime-sized arrays can only be used in the <storage> address "
+                "space",
                 usage);
             return false;
         }
 
-        return ApplyStorageClassUsageToType(sc, const_cast<sem::Type*>(arr->ElemType()), usage);
+        return ApplyAddressSpaceUsageToType(sc, const_cast<sem::Type*>(arr->ElemType()), usage);
     }
 
     if (ast::IsHostShareable(sc) && !validator_.IsHostShareable(ty)) {
         std::stringstream err;
-        err << "Type '" << sem_.TypeNameOf(ty) << "' cannot be used in storage class '" << sc
+        err << "Type '" << sem_.TypeNameOf(ty) << "' cannot be used in address space '" << sc
             << "' as it is non-host-shareable";
         AddError(err.str(), usage);
         return false;
diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h
index 7e115b3..cb95d0ca 100644
--- a/src/tint/resolver/resolver.h
+++ b/src/tint/resolver/resolver.h
@@ -387,20 +387,20 @@
     /// @param index the index of the parameter
     sem::Parameter* Parameter(const ast::Parameter* param, uint32_t index);
 
-    /// Records the storage class usage for the given type, and any transient
+    /// Records the address space usage for the given type, and any transient
     /// dependencies of the type. Validates that the type can be used for the
-    /// given storage class, erroring if it cannot.
-    /// @param sc the storage class to apply to the type and transitent types
-    /// @param ty the type to apply the storage class on
+    /// given address space, erroring if it cannot.
+    /// @param sc the address space to apply to the type and transitent types
+    /// @param ty the type to apply the address space on
     /// @param usage the Source of the root variable declaration that uses the
-    /// given type and storage class. Used for generating sensible error
+    /// given type and address space. Used for generating sensible error
     /// messages.
     /// @returns true on success, false on error
-    bool ApplyStorageClassUsageToType(ast::StorageClass sc, sem::Type* ty, const Source& usage);
+    bool ApplyAddressSpaceUsageToType(ast::AddressSpace sc, sem::Type* ty, const Source& usage);
 
-    /// @param storage_class the storage class
-    /// @returns the default access control for the given storage class
-    ast::Access DefaultAccessForStorageClass(ast::StorageClass storage_class);
+    /// @param address_space the address space
+    /// @returns the default access control for the given address space
+    ast::Access DefaultAccessForAddressSpace(ast::AddressSpace address_space);
 
     /// Allocate constant IDs for pipeline-overridable constants.
     /// @returns true on success, false on error
diff --git a/src/tint/resolver/resolver_is_storeable_test.cc b/src/tint/resolver/resolver_is_storeable_test.cc
deleted file mode 100644
index f4cde70..0000000
--- a/src/tint/resolver/resolver_is_storeable_test.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2021 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.
-
-#include "src/tint/resolver/resolver.h"
-
-#include "gmock/gmock.h"
-#include "src/tint/resolver/resolver_test_helper.h"
-#include "src/tint/sem/atomic.h"
-
-namespace tint::resolver {
-namespace {
-
-using ResolverIsStorableTest = ResolverTest;
-
-TEST_F(ResolverIsStorableTest, Struct_AllMembersStorable) {
-    Structure("S", {
-                       Member("a", ty.i32()),
-                       Member("b", ty.f32()),
-                   });
-
-    ASSERT_TRUE(r()->Resolve()) << r()->error();
-}
-
-TEST_F(ResolverIsStorableTest, Struct_SomeMembersNonStorable) {
-    Structure("S", {
-                       Member("a", ty.i32()),
-                       Member("b", ty.pointer<i32>(ast::StorageClass::kPrivate)),
-                   });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(error: ptr<private, i32, read_write> cannot be used as the type of a structure member)");
-}
-
-TEST_F(ResolverIsStorableTest, Struct_NestedStorable) {
-    auto* storable = Structure("Storable", {
-                                               Member("a", ty.i32()),
-                                               Member("b", ty.f32()),
-                                           });
-    Structure("S", {
-                       Member("a", ty.i32()),
-                       Member("b", ty.Of(storable)),
-                   });
-
-    ASSERT_TRUE(r()->Resolve()) << r()->error();
-}
-
-TEST_F(ResolverIsStorableTest, Struct_NestedNonStorable) {
-    auto* non_storable =
-        Structure("nonstorable", {
-                                     Member("a", ty.i32()),
-                                     Member("b", ty.pointer<i32>(ast::StorageClass::kPrivate)),
-                                 });
-    Structure("S", {
-                       Member("a", ty.i32()),
-                       Member("b", ty.Of(non_storable)),
-                   });
-
-    EXPECT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(error: ptr<private, i32, read_write> cannot be used as the type of a structure member)");
-}
-
-}  // namespace
-}  // namespace tint::resolver
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index cde4735..631725a 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -316,7 +316,7 @@
 
 TEST_F(ResolverTest, Stmt_VariableDecl_ModuleScope) {
     auto* init = Expr(2_i);
-    GlobalVar("my_var", ty.i32(), ast::StorageClass::kPrivate, init);
+    GlobalVar("my_var", ty.i32(), ast::AddressSpace::kPrivate, init);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -396,7 +396,7 @@
     Func("func_i32", utils::Empty, ty.void_(), utils::Vector{fn_i32_decl});
 
     // Declare f32 "foo" at module scope
-    auto* mod_f32 = Var("foo", ty.f32(), ast::StorageClass::kPrivate, Expr(2_f));
+    auto* mod_f32 = Var("foo", ty.f32(), ast::AddressSpace::kPrivate, Expr(2_f));
     auto* mod_init = mod_f32->constructor;
     AST().AddGlobalVariable(mod_f32);
 
@@ -424,7 +424,7 @@
 
 TEST_F(ResolverTest, ArraySize_UnsignedLiteral) {
     // var<private> a : array<f32, 10u>;
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_u)), ast::StorageClass::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_u)), ast::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -437,7 +437,7 @@
 
 TEST_F(ResolverTest, ArraySize_SignedLiteral) {
     // var<private> a : array<f32, 10i>;
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_i)), ast::StorageClass::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr(10_i)), ast::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -452,7 +452,7 @@
     // const size = 10u;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(10_u));
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -467,7 +467,7 @@
     // const size = 0;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(10_i));
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -482,7 +482,7 @@
     // override size = 0;
     // var<workgroup> a : array<f32, size>;
     auto* override = Override("size", Expr(10_i));
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kWorkgroup);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -500,8 +500,8 @@
     // var<workgroup> a : array<f32, size>;
     // var<workgroup> b : array<f32, size>;
     auto* override = Override("size", Expr(10_i));
-    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kWorkgroup);
-    auto* b = GlobalVar("b", ty.array(ty.f32(), Expr("size")), ast::StorageClass::kWorkgroup);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kWorkgroup);
+    auto* b = GlobalVar("b", ty.array(ty.f32(), Expr("size")), ast::AddressSpace::kWorkgroup);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -523,7 +523,7 @@
 }
 
 TEST_F(ResolverTest, Expr_Bitcast) {
-    GlobalVar("name", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("name", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* bitcast = create<ast::BitcastExpression>(ty.f32(), Expr("name"));
     WrapInFunction(bitcast);
@@ -586,7 +586,7 @@
 }
 
 TEST_F(ResolverTest, Expr_Cast) {
-    GlobalVar("name", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("name", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* cast = Construct(ty.f32(), "name");
     WrapInFunction(cast);
@@ -644,7 +644,7 @@
 }
 
 TEST_F(ResolverTest, Expr_Identifier_GlobalVariable) {
-    auto* my_var = GlobalVar("my_var", ty.f32(), ast::StorageClass::kPrivate);
+    auto* my_var = GlobalVar("my_var", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* ident = Expr("my_var");
     WrapInFunction(ident);
@@ -747,7 +747,7 @@
     auto* v = Expr("v");
     auto* p = Expr("p");
     auto* v_decl = Decl(Var("v", ty.f32()));
-    auto* p_decl = Decl(Let("p", ty.pointer<f32>(ast::StorageClass::kFunction), AddressOf(v)));
+    auto* p_decl = Decl(Let("p", ty.pointer<f32>(ast::AddressSpace::kFunction), AddressOf(v)));
     auto* assign = Assign(Deref(p), 1.23_f);
     Func("my_func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -822,7 +822,7 @@
     auto* param_b = Param("b", ty.u32(), utils::Vector{Builtin(ast::BuiltinValue::kVertexIndex)});
     auto* param_c = Param("c", ty.u32(), utils::Vector{Location(1_a)});
 
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     auto* func = Func("my_func",
                       utils::Vector{
                           param_a,
@@ -852,8 +852,8 @@
 
 TEST_F(ResolverTest, Function_GlobalVariable_Location) {
     auto* var = GlobalVar(
-        "my_vec", ty.vec4<f32>(), ast::StorageClass::kIn,
-        utils::Vector{Location(3_a), Disable(ast::DisabledValidation::kIgnoreStorageClass)});
+        "my_vec", ty.vec4<f32>(), ast::AddressSpace::kIn,
+        utils::Vector{Location(3_a), Disable(ast::DisabledValidation::kIgnoreAddressSpace)});
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -865,10 +865,10 @@
 TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
     auto* s = Structure("S", utils::Vector{Member("m", ty.u32())});
 
-    auto* sb_var = GlobalVar("sb_var", ty.Of(s), ast::StorageClass::kStorage,
+    auto* sb_var = GlobalVar("sb_var", ty.Of(s), ast::AddressSpace::kStorage,
                              ast::Access::kReadWrite, Binding(0_a), Group(0_a));
-    auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
-    auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::StorageClass::kPrivate);
+    auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::AddressSpace::kWorkgroup);
+    auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* func = Func("my_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -911,7 +911,7 @@
 }
 
 TEST_F(ResolverTest, Function_ReturnType_NoLocation) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     auto* func = Func("my_func", utils::Empty, ty.vec4<f32>(),
                       utils::Vector{
                           Return("my_vec"),
@@ -933,10 +933,10 @@
 TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
     auto* s = Structure("S", utils::Vector{Member("m", ty.u32())});
 
-    auto* sb_var = GlobalVar("sb_var", ty.Of(s), ast::StorageClass::kStorage,
+    auto* sb_var = GlobalVar("sb_var", ty.Of(s), ast::AddressSpace::kStorage,
                              ast::Access::kReadWrite, Binding(0_a), Group(0_a));
-    auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
-    auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::StorageClass::kPrivate);
+    auto* wg_var = GlobalVar("wg_var", ty.f32(), ast::AddressSpace::kWorkgroup);
+    auto* priv_var = GlobalVar("priv_var", ty.f32(), ast::AddressSpace::kPrivate);
 
     Func("my_func", utils::Empty, ty.f32(),
          utils::Vector{Assign("wg_var", "wg_var"), Assign("sb_var", "sb_var"),
@@ -1187,7 +1187,7 @@
 TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
     auto* st = Structure(
         "S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())});
-    GlobalVar("my_struct", ty.Of(st), ast::StorageClass::kPrivate);
+    GlobalVar("my_struct", ty.Of(st), ast::AddressSpace::kPrivate);
 
     auto* mem = MemberAccessor("my_struct", "second_member");
     WrapInFunction(mem);
@@ -1211,7 +1211,7 @@
     auto* st = Structure(
         "S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())});
     auto* alias = Alias("alias", ty.Of(st));
-    GlobalVar("my_struct", ty.Of(alias), ast::StorageClass::kPrivate);
+    GlobalVar("my_struct", ty.Of(alias), ast::AddressSpace::kPrivate);
 
     auto* mem = MemberAccessor("my_struct", "second_member");
     WrapInFunction(mem);
@@ -1231,7 +1231,7 @@
 }
 
 TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
 
     auto* mem = MemberAccessor("my_vec", "xzyw");
     WrapInFunction(mem);
@@ -1249,7 +1249,7 @@
 }
 
 TEST_F(ResolverTest, Expr_MemberAccessor_VectorSwizzle_SingleElement) {
-    GlobalVar("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* mem = MemberAccessor("my_vec", "b");
     WrapInFunction(mem);
@@ -1285,7 +1285,7 @@
 
     auto* stB = Structure("B", utils::Vector{Member("foo", ty.vec4<f32>())});
     auto* stA = Structure("A", utils::Vector{Member("mem", ty.array(ty.Of(stB), 3_i))});
-    GlobalVar("c", ty.Of(stA), ast::StorageClass::kPrivate);
+    GlobalVar("c", ty.Of(stA), ast::AddressSpace::kPrivate);
 
     auto* mem =
         MemberAccessor(MemberAccessor(IndexAccessor(MemberAccessor("c", "mem"), 0_i), "foo"), "yx");
@@ -1303,7 +1303,7 @@
 TEST_F(ResolverTest, Expr_MemberAccessor_InBinaryOp) {
     auto* st = Structure(
         "S", utils::Vector{Member("first_member", ty.f32()), Member("second_member", ty.f32())});
-    GlobalVar("my_struct", ty.Of(st), ast::StorageClass::kPrivate);
+    GlobalVar("my_struct", ty.Of(st), ast::AddressSpace::kPrivate);
 
     auto* expr = Add(MemberAccessor("my_struct", "first_member"),
                      MemberAccessor("my_struct", "second_member"));
@@ -1606,8 +1606,8 @@
     ss << FriendlyName(lhs_type) << " " << params.op << " " << FriendlyName(rhs_type);
     SCOPED_TRACE(ss.str());
 
-    GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
+    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(params.op, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1641,8 +1641,8 @@
        << FriendlyName(rhs_type);
     SCOPED_TRACE(ss.str());
 
-    GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
+    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(params.op, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1687,8 +1687,8 @@
     ss << FriendlyName(lhs_type) << " " << op << " " << FriendlyName(rhs_type);
     SCOPED_TRACE(ss.str());
 
-    GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
+    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(Source{{12, 34}}, op, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1727,8 +1727,8 @@
         is_valid_expr = vec_size == mat_cols;
     }
 
-    GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
+    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
 
     auto* expr = Mul(Source{{12, 34}}, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1764,8 +1764,8 @@
     auto* col = create<sem::Vector>(f32, lhs_mat_rows);
     auto* result_type = create<sem::Matrix>(col, rhs_mat_cols);
 
-    GlobalVar("lhs", lhs_type, ast::StorageClass::kPrivate);
-    GlobalVar("rhs", rhs_type, ast::StorageClass::kPrivate);
+    GlobalVar("lhs", lhs_type, ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", rhs_type, ast::AddressSpace::kPrivate);
 
     auto* expr = Mul(Source{{12, 34}}, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -1793,11 +1793,11 @@
     auto op = GetParam();
 
     if (op == ast::UnaryOp::kNot) {
-        GlobalVar("ident", ty.vec4<bool>(), ast::StorageClass::kPrivate);
+        GlobalVar("ident", ty.vec4<bool>(), ast::AddressSpace::kPrivate);
     } else if (op == ast::UnaryOp::kNegation || op == ast::UnaryOp::kComplement) {
-        GlobalVar("ident", ty.vec4<i32>(), ast::StorageClass::kPrivate);
+        GlobalVar("ident", ty.vec4<i32>(), ast::AddressSpace::kPrivate);
     } else {
-        GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+        GlobalVar("ident", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     }
     auto* der = create<ast::UnaryOpExpression>(op, Expr("ident"));
     WrapInFunction(der);
@@ -1821,7 +1821,7 @@
                                          ast::UnaryOp::kNegation,
                                          ast::UnaryOp::kNot));
 
-TEST_F(ResolverTest, StorageClass_SetsIfMissing) {
+TEST_F(ResolverTest, AddressSpace_SetsIfMissing) {
     auto* var = Var("var", ty.i32());
 
     auto* stmt = Decl(var);
@@ -1829,42 +1829,42 @@
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kFunction);
+    EXPECT_EQ(Sem().Get(var)->AddressSpace(), ast::AddressSpace::kFunction);
 }
 
-TEST_F(ResolverTest, StorageClass_SetForSampler) {
+TEST_F(ResolverTest, AddressSpace_SetForSampler) {
     auto* t = ty.sampler(ast::SamplerKind::kSampler);
     auto* var = GlobalVar("var", t, Binding(0_a), Group(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kHandle);
+    EXPECT_EQ(Sem().Get(var)->AddressSpace(), ast::AddressSpace::kHandle);
 }
 
-TEST_F(ResolverTest, StorageClass_SetForTexture) {
+TEST_F(ResolverTest, AddressSpace_SetForTexture) {
     auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
     auto* var = GlobalVar("var", t, Binding(0_a), Group(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kHandle);
+    EXPECT_EQ(Sem().Get(var)->AddressSpace(), ast::AddressSpace::kHandle);
 }
 
-TEST_F(ResolverTest, StorageClass_DoesNotSetOnConst) {
+TEST_F(ResolverTest, AddressSpace_DoesNotSetOnConst) {
     auto* var = Let("var", ty.i32(), Construct(ty.i32()));
     auto* stmt = Decl(var);
     Func("func", utils::Empty, ty.void_(), utils::Vector{stmt});
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(var)->StorageClass(), ast::StorageClass::kNone);
+    EXPECT_EQ(Sem().Get(var)->AddressSpace(), ast::AddressSpace::kNone);
 }
 
 TEST_F(ResolverTest, Access_SetForStorageBuffer) {
     // struct S { x : i32 };
     // var<storage> g : S;
     auto* s = Structure("S", utils::Vector{Member(Source{{12, 34}}, "x", ty.i32())});
-    auto* var = GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::StorageClass::kStorage,
+    auto* var = GlobalVar(Source{{56, 78}}, "g", ty.Of(s), ast::AddressSpace::kStorage,
                           Binding(0_a), Group(0_a));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1897,11 +1897,11 @@
     // ep_1 -> {}
     // ep_2 -> {}
 
-    GlobalVar("first", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("second", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("call_a", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("call_b", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("call_c", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("first", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("second", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("call_a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("call_b", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("call_c", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* func_b = Func("b", utils::Empty, ty.f32(),
                         utils::Vector{
@@ -2041,8 +2041,8 @@
         {
             ProgramBuilder b;
             auto* expr = b.Expr(1_i);
-            b.GlobalVar("a", b.ty.i32(), ast::StorageClass::kPrivate, expr);
-            b.GlobalVar("b", b.ty.i32(), ast::StorageClass::kPrivate, expr);
+            b.GlobalVar("a", b.ty.i32(), ast::AddressSpace::kPrivate, expr);
+            b.GlobalVar("b", b.ty.i32(), ast::AddressSpace::kPrivate, expr);
             Resolver(&b).Resolve();
         },
         "internal compiler error: AST node 'tint::ast::IntLiteralExpression' was encountered twice "
@@ -2050,7 +2050,7 @@
 }
 
 TEST_F(ResolverTest, UnaryOp_Not) {
-    GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("ident", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     auto* der = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr(Source{{12, 34}}, "ident"));
     WrapInFunction(der);
 
@@ -2059,7 +2059,7 @@
 }
 
 TEST_F(ResolverTest, UnaryOp_Complement) {
-    GlobalVar("ident", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("ident", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     auto* der =
         create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr(Source{{12, 34}}, "ident"));
     WrapInFunction(der);
@@ -2069,7 +2069,7 @@
 }
 
 TEST_F(ResolverTest, UnaryOp_Negation) {
-    GlobalVar("ident", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("ident", ty.u32(), ast::AddressSpace::kPrivate);
     auto* der =
         create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(Source{{12, 34}}, "ident"));
     WrapInFunction(der);
@@ -2214,15 +2214,15 @@
 
 TEST_F(ResolverTest, ModuleDependencyOrderedDeclarations) {
     auto* f0 = Func("f0", utils::Empty, ty.void_(), utils::Empty);
-    auto* v0 = GlobalVar("v0", ty.i32(), ast::StorageClass::kPrivate);
+    auto* v0 = GlobalVar("v0", ty.i32(), ast::AddressSpace::kPrivate);
     auto* a0 = Alias("a0", ty.i32());
     auto* s0 = Structure("s0", utils::Vector{Member("m", ty.i32())});
     auto* f1 = Func("f1", utils::Empty, ty.void_(), utils::Empty);
-    auto* v1 = GlobalVar("v1", ty.i32(), ast::StorageClass::kPrivate);
+    auto* v1 = GlobalVar("v1", ty.i32(), ast::AddressSpace::kPrivate);
     auto* a1 = Alias("a1", ty.i32());
     auto* s1 = Structure("s1", utils::Vector{Member("m", ty.i32())});
     auto* f2 = Func("f2", utils::Empty, ty.void_(), utils::Empty);
-    auto* v2 = GlobalVar("v2", ty.i32(), ast::StorageClass::kPrivate);
+    auto* v2 = GlobalVar("v2", ty.i32(), ast::AddressSpace::kPrivate);
     auto* a2 = Alias("a2", ty.i32());
     auto* s2 = Structure("s2", utils::Vector{Member("m", ty.i32())});
 
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index b22e14b..501cd0f 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -604,13 +604,13 @@
     /// @param b the ProgramBuilder
     /// @return a new AST alias type
     static inline const ast::Type* AST(ProgramBuilder& b) {
-        return b.create<ast::Pointer>(DataType<T>::AST(b), ast::StorageClass::kPrivate,
+        return b.create<ast::Pointer>(DataType<T>::AST(b), ast::AddressSpace::kPrivate,
                                       ast::Access::kReadWrite);
     }
     /// @param b the ProgramBuilder
     /// @return the semantic aliased type
     static inline const sem::Type* Sem(ProgramBuilder& b) {
-        return b.create<sem::Pointer>(DataType<T>::Sem(b), ast::StorageClass::kPrivate,
+        return b.create<sem::Pointer>(DataType<T>::Sem(b), ast::AddressSpace::kPrivate,
                                       ast::Access::kReadWrite);
     }
 
@@ -618,7 +618,7 @@
     /// @return a new AST expression of the pointer type
     static inline const ast::Expression* Expr(ProgramBuilder& b, ScalarArgs /*unused*/) {
         auto sym = b.Symbols().New("global_for_ptr");
-        b.GlobalVar(sym, DataType<T>::AST(b), ast::StorageClass::kPrivate);
+        b.GlobalVar(sym, DataType<T>::AST(b), ast::AddressSpace::kPrivate);
         return b.AddressOf(sym);
     }
 
diff --git a/src/tint/resolver/side_effects_test.cc b/src/tint/resolver/side_effects_test.cc
index 17604a9..8c3d387 100644
--- a/src/tint/resolver/side_effects_test.cc
+++ b/src/tint/resolver/side_effects_test.cc
@@ -30,7 +30,7 @@
     template <typename T>
     void MakeSideEffectFunc(const char* name) {
         auto global = Sym();
-        GlobalVar(global, ty.Of<T>(), ast::StorageClass::kPrivate);
+        GlobalVar(global, ty.Of<T>(), ast::AddressSpace::kPrivate);
         auto local = Sym();
         Func(name, utils::Empty, ty.Of<T>(),
              utils::Vector{
@@ -43,7 +43,7 @@
     template <typename MAKE_TYPE_FUNC>
     void MakeSideEffectFunc(const char* name, MAKE_TYPE_FUNC make_type) {
         auto global = Sym();
-        GlobalVar(global, make_type(), ast::StorageClass::kPrivate);
+        GlobalVar(global, make_type(), ast::AddressSpace::kPrivate);
         auto local = Sym();
         Func(name, utils::Empty, make_type(),
              utils::Vector{
@@ -88,7 +88,7 @@
 }
 
 TEST_F(SideEffectsTest, Call_Builtin_NoSE) {
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
     auto* expr = Call("dpdx", "a");
     Func("f", utils::Empty, ty.void_(), utils::Vector{Ignore(expr)},
          utils::Vector{create<ast::StageAttribute>(ast::PipelineStage::kFragment)});
@@ -114,7 +114,7 @@
 }
 
 TEST_F(SideEffectsTest, Call_Builtin_SE) {
-    GlobalVar("a", ty.atomic(ty.i32()), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.atomic(ty.i32()), ast::AddressSpace::kWorkgroup);
     auto* expr = Call("atomicAdd", AddressOf("a"), 1_i);
     WrapInFunction(expr);
 
@@ -163,20 +163,20 @@
     auto& c = GetParam();
 
     uint32_t next_binding = 0;
-    GlobalVar("f", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("i", ty.i32(), ast::StorageClass::kPrivate);
-    GlobalVar("u", ty.u32(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("vf", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("vf2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("vi2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
-    GlobalVar("vf4", ty.vec4<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("vb", ty.vec3<bool>(), ast::StorageClass::kPrivate);
-    GlobalVar("m", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("arr", ty.array<f32, 10>(), ast::StorageClass::kPrivate);
-    GlobalVar("storage_arr", ty.array<f32>(), ast::StorageClass::kStorage, Group(0_a),
+    GlobalVar("f", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("i", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("u", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("vf", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("vf2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("vi2", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("vf4", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("vb", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
+    GlobalVar("m", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("arr", ty.array<f32, 10>(), ast::AddressSpace::kPrivate);
+    GlobalVar("storage_arr", ty.array<f32>(), ast::AddressSpace::kStorage, Group(0_a),
               Binding(AInt(next_binding++)));
-    GlobalVar("a", ty.atomic(ty.i32()), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+    GlobalVar("a", ty.atomic(ty.i32()), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
               Group(0_a), Binding(AInt(next_binding++)));
     if (c.pipeline_stage != ast::PipelineStage::kCompute) {
         GlobalVar("t2d", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()), Group(0_a),
diff --git a/src/tint/resolver/source_variable_test.cc b/src/tint/resolver/source_variable_test.cc
index 85d0c31..e662395 100644
--- a/src/tint/resolver/source_variable_test.cc
+++ b/src/tint/resolver/source_variable_test.cc
@@ -26,7 +26,7 @@
 class ResolverSourceVariableTest : public ResolverTest {};
 
 TEST_F(ResolverSourceVariableTest, GlobalPrivateVar) {
-    auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
     auto* expr = Expr(a);
     WrapInFunction(expr);
 
@@ -37,7 +37,7 @@
 }
 
 TEST_F(ResolverSourceVariableTest, GlobalWorkgroupVar) {
-    auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kWorkgroup);
+    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kWorkgroup);
     auto* expr = Expr(a);
     WrapInFunction(expr);
 
@@ -48,7 +48,7 @@
 }
 
 TEST_F(ResolverSourceVariableTest, GlobalStorageVar) {
-    auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kStorage, Group(0_a), Binding(0_a));
+    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
     WrapInFunction(expr);
 
@@ -59,7 +59,7 @@
 }
 
 TEST_F(ResolverSourceVariableTest, GlobalUniformVar) {
-    auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kUniform, Group(0_a), Binding(0_a));
+    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
     WrapInFunction(expr);
 
@@ -71,7 +71,7 @@
 
 TEST_F(ResolverSourceVariableTest, GlobalTextureVar) {
     auto* a = GlobalVar("a", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
-                        ast::StorageClass::kNone, Group(0_a), Binding(0_a));
+                        ast::AddressSpace::kNone, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
     WrapInFunction(Call("textureDimensions", expr));
 
@@ -141,7 +141,7 @@
     // {
     //   let b = a;
     // }
-    auto* param = Param("a", ty.pointer(ty.f32(), ast::StorageClass::kFunction));
+    auto* param = Param("a", ty.pointer(ty.f32(), ast::AddressSpace::kFunction));
     auto* expr_param = Expr(param);
     auto* let = Let("b", expr_param);
     auto* expr_let = Expr("b");
@@ -198,7 +198,7 @@
     // {
     //   a[2i]
     // }
-    auto* a = GlobalVar("a", ty.array(ty.f32(), 4_u), ast::StorageClass::kPrivate);
+    auto* a = GlobalVar("a", ty.array(ty.f32(), 4_u), ast::AddressSpace::kPrivate);
     auto* expr = IndexAccessor(a, 2_i);
     WrapInFunction(expr);
 
@@ -215,7 +215,7 @@
     //   a.f
     // }
     auto* S = Structure("S", utils::Vector{Member("f", ty.f32())});
-    auto* a = GlobalVar("a", ty.Of(S), ast::StorageClass::kPrivate);
+    auto* a = GlobalVar("a", ty.Of(S), ast::AddressSpace::kPrivate);
     auto* expr = MemberAccessor(a, "f");
     WrapInFunction(expr);
 
@@ -231,7 +231,7 @@
     //   let a_ptr1 = &*&a;
     //   let a_ptr2 = &*a_ptr1;
     // }
-    auto* a = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
     auto* address_of_1 = AddressOf(a);
     auto* deref_1 = Deref(address_of_1);
     auto* address_of_2 = AddressOf(deref_1);
diff --git a/src/tint/resolver/static_assert_test.cc b/src/tint/resolver/static_assert_test.cc
index 3cb67c9..72c2c6f 100644
--- a/src/tint/resolver/static_assert_test.cc
+++ b/src/tint/resolver/static_assert_test.cc
@@ -86,7 +86,7 @@
 }
 
 TEST_F(ResolverStaticAssertTest, Local_NonConst) {
-    GlobalVar("V", ty.bool_(), Expr(true), ast::StorageClass::kPrivate);
+    GlobalVar("V", ty.bool_(), Expr(true), ast::AddressSpace::kPrivate);
     WrapInFunction(StaticAssert(Expr(Source{{12, 34}}, "V")));
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
diff --git a/src/tint/resolver/struct_storage_class_use_test.cc b/src/tint/resolver/struct_address_space_use_test.cc
similarity index 63%
rename from src/tint/resolver/struct_storage_class_use_test.cc
rename to src/tint/resolver/struct_address_space_use_test.cc
index 4d709e3..ff85ce4 100644
--- a/src/tint/resolver/struct_storage_class_use_test.cc
+++ b/src/tint/resolver/struct_address_space_use_test.cc
@@ -25,19 +25,19 @@
 namespace tint::resolver {
 namespace {
 
-using ResolverStorageClassUseTest = ResolverTest;
+using ResolverAddressSpaceUseTest = ResolverTest;
 
-TEST_F(ResolverStorageClassUseTest, UnreachableStruct) {
+TEST_F(ResolverAddressSpaceUseTest, UnreachableStruct) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_TRUE(sem->StorageClassUsage().empty());
+    EXPECT_TRUE(sem->AddressSpaceUsage().empty());
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableFromParameter) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableFromParameter) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
 
     Func("f", utils::Vector{Param("param", ty.Of(s))}, ty.void_(), utils::Empty, utils::Empty);
@@ -46,10 +46,10 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kNone));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kNone));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableFromReturnType) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableFromReturnType) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
 
     Func("f", utils::Empty, ty.Of(s), utils::Vector{Return(Construct(ty.Of(s)))}, utils::Empty);
@@ -58,58 +58,58 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kNone));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kNone));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableFromGlobal) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableFromGlobal) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
 
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kPrivate));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kPrivate));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalAlias) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalAlias) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* a = Alias("A", ty.Of(s));
-    GlobalVar("g", ty.Of(a), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(a), ast::AddressSpace::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kPrivate));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kPrivate));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalStruct) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalStruct) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* o = Structure("O", utils::Vector{Member("a", ty.Of(s))});
-    GlobalVar("g", ty.Of(o), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(o), ast::AddressSpace::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kPrivate));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kPrivate));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableViaGlobalArray) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableViaGlobalArray) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* a = ty.array(ty.Of(s), 3_u);
-    GlobalVar("g", a, ast::StorageClass::kPrivate);
+    GlobalVar("g", a, ast::AddressSpace::kPrivate);
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kPrivate));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kPrivate));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableFromLocal) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableFromLocal) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
 
     WrapInFunction(Var("g", ty.Of(s)));
@@ -118,10 +118,10 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kFunction));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalAlias) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalAlias) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* a = Alias("A", ty.Of(s));
     WrapInFunction(Var("g", ty.Of(a)));
@@ -130,10 +130,10 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kFunction));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalStruct) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalStruct) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* o = Structure("O", utils::Vector{Member("a", ty.Of(s))});
     WrapInFunction(Var("g", ty.Of(o)));
@@ -142,10 +142,10 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kFunction));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalArray) {
+TEST_F(ResolverAddressSpaceUseTest, StructReachableViaLocalArray) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
     auto* a = ty.array(ty.Of(s), 3_u);
     WrapInFunction(Var("g", a));
@@ -154,13 +154,13 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(), UnorderedElementsAre(ast::StorageClass::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(), UnorderedElementsAre(ast::AddressSpace::kFunction));
 }
 
-TEST_F(ResolverStorageClassUseTest, StructMultipleStorageClassUses) {
+TEST_F(ResolverAddressSpaceUseTest, StructMultipleAddressSpaceUses) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.f32())});
-    GlobalVar("x", ty.Of(s), ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
-    GlobalVar("y", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("x", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
+    GlobalVar("y", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(0_a));
     WrapInFunction(Var("g", ty.Of(s)));
 
@@ -168,9 +168,9 @@
 
     auto* sem = TypeOf(s)->As<sem::Struct>();
     ASSERT_NE(sem, nullptr);
-    EXPECT_THAT(sem->StorageClassUsage(),
-                UnorderedElementsAre(ast::StorageClass::kUniform, ast::StorageClass::kStorage,
-                                     ast::StorageClass::kFunction));
+    EXPECT_THAT(sem->AddressSpaceUsage(),
+                UnorderedElementsAre(ast::AddressSpace::kUniform, ast::AddressSpace::kStorage,
+                                     ast::AddressSpace::kFunction));
 }
 
 }  // namespace
diff --git a/src/tint/resolver/type_constructor_validation_test.cc b/src/tint/resolver/type_constructor_validation_test.cc
index de64e9a..353e517 100644
--- a/src/tint/resolver/type_constructor_validation_test.cc
+++ b/src/tint/resolver/type_constructor_validation_test.cc
@@ -69,10 +69,10 @@
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     ASSERT_TRUE(TypeOf(a_ident)->Is<sem::Reference>());
     EXPECT_TRUE(TypeOf(a_ident)->As<sem::Reference>()->StoreType()->Is<sem::I32>());
-    EXPECT_EQ(TypeOf(a_ident)->As<sem::Reference>()->StorageClass(), ast::StorageClass::kFunction);
+    EXPECT_EQ(TypeOf(a_ident)->As<sem::Reference>()->AddressSpace(), ast::AddressSpace::kFunction);
     ASSERT_TRUE(TypeOf(b_ident)->Is<sem::Reference>());
     EXPECT_TRUE(TypeOf(b_ident)->As<sem::Reference>()->StoreType()->Is<sem::I32>());
-    EXPECT_EQ(TypeOf(b_ident)->As<sem::Reference>()->StorageClass(), ast::StorageClass::kFunction);
+    EXPECT_EQ(TypeOf(b_ident)->As<sem::Reference>()->AddressSpace(), ast::AddressSpace::kFunction);
 }
 
 using InferTypeTest_FromConstructorExpression = ResolverTestWithParam<Params>;
@@ -96,7 +96,7 @@
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* got = TypeOf(a_ident);
     auto* expected = create<sem::Reference>(params.create_rhs_sem_type(*this),
-                                            ast::StorageClass::kFunction, ast::Access::kReadWrite);
+                                            ast::AddressSpace::kFunction, ast::Access::kReadWrite);
     ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                              << "expected: " << FriendlyName(expected) << "\n";
 }
@@ -150,7 +150,7 @@
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* got = TypeOf(a_ident);
     auto* expected = create<sem::Reference>(params.create_rhs_sem_type(*this),
-                                            ast::StorageClass::kFunction, ast::Access::kReadWrite);
+                                            ast::AddressSpace::kFunction, ast::Access::kReadWrite);
     ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                              << "expected: " << FriendlyName(expected) << "\n";
 }
@@ -198,7 +198,7 @@
     ASSERT_TRUE(r()->Resolve()) << r()->error();
     auto* got = TypeOf(a_ident);
     auto* expected = create<sem::Reference>(params.create_rhs_sem_type(*this),
-                                            ast::StorageClass::kFunction, ast::Access::kReadWrite);
+                                            ast::AddressSpace::kFunction, ast::Access::kReadWrite);
     ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                              << "expected: " << FriendlyName(expected) << "\n";
 }
@@ -1968,7 +1968,7 @@
 
 TEST_F(ResolverTypeConstructorValidationTest, Vector_Alias_Argument_Error) {
     auto* alias = Alias("UnsignedInt", ty.u32());
-    GlobalVar("uint_var", ty.Of(alias), ast::StorageClass::kPrivate);
+    GlobalVar("uint_var", ty.Of(alias), ast::AddressSpace::kPrivate);
 
     auto* tc = vec2<f32>(Source{{12, 34}}, "uint_var");
     WrapInFunction(tc);
@@ -1980,8 +1980,8 @@
 TEST_F(ResolverTypeConstructorValidationTest, Vector_Alias_Argument_Success) {
     auto* f32_alias = Alias("Float32", ty.f32());
     auto* vec2_alias = Alias("VectorFloat2", ty.vec2<f32>());
-    GlobalVar("my_f32", ty.Of(f32_alias), ast::StorageClass::kPrivate);
-    GlobalVar("my_vec2", ty.Of(vec2_alias), ast::StorageClass::kPrivate);
+    GlobalVar("my_f32", ty.Of(f32_alias), ast::AddressSpace::kPrivate);
+    GlobalVar("my_vec2", ty.Of(vec2_alias), ast::AddressSpace::kPrivate);
 
     auto* tc = vec3<f32>("my_vec2", "my_f32");
     WrapInFunction(tc);
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index 418cae0..d9e67e2 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -80,14 +80,14 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverTypeValidationTest, GlobalVariableWithStorageClass_Pass) {
+TEST_F(ResolverTypeValidationTest, GlobalVariableWithAddressSpace_Pass) {
     // var<private> global_var: f32;
-    GlobalVar(Source{{12, 34}}, "global_var", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{12, 34}}, "global_var", ty.f32(), ast::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
-TEST_F(ResolverTypeValidationTest, GlobalConstNoStorageClass_Pass) {
+TEST_F(ResolverTypeValidationTest, GlobalConstNoAddressSpace_Pass) {
     // const global_const: f32 = f32();
     GlobalConst(Source{{12, 34}}, "global_const", ty.f32(), Construct(ty.f32()));
 
@@ -98,9 +98,9 @@
     // var global_var0 : f32 = 0.1;
     // var global_var1 : i32 = 0;
 
-    GlobalVar("global_var0", ty.f32(), ast::StorageClass::kPrivate, Expr(0.1_f));
+    GlobalVar("global_var0", ty.f32(), ast::AddressSpace::kPrivate, Expr(0.1_f));
 
-    GlobalVar(Source{{12, 34}}, "global_var1", ty.f32(), ast::StorageClass::kPrivate, Expr(1_f));
+    GlobalVar(Source{{12, 34}}, "global_var1", ty.f32(), ast::AddressSpace::kPrivate, Expr(1_f));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -116,7 +116,7 @@
              Decl(Var("a", ty.f32(), Expr(2_f))),
          });
 
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate, Expr(2.1_f));
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -180,19 +180,19 @@
 
 TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Pass) {
     // var<private> a : array<f32, 4>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_a)), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_a)), ast::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Pass) {
     // var<private> a : array<f32, 4u>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_u)), ast::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Pass) {
     // var<private> a : array<f32, 4i>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_i)), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 4_i)), ast::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
@@ -200,7 +200,7 @@
     // const size = 4u;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(4_u));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
@@ -208,34 +208,34 @@
     // const size = 4i;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(4_i));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_AIntLiteral_Zero) {
     // var<private> a : array<f32, 0>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_a)), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_UnsignedLiteral_Zero) {
     // var<private> a : array<f32, 0u>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_u)), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Zero) {
     // var<private> a : array<f32, 0i>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_i)), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0_i)), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_SignedLiteral_Negative) {
     // var<private> a : array<f32, -10i>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10_i)), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, -10_i)), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size (-10) must be greater than 0");
 }
@@ -244,7 +244,7 @@
     // const size = 0u;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(0_u));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
@@ -253,7 +253,7 @@
     // const size = 0i;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(0_i));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size (0) must be greater than 0");
 }
@@ -262,14 +262,14 @@
     // const size = -10i;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(-10_i));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: array size (-10) must be greater than 0");
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_FloatLiteral) {
     // var<private> a : array<f32, 10.0>;
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 10_f)), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 10_f)), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size must evaluate to a constant integer expression, but is type "
@@ -279,7 +279,7 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_IVecLiteral) {
     // var<private> a : array<f32, vec2<i32>(10, 10)>;
     GlobalVar("a", ty.array(ty.f32(), Construct(Source{{12, 34}}, ty.vec2<i32>(), 10_i, 10_i)),
-              ast::StorageClass::kPrivate);
+              ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size must evaluate to a constant integer expression, but is type "
@@ -290,7 +290,7 @@
     // const size = 10.0;
     // var<private> a : array<f32, size>;
     GlobalConst("size", Expr(10_f));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size must evaluate to a constant integer expression, but is type "
@@ -301,7 +301,7 @@
     // const size = vec2<i32>(100, 100);
     // var<private> a : array<f32, size>;
     GlobalConst("size", Construct(ty.vec2<i32>(), 100_i, 100_i));
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size must evaluate to a constant integer expression, but is type "
@@ -311,7 +311,7 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ImplicitStride) {
     // var<private> a : array<f32, 0x40000000u>;
     GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0x40000000_u)),
-              ast::StorageClass::kPrivate);
+              ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size (0x100000000) must not exceed 0xffffffff bytes");
@@ -320,7 +320,7 @@
 TEST_F(ResolverTypeValidationTest, ArraySize_TooBig_ExplicitStride) {
     // var<private> a : @stride(8) array<f32, 0x20000000u>;
     GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, 0x20000000_u), 8),
-              ast::StorageClass::kPrivate);
+              ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size (0x100000000) must not exceed 0xffffffff bytes");
@@ -330,7 +330,7 @@
     // override size = 10i;
     // var<private> a : array<f32, size>;
     Override("size", Expr(10_i));
-    GlobalVar("a", ty.array(Source{{12, 34}}, ty.f32(), "size"), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.array(Source{{12, 34}}, ty.f32(), "size"), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array with an 'override' element count can only be used as the store "
@@ -342,7 +342,7 @@
     // var<workgroup> a : array<f32, size + 1>;
     Override("size", Expr(10_i));
     GlobalVar("a", ty.array(ty.f32(), Add(Source{{12, 34}}, "size", 1_i)),
-              ast::StorageClass::kWorkgroup);
+              ast::AddressSpace::kWorkgroup);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array size must evaluate to a constant integer expression or override "
@@ -354,7 +354,7 @@
     // var<workgroup> a : array<array<f32, size>, 4>;
     Override("size", Expr(10_i));
     GlobalVar("a", ty.array(ty.array(Source{{12, 34}}, ty.f32(), "size"), 4_a),
-              ast::StorageClass::kWorkgroup);
+              ast::AddressSpace::kWorkgroup);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: array with an 'override' element count can only be used as the store "
@@ -413,7 +413,7 @@
     //   var a = w;
     // }
     Override("size", Expr(10_i));
-    GlobalVar("w", ty.array(ty.f32(), "size"), ast::StorageClass::kWorkgroup);
+    GlobalVar("w", ty.array(ty.f32(), "size"), ast::AddressSpace::kWorkgroup);
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Var("a", Expr(Source{{12, 34}}, "w"))),
@@ -431,7 +431,7 @@
     //   let a = w;
     // }
     Override("size", Expr(10_i));
-    GlobalVar("w", ty.array(ty.f32(), "size"), ast::StorageClass::kWorkgroup);
+    GlobalVar("w", ty.array(ty.f32(), "size"), ast::AddressSpace::kWorkgroup);
     Func("f", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("a", Expr(Source{{12, 34}}, "w"))),
@@ -468,15 +468,15 @@
     // var<workgroup> a : array<f32, size>;
     Override("size", Expr(10_i));
     GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")),
-              ast::StorageClass::kWorkgroup);
+              ast::AddressSpace::kWorkgroup);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, ArraySize_ModuleVar) {
     // var<private> size : i32 = 10i;
     // var<private> a : array<f32, size>;
-    GlobalVar("size", ty.i32(), Expr(10_i), ast::StorageClass::kPrivate);
-    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::StorageClass::kPrivate);
+    GlobalVar("size", ty.i32(), Expr(10_i), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.array(ty.f32(), Expr(Source{{12, 34}}, "size")), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               R"(12:34 error: var 'size' cannot be referenced at module-scope
@@ -531,7 +531,7 @@
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
 12:34 note: while instantiating 'var' a)");
 }
 
@@ -631,7 +631,7 @@
 
     Structure("Foo", utils::Vector{Member("rt", ty.array<f32>())});
     GlobalVar("v", ty.array(ty.type_name(Source{{12, 34}}, "Foo"), 4_u),
-              ast::StorageClass::kPrivate);
+              ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
@@ -676,12 +676,12 @@
 }
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayAsGlobalVariable) {
-    GlobalVar(Source{{56, 78}}, "g", ty.array<i32>(), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{56, 78}}, "g", ty.array<i32>(), ast::AddressSpace::kPrivate);
 
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              R"(56:78 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(56:78 error: runtime-sized arrays can only be used in the <storage> address space
 56:78 note: while instantiating 'var' g)");
 }
 
@@ -692,7 +692,7 @@
     ASSERT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              R"(56:78 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(56:78 error: runtime-sized arrays can only be used in the <storage> address space
 56:78 note: while instantiating 'var' g)");
 }
 
@@ -717,7 +717,7 @@
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
 12:34 note: while instantiating parameter a)");
 }
 
@@ -725,7 +725,7 @@
     // fn func(a : ptr<workgroup, array<u32>>) {}
 
     auto* param =
-        Param(Source{{12, 34}}, "a", ty.pointer(ty.array<i32>(), ast::StorageClass::kWorkgroup));
+        Param(Source{{12, 34}}, "a", ty.pointer(ty.array<i32>(), ast::AddressSpace::kWorkgroup));
 
     Func("func", utils::Vector{param}, ty.void_(),
          utils::Vector{
@@ -734,7 +734,7 @@
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
 12:34 note: while instantiating parameter a)");
 }
 
@@ -774,7 +774,7 @@
 
 TEST_F(ResolverTypeValidationTest, ArrayOfNonStorableType) {
     auto* tex_ty = ty.sampled_texture(Source{{12, 34}}, ast::TextureDimension::k2d, ty.f32());
-    GlobalVar("arr", ty.array(tex_ty, 4_i), ast::StorageClass::kPrivate);
+    GlobalVar("arr", ty.array(tex_ty, 4_i), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -784,8 +784,8 @@
 TEST_F(ResolverTypeValidationTest, VariableAsType) {
     // var<private> a : i32;
     // var<private> b : a;
-    GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.type_name("a"), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.type_name("a"), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -797,7 +797,7 @@
     // fn f() {}
     // var<private> v : f;
     Func("f", utils::Empty, ty.void_(), {});
-    GlobalVar("v", ty.type_name("f"), ast::StorageClass::kPrivate);
+    GlobalVar("v", ty.type_name("f"), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
@@ -807,7 +807,7 @@
 
 TEST_F(ResolverTypeValidationTest, BuiltinAsType) {
     // var<private> v : max;
-    GlobalVar("v", ty.type_name("max"), ast::StorageClass::kPrivate);
+    GlobalVar("v", ty.type_name("max"), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "error: cannot use builtin 'max' as type");
@@ -818,14 +818,14 @@
     // var<private> v : f16;
     Enable(ast::Extension::kF16);
 
-    GlobalVar("v", ty.f16(), ast::StorageClass::kPrivate);
+    GlobalVar("v", ty.f16(), ast::AddressSpace::kPrivate);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverTypeValidationTest, F16TypeUsedWithoutExtension) {
     // var<private> v : f16;
-    GlobalVar("v", ty.f16(), ast::StorageClass::kPrivate);
+    GlobalVar("v", ty.f16(), ast::AddressSpace::kPrivate);
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "error: f16 used without 'f16' extension enabled");
@@ -1179,7 +1179,7 @@
     Enable(ast::Extension::kF16);
 
     GlobalVar("a", ty.mat(params.elem_ty(*this), params.columns, params.rows),
-              ast::StorageClass::kPrivate);
+              ast::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
@@ -1217,7 +1217,7 @@
     Enable(ast::Extension::kF16);
 
     GlobalVar("a", ty.mat(Source{{12, 34}}, params.elem_ty(*this), params.columns, params.rows),
-              ast::StorageClass::kPrivate);
+              ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), "12:34 error: matrix element type must be 'f32' or 'f16'");
 }
@@ -1258,7 +1258,7 @@
 
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec(params.elem_ty(*this), params.width), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec(params.elem_ty(*this), params.width), ast::AddressSpace::kPrivate);
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
@@ -1292,7 +1292,7 @@
     Enable(ast::Extension::kF16);
 
     GlobalVar("a", ty.vec(Source{{12, 34}}, params.elem_ty(*this), params.width),
-              ast::StorageClass::kPrivate);
+              ast::AddressSpace::kPrivate);
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
               "12:34 error: vector element type must be 'bool', 'f32', 'f16', 'i32' "
diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc
index b5e5687..f75536b 100644
--- a/src/tint/resolver/uniformity.cc
+++ b/src/tint/resolver/uniformity.cc
@@ -1468,14 +1468,14 @@
             [&](const ast::IdentifierExpression* ident) {
                 std::string var_type = "";
                 auto* var = sem_.Get<sem::VariableUser>(ident)->Variable();
-                switch (var->StorageClass()) {
-                    case ast::StorageClass::kStorage:
+                switch (var->AddressSpace()) {
+                    case ast::AddressSpace::kStorage:
                         var_type = "read_write storage buffer ";
                         break;
-                    case ast::StorageClass::kWorkgroup:
+                    case ast::AddressSpace::kWorkgroup:
                         var_type = "workgroup storage variable ";
                         break;
-                    case ast::StorageClass::kPrivate:
+                    case ast::AddressSpace::kPrivate:
                         var_type = "module-scope private variable ";
                         break;
                     default:
diff --git a/src/tint/resolver/uniformity_test.cc b/src/tint/resolver/uniformity_test.cc
index 18e6a16..52cccbe 100644
--- a/src/tint/resolver/uniformity_test.cc
+++ b/src/tint/resolver/uniformity_test.cc
@@ -5291,7 +5291,7 @@
     foo_body.Push(b.Decl(b.Let("rhs", rhs_init)));
     for (int i = 0; i < 255; i++) {
         params.Push(
-            b.Param("p" + std::to_string(i), ty.pointer(ty.i32(), ast::StorageClass::kFunction)));
+            b.Param("p" + std::to_string(i), ty.pointer(ty.i32(), ast::AddressSpace::kFunction)));
         if (i > 0) {
             foo_body.Push(b.Assign(b.Deref("p" + std::to_string(i)), "rhs"));
         }
@@ -5310,7 +5310,7 @@
     //     workgroupBarrier();
     //   }
     // }
-    b.GlobalVar("non_uniform_global", ty.i32(), ast::StorageClass::kPrivate);
+    b.GlobalVar("non_uniform_global", ty.i32(), ast::AddressSpace::kPrivate);
     utils::Vector<const ast::Statement*, 8> main_body;
     utils::Vector<const ast::Expression*, 8> args;
     for (int i = 0; i < 255; i++) {
@@ -6519,7 +6519,7 @@
     //     workgroupBarrier();
     //   }
     // }
-    b.GlobalVar("v0", ty.i32(), ast::StorageClass::kPrivate, b.Expr(0_i));
+    b.GlobalVar("v0", ty.i32(), ast::AddressSpace::kPrivate, b.Expr(0_i));
     utils::Vector<const ast::Statement*, 8> foo_body;
     std::string v_last = "v0";
     for (int i = 1; i < 100000; i++) {
diff --git a/src/tint/resolver/validation_test.cc b/src/tint/resolver/validation_test.cc
index 825fbc9..f4fa3cc 100644
--- a/src/tint/resolver/validation_test.cc
+++ b/src/tint/resolver/validation_test.cc
@@ -61,8 +61,8 @@
 };
 
 TEST_F(ResolverValidationTest, WorkgroupMemoryUsedInVertexStage) {
-    GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("dst", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
 
     Func(Source{{9, 10}}, "f0", utils::Empty, ty.vec4<f32>(),
@@ -93,8 +93,8 @@
     //  f1();
     //}
 
-    GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar(Source{{1, 2}}, "wg", ty.vec4<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("dst", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
 
     Func(Source{{5, 6}}, "f2", utils::Empty, ty.void_(), utils::Vector{stmt});
@@ -226,7 +226,7 @@
     //   return;
     // }
 
-    GlobalVar("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
+    GlobalVar("global_var", ty.f32(), ast::AddressSpace::kPrivate, Expr(2.1_f));
 
     Func("my_func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -299,8 +299,8 @@
     EXPECT_EQ(r()->error(), "12:34 error: unknown identifier: 'a'");
 }
 
-TEST_F(ResolverValidationTest, StorageClass_FunctionVariableWorkgroupClass) {
-    auto* var = Var("var", ty.i32(), ast::StorageClass::kWorkgroup);
+TEST_F(ResolverValidationTest, AddressSpace_FunctionVariableWorkgroupClass) {
+    auto* var = Var("var", ty.i32(), ast::AddressSpace::kWorkgroup);
 
     Func("func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -310,11 +310,11 @@
     EXPECT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              "error: function-scope 'var' declaration must use 'function' storage class");
+              "error: function-scope 'var' declaration must use 'function' address space");
 }
 
-TEST_F(ResolverValidationTest, StorageClass_FunctionVariableI32) {
-    auto* var = Var("s", ty.i32(), ast::StorageClass::kPrivate);
+TEST_F(ResolverValidationTest, AddressSpace_FunctionVariableI32) {
+    auto* var = Var("s", ty.i32(), ast::AddressSpace::kPrivate);
 
     Func("func", utils::Empty, ty.void_(),
          utils::Vector{
@@ -324,31 +324,31 @@
     EXPECT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              "error: function-scope 'var' declaration must use 'function' storage class");
+              "error: function-scope 'var' declaration must use 'function' address space");
 }
 
-TEST_F(ResolverValidationTest, StorageClass_SamplerExplicitStorageClass) {
+TEST_F(ResolverValidationTest, AddressSpace_SamplerExplicitAddressSpace) {
     auto* t = ty.sampler(ast::SamplerKind::kSampler);
-    GlobalVar(Source{{12, 34}}, "var", t, ast::StorageClass::kHandle, Binding(0_a), Group(0_a));
+    GlobalVar(Source{{12, 34}}, "var", t, ast::AddressSpace::kHandle, Binding(0_a), Group(0_a));
 
     EXPECT_FALSE(r()->Resolve());
 
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: variables of type 'sampler' must not have a storage class)");
+              R"(12:34 error: variables of type 'sampler' must not have a address space)");
 }
 
-TEST_F(ResolverValidationTest, StorageClass_TextureExplicitStorageClass) {
+TEST_F(ResolverValidationTest, AddressSpace_TextureExplicitAddressSpace) {
     auto* t = ty.sampled_texture(ast::TextureDimension::k1d, ty.f32());
-    GlobalVar(Source{{12, 34}}, "var", t, ast::StorageClass::kHandle, Binding(0_a), Group(0_a));
+    GlobalVar(Source{{12, 34}}, "var", t, ast::AddressSpace::kHandle, Binding(0_a), Group(0_a));
 
     EXPECT_FALSE(r()->Resolve()) << r()->error();
 
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: variables of type 'texture_1d<f32>' must not have a storage class)");
+              R"(12:34 error: variables of type 'texture_1d<f32>' must not have a address space)");
 }
 
 TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadChar) {
-    GlobalVar("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* ident = Expr(Source{{{3, 3}, {3, 7}}}, "xyqz");
 
@@ -360,7 +360,7 @@
 }
 
 TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_MixedChars) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
 
     auto* ident = Expr(Source{{{3, 3}, {3, 7}}}, "rgyw");
 
@@ -373,7 +373,7 @@
 }
 
 TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadLength) {
-    GlobalVar("my_vec", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* ident = Expr(Source{{{3, 3}, {3, 8}}}, "zzzzz");
     auto* mem = MemberAccessor("my_vec", ident);
@@ -384,7 +384,7 @@
 }
 
 TEST_F(ResolverValidationTest, Expr_MemberAccessor_VectorSwizzle_BadIndex) {
-    GlobalVar("my_vec", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
 
     auto* ident = Expr(Source{{3, 3}}, "z");
     auto* mem = MemberAccessor("my_vec", ident);
@@ -417,7 +417,7 @@
     //     let x: f32 = (*p).z;
     //     return x;
     // }
-    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction));
+    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction));
     auto* star_p = Deref(p);
     auto* z = Expr(Source{{{3, 3}, {3, 8}}}, "z");
     auto* accessor_expr = MemberAccessor(star_p, z);
@@ -435,7 +435,7 @@
     //     let x: f32 = *p.z;
     //     return x;
     // }
-    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction));
+    auto* p = Param("p", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction));
     auto* z = Expr(Source{{{3, 3}, {3, 8}}}, "z");
     auto* accessor_expr = MemberAccessor(p, z);
     auto* star_p = Deref(accessor_expr);
@@ -1312,8 +1312,8 @@
 TEST_F(ResolverTest, Expr_Constructor_Cast_Pointer) {
     auto* vf = Var("vf", ty.f32());
     auto* c =
-        Construct(Source{{12, 34}}, ty.pointer<i32>(ast::StorageClass::kFunction), ExprList(vf));
-    auto* ip = Let("ip", ty.pointer<i32>(ast::StorageClass::kFunction), c);
+        Construct(Source{{12, 34}}, ty.pointer<i32>(ast::AddressSpace::kFunction), ExprList(vf));
+    auto* ip = Let("ip", ty.pointer<i32>(ast::AddressSpace::kFunction), c);
     WrapInFunction(Decl(vf), Decl(ip));
 
     EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index c1f52fb..36ac610 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -322,7 +322,7 @@
 }
 
 bool Validator::VariableInitializer(const ast::Variable* v,
-                                    ast::StorageClass storage_class,
+                                    ast::AddressSpace address_space,
                                     const sem::Type* storage_ty,
                                     const sem::Expression* initializer) const {
     auto* initializer_ty = initializer->Type();
@@ -338,17 +338,17 @@
     }
 
     if (v->Is<ast::Var>()) {
-        switch (storage_class) {
-            case ast::StorageClass::kPrivate:
-            case ast::StorageClass::kFunction:
+        switch (address_space) {
+            case ast::AddressSpace::kPrivate:
+            case ast::AddressSpace::kFunction:
                 break;  // Allowed an initializer
             default:
                 // https://gpuweb.github.io/gpuweb/wgsl/#var-and-let
                 // Optionally has an initializer expression, if the variable is in the
-                // private or function storage classes.
-                AddError("var of storage class '" + utils::ToString(storage_class) +
+                // private or function address spacees.
+                AddError("var of address space '" + utils::ToString(address_space) +
                              "' cannot have an initializer. var initializers are only "
-                             "supported for the storage classes "
+                             "supported for the address spacees "
                              "'private' and 'function'",
                          v->source);
                 return false;
@@ -358,18 +358,19 @@
     return true;
 }
 
-bool Validator::StorageClassLayout(const sem::Type* store_ty,
-                                   ast::StorageClass sc,
+bool Validator::AddressSpaceLayout(const sem::Type* store_ty,
+                                   ast::AddressSpace address_space,
                                    Source source,
                                    ValidTypeStorageLayouts& layouts) const {
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class-layout-constraints
 
-    auto is_uniform_struct_or_array = [sc](const sem::Type* ty) {
-        return sc == ast::StorageClass::kUniform && ty->IsAnyOf<sem::Array, sem::Struct>();
+    auto is_uniform_struct_or_array = [address_space](const sem::Type* ty) {
+        return address_space == ast::AddressSpace::kUniform &&
+               ty->IsAnyOf<sem::Array, sem::Struct>();
     };
 
-    auto is_uniform_struct = [sc](const sem::Type* ty) {
-        return sc == ast::StorageClass::kUniform && ty->Is<sem::Struct>();
+    auto is_uniform_struct = [address_space](const sem::Type* ty) {
+        return address_space == ast::AddressSpace::kUniform && ty->Is<sem::Struct>();
     };
 
     auto required_alignment_of = [&](const sem::Type* ty) {
@@ -385,22 +386,22 @@
         return symbols_.NameFor(sm->Declaration()->symbol);
     };
 
-    // Cache result of type + storage class pair.
-    if (!layouts.emplace(store_ty, sc).second) {
+    // Cache result of type + address space pair.
+    if (!layouts.emplace(store_ty, address_space).second) {
         return true;
     }
 
-    if (!ast::IsHostShareable(sc)) {
+    if (!ast::IsHostShareable(address_space)) {
         return true;
     }
 
-    // Temporally forbid using f16 types in "uniform" and "storage" storage class.
+    // Temporally forbid using f16 types in "uniform" and "storage" address space.
     // TODO(tint:1473, tint:1502): Remove this error after f16 is supported in "uniform" and
-    // "storage" storage class but keep for "push_constant" storage class.
+    // "storage" address space but keep for "push_constant" address space.
     if (Is<sem::F16>(sem::Type::DeepestElementOf(store_ty))) {
-        AddError(
-            "using f16 types in '" + utils::ToString(sc) + "' storage class is not implemented yet",
-            source);
+        AddError("using f16 types in '" + utils::ToString(address_space) +
+                     "' address space is not implemented yet",
+                 source);
         return false;
     }
 
@@ -410,7 +411,8 @@
             uint32_t required_align = required_alignment_of(m->Type());
 
             // Recurse into the member type.
-            if (!StorageClassLayout(m->Type(), sc, m->Declaration()->type->source, layouts)) {
+            if (!AddressSpaceLayout(m->Type(), address_space, m->Declaration()->type->source,
+                                    layouts)) {
                 AddNote("see layout of struct:\n" + str->Layout(symbols_),
                         str->Declaration()->source);
                 return false;
@@ -420,7 +422,7 @@
             if (m->Offset() % required_align != 0) {
                 AddError("the offset of a struct member of type '" +
                              m->Type()->UnwrapRef()->FriendlyName(symbols_) +
-                             "' in storage class '" + utils::ToString(sc) +
+                             "' in address space '" + utils::ToString(address_space) +
                              "' must be a multiple of " + std::to_string(required_align) +
                              " bytes, but '" + member_name_of(m) + "' is currently at offset " +
                              std::to_string(m->Offset()) + ". Consider setting @align(" +
@@ -474,11 +476,11 @@
         // TODO(crbug.com/tint/1388): Ideally we'd pass the source for nested
         // element type here, but we can't easily get that from the semantic node.
         // We should consider recursing through the AST type nodes instead.
-        if (!StorageClassLayout(arr->ElemType(), sc, source, layouts)) {
+        if (!AddressSpaceLayout(arr->ElemType(), address_space, source, layouts)) {
             return false;
         }
 
-        if (sc == ast::StorageClass::kUniform) {
+        if (address_space == ast::AddressSpace::kUniform) {
             // We already validated that this array member is itself aligned to 16
             // bytes above, so we only need to validate that stride is a multiple
             // of 16 bytes.
@@ -516,22 +518,22 @@
     return true;
 }
 
-bool Validator::StorageClassLayout(const sem::Variable* var,
+bool Validator::AddressSpaceLayout(const sem::Variable* var,
                                    const ast::Extensions& enabled_extensions,
                                    ValidTypeStorageLayouts& layouts) const {
-    if (var->StorageClass() == ast::StorageClass::kPushConstant &&
+    if (var->AddressSpace() == ast::AddressSpace::kPushConstant &&
         !enabled_extensions.Contains(ast::Extension::kChromiumExperimentalPushConstant) &&
         IsValidationEnabled(var->Declaration()->attributes,
-                            ast::DisabledValidation::kIgnoreStorageClass)) {
+                            ast::DisabledValidation::kIgnoreAddressSpace)) {
         AddError(
-            "use of variable storage class 'push_constant' requires enabling extension "
+            "use of variable address space 'push_constant' requires enabling extension "
             "'chromium_experimental_push_constant'",
             var->Declaration()->source);
         return false;
     }
 
     if (auto* str = var->Type()->UnwrapRef()->As<sem::Struct>()) {
-        if (!StorageClassLayout(str, var->StorageClass(), str->Declaration()->source, layouts)) {
+        if (!AddressSpaceLayout(str, var->AddressSpace(), str->Declaration()->source, layouts)) {
             AddNote("see declaration of variable", var->Declaration()->source);
             return false;
         }
@@ -540,7 +542,7 @@
         if (var->Declaration()->type) {
             source = var->Declaration()->type->source;
         }
-        if (!StorageClassLayout(var->Type()->UnwrapRef(), var->StorageClass(), source, layouts)) {
+        if (!AddressSpaceLayout(var->Type()->UnwrapRef(), var->AddressSpace(), source, layouts)) {
             return false;
         }
     }
@@ -559,7 +561,7 @@
         decl,  //
         [&](const ast::Var* var) {
             if (IsValidationEnabled(var->attributes,
-                                    ast::DisabledValidation::kIgnoreStorageClass)) {
+                                    ast::DisabledValidation::kIgnoreAddressSpace)) {
                 if (!local->Type()->UnwrapRef()->IsConstructible()) {
                     AddError("function-scope 'var' must have a constructible type",
                              var->type ? var->type->source : var->source);
@@ -583,7 +585,7 @@
     const std::unordered_map<OverrideId, const sem::Variable*>& override_ids,
     const std::unordered_map<const sem::Type*, const Source&>& atomic_composite_info) const {
     auto* decl = global->Declaration();
-    if (global->StorageClass() != ast::StorageClass::kWorkgroup &&
+    if (global->AddressSpace() != ast::AddressSpace::kWorkgroup &&
         IsArrayWithOverrideCount(global->Type())) {
         RaiseArrayWithOverrideCountError(decl->type ? decl->type->source
                                                     : decl->constructor->source);
@@ -599,8 +601,8 @@
                 return false;
             }
 
-            if (global->StorageClass() == ast::StorageClass::kNone) {
-                AddError("module-scope 'var' declaration must have a storage class", decl->source);
+            if (global->AddressSpace() == ast::AddressSpace::kNone) {
+                AddError("module-scope 'var' declaration must have a address space", decl->source);
                 return false;
             }
 
@@ -608,11 +610,11 @@
                 bool is_shader_io_attribute =
                     attr->IsAnyOf<ast::BuiltinAttribute, ast::InterpolateAttribute,
                                   ast::InvariantAttribute, ast::LocationAttribute>();
-                bool has_io_storage_class = global->StorageClass() == ast::StorageClass::kIn ||
-                                            global->StorageClass() == ast::StorageClass::kOut;
+                bool has_io_address_space = global->AddressSpace() == ast::AddressSpace::kIn ||
+                                            global->AddressSpace() == ast::AddressSpace::kOut;
                 if (!attr->IsAnyOf<ast::BindingAttribute, ast::GroupAttribute,
                                    ast::InternalAttribute>() &&
-                    (!is_shader_io_attribute || !has_io_storage_class)) {
+                    (!is_shader_io_attribute || !has_io_address_space)) {
                     AddError("attribute '" + attr->Name() + "' is not valid for module-scope 'var'",
                              attr->source);
                     return false;
@@ -621,9 +623,9 @@
 
             // https://gpuweb.github.io/gpuweb/wgsl/#variable-declaration
             // The access mode always has a default, and except for variables in the
-            // storage storage class, must not be written.
+            // storage address space, must not be written.
             if (var->declared_access != ast::Access::kUndefined) {
-                if (global->StorageClass() == ast::StorageClass::kStorage) {
+                if (global->AddressSpace() == ast::AddressSpace::kStorage) {
                     // The access mode for the storage address space can only be 'read' or
                     // 'read_write'.
                     if (var->declared_access == ast::Access::kWrite) {
@@ -632,7 +634,7 @@
                         return false;
                     }
                 } else {
-                    AddError("only variables in <storage> storage class may declare an access mode",
+                    AddError("only variables in <storage> address space may declare an access mode",
                              decl->source);
                     return false;
                 }
@@ -672,15 +674,15 @@
         return false;
     }
 
-    if (global->StorageClass() == ast::StorageClass::kFunction) {
-        AddError("module-scope 'var' must not use storage class 'function'", decl->source);
+    if (global->AddressSpace() == ast::AddressSpace::kFunction) {
+        AddError("module-scope 'var' must not use address space 'function'", decl->source);
         return false;
     }
 
-    switch (global->StorageClass()) {
-        case ast::StorageClass::kUniform:
-        case ast::StorageClass::kStorage:
-        case ast::StorageClass::kHandle: {
+    switch (global->AddressSpace()) {
+        case ast::AddressSpace::kUniform:
+        case ast::AddressSpace::kStorage:
+        case ast::AddressSpace::kHandle: {
             // https://gpuweb.github.io/gpuweb/wgsl/#resource-interface
             // Each resource variable must be declared with both group and binding
             // attributes.
@@ -712,29 +714,32 @@
 bool Validator::AtomicVariable(
     const sem::Variable* var,
     std::unordered_map<const sem::Type*, const Source&> atomic_composite_info) const {
-    auto sc = var->StorageClass();
+    auto address_space = var->AddressSpace();
     auto* decl = var->Declaration();
     auto access = var->Access();
     auto* type = var->Type()->UnwrapRef();
     auto source = decl->type ? decl->type->source : decl->source;
 
     if (type->Is<sem::Atomic>()) {
-        if (sc != ast::StorageClass::kWorkgroup && sc != ast::StorageClass::kStorage) {
-            AddError("atomic variables must have <storage> or <workgroup> storage class", source);
+        if (address_space != ast::AddressSpace::kWorkgroup &&
+            address_space != ast::AddressSpace::kStorage) {
+            AddError("atomic variables must have <storage> or <workgroup> address space", source);
             return false;
         }
     } else if (type->IsAnyOf<sem::Struct, sem::Array>()) {
         auto found = atomic_composite_info.find(type);
         if (found != atomic_composite_info.end()) {
-            if (sc != ast::StorageClass::kStorage && sc != ast::StorageClass::kWorkgroup) {
-                AddError("atomic variables must have <storage> or <workgroup> storage class",
+            if (address_space != ast::AddressSpace::kStorage &&
+                address_space != ast::AddressSpace::kWorkgroup) {
+                AddError("atomic variables must have <storage> or <workgroup> address space",
                          source);
                 AddNote("atomic sub-type of '" + sem_.TypeNameOf(type) + "' is declared here",
                         found->second);
                 return false;
-            } else if (sc == ast::StorageClass::kStorage && access != ast::Access::kReadWrite) {
+            } else if (address_space == ast::AddressSpace::kStorage &&
+                       access != ast::Access::kReadWrite) {
                 AddError(
-                    "atomic variables in <storage> storage class must have read_write "
+                    "atomic variables in <storage> address space must have read_write "
                     "access mode",
                     source);
                 AddNote("atomic sub-type of '" + sem_.TypeNameOf(type) + "' is declared here",
@@ -756,21 +761,21 @@
         return false;
     }
 
-    if (storage_ty->is_handle() && var->declared_storage_class != ast::StorageClass::kNone) {
+    if (storage_ty->is_handle() && var->declared_address_space != ast::AddressSpace::kNone) {
         // https://gpuweb.github.io/gpuweb/wgsl/#module-scope-variables
         // If the store type is a texture type or a sampler type, then the
-        // variable declaration must not have a storage class attribute. The
-        // storage class will always be handle.
+        // variable declaration must not have a address space attribute. The
+        // address space will always be handle.
         AddError(
-            "variables of type '" + sem_.TypeNameOf(storage_ty) + "' must not have a storage class",
+            "variables of type '" + sem_.TypeNameOf(storage_ty) + "' must not have a address space",
             var->source);
         return false;
     }
 
-    if (IsValidationEnabled(var->attributes, ast::DisabledValidation::kIgnoreStorageClass) &&
-        (var->declared_storage_class == ast::StorageClass::kIn ||
-         var->declared_storage_class == ast::StorageClass::kOut)) {
-        AddError("invalid use of input/output storage class", var->source);
+    if (IsValidationEnabled(var->attributes, ast::DisabledValidation::kIgnoreAddressSpace) &&
+        (var->declared_address_space == ast::AddressSpace::kIn ||
+         var->declared_address_space == ast::AddressSpace::kOut)) {
+        AddError("invalid use of input/output address space", var->source);
         return false;
     }
     return true;
@@ -873,12 +878,14 @@
     }
 
     if (auto* ref = var->Type()->As<sem::Pointer>()) {
-        auto sc = ref->StorageClass();
-        if (!(sc == ast::StorageClass::kFunction || sc == ast::StorageClass::kPrivate ||
-              sc == ast::StorageClass::kWorkgroup) &&
-            IsValidationEnabled(decl->attributes, ast::DisabledValidation::kIgnoreStorageClass)) {
+        auto address_space = ref->AddressSpace();
+        if (!(address_space == ast::AddressSpace::kFunction ||
+              address_space == ast::AddressSpace::kPrivate ||
+              address_space == ast::AddressSpace::kWorkgroup) &&
+            IsValidationEnabled(decl->attributes, ast::DisabledValidation::kIgnoreAddressSpace)) {
             std::stringstream ss;
-            ss << "function parameter of pointer type cannot be in '" << sc << "' storage class";
+            ss << "function parameter of pointer type cannot be in '" << address_space
+               << "' address space";
             AddError(ss.str(), decl->source);
             return false;
         }
@@ -1954,7 +1961,7 @@
         auto stage = entry_point->Declaration()->PipelineStage();
         if (stage != ast::PipelineStage::kCompute) {
             for (auto* var : func->DirectlyReferencedGlobals()) {
-                if (var->StorageClass() == ast::StorageClass::kWorkgroup) {
+                if (var->AddressSpace() == ast::AddressSpace::kWorkgroup) {
                     std::stringstream stage_name;
                     stage_name << stage;
                     for (auto* user : var->Users()) {
@@ -2042,7 +2049,7 @@
 
         auto check_push_constant = [&](const sem::Function* func, const sem::Function* ep) {
             for (auto* var : func->DirectlyReferencedGlobals()) {
-                if (var->StorageClass() != ast::StorageClass::kPushConstant ||
+                if (var->AddressSpace() != ast::AddressSpace::kPushConstant ||
                     var == push_constant_var) {
                     continue;
                 }
diff --git a/src/tint/resolver/validator.h b/src/tint/resolver/validator.h
index b79a850..2b84ad1 100644
--- a/src/tint/resolver/validator.h
+++ b/src/tint/resolver/validator.h
@@ -72,7 +72,7 @@
 class Validator {
   public:
     /// The valid type storage layouts typedef
-    using ValidTypeStorageLayouts = std::set<std::pair<const sem::Type*, ast::StorageClass>>;
+    using ValidTypeStorageLayouts = std::set<std::pair<const sem::Type*, ast::AddressSpace>>;
 
     /// Constructor
     /// @param builder the program builder
@@ -389,12 +389,12 @@
 
     /// Validates a variable initializer
     /// @param v the variable to validate
-    /// @param storage_class the storage class of the variable
+    /// @param address_space the address space of the variable
     /// @param storage_type the type of the storage
     /// @param initializer the RHS initializer expression
     /// @returns true on succes, false otherwise
     bool VariableInitializer(const ast::Variable* v,
-                             ast::StorageClass storage_class,
+                             ast::AddressSpace address_space,
                              const sem::Type* storage_type,
                              const sem::Expression* initializer) const;
 
@@ -427,23 +427,23 @@
     /// @returns true on success, false otherwise.
     bool NoDuplicateAttributes(utils::VectorRef<const ast::Attribute*> attributes) const;
 
-    /// Validates a storage class layout
+    /// Validates a address space layout
     /// @param type the type to validate
-    /// @param sc the storage class
+    /// @param sc the address space
     /// @param source the source of the type
     /// @param layouts previously validated storage layouts
     /// @returns true on success, false otherwise
-    bool StorageClassLayout(const sem::Type* type,
-                            ast::StorageClass sc,
+    bool AddressSpaceLayout(const sem::Type* type,
+                            ast::AddressSpace sc,
                             Source source,
                             ValidTypeStorageLayouts& layouts) const;
 
-    /// Validates a storage class layout
+    /// Validates a address space layout
     /// @param var the variable to validate
     /// @param layouts previously validated storage layouts
     /// @param enabled_extensions all the extensions declared in current module
     /// @returns true on success, false otherwise.
-    bool StorageClassLayout(const sem::Variable* var,
+    bool AddressSpaceLayout(const sem::Variable* var,
                             const ast::Extensions& enabled_extensions,
                             ValidTypeStorageLayouts& layouts) const;
 
diff --git a/src/tint/resolver/validator_is_storeable_test.cc b/src/tint/resolver/validator_is_storeable_test.cc
index 015b095..9fa064ac 100644
--- a/src/tint/resolver/validator_is_storeable_test.cc
+++ b/src/tint/resolver/validator_is_storeable_test.cc
@@ -78,7 +78,7 @@
 }
 
 TEST_F(ValidatorIsStorableTest, Pointer) {
-    auto* ptr = create<sem::Pointer>(create<sem::I32>(), ast::StorageClass::kPrivate,
+    auto* ptr = create<sem::Pointer>(create<sem::I32>(), ast::AddressSpace::kPrivate,
                                      ast::Access::kReadWrite);
     EXPECT_FALSE(v()->IsStorable(ptr));
 }
diff --git a/src/tint/resolver/variable_test.cc b/src/tint/resolver/variable_test.cc
index 8842141..ebc6584 100644
--- a/src/tint/resolver/variable_test.cc
+++ b/src/tint/resolver/variable_test.cc
@@ -238,7 +238,7 @@
     //   var a = a;
     // }
 
-    auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* g = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
     auto* v = Var("a", Expr("a"));
     Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(v)});
 
@@ -419,7 +419,7 @@
     auto* b = Let("b", ty.bool_(), b_c);
     auto* s = Let("s", ty.Of(S), s_c);
     auto* a = Let("a", ty.Of(A), a_c);
-    auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), p_c);
+    auto* p = Let("p", ty.pointer<i32>(ast::AddressSpace::kFunction), p_c);
 
     Func("F", utils::Empty, ty.void_(),
          utils::Vector{
@@ -470,7 +470,7 @@
     // }
     auto* inner = Structure("Inner", utils::Vector{Member("arr", ty.array<i32, 4>())});
     auto* buf = Structure("S", utils::Vector{Member("inner", ty.Of(inner))});
-    auto* storage = GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+    auto* storage = GlobalVar("s", ty.Of(buf), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
                               Binding(0_a), Group(0_a));
 
     auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 3_i);
@@ -552,7 +552,7 @@
     //   let a = a;
     // }
 
-    auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* g = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
     auto* l = Let("a", Expr("a"));
     Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(l)});
 
@@ -762,7 +762,7 @@
     //   const a = 1i;
     // }
 
-    auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* g = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
     auto* c = Const("a", Expr(1_i));
     Func("F", utils::Empty, ty.void_(), utils::Vector{Decl(c)});
 
@@ -1030,16 +1030,16 @@
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Module-scope 'var'
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-TEST_F(ResolverVariableTest, GlobalVar_StorageClass) {
+TEST_F(ResolverVariableTest, GlobalVar_AddressSpace) {
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
 
     auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
-    auto* private_ = GlobalVar("p", ty.i32(), ast::StorageClass::kPrivate);
-    auto* workgroup = GlobalVar("w", ty.i32(), ast::StorageClass::kWorkgroup);
+    auto* private_ = GlobalVar("p", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* workgroup = GlobalVar("w", ty.i32(), ast::AddressSpace::kWorkgroup);
     auto* uniform =
-        GlobalVar("ub", ty.Of(buf), ast::StorageClass::kUniform, Binding(0_a), Group(0_a));
+        GlobalVar("ub", ty.Of(buf), ast::AddressSpace::kUniform, Binding(0_a), Group(0_a));
     auto* storage =
-        GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage, Binding(1_a), Group(0_a));
+        GlobalVar("sb", ty.Of(buf), ast::AddressSpace::kStorage, Binding(1_a), Group(0_a));
     auto* handle =
         GlobalVar("h", ty.depth_texture(ast::TextureDimension::k2d), Binding(2_a), Group(0_a));
 
@@ -1058,11 +1058,11 @@
     EXPECT_EQ(TypeOf(handle)->As<sem::Reference>()->Access(), ast::Access::kRead);
 }
 
-TEST_F(ResolverVariableTest, GlobalVar_ExplicitStorageClass) {
+TEST_F(ResolverVariableTest, GlobalVar_ExplicitAddressSpace) {
     // https://gpuweb.github.io/gpuweb/wgsl/#storage-class
 
     auto* buf = Structure("S", utils::Vector{Member("m", ty.i32())});
-    auto* storage = GlobalVar("sb", ty.Of(buf), ast::StorageClass::kStorage,
+    auto* storage = GlobalVar("sb", ty.Of(buf), ast::AddressSpace::kStorage,
                               ast::Access::kReadWrite, Binding(1_a), Group(0_a));
 
     ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -1220,7 +1220,7 @@
     // fn F(a : bool) {
     // }
 
-    auto* g = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* g = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
     auto* p = Param("a", ty.bool_());
     Func("F", utils::Vector{p}, ty.void_(), utils::Empty);
 
diff --git a/src/tint/resolver/variable_validation_test.cc b/src/tint/resolver/variable_validation_test.cc
index ea67071..28f8dc3 100644
--- a/src/tint/resolver/variable_validation_test.cc
+++ b/src/tint/resolver/variable_validation_test.cc
@@ -61,8 +61,8 @@
 TEST_F(ResolverVariableValidationTest, GlobalVarUsedAtModuleScope) {
     // var<private> a : i32;
     // var<private> b : i32 = a;
-    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.i32(), ast::StorageClass::kPrivate, Expr(Source{{56, 78}}, "a"));
+    GlobalVar(Source{{12, 34}}, "a", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.i32(), ast::AddressSpace::kPrivate, Expr(Source{{56, 78}}, "a"));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(), R"(56:78 error: var 'a' cannot be referenced at module-scope
@@ -112,8 +112,8 @@
     // var i : i32;
     // var p : pointer<function, i32> = &v;
     auto* i = Var("i", ty.i32());
-    auto* p = Var("a", ty.pointer<i32>(Source{{56, 78}}, ast::StorageClass::kFunction),
-                  ast::StorageClass::kNone, AddressOf(Source{{12, 34}}, "i"));
+    auto* p = Var("a", ty.pointer<i32>(Source{{56, 78}}, ast::AddressSpace::kFunction),
+                  ast::AddressSpace::kNone, AddressOf(Source{{12, 34}}, "i"));
     WrapInFunction(i, p);
 
     EXPECT_FALSE(r()->Resolve());
@@ -205,7 +205,7 @@
 TEST_F(ResolverVariableValidationTest, LetOfPtrConstructedWithRef) {
     // var a : f32;
     // let b : ptr<function,f32> = a;
-    const auto priv = ast::StorageClass::kFunction;
+    const auto priv = ast::AddressSpace::kFunction;
     auto* var_a = Var("a", ty.f32(), priv);
     auto* var_b = Let(Source{{12, 34}}, "b", ty.pointer<f32>(priv), Expr("a"));
     WrapInFunction(var_a, var_b);
@@ -236,7 +236,7 @@
     //   return 0;
     // }
 
-    GlobalVar("v", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
+    GlobalVar("v", ty.f32(), ast::AddressSpace::kPrivate, Expr(2.1_f));
 
     WrapInFunction(Var(Source{{12, 34}}, "v", ty.f32(), Expr(2_f)));
 
@@ -295,12 +295,12 @@
                                    Member("inner", ty.Of(inner)),
                                });
     auto* storage =
-        GlobalVar("s", ty.Of(buf), ast::StorageClass::kStorage, Binding(0_a), Group(0_a));
+        GlobalVar("s", ty.Of(buf), ast::AddressSpace::kStorage, Binding(0_a), Group(0_a));
 
     auto* expr = IndexAccessor(MemberAccessor(MemberAccessor(storage, "inner"), "arr"), 2_i);
     auto* ptr =
         Let(Source{{12, 34}}, "p",
-            ty.pointer<i32>(ast::StorageClass::kStorage, ast::Access::kReadWrite), AddressOf(expr));
+            ty.pointer<i32>(ast::AddressSpace::kStorage, ast::Access::kReadWrite), AddressOf(expr));
 
     WrapInFunction(ptr);
 
@@ -328,7 +328,7 @@
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              R"(12:34 error: runtime-sized arrays can only be used in the <storage> storage class
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
 56:78 note: while analysing structure member S.m
 12:34 note: while instantiating 'var' v)");
 }
@@ -357,15 +357,15 @@
     EXPECT_EQ(r()->error(), "12:34 error: function-scope 'var' must have a constructible type");
 }
 
-TEST_F(ResolverVariableValidationTest, InvalidStorageClassForInitializer) {
+TEST_F(ResolverVariableValidationTest, InvalidAddressSpaceForInitializer) {
     // var<workgroup> v : f32 = 1.23;
-    GlobalVar(Source{{12, 34}}, "v", ty.f32(), ast::StorageClass::kWorkgroup, Expr(1.23_f));
+    GlobalVar(Source{{12, 34}}, "v", ty.f32(), ast::AddressSpace::kWorkgroup, Expr(1.23_f));
 
     EXPECT_FALSE(r()->Resolve());
     EXPECT_EQ(r()->error(),
-              "12:34 error: var of storage class 'workgroup' cannot have "
+              "12:34 error: var of address space 'workgroup' cannot have "
               "an initializer. var initializers are only supported for the "
-              "storage classes 'private' and 'function'");
+              "address spacees 'private' and 'function'");
 }
 
 TEST_F(ResolverVariableValidationTest, VectorConstNoType) {
diff --git a/src/tint/sem/function.cc b/src/tint/sem/function.cc
index fc7809b..af2ee12 100644
--- a/src/tint/sem/function.cc
+++ b/src/tint/sem/function.cc
@@ -68,7 +68,7 @@
     VariableBindings ret;
 
     for (auto* global : TransitivelyReferencedGlobals()) {
-        if (global->StorageClass() != ast::StorageClass::kUniform) {
+        if (global->AddressSpace() != ast::AddressSpace::kUniform) {
             continue;
         }
 
@@ -83,7 +83,7 @@
     VariableBindings ret;
 
     for (auto* global : TransitivelyReferencedGlobals()) {
-        if (global->StorageClass() != ast::StorageClass::kStorage) {
+        if (global->AddressSpace() != ast::AddressSpace::kStorage) {
             continue;
         }
 
diff --git a/src/tint/sem/pointer.cc b/src/tint/sem/pointer.cc
index e00a4bf..3918233 100644
--- a/src/tint/sem/pointer.cc
+++ b/src/tint/sem/pointer.cc
@@ -22,19 +22,19 @@
 
 namespace tint::sem {
 
-Pointer::Pointer(const Type* subtype, ast::StorageClass storage_class, ast::Access access)
-    : subtype_(subtype), storage_class_(storage_class), access_(access) {
+Pointer::Pointer(const Type* subtype, ast::AddressSpace address_space, ast::Access access)
+    : subtype_(subtype), address_space_(address_space), access_(access) {
     TINT_ASSERT(Semantic, !subtype->Is<Reference>());
     TINT_ASSERT(Semantic, access != ast::Access::kUndefined);
 }
 
 size_t Pointer::Hash() const {
-    return utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, storage_class_, subtype_, access_);
+    return utils::Hash(TypeInfo::Of<Pointer>().full_hashcode, address_space_, subtype_, access_);
 }
 
 bool Pointer::Equals(const sem::Type& other) const {
     if (auto* o = other.As<Pointer>()) {
-        return o->storage_class_ == storage_class_ && o->subtype_ == subtype_ &&
+        return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
                o->access_ == access_;
     }
     return false;
@@ -43,8 +43,8 @@
 std::string Pointer::FriendlyName(const SymbolTable& symbols) const {
     std::ostringstream out;
     out << "ptr<";
-    if (storage_class_ != ast::StorageClass::kNone) {
-        out << storage_class_ << ", ";
+    if (address_space_ != ast::AddressSpace::kNone) {
+        out << address_space_ << ", ";
     }
     out << subtype_->FriendlyName(symbols) << ", " << access_;
     out << ">";
diff --git a/src/tint/sem/pointer.h b/src/tint/sem/pointer.h
index 0c82e77..806dcaa 100644
--- a/src/tint/sem/pointer.h
+++ b/src/tint/sem/pointer.h
@@ -18,7 +18,7 @@
 #include <string>
 
 #include "src/tint/ast/access.h"
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/sem/type.h"
 
 namespace tint::sem {
@@ -28,9 +28,9 @@
   public:
     /// Constructor
     /// @param subtype the pointee type
-    /// @param storage_class the storage class of the pointer
+    /// @param address_space the address space of the pointer
     /// @param access the resolved access control of the reference
-    Pointer(const Type* subtype, ast::StorageClass storage_class, ast::Access access);
+    Pointer(const Type* subtype, ast::AddressSpace address_space, ast::Access access);
 
     /// Move constructor
     Pointer(Pointer&&);
@@ -46,8 +46,8 @@
     /// @returns the pointee type
     const Type* StoreType() const { return subtype_; }
 
-    /// @returns the storage class of the pointer
-    ast::StorageClass StorageClass() const { return storage_class_; }
+    /// @returns the address space of the pointer
+    ast::AddressSpace AddressSpace() const { return address_space_; }
 
     /// @returns the access control of the reference
     ast::Access Access() const { return access_; }
@@ -59,7 +59,7 @@
 
   private:
     Type const* const subtype_;
-    ast::StorageClass const storage_class_;
+    ast::AddressSpace const address_space_;
     ast::Access const access_;
 };
 
diff --git a/src/tint/sem/pointer_test.cc b/src/tint/sem/pointer_test.cc
index 575db41..4f7533e 100644
--- a/src/tint/sem/pointer_test.cc
+++ b/src/tint/sem/pointer_test.cc
@@ -21,14 +21,14 @@
 using PointerTest = TestHelper;
 
 TEST_F(PointerTest, Creation) {
-    auto* a = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* b = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* c = create<Pointer>(create<F32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* d = create<Pointer>(create<I32>(), ast::StorageClass::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kRead);
+    auto* a = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* b = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* c = create<Pointer>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* d = create<Pointer>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
+    auto* e = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
 
     EXPECT_TRUE(a->StoreType()->Is<sem::I32>());
-    EXPECT_EQ(a->StorageClass(), ast::StorageClass::kStorage);
+    EXPECT_EQ(a->AddressSpace(), ast::AddressSpace::kStorage);
     EXPECT_EQ(a->Access(), ast::Access::kReadWrite);
 
     EXPECT_EQ(a, b);
@@ -38,11 +38,11 @@
 }
 
 TEST_F(PointerTest, Hash) {
-    auto* a = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* b = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* c = create<Pointer>(create<F32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* d = create<Pointer>(create<I32>(), ast::StorageClass::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kRead);
+    auto* a = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* b = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* c = create<Pointer>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* d = create<Pointer>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
+    auto* e = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
 
     EXPECT_EQ(a->Hash(), b->Hash());
     EXPECT_NE(a->Hash(), c->Hash());
@@ -51,11 +51,11 @@
 }
 
 TEST_F(PointerTest, Equals) {
-    auto* a = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* b = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* c = create<Pointer>(create<F32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
-    auto* d = create<Pointer>(create<I32>(), ast::StorageClass::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Pointer>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kRead);
+    auto* a = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* b = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* c = create<Pointer>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
+    auto* d = create<Pointer>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
+    auto* e = create<Pointer>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
 
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
@@ -65,12 +65,12 @@
 }
 
 TEST_F(PointerTest, FriendlyName) {
-    auto* r = create<Pointer>(create<I32>(), ast::StorageClass::kNone, ast::Access::kRead);
+    auto* r = create<Pointer>(create<I32>(), ast::AddressSpace::kNone, ast::Access::kRead);
     EXPECT_EQ(r->FriendlyName(Symbols()), "ptr<i32, read>");
 }
 
-TEST_F(PointerTest, FriendlyNameWithStorageClass) {
-    auto* r = create<Pointer>(create<I32>(), ast::StorageClass::kWorkgroup, ast::Access::kRead);
+TEST_F(PointerTest, FriendlyNameWithAddressSpace) {
+    auto* r = create<Pointer>(create<I32>(), ast::AddressSpace::kWorkgroup, ast::Access::kRead);
     EXPECT_EQ(r->FriendlyName(Symbols()), "ptr<workgroup, i32, read>");
 }
 
diff --git a/src/tint/sem/reference.cc b/src/tint/sem/reference.cc
index 4751563..a3a9f24 100644
--- a/src/tint/sem/reference.cc
+++ b/src/tint/sem/reference.cc
@@ -21,19 +21,19 @@
 
 namespace tint::sem {
 
-Reference::Reference(const Type* subtype, ast::StorageClass storage_class, ast::Access access)
-    : subtype_(subtype), storage_class_(storage_class), access_(access) {
+Reference::Reference(const Type* subtype, ast::AddressSpace address_space, ast::Access access)
+    : subtype_(subtype), address_space_(address_space), access_(access) {
     TINT_ASSERT(Semantic, !subtype->Is<Reference>());
     TINT_ASSERT(Semantic, access != ast::Access::kUndefined);
 }
 
 size_t Reference::Hash() const {
-    return utils::Hash(TypeInfo::Of<Reference>().full_hashcode, storage_class_, subtype_, access_);
+    return utils::Hash(TypeInfo::Of<Reference>().full_hashcode, address_space_, subtype_, access_);
 }
 
 bool Reference::Equals(const sem::Type& other) const {
     if (auto* o = other.As<Reference>()) {
-        return o->storage_class_ == storage_class_ && o->subtype_ == subtype_ &&
+        return o->address_space_ == address_space_ && o->subtype_ == subtype_ &&
                o->access_ == access_;
     }
     return false;
@@ -42,8 +42,8 @@
 std::string Reference::FriendlyName(const SymbolTable& symbols) const {
     std::ostringstream out;
     out << "ref<";
-    if (storage_class_ != ast::StorageClass::kNone) {
-        out << storage_class_ << ", ";
+    if (address_space_ != ast::AddressSpace::kNone) {
+        out << address_space_ << ", ";
     }
     out << subtype_->FriendlyName(symbols) << ", " << access_;
     out << ">";
diff --git a/src/tint/sem/reference.h b/src/tint/sem/reference.h
index 5db9b62..f843da6 100644
--- a/src/tint/sem/reference.h
+++ b/src/tint/sem/reference.h
@@ -18,7 +18,7 @@
 #include <string>
 
 #include "src/tint/ast/access.h"
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/sem/type.h"
 
 namespace tint::sem {
@@ -28,9 +28,9 @@
   public:
     /// Constructor
     /// @param subtype the pointee type
-    /// @param storage_class the storage class of the reference
+    /// @param address_space the address space of the reference
     /// @param access the resolved access control of the reference
-    Reference(const Type* subtype, ast::StorageClass storage_class, ast::Access access);
+    Reference(const Type* subtype, ast::AddressSpace address_space, ast::Access access);
 
     /// Move constructor
     Reference(Reference&&);
@@ -46,8 +46,8 @@
     /// @returns the pointee type
     const Type* StoreType() const { return subtype_; }
 
-    /// @returns the storage class of the reference
-    ast::StorageClass StorageClass() const { return storage_class_; }
+    /// @returns the address space of the reference
+    ast::AddressSpace AddressSpace() const { return address_space_; }
 
     /// @returns the resolved access control of the reference.
     ast::Access Access() const { return access_; }
@@ -59,7 +59,7 @@
 
   private:
     Type const* const subtype_;
-    ast::StorageClass const storage_class_;
+    ast::AddressSpace const address_space_;
     ast::Access const access_;
 };
 
diff --git a/src/tint/sem/reference_test.cc b/src/tint/sem/reference_test.cc
index 27b1ebd..53ba21b 100644
--- a/src/tint/sem/reference_test.cc
+++ b/src/tint/sem/reference_test.cc
@@ -22,17 +22,17 @@
 
 TEST_F(ReferenceTest, Creation) {
     auto* a =
-        create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* b =
-        create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* c =
-        create<Reference>(create<F32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* d =
-        create<Reference>(create<I32>(), ast::StorageClass::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kRead);
+        create<Reference>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
+    auto* e = create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
 
     EXPECT_TRUE(a->StoreType()->Is<sem::I32>());
-    EXPECT_EQ(a->StorageClass(), ast::StorageClass::kStorage);
+    EXPECT_EQ(a->AddressSpace(), ast::AddressSpace::kStorage);
     EXPECT_EQ(a->Access(), ast::Access::kReadWrite);
 
     EXPECT_EQ(a, b);
@@ -43,14 +43,14 @@
 
 TEST_F(ReferenceTest, Hash) {
     auto* a =
-        create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* b =
-        create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* c =
-        create<Reference>(create<F32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* d =
-        create<Reference>(create<I32>(), ast::StorageClass::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kRead);
+        create<Reference>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
+    auto* e = create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
 
     EXPECT_EQ(a->Hash(), b->Hash());
     EXPECT_NE(a->Hash(), c->Hash());
@@ -60,14 +60,14 @@
 
 TEST_F(ReferenceTest, Equals) {
     auto* a =
-        create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* b =
-        create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* c =
-        create<Reference>(create<F32>(), ast::StorageClass::kStorage, ast::Access::kReadWrite);
+        create<Reference>(create<F32>(), ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     auto* d =
-        create<Reference>(create<I32>(), ast::StorageClass::kPrivate, ast::Access::kReadWrite);
-    auto* e = create<Reference>(create<I32>(), ast::StorageClass::kStorage, ast::Access::kRead);
+        create<Reference>(create<I32>(), ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
+    auto* e = create<Reference>(create<I32>(), ast::AddressSpace::kStorage, ast::Access::kRead);
 
     EXPECT_TRUE(a->Equals(*b));
     EXPECT_FALSE(a->Equals(*c));
@@ -77,12 +77,12 @@
 }
 
 TEST_F(ReferenceTest, FriendlyName) {
-    auto* r = create<Reference>(create<I32>(), ast::StorageClass::kNone, ast::Access::kRead);
+    auto* r = create<Reference>(create<I32>(), ast::AddressSpace::kNone, ast::Access::kRead);
     EXPECT_EQ(r->FriendlyName(Symbols()), "ref<i32, read>");
 }
 
-TEST_F(ReferenceTest, FriendlyNameWithStorageClass) {
-    auto* r = create<Reference>(create<I32>(), ast::StorageClass::kWorkgroup, ast::Access::kRead);
+TEST_F(ReferenceTest, FriendlyNameWithAddressSpace) {
+    auto* r = create<Reference>(create<I32>(), ast::AddressSpace::kWorkgroup, ast::Access::kRead);
     EXPECT_EQ(r->FriendlyName(Symbols()), "ref<workgroup, i32, read>");
 }
 
diff --git a/src/tint/sem/struct.h b/src/tint/sem/struct.h
index 0f3213a..80ab53b 100644
--- a/src/tint/sem/struct.h
+++ b/src/tint/sem/struct.h
@@ -22,7 +22,7 @@
 #include <unordered_set>
 #include <vector>
 
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/struct.h"
 #include "src/tint/sem/node.h"
 #include "src/tint/sem/type.h"
@@ -109,23 +109,23 @@
     /// alignment padding
     uint32_t SizeNoPadding() const { return size_no_padding_; }
 
-    /// Adds the StorageClass usage to the structure.
+    /// Adds the AddressSpace usage to the structure.
     /// @param usage the storage usage
-    void AddUsage(ast::StorageClass usage) { storage_class_usage_.emplace(usage); }
+    void AddUsage(ast::AddressSpace usage) { address_space_usage_.emplace(usage); }
 
-    /// @returns the set of storage class uses of this structure
-    const std::unordered_set<ast::StorageClass>& StorageClassUsage() const {
-        return storage_class_usage_;
+    /// @returns the set of address space uses of this structure
+    const std::unordered_set<ast::AddressSpace>& AddressSpaceUsage() const {
+        return address_space_usage_;
     }
 
-    /// @param usage the ast::StorageClass usage type to query
-    /// @returns true iff this structure has been used as the given storage class
-    bool UsedAs(ast::StorageClass usage) const { return storage_class_usage_.count(usage) > 0; }
+    /// @param usage the ast::AddressSpace usage type to query
+    /// @returns true iff this structure has been used as the given address space
+    bool UsedAs(ast::AddressSpace usage) const { return address_space_usage_.count(usage) > 0; }
 
-    /// @returns true iff this structure has been used by storage class that's
+    /// @returns true iff this structure has been used by address space that's
     /// host-shareable.
     bool IsHostShareable() const {
-        for (auto sc : storage_class_usage_) {
+        for (auto sc : address_space_usage_) {
             if (ast::IsHostShareable(sc)) {
                 return true;
             }
@@ -165,7 +165,7 @@
     const uint32_t align_;
     const uint32_t size_;
     const uint32_t size_no_padding_;
-    std::unordered_set<ast::StorageClass> storage_class_usage_;
+    std::unordered_set<ast::AddressSpace> address_space_usage_;
     std::unordered_set<PipelineStageUsage> pipeline_stage_uses_;
     bool constructible_;
 };
diff --git a/src/tint/sem/type_test.cc b/src/tint/sem/type_test.cc
index 6ea97d3..02c76c2 100644
--- a/src/tint/sem/type_test.cc
+++ b/src/tint/sem/type_test.cc
@@ -43,7 +43,7 @@
     const sem::Matrix* mat4x3_f16 = create<Matrix>(vec3_f16, 4u);
     const sem::Matrix* mat4x3_af = create<Matrix>(vec3_af, 4u);
     const sem::Reference* ref_u32 =
-        create<Reference>(u32, ast::StorageClass::kPrivate, ast::Access::kReadWrite);
+        create<Reference>(u32, ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
     const sem::Struct* str = create<Struct>(nullptr,
                                             Sym("s"),
                                             StructMemberList{
diff --git a/src/tint/sem/variable.cc b/src/tint/sem/variable.cc
index 6dcec63..9336947 100644
--- a/src/tint/sem/variable.cc
+++ b/src/tint/sem/variable.cc
@@ -31,13 +31,13 @@
 Variable::Variable(const ast::Variable* declaration,
                    const sem::Type* type,
                    EvaluationStage stage,
-                   ast::StorageClass storage_class,
+                   ast::AddressSpace address_space,
                    ast::Access access,
                    const Constant* constant_value)
     : declaration_(declaration),
       type_(type),
       stage_(stage),
-      storage_class_(storage_class),
+      address_space_(address_space),
       access_(access),
       constant_value_(constant_value) {}
 
@@ -46,11 +46,11 @@
 LocalVariable::LocalVariable(const ast::Variable* declaration,
                              const sem::Type* type,
                              EvaluationStage stage,
-                             ast::StorageClass storage_class,
+                             ast::AddressSpace address_space,
                              ast::Access access,
                              const sem::Statement* statement,
                              const Constant* constant_value)
-    : Base(declaration, type, stage, storage_class, access, constant_value),
+    : Base(declaration, type, stage, address_space, access, constant_value),
       statement_(statement) {}
 
 LocalVariable::~LocalVariable() = default;
@@ -58,12 +58,12 @@
 GlobalVariable::GlobalVariable(const ast::Variable* declaration,
                                const sem::Type* type,
                                EvaluationStage stage,
-                               ast::StorageClass storage_class,
+                               ast::AddressSpace address_space,
                                ast::Access access,
                                const Constant* constant_value,
                                sem::BindingPoint binding_point,
                                std::optional<uint32_t> location)
-    : Base(declaration, type, stage, storage_class, access, constant_value),
+    : Base(declaration, type, stage, address_space, access, constant_value),
       binding_point_(binding_point),
       location_(location) {}
 
@@ -72,12 +72,12 @@
 Parameter::Parameter(const ast::Parameter* declaration,
                      uint32_t index,
                      const sem::Type* type,
-                     ast::StorageClass storage_class,
+                     ast::AddressSpace address_space,
                      ast::Access access,
                      const ParameterUsage usage /* = ParameterUsage::kNone */,
                      sem::BindingPoint binding_point /* = {} */,
                      std::optional<uint32_t> location /* = std::nullopt */)
-    : Base(declaration, type, EvaluationStage::kRuntime, storage_class, access, nullptr),
+    : Base(declaration, type, EvaluationStage::kRuntime, address_space, access, nullptr),
       index_(index),
       usage_(usage),
       binding_point_(binding_point),
diff --git a/src/tint/sem/variable.h b/src/tint/sem/variable.h
index 5ea70b9..1d91e15 100644
--- a/src/tint/sem/variable.h
+++ b/src/tint/sem/variable.h
@@ -22,7 +22,7 @@
 #include "tint/override_id.h"
 
 #include "src/tint/ast/access.h"
-#include "src/tint/ast/storage_class.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/sem/binding_point.h"
 #include "src/tint/sem/expression.h"
 #include "src/tint/sem/parameter_usage.h"
@@ -49,13 +49,13 @@
     /// @param declaration the AST declaration node
     /// @param type the variable type
     /// @param stage the evaluation stage for an expression of this variable type
-    /// @param storage_class the variable storage class
+    /// @param address_space the variable address space
     /// @param access the variable access control type
     /// @param constant_value the constant value for the variable. May be null
     Variable(const ast::Variable* declaration,
              const sem::Type* type,
              EvaluationStage stage,
-             ast::StorageClass storage_class,
+             ast::AddressSpace address_space,
              ast::Access access,
              const Constant* constant_value);
 
@@ -71,8 +71,8 @@
     /// @returns the evaluation stage for an expression of this variable type
     EvaluationStage Stage() const { return stage_; }
 
-    /// @returns the storage class for the variable
-    ast::StorageClass StorageClass() const { return storage_class_; }
+    /// @returns the address space for the variable
+    ast::AddressSpace AddressSpace() const { return address_space_; }
 
     /// @returns the access control for the variable
     ast::Access Access() const { return access_; }
@@ -98,7 +98,7 @@
     const ast::Variable* const declaration_;
     const sem::Type* const type_;
     const EvaluationStage stage_;
-    const ast::StorageClass storage_class_;
+    const ast::AddressSpace address_space_;
     const ast::Access access_;
     const Constant* constant_value_;
     const Expression* constructor_ = nullptr;
@@ -112,14 +112,14 @@
     /// @param declaration the AST declaration node
     /// @param type the variable type
     /// @param stage the evaluation stage for an expression of this variable type
-    /// @param storage_class the variable storage class
+    /// @param address_space the variable address space
     /// @param access the variable access control type
     /// @param statement the statement that declared this local variable
     /// @param constant_value the constant value for the variable. May be null
     LocalVariable(const ast::Variable* declaration,
                   const sem::Type* type,
                   EvaluationStage stage,
-                  ast::StorageClass storage_class,
+                  ast::AddressSpace address_space,
                   ast::Access access,
                   const sem::Statement* statement,
                   const Constant* constant_value);
@@ -149,7 +149,7 @@
     /// @param declaration the AST declaration node
     /// @param type the variable type
     /// @param stage the evaluation stage for an expression of this variable type
-    /// @param storage_class the variable storage class
+    /// @param address_space the variable address space
     /// @param access the variable access control type
     /// @param constant_value the constant value for the variable. May be null
     /// @param binding_point the optional resource binding point of the variable
@@ -160,7 +160,7 @@
     GlobalVariable(const ast::Variable* declaration,
                    const sem::Type* type,
                    EvaluationStage stage,
-                   ast::StorageClass storage_class,
+                   ast::AddressSpace address_space,
                    ast::Access access,
                    const Constant* constant_value,
                    sem::BindingPoint binding_point = {},
@@ -195,7 +195,7 @@
     /// @param declaration the AST declaration node
     /// @param index the index of the parmeter in the function
     /// @param type the variable type
-    /// @param storage_class the variable storage class
+    /// @param address_space the variable address space
     /// @param access the variable access control type
     /// @param usage the semantic usage for the parameter
     /// @param binding_point the optional resource binding point of the parameter
@@ -203,7 +203,7 @@
     Parameter(const ast::Parameter* declaration,
               uint32_t index,
               const sem::Type* type,
-              ast::StorageClass storage_class,
+              ast::AddressSpace address_space,
               ast::Access access,
               const ParameterUsage usage = ParameterUsage::kNone,
               sem::BindingPoint binding_point = {},
diff --git a/src/tint/transform/add_block_attribute.cc b/src/tint/transform/add_block_attribute.cc
index 619083d..97c531e 100644
--- a/src/tint/transform/add_block_attribute.cc
+++ b/src/tint/transform/add_block_attribute.cc
@@ -29,7 +29,7 @@
 
 namespace {
 
-bool IsUsedAsNonBuffer(const std::unordered_set<tint::ast::StorageClass>& uses) {
+bool IsUsedAsNonBuffer(const std::unordered_set<tint::ast::AddressSpace>& uses) {
     for (auto use : uses) {
         if (!ast::IsHostShareable(use)) {
             return true;
@@ -73,8 +73,8 @@
     // Process global 'var' declarations that are buffers.
     for (auto* global : ctx.src->AST().GlobalVariables()) {
         auto* var = sem.Get(global);
-        if (!ast::IsHostShareable(var->StorageClass())) {
-            // Not declared in a host-sharable storage class
+        if (!ast::IsHostShareable(var->AddressSpace())) {
+            // Not declared in a host-sharable address space
             continue;
         }
 
@@ -83,7 +83,7 @@
         bool needs_wrapping =
             !str ||                                       // Type is not a structure
             nested_structs.Contains(str) ||               // Structure is nested by another type
-            IsUsedAsNonBuffer(str->StorageClassUsage());  // Structure is used as a non-buffer usage
+            IsUsedAsNonBuffer(str->AddressSpaceUsage());  // Structure is used as a non-buffer usage
 
         if (needs_wrapping) {
             const char* kMemberName = "inner";
diff --git a/src/tint/transform/array_length_from_uniform.cc b/src/tint/transform/array_length_from_uniform.cc
index 71a5cca..3938b0c 100644
--- a/src/tint/transform/array_length_from_uniform.cc
+++ b/src/tint/transform/array_length_from_uniform.cc
@@ -162,7 +162,7 @@
                                                       u32((max_buffer_size_index / 4) + 1))),
                 });
             buffer_size_ubo = ctx.dst->GlobalVar(ctx.dst->Sym(), ctx.dst->ty.Of(buffer_size_struct),
-                                                 ast::StorageClass::kUniform,
+                                                 ast::AddressSpace::kUniform,
                                                  ctx.dst->Group(AInt(cfg->ubo_binding.group)),
                                                  ctx.dst->Binding(AInt(cfg->ubo_binding.binding)));
         }
diff --git a/src/tint/transform/binding_remapper.cc b/src/tint/transform/binding_remapper.cc
index 487752e..a9a3dfb 100644
--- a/src/tint/transform/binding_remapper.cc
+++ b/src/tint/transform/binding_remapper.cc
@@ -128,18 +128,18 @@
                     return;
                 }
                 auto* sem = ctx.src->Sem().Get(var);
-                if (sem->StorageClass() != ast::StorageClass::kStorage) {
+                if (sem->AddressSpace() != ast::AddressSpace::kStorage) {
                     ctx.dst->Diagnostics().add_error(
                         diag::System::Transform,
-                        "cannot apply access control to variable with storage class " +
-                            std::string(utils::ToString(sem->StorageClass())));
+                        "cannot apply access control to variable with address space " +
+                            std::string(utils::ToString(sem->AddressSpace())));
                     return;
                 }
                 auto* ty = sem->Type()->UnwrapRef();
                 const ast::Type* inner_ty = CreateASTTypeFor(ctx, ty);
                 auto* new_var =
                     ctx.dst->Var(ctx.Clone(var->source), ctx.Clone(var->symbol), inner_ty,
-                                 var->declared_storage_class, ac, ctx.Clone(var->constructor),
+                                 var->declared_address_space, ac, ctx.Clone(var->constructor),
                                  ctx.Clone(var->attributes));
                 ctx.Replace(var, new_var);
             }
diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc
index b06f7b6..2ca5e54 100644
--- a/src/tint/transform/calculate_array_length.cc
+++ b/src/tint/transform/calculate_array_length.cc
@@ -103,11 +103,11 @@
                 name,
                 utils::Vector{
                     ctx.dst->Param("buffer",
-                                   ctx.dst->ty.pointer(type, buffer_type->StorageClass(),
+                                   ctx.dst->ty.pointer(type, buffer_type->AddressSpace(),
                                                        buffer_type->Access()),
                                    utils::Vector{disable_validation}),
                     ctx.dst->Param("result", ctx.dst->ty.pointer(ctx.dst->ty.u32(),
-                                                                 ast::StorageClass::kFunction)),
+                                                                 ast::AddressSpace::kFunction)),
                 },
                 ctx.dst->ty.void_(), nullptr,
                 utils::Vector{
diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc
index b08d44d..0ff1084 100644
--- a/src/tint/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/transform/canonicalize_entry_point_io.cc
@@ -190,15 +190,15 @@
                                                      ast::InterpolationSampling::kNone));
             }
 
-            // Disable validation for use of the `input` storage class.
-            attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+            // Disable validation for use of the `input` address space.
+            attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace));
 
             // In GLSL, if it's a builtin, override the name with the
             // corresponding gl_ builtin name
             auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(attributes);
             if (cfg.shader_style == ShaderStyle::kGlsl && builtin) {
                 name = GLSLBuiltinToString(builtin->builtin, func_ast->PipelineStage(),
-                                           ast::StorageClass::kIn);
+                                           ast::AddressSpace::kIn);
             }
             auto symbol = ctx.dst->Symbols().New(name);
 
@@ -215,7 +215,7 @@
                     value = ctx.dst->IndexAccessor(value, 0_i);
                 }
             }
-            ctx.dst->GlobalVar(symbol, ast_type, ast::StorageClass::kIn, std::move(attributes));
+            ctx.dst->GlobalVar(symbol, ast_type, ast::AddressSpace::kIn, std::move(attributes));
             return value;
         } else if (cfg.shader_style == ShaderStyle::kMsl &&
                    ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
@@ -264,7 +264,7 @@
         if (cfg.shader_style == ShaderStyle::kGlsl) {
             if (auto* b = ast::GetAttribute<ast::BuiltinAttribute>(attributes)) {
                 name = GLSLBuiltinToString(b->builtin, func_ast->PipelineStage(),
-                                           ast::StorageClass::kOut);
+                                           ast::AddressSpace::kOut);
                 value = ToGLSLBuiltin(b->builtin, value, type);
             }
         }
@@ -480,9 +480,9 @@
     /// Create and assign the wrapper function's output variables.
     void CreateGlobalOutputVariables() {
         for (auto& outval : wrapper_output_values) {
-            // Disable validation for use of the `output` storage class.
+            // Disable validation for use of the `output` address space.
             utils::Vector<const ast::Attribute*, 8> attributes = std::move(outval.attributes);
-            attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+            attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace));
 
             // Create the global variable and assign it the output value.
             auto name = ctx.dst->Symbols().New(outval.name);
@@ -494,7 +494,7 @@
                 type = ctx.dst->ty.array(type, 1_u);
                 lhs = ctx.dst->IndexAccessor(lhs, 0_i);
             }
-            ctx.dst->GlobalVar(name, type, ast::StorageClass::kOut, std::move(attributes));
+            ctx.dst->GlobalVar(name, type, ast::AddressSpace::kOut, std::move(attributes));
             wrapper_body.Push(ctx.dst->Assign(lhs, outval.value));
         }
     }
@@ -634,11 +634,11 @@
     /// Retrieve the gl_ string corresponding to a builtin.
     /// @param builtin the builtin
     /// @param stage the current pipeline stage
-    /// @param storage_class the storage class (input or output)
+    /// @param address_space the address space (input or output)
     /// @returns the gl_ string corresponding to that builtin
     const char* GLSLBuiltinToString(ast::BuiltinValue builtin,
                                     ast::PipelineStage stage,
-                                    ast::StorageClass storage_class) {
+                                    ast::AddressSpace address_space) {
         switch (builtin) {
             case ast::BuiltinValue::kPosition:
                 switch (stage) {
@@ -670,7 +670,7 @@
             case ast::BuiltinValue::kSampleIndex:
                 return "gl_SampleID";
             case ast::BuiltinValue::kSampleMask:
-                if (storage_class == ast::StorageClass::kIn) {
+                if (address_space == ast::AddressSpace::kIn) {
                     return "gl_SampleMaskIn";
                 } else {
                     return "gl_SampleMask";
diff --git a/src/tint/transform/canonicalize_entry_point_io_test.cc b/src/tint/transform/canonicalize_entry_point_io_test.cc
index f2af213..3fc0033 100644
--- a/src/tint/transform/canonicalize_entry_point_io_test.cc
+++ b/src/tint/transform/canonicalize_entry_point_io_test.cc
@@ -67,11 +67,11 @@
 )";
 
     auto* expect = R"(
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> loc1_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> loc1_1 : f32;
 
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> loc2_1 : vec4<u32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> loc2_1 : vec4<u32>;
 
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<in> coord_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<in> coord_1 : vec4<f32>;
 
 fn frag_main_inner(loc1 : f32, loc2 : vec4<u32>, coord : vec4<f32>) {
   var col : f32 = (coord.x * loc1);
@@ -251,13 +251,13 @@
 )";
 
     auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> loc0_1 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> loc0_1 : f32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> loc1_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> loc1_1 : f32;
 
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> loc2_1 : vec4<u32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> loc2_1 : vec4<u32>;
 
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<in> coord_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<in> coord_1 : vec4<f32>;
 
 struct FragBuiltins {
   coord : vec4<f32>,
@@ -304,13 +304,13 @@
 )";
 
     auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> loc0_1 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> loc0_1 : f32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> loc1_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> loc1_1 : f32;
 
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> loc2_1 : vec4<u32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> loc2_1 : vec4<u32>;
 
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<in> coord_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<in> coord_1 : vec4<f32>;
 
 fn frag_main_inner(loc0 : f32, locations : FragLocations, builtins : FragBuiltins) {
   var col : f32 = ((builtins.coord.x * locations.loc1) + loc0);
@@ -567,7 +567,7 @@
 )";
 
     auto* expect = R"(
-@builtin(frag_depth) @internal(disable_validation__ignore_storage_class) var<out> value : f32;
+@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<out> value : f32;
 
 fn frag_main_inner() -> f32 {
   return 1.0;
@@ -674,11 +674,11 @@
 )";
 
     auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<out> color_1 : vec4<f32>;
+@location(0) @internal(disable_validation__ignore_address_space) var<out> color_1 : vec4<f32>;
 
-@builtin(frag_depth) @internal(disable_validation__ignore_storage_class) var<out> depth_1 : f32;
+@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<out> depth_1 : f32;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> mask_1 : array<u32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<out> mask_1 : array<u32, 1u>;
 
 struct FragOutput {
   color : vec4<f32>,
@@ -729,11 +729,11 @@
 )";
 
     auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<out> color_1 : vec4<f32>;
+@location(0) @internal(disable_validation__ignore_address_space) var<out> color_1 : vec4<f32>;
 
-@builtin(frag_depth) @internal(disable_validation__ignore_storage_class) var<out> depth_1 : f32;
+@builtin(frag_depth) @internal(disable_validation__ignore_address_space) var<out> depth_1 : f32;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> mask_1 : array<u32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<out> mask_1 : array<u32, 1u>;
 
 fn frag_main_inner() -> FragOutput {
   var output : FragOutput;
@@ -1028,13 +1028,13 @@
 )";
 
     auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> value_1 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> value_1 : f32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> mul_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> mul_1 : f32;
 
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> value_2 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> value_2 : f32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> mul_2 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> mul_2 : f32;
 
 struct FragmentInput {
   value : f32,
@@ -1094,13 +1094,13 @@
 )";
 
     auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> value_1 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> value_1 : f32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> mul_1 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> mul_1 : f32;
 
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> value_2 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> value_2 : f32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> mul_2 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> mul_2 : f32;
 
 fn frag_main1_inner(inputs : FragmentInput) {
   var x : f32 = foo(inputs);
@@ -1952,39 +1952,39 @@
 
     auto* expect =
         R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> i_1 : i32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> i_1 : i32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> u_1 : u32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> u_1 : u32;
 
-@location(2) @internal(disable_validation__ignore_storage_class) var<in> vi_1 : vec4<i32>;
+@location(2) @internal(disable_validation__ignore_address_space) var<in> vi_1 : vec4<i32>;
 
-@location(3) @internal(disable_validation__ignore_storage_class) var<in> vu_1 : vec4<u32>;
+@location(3) @internal(disable_validation__ignore_address_space) var<in> vu_1 : vec4<u32>;
 
-@location(0) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<out> i_2 : i32;
+@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> i_2 : i32;
 
-@location(1) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<out> u_2 : u32;
+@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> u_2 : u32;
 
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<out> vi_2 : vec4<i32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> vi_2 : vec4<i32>;
 
-@location(3) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<out> vu_2 : vec4<u32>;
+@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> vu_2 : vec4<u32>;
 
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<out> pos_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<out> pos_1 : vec4<f32>;
 
-@location(0) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> i_3 : i32;
+@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> i_3 : i32;
 
-@location(1) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> u_3 : u32;
+@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> u_3 : u32;
 
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> vi_3 : vec4<i32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> vi_3 : vec4<i32>;
 
-@location(3) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> vu_3 : vec4<u32>;
+@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> vu_3 : vec4<u32>;
 
-@location(0) @internal(disable_validation__ignore_storage_class) var<out> i_4 : i32;
+@location(0) @internal(disable_validation__ignore_address_space) var<out> i_4 : i32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<out> u_4 : u32;
+@location(1) @internal(disable_validation__ignore_address_space) var<out> u_4 : u32;
 
-@location(2) @internal(disable_validation__ignore_storage_class) var<out> vi_4 : vec4<i32>;
+@location(2) @internal(disable_validation__ignore_address_space) var<out> vi_4 : vec4<i32>;
 
-@location(3) @internal(disable_validation__ignore_storage_class) var<out> vu_4 : vec4<u32>;
+@location(3) @internal(disable_validation__ignore_address_space) var<out> vu_4 : vec4<u32>;
 
 struct VertexIn {
   i : i32,
@@ -2082,39 +2082,39 @@
 
     auto* expect =
         R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> i_1 : i32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> i_1 : i32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> u_1 : u32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> u_1 : u32;
 
-@location(2) @internal(disable_validation__ignore_storage_class) var<in> vi_1 : vec4<i32>;
+@location(2) @internal(disable_validation__ignore_address_space) var<in> vi_1 : vec4<i32>;
 
-@location(3) @internal(disable_validation__ignore_storage_class) var<in> vu_1 : vec4<u32>;
+@location(3) @internal(disable_validation__ignore_address_space) var<in> vu_1 : vec4<u32>;
 
-@location(0) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<out> i_2 : i32;
+@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> i_2 : i32;
 
-@location(1) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<out> u_2 : u32;
+@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> u_2 : u32;
 
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<out> vi_2 : vec4<i32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> vi_2 : vec4<i32>;
 
-@location(3) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<out> vu_2 : vec4<u32>;
+@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<out> vu_2 : vec4<u32>;
 
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<out> pos_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<out> pos_1 : vec4<f32>;
 
-@location(0) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> i_3 : i32;
+@location(0) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> i_3 : i32;
 
-@location(1) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> u_3 : u32;
+@location(1) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> u_3 : u32;
 
-@location(2) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> vi_3 : vec4<i32>;
+@location(2) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> vi_3 : vec4<i32>;
 
-@location(3) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> vu_3 : vec4<u32>;
+@location(3) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> vu_3 : vec4<u32>;
 
-@location(0) @internal(disable_validation__ignore_storage_class) var<out> i_4 : i32;
+@location(0) @internal(disable_validation__ignore_address_space) var<out> i_4 : i32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<out> u_4 : u32;
+@location(1) @internal(disable_validation__ignore_address_space) var<out> u_4 : u32;
 
-@location(2) @internal(disable_validation__ignore_storage_class) var<out> vi_4 : vec4<i32>;
+@location(2) @internal(disable_validation__ignore_address_space) var<out> vi_4 : vec4<i32>;
 
-@location(3) @internal(disable_validation__ignore_storage_class) var<out> vu_4 : vec4<u32>;
+@location(3) @internal(disable_validation__ignore_address_space) var<out> vu_4 : vec4<u32>;
 
 fn vert_main_inner(in : VertexIn) -> VertexOut {
   return VertexOut(in.i, in.u, in.vi, in.vu, vec4<f32>());
@@ -3161,9 +3161,9 @@
 )";
 
     auto* expect = R"(
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<out> value : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<out> value : vec4<f32>;
 
-@builtin(point_size) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size : f32;
 
 fn vert_main_inner() -> vec4<f32> {
   return vec4<f32>();
@@ -3236,9 +3236,9 @@
 )";
 
     auto* expect = R"(
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<out> pos_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<out> pos_1 : vec4<f32>;
 
-@builtin(point_size) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size : f32;
 
 struct VertOut {
   pos : vec4<f32>,
@@ -3277,9 +3277,9 @@
 )";
 
     auto* expect = R"(
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<out> pos_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<out> pos_1 : vec4<f32>;
 
-@builtin(point_size) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size : f32;
 
 fn vert_main_inner() -> VertOut {
   return VertOut();
@@ -3424,15 +3424,15 @@
 )";
 
     auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> collide_2 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> collide_2 : f32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> collide_3 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> collide_3 : f32;
 
-@location(0) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size_3 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_3 : f32;
 
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size_1_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_1_1 : vec4<f32>;
 
-@builtin(point_size) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size_4 : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_4 : f32;
 
 var<private> vertex_point_size : f32;
 
@@ -3502,15 +3502,15 @@
 )";
 
     auto* expect = R"(
-@location(0) @internal(disable_validation__ignore_storage_class) var<in> collide_2 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<in> collide_2 : f32;
 
-@location(1) @internal(disable_validation__ignore_storage_class) var<in> collide_3 : f32;
+@location(1) @internal(disable_validation__ignore_address_space) var<in> collide_3 : f32;
 
-@location(0) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size_3 : f32;
+@location(0) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_3 : f32;
 
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size_1_1 : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_1_1 : vec4<f32>;
 
-@builtin(point_size) @internal(disable_validation__ignore_storage_class) var<out> vertex_point_size_4 : f32;
+@builtin(point_size) @internal(disable_validation__ignore_address_space) var<out> vertex_point_size_4 : f32;
 
 fn vert_main_inner(collide : VertIn1, collide_1 : VertIn2) -> VertOut {
   let x = (collide.collide + collide_1.collide);
@@ -3868,11 +3868,11 @@
 )";
 
     auto* expect = R"(
-@builtin(sample_index) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> sample_index_1 : u32;
+@builtin(sample_index) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> sample_index_1 : u32;
 
-@builtin(sample_mask) @interpolate(flat) @internal(disable_validation__ignore_storage_class) var<in> mask_in_1 : array<u32, 1u>;
+@builtin(sample_mask) @interpolate(flat) @internal(disable_validation__ignore_address_space) var<in> mask_in_1 : array<u32, 1u>;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> value : array<u32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<out> value : array<u32, 1u>;
 
 fn main_inner(sample_index : u32, mask_in : u32) -> u32 {
   return mask_in;
@@ -3903,11 +3903,11 @@
 )";
 
     auto* expect = R"(
-@builtin(sample_index) @internal(disable_validation__ignore_storage_class) var<in> gl_SampleID : i32;
+@builtin(sample_index) @internal(disable_validation__ignore_address_space) var<in> gl_SampleID : i32;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<in> gl_SampleMaskIn : array<i32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<in> gl_SampleMaskIn : array<i32, 1u>;
 
-@builtin(sample_mask) @internal(disable_validation__ignore_storage_class) var<out> gl_SampleMask : array<i32, 1u>;
+@builtin(sample_mask) @internal(disable_validation__ignore_address_space) var<out> gl_SampleMask : array<i32, 1u>;
 
 fn fragment_main(sample_index : u32, mask_in : u32) -> u32 {
   return mask_in;
@@ -3938,11 +3938,11 @@
 )";
 
     auto* expect = R"(
-@builtin(vertex_index) @internal(disable_validation__ignore_storage_class) var<in> gl_VertexID : i32;
+@builtin(vertex_index) @internal(disable_validation__ignore_address_space) var<in> gl_VertexID : i32;
 
-@builtin(instance_index) @internal(disable_validation__ignore_storage_class) var<in> gl_InstanceID : i32;
+@builtin(instance_index) @internal(disable_validation__ignore_address_space) var<in> gl_InstanceID : i32;
 
-@builtin(position) @internal(disable_validation__ignore_storage_class) var<out> gl_Position : vec4<f32>;
+@builtin(position) @internal(disable_validation__ignore_address_space) var<out> gl_Position : vec4<f32>;
 
 fn vertex_main(vertexID : u32, instanceID : u32) -> vec4<f32> {
   return vec4<f32>((f32(vertexID) + f32(instanceID)));
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index 5920d5b..ffdf88e 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -97,17 +97,17 @@
 
 /// LoadStoreKey is the unordered map key to a load or store intrinsic.
 struct LoadStoreKey {
-    ast::StorageClass const storage_class;  // buffer storage class
+    ast::AddressSpace const address_space;  // buffer address space
     ast::Access const access;               // buffer access
     sem::Type const* buf_ty = nullptr;      // buffer type
     sem::Type const* el_ty = nullptr;       // element type
     bool operator==(const LoadStoreKey& rhs) const {
-        return storage_class == rhs.storage_class && access == rhs.access && buf_ty == rhs.buf_ty &&
+        return address_space == rhs.address_space && access == rhs.access && buf_ty == rhs.buf_ty &&
                el_ty == rhs.el_ty;
     }
     struct Hasher {
         inline std::size_t operator()(const LoadStoreKey& u) const {
-            return utils::Hash(u.storage_class, u.access, u.buf_ty, u.el_ty);
+            return utils::Hash(u.address_space, u.access, u.buf_ty, u.el_ty);
         }
     };
 };
@@ -195,7 +195,7 @@
 /// @returns a DecomposeMemoryAccess::Intrinsic attribute that can be applied
 /// to a stub function to load the type `ty`.
 DecomposeMemoryAccess::Intrinsic* IntrinsicLoadFor(ProgramBuilder* builder,
-                                                   ast::StorageClass storage_class,
+                                                   ast::AddressSpace address_space,
                                                    const sem::Type* ty) {
     DecomposeMemoryAccess::Intrinsic::DataType type;
     if (!IntrinsicDataTypeFor(ty, type)) {
@@ -203,13 +203,13 @@
     }
     return builder->ASTNodes().Create<DecomposeMemoryAccess::Intrinsic>(
         builder->ID(), builder->AllocateNodeID(), DecomposeMemoryAccess::Intrinsic::Op::kLoad,
-        storage_class, type);
+        address_space, type);
 }
 
 /// @returns a DecomposeMemoryAccess::Intrinsic attribute that can be applied
 /// to a stub function to store the type `ty`.
 DecomposeMemoryAccess::Intrinsic* IntrinsicStoreFor(ProgramBuilder* builder,
-                                                    ast::StorageClass storage_class,
+                                                    ast::AddressSpace address_space,
                                                     const sem::Type* ty) {
     DecomposeMemoryAccess::Intrinsic::DataType type;
     if (!IntrinsicDataTypeFor(ty, type)) {
@@ -217,7 +217,7 @@
     }
     return builder->ASTNodes().Create<DecomposeMemoryAccess::Intrinsic>(
         builder->ID(), builder->AllocateNodeID(), DecomposeMemoryAccess::Intrinsic::Op::kStore,
-        storage_class, type);
+        address_space, type);
 }
 
 /// @returns a DecomposeMemoryAccess::Intrinsic attribute that can be applied
@@ -272,7 +272,7 @@
         return nullptr;
     }
     return builder->ASTNodes().Create<DecomposeMemoryAccess::Intrinsic>(
-        builder->ID(), builder->AllocateNodeID(), op, ast::StorageClass::kStorage, type);
+        builder->ID(), builder->AllocateNodeID(), op, ast::AddressSpace::kStorage, type);
 }
 
 /// BufferAccess describes a single storage or uniform buffer access
@@ -436,20 +436,20 @@
     Symbol LoadFunc(const sem::Type* buf_ty,
                     const sem::Type* el_ty,
                     const sem::VariableUser* var_user) {
-        auto storage_class = var_user->Variable()->StorageClass();
+        auto address_space = var_user->Variable()->AddressSpace();
         auto access = var_user->Variable()->Access();
         return utils::GetOrCreate(
-            load_funcs, LoadStoreKey{storage_class, access, buf_ty, el_ty}, [&] {
+            load_funcs, LoadStoreKey{address_space, access, buf_ty, el_ty}, [&] {
                 utils::Vector params{
                     b.Param("buffer",
-                            b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), storage_class, access),
+                            b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), address_space, access),
                             utils::Vector{b.Disable(ast::DisabledValidation::kFunctionParameter)}),
                     b.Param("offset", b.ty.u32()),
                 };
 
                 auto name = b.Sym();
 
-                if (auto* intrinsic = IntrinsicLoadFor(ctx.dst, storage_class, el_ty)) {
+                if (auto* intrinsic = IntrinsicLoadFor(ctx.dst, address_space, el_ty)) {
                     auto* el_ast_ty = CreateASTTypeFor(ctx, el_ty);
                     auto* func = b.create<ast::Function>(
                         name, params, el_ast_ty, nullptr,
@@ -532,13 +532,13 @@
     Symbol StoreFunc(const sem::Type* buf_ty,
                      const sem::Type* el_ty,
                      const sem::VariableUser* var_user) {
-        auto storage_class = var_user->Variable()->StorageClass();
+        auto address_space = var_user->Variable()->AddressSpace();
         auto access = var_user->Variable()->Access();
         return utils::GetOrCreate(
-            store_funcs, LoadStoreKey{storage_class, access, buf_ty, el_ty}, [&] {
+            store_funcs, LoadStoreKey{address_space, access, buf_ty, el_ty}, [&] {
                 utils::Vector params{
                     b.Param("buffer",
-                            b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), storage_class, access),
+                            b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), address_space, access),
                             utils::Vector{b.Disable(ast::DisabledValidation::kFunctionParameter)}),
                     b.Param("offset", b.ty.u32()),
                     b.Param("value", CreateASTTypeFor(ctx, el_ty)),
@@ -546,7 +546,7 @@
 
                 auto name = b.Sym();
 
-                if (auto* intrinsic = IntrinsicStoreFor(ctx.dst, storage_class, el_ty)) {
+                if (auto* intrinsic = IntrinsicStoreFor(ctx.dst, address_space, el_ty)) {
                     auto* func = b.create<ast::Function>(
                         name, params, b.ty.void_(), nullptr,
                         utils::Vector{
@@ -648,7 +648,7 @@
             // atomic. This is replaced with two parameters: the buffer and offset.
             utils::Vector params{
                 b.Param("buffer",
-                        b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), ast::StorageClass::kStorage,
+                        b.ty.pointer(CreateASTTypeFor(ctx, buf_ty), ast::AddressSpace::kStorage,
                                      access),
                         utils::Vector{b.Disable(ast::DisabledValidation::kFunctionParameter)}),
                 b.Param("offset", b.ty.u32()),
@@ -706,9 +706,9 @@
 DecomposeMemoryAccess::Intrinsic::Intrinsic(ProgramID pid,
                                             ast::NodeID nid,
                                             Op o,
-                                            ast::StorageClass sc,
+                                            ast::AddressSpace sc,
                                             DataType ty)
-    : Base(pid, nid), op(o), storage_class(sc), type(ty) {}
+    : Base(pid, nid), op(o), address_space(sc), type(ty) {}
 DecomposeMemoryAccess::Intrinsic::~Intrinsic() = default;
 std::string DecomposeMemoryAccess::Intrinsic::InternalName() const {
     std::stringstream ss;
@@ -753,7 +753,7 @@
             ss << "intrinsic_atomic_compare_exchange_weak_";
             break;
     }
-    ss << storage_class << "_";
+    ss << address_space << "_";
     switch (type) {
         case DataType::kU32:
             ss << "u32";
@@ -798,7 +798,7 @@
 const DecomposeMemoryAccess::Intrinsic* DecomposeMemoryAccess::Intrinsic::Clone(
     CloneContext* ctx) const {
     return ctx->dst->ASTNodes().Create<DecomposeMemoryAccess::Intrinsic>(
-        ctx->dst->ID(), ctx->dst->AllocateNodeID(), op, storage_class, type);
+        ctx->dst->ID(), ctx->dst->AllocateNodeID(), op, address_space, type);
 }
 
 bool DecomposeMemoryAccess::Intrinsic::IsAtomic() const {
@@ -811,8 +811,8 @@
 bool DecomposeMemoryAccess::ShouldRun(const Program* program, const DataMap&) const {
     for (auto* decl : program->AST().GlobalDeclarations()) {
         if (auto* var = program->Sem().Get<sem::Variable>(decl)) {
-            if (var->StorageClass() == ast::StorageClass::kStorage ||
-                var->StorageClass() == ast::StorageClass::kUniform) {
+            if (var->AddressSpace() == ast::AddressSpace::kStorage ||
+                var->AddressSpace() == ast::AddressSpace::kUniform) {
                 return true;
             }
         }
@@ -837,8 +837,8 @@
         if (auto* ident = node->As<ast::IdentifierExpression>()) {
             // X
             if (auto* var = sem.Get<sem::VariableUser>(ident)) {
-                if (var->Variable()->StorageClass() == ast::StorageClass::kStorage ||
-                    var->Variable()->StorageClass() == ast::StorageClass::kUniform) {
+                if (var->Variable()->AddressSpace() == ast::AddressSpace::kStorage ||
+                    var->Variable()->AddressSpace() == ast::AddressSpace::kUniform) {
                     // Variable to a storage or uniform buffer
                     state.AddAccess(ident, {
                                                var,
diff --git a/src/tint/transform/decompose_memory_access.h b/src/tint/transform/decompose_memory_access.h
index 1d95dc4..2e92a3a 100644
--- a/src/tint/transform/decompose_memory_access.h
+++ b/src/tint/transform/decompose_memory_access.h
@@ -75,9 +75,9 @@
         /// @param pid the identifier of the program that owns this node
         /// @param nid the unique node identifier
         /// @param o the op of the intrinsic
-        /// @param sc the storage class of the buffer
+        /// @param sc the address space of the buffer
         /// @param ty the data type of the intrinsic
-        Intrinsic(ProgramID pid, ast::NodeID nid, Op o, ast::StorageClass sc, DataType ty);
+        Intrinsic(ProgramID pid, ast::NodeID nid, Op o, ast::AddressSpace sc, DataType ty);
         /// Destructor
         ~Intrinsic() override;
 
@@ -96,8 +96,8 @@
         /// The op of the intrinsic
         const Op op;
 
-        /// The storage class of the buffer this intrinsic operates on
-        ast::StorageClass const storage_class;
+        /// The address space of the buffer this intrinsic operates on
+        ast::AddressSpace const address_space;
 
         /// The type of the intrinsic
         const DataType type;
diff --git a/src/tint/transform/decompose_strided_array_test.cc b/src/tint/transform/decompose_strided_array_test.cc
index 58908fb..96a95fc 100644
--- a/src/tint/transform/decompose_strided_array_test.cc
+++ b/src/tint/transform/decompose_strided_array_test.cc
@@ -39,7 +39,7 @@
     // var<private> arr : array<f32, 4u>
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(), ast::StorageClass::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(), ast::AddressSpace::kPrivate);
     EXPECT_FALSE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
@@ -47,7 +47,7 @@
     // var<private> arr : @stride(4) array<f32, 4u>
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::AddressSpace::kPrivate);
     EXPECT_TRUE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
@@ -55,7 +55,7 @@
     // var<private> arr : @stride(16) array<f32, 4u>
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(16), ast::StorageClass::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(16), ast::AddressSpace::kPrivate);
     EXPECT_TRUE(ShouldRun<DecomposeStridedArray>(Program(std::move(b))));
 }
 
@@ -78,7 +78,7 @@
     // }
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::StorageClass::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(4), ast::AddressSpace::kPrivate);
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.Expr("arr"))),
@@ -114,7 +114,7 @@
     // }
 
     ProgramBuilder b;
-    b.GlobalVar("arr", b.ty.array<f32, 4u>(32), ast::StorageClass::kPrivate);
+    b.GlobalVar("arr", b.ty.array<f32, 4u>(32), ast::AddressSpace::kPrivate);
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.Expr("arr"))),
@@ -158,7 +158,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
@@ -206,7 +206,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array(b.ty.vec4<f32>(), 4_u, 16))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func(
         "f", utils::Empty, b.ty.void_(),
         utils::Vector{
@@ -252,7 +252,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(32), b.MemberAccessor("s", "a"))),
@@ -300,7 +300,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(4))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("a", b.ty.array<f32, 4u>(4), b.MemberAccessor("s", "a"))),
@@ -344,7 +344,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
@@ -398,7 +398,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(4))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
@@ -450,7 +450,7 @@
     // }
     ProgramBuilder b;
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.array<f32, 4u>(32))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
@@ -511,7 +511,7 @@
     ProgramBuilder b;
     b.Alias("ARR", b.ty.array<f32, 4u>(32));
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.type_name("ARR"))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
@@ -581,7 +581,7 @@
                 b.ty.array(b.ty.type_name("ARR_A"), 3_u, 16),  //
                 4_u, 128));
     auto* S = b.Structure("S", utils::Vector{b.Member("a", b.ty.type_name("ARR_B"))});
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
diff --git a/src/tint/transform/decompose_strided_matrix.cc b/src/tint/transform/decompose_strided_matrix.cc
index 75c96f6..91aed43 100644
--- a/src/tint/transform/decompose_strided_matrix.cc
+++ b/src/tint/transform/decompose_strided_matrix.cc
@@ -71,8 +71,8 @@
     for (auto* node : program->ASTNodes().Objects()) {
         if (auto* str = node->As<ast::Struct>()) {
             auto* str_ty = program->Sem().Get(str);
-            if (!str_ty->UsedAs(ast::StorageClass::kUniform) &&
-                !str_ty->UsedAs(ast::StorageClass::kStorage)) {
+            if (!str_ty->UsedAs(ast::AddressSpace::kUniform) &&
+                !str_ty->UsedAs(ast::AddressSpace::kStorage)) {
                 continue;
             }
             for (auto* member : str_ty->Members()) {
diff --git a/src/tint/transform/decompose_strided_matrix_test.cc b/src/tint/transform/decompose_strided_matrix_test.cc
index 6bfba7c..bd202c9 100644
--- a/src/tint/transform/decompose_strided_matrix_test.cc
+++ b/src/tint/transform/decompose_strided_matrix_test.cc
@@ -76,7 +76,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -132,7 +132,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func(
         "f", utils::Empty, b.ty.void_(),
         utils::Vector{
@@ -185,7 +185,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -238,7 +238,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
@@ -295,7 +295,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func(
         "f", utils::Empty, b.ty.void_(),
@@ -349,7 +349,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
@@ -407,7 +407,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
@@ -466,7 +466,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kStorage, ast::Access::kReadWrite, b.Group(0_a),
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kStorage, ast::Access::kReadWrite, b.Group(0_a),
                 b.Binding(0_a));
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
@@ -537,7 +537,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kPrivate);
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kPrivate);
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Decl(b.Let("x", b.ty.mat2x2<f32>(), b.MemberAccessor("s", "m"))),
@@ -590,7 +590,7 @@
                               b.Disable(ast::DisabledValidation::kIgnoreStrideAttribute),
                           }),
              });
-    b.GlobalVar("s", b.ty.Of(S), ast::StorageClass::kPrivate);
+    b.GlobalVar("s", b.ty.Of(S), ast::AddressSpace::kPrivate);
     b.Func("f", utils::Empty, b.ty.void_(),
            utils::Vector{
                b.Assign(b.MemberAccessor("s", "m"),
diff --git a/src/tint/transform/first_index_offset.cc b/src/tint/transform/first_index_offset.cc
index 918fd5b..cafca32 100644
--- a/src/tint/transform/first_index_offset.cc
+++ b/src/tint/transform/first_index_offset.cc
@@ -121,7 +121,7 @@
 
         // Create a global to hold the uniform buffer
         Symbol buffer_name = ctx.dst->Sym();
-        ctx.dst->GlobalVar(buffer_name, ctx.dst->ty.Of(struct_), ast::StorageClass::kUniform,
+        ctx.dst->GlobalVar(buffer_name, ctx.dst->ty.Of(struct_), ast::AddressSpace::kUniform,
                            utils::Vector{
                                ctx.dst->Binding(AInt(ub_binding)),
                                ctx.dst->Group(AInt(ub_group)),
diff --git a/src/tint/transform/localize_struct_array_assignment.cc b/src/tint/transform/localize_struct_array_assignment.cc
index 8286845..8077393 100644
--- a/src/tint/transform/localize_struct_array_assignment.cc
+++ b/src/tint/transform/localize_struct_array_assignment.cc
@@ -62,10 +62,10 @@
         return result;
     }
 
-    // Returns the type and storage class of the originating variable of the lhs
+    // Returns the type and address space of the originating variable of the lhs
     // of the assignment statement.
     // See https://www.w3.org/TR/WGSL/#originating-variable-section
-    std::pair<const sem::Type*, ast::StorageClass> GetOriginatingTypeAndStorageClass(
+    std::pair<const sem::Type*, ast::AddressSpace> GetOriginatingTypeAndAddressSpace(
         const ast::AssignmentStatement* assign_stmt) {
         auto* source_var = ctx.src->Sem().Get(assign_stmt->lhs)->SourceVariable();
         if (!source_var) {
@@ -77,9 +77,9 @@
 
         auto* type = source_var->Type();
         if (auto* ref = type->As<sem::Reference>()) {
-            return {ref->StoreType(), ref->StorageClass()};
+            return {ref->StoreType(), ref->AddressSpace()};
         } else if (auto* ptr = type->As<sem::Pointer>()) {
-            return {ptr->StoreType(), ptr->StorageClass()};
+            return {ptr->StoreType(), ptr->AddressSpace()};
         }
 
         TINT_ICE(Transform, b.Diagnostics())
@@ -111,9 +111,9 @@
             if (!ContainsStructArrayIndex(assign_stmt->lhs)) {
                 return nullptr;
             }
-            auto og = GetOriginatingTypeAndStorageClass(assign_stmt);
-            if (!(og.first->Is<sem::Struct>() && (og.second == ast::StorageClass::kFunction ||
-                                                  og.second == ast::StorageClass::kPrivate))) {
+            auto og = GetOriginatingTypeAndAddressSpace(assign_stmt);
+            if (!(og.first->Is<sem::Struct>() && (og.second == ast::AddressSpace::kFunction ||
+                                                  og.second == ast::AddressSpace::kPrivate))) {
                 return nullptr;
             }
 
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.cc b/src/tint/transform/module_scope_var_to_entry_point_param.cc
index 122fb3c..2004c4c 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param.cc
@@ -114,9 +114,9 @@
         // Helper to create an AST node for the store type of the variable.
         auto store_type = [&]() { return CreateASTTypeFor(ctx, ty); };
 
-        ast::StorageClass sc = var->StorageClass();
+        ast::AddressSpace sc = var->AddressSpace();
         switch (sc) {
-            case ast::StorageClass::kHandle: {
+            case ast::AddressSpace::kHandle: {
                 // For a texture or sampler variable, redeclare it as an entry point parameter.
                 // Disable entry point parameter validation.
                 auto* disable_validation =
@@ -128,13 +128,13 @@
 
                 break;
             }
-            case ast::StorageClass::kStorage:
-            case ast::StorageClass::kUniform: {
-                // Variables into the Storage and Uniform storage classes are redeclared as entry
+            case ast::AddressSpace::kStorage:
+            case ast::AddressSpace::kUniform: {
+                // Variables into the Storage and Uniform address spacees are redeclared as entry
                 // point parameters with a pointer type.
                 auto attributes = ctx.Clone(var->Declaration()->attributes);
                 attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter));
-                attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+                attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace));
 
                 auto* param_type = store_type();
                 if (auto* arr = ty->As<sem::Array>(); arr && arr->IsRuntimeSized()) {
@@ -157,7 +157,7 @@
 
                 break;
             }
-            case ast::StorageClass::kWorkgroup: {
+            case ast::AddressSpace::kWorkgroup: {
                 if (ContainsMatrix(var->Type())) {
                     // Due to a bug in the MSL compiler, we use a threadgroup memory argument for
                     // any workgroup allocation that contains a matrix. See crbug.com/tint/938.
@@ -173,7 +173,7 @@
                         ctx.dst->MemberAccessor(ctx.dst->Deref(workgroup_param()), member));
                     auto* local_var = ctx.dst->Let(
                         new_var_symbol,
-                        ctx.dst->ty.pointer(store_type(), ast::StorageClass::kWorkgroup),
+                        ctx.dst->ty.pointer(store_type(), ast::AddressSpace::kWorkgroup),
                         member_ptr);
                     ctx.InsertFront(func->body->statements, ctx.dst->Decl(local_var));
                     is_pointer = true;
@@ -182,11 +182,11 @@
                 }
                 [[fallthrough]];
             }
-            case ast::StorageClass::kPrivate: {
-                // Variables in the Private and Workgroup storage classes are redeclared at function
-                // scope. Disable storage class validation on this variable.
+            case ast::AddressSpace::kPrivate: {
+                // Variables in the Private and Workgroup address spacees are redeclared at function
+                // scope. Disable address space validation on this variable.
                 auto* disable_validation =
-                    ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass);
+                    ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace);
                 auto* constructor = ctx.Clone(var->Declaration()->constructor);
                 auto* local_var = ctx.dst->Var(new_var_symbol, store_type(), sc, constructor,
                                                utils::Vector{disable_validation});
@@ -194,15 +194,15 @@
 
                 break;
             }
-            case ast::StorageClass::kPushConstant: {
+            case ast::AddressSpace::kPushConstant: {
                 ctx.dst->Diagnostics().add_error(
                     diag::System::Transform,
-                    "unhandled module-scope storage class (" + utils::ToString(sc) + ")");
+                    "unhandled module-scope address space (" + utils::ToString(sc) + ")");
                 break;
             }
             default: {
                 TINT_ICE(Transform, ctx.dst->Diagnostics())
-                    << "unhandled module-scope storage class (" << sc << ")";
+                    << "unhandled module-scope address space (" << sc << ")";
                 break;
             }
         }
@@ -221,23 +221,23 @@
         auto* var_ast = var->Declaration()->As<ast::Var>();
         auto* ty = var->Type()->UnwrapRef();
         auto* param_type = CreateASTTypeFor(ctx, ty);
-        auto sc = var->StorageClass();
+        auto sc = var->AddressSpace();
         switch (sc) {
-            case ast::StorageClass::kPrivate:
-            case ast::StorageClass::kStorage:
-            case ast::StorageClass::kUniform:
-            case ast::StorageClass::kHandle:
-            case ast::StorageClass::kWorkgroup:
+            case ast::AddressSpace::kPrivate:
+            case ast::AddressSpace::kStorage:
+            case ast::AddressSpace::kUniform:
+            case ast::AddressSpace::kHandle:
+            case ast::AddressSpace::kWorkgroup:
                 break;
-            case ast::StorageClass::kPushConstant: {
+            case ast::AddressSpace::kPushConstant: {
                 ctx.dst->Diagnostics().add_error(
                     diag::System::Transform,
-                    "unhandled module-scope storage class (" + utils::ToString(sc) + ")");
+                    "unhandled module-scope address space (" + utils::ToString(sc) + ")");
                 break;
             }
             default: {
                 TINT_ICE(Transform, ctx.dst->Diagnostics())
-                    << "unhandled module-scope storage class (" << sc << ")";
+                    << "unhandled module-scope address space (" << sc << ")";
             }
         }
 
@@ -247,8 +247,8 @@
             param_type = ctx.dst->ty.pointer(param_type, sc, var_ast->declared_access);
             is_pointer = true;
 
-            // Disable validation of the parameter's storage class and of arguments passed to it.
-            attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass));
+            // Disable validation of the parameter's address space and of arguments passed to it.
+            attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace));
             attributes.Push(
                 ctx.dst->Disable(ast::DisabledValidation::kIgnoreInvalidPointerArgument));
         }
@@ -311,7 +311,7 @@
 
             bool needs_processing = false;
             for (auto* var : func_sem->TransitivelyReferencedGlobals()) {
-                if (var->StorageClass() != ast::StorageClass::kNone) {
+                if (var->AddressSpace() != ast::AddressSpace::kNone) {
                     needs_processing = true;
                     break;
                 }
@@ -367,7 +367,7 @@
 
             // Process and redeclare all variables referenced by the function.
             for (auto* var : func_sem->TransitivelyReferencedGlobals()) {
-                if (var->StorageClass() == ast::StorageClass::kNone) {
+                if (var->AddressSpace() == ast::AddressSpace::kNone) {
                     continue;
                 }
                 if (local_private_vars_.count(var)) {
@@ -385,7 +385,7 @@
 
                 // Check if this is a private variable that is only referenced by this function.
                 bool local_private = false;
-                if (var->StorageClass() == ast::StorageClass::kPrivate) {
+                if (var->AddressSpace() == ast::AddressSpace::kPrivate) {
                     local_private = true;
                     for (auto* user : var->Users()) {
                         auto* stmt = user->Stmt();
@@ -399,11 +399,11 @@
                 if (local_private) {
                     // Redeclare the variable at function scope.
                     auto* disable_validation =
-                        ctx.dst->Disable(ast::DisabledValidation::kIgnoreStorageClass);
+                        ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace);
                     auto* constructor = ctx.Clone(var->Declaration()->constructor);
                     auto* local_var = ctx.dst->Var(new_var_symbol,
                                                    CreateASTTypeFor(ctx, var->Type()->UnwrapRef()),
-                                                   ast::StorageClass::kPrivate, constructor,
+                                                   ast::AddressSpace::kPrivate, constructor,
                                                    utils::Vector{disable_validation});
                     ctx.InsertFront(func_ast->body->statements, ctx.dst->Decl(local_var));
                     local_private_vars_.insert(var);
@@ -431,7 +431,7 @@
                 auto* str =
                     ctx.dst->Structure(ctx.dst->Sym(), std::move(workgroup_parameter_members));
                 auto* param_type =
-                    ctx.dst->ty.pointer(ctx.dst->ty.Of(str), ast::StorageClass::kWorkgroup);
+                    ctx.dst->ty.pointer(ctx.dst->ty.Of(str), ast::AddressSpace::kWorkgroup);
                 auto* disable_validation =
                     ctx.dst->Disable(ast::DisabledValidation::kEntryPointParameter);
                 auto* param = ctx.dst->Param(workgroup_param(), param_type,
@@ -447,8 +447,8 @@
                 // Add new arguments for any variables that are needed by the callee.
                 // For entry points, pass non-handle types as pointers.
                 for (auto* target_var : target_sem->TransitivelyReferencedGlobals()) {
-                    auto sc = target_var->StorageClass();
-                    if (sc == ast::StorageClass::kNone) {
+                    auto sc = target_var->AddressSpace();
+                    if (sc == ast::AddressSpace::kNone) {
                         continue;
                     }
 
@@ -476,10 +476,10 @@
             }
         }
 
-        // Now remove all module-scope variables with these storage classes.
+        // Now remove all module-scope variables with these address spacees.
         for (auto* var_ast : ctx.src->AST().GlobalVariables()) {
             auto* var_sem = ctx.src->Sem().Get(var_ast);
-            if (var_sem->StorageClass() != ast::StorageClass::kNone) {
+            if (var_sem->AddressSpace() != ast::AddressSpace::kNone) {
                 ctx.Remove(ctx.src->AST().GlobalDeclarations(), var_ast);
             }
         }
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.h b/src/tint/transform/module_scope_var_to_entry_point_param.h
index 40e6b7d..75bdaf3 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param.h
+++ b/src/tint/transform/module_scope_var_to_entry_point_param.h
@@ -27,7 +27,7 @@
 /// then passes them as pointer parameters to any function that references them.
 ///
 /// Since WGSL does not allow entry point parameters or function-scope variables
-/// to have these storage classes, we annotate the new variable declarations
+/// to have these address spaces, we annotate the new variable declarations
 /// with an attribute that bypasses that validation rule.
 ///
 /// Before:
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param_test.cc b/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
index dcf8912..34058a7 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param_test.cc
@@ -51,8 +51,8 @@
     auto* expect = R"(
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol : f32;
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_1 : f32;
+  @internal(disable_validation__ignore_address_space) var<workgroup> tint_symbol : f32;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol_1 : f32;
   tint_symbol = tint_symbol_1;
 }
 )";
@@ -76,8 +76,8 @@
     auto* expect = R"(
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol : f32;
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_1 : f32;
+  @internal(disable_validation__ignore_address_space) var<workgroup> tint_symbol : f32;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol_1 : f32;
   tint_symbol = tint_symbol_1;
 }
 )";
@@ -121,17 +121,17 @@
 fn no_uses() {
 }
 
-fn zoo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<private, f32>) {
+fn zoo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<private, f32>) {
   *(tint_symbol) = (*(tint_symbol) * 2.0);
 }
 
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<workgroup, f32>) {
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<private, f32>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<workgroup, f32>) {
   *(tint_symbol_1) = a;
   *(tint_symbol_2) = b;
   zoo(tint_symbol_1);
 }
 
-fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_4 : ptr<workgroup, f32>) {
+fn foo(a : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<private, f32>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_4 : ptr<workgroup, f32>) {
   let b : f32 = 2.0;
   bar(a, b, tint_symbol_3, tint_symbol_4);
   no_uses();
@@ -139,8 +139,8 @@
 
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_5 : f32;
-  @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_6 : f32;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol_5 : f32;
+  @internal(disable_validation__ignore_address_space) var<workgroup> tint_symbol_6 : f32;
   foo(1.0, &(tint_symbol_5), &(tint_symbol_6));
 }
 )";
@@ -183,12 +183,12 @@
     auto* expect = R"(
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_5 : f32;
-  @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_6 : f32;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol_5 : f32;
+  @internal(disable_validation__ignore_address_space) var<workgroup> tint_symbol_6 : f32;
   foo(1.0, &(tint_symbol_5), &(tint_symbol_6));
 }
 
-fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_4 : ptr<workgroup, f32>) {
+fn foo(a : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<private, f32>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_4 : ptr<workgroup, f32>) {
   let b : f32 = 2.0;
   bar(a, b, tint_symbol_3, tint_symbol_4);
   no_uses();
@@ -197,13 +197,13 @@
 fn no_uses() {
 }
 
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<private, f32>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<workgroup, f32>) {
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<private, f32>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<workgroup, f32>) {
   *(tint_symbol_1) = a;
   *(tint_symbol_2) = b;
   zoo(tint_symbol_1);
 }
 
-fn zoo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<private, f32>) {
+fn zoo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<private, f32>) {
   *(tint_symbol) = (*(tint_symbol) * 2.0);
 }
 )";
@@ -227,8 +227,8 @@
     auto* expect = R"(
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32 = 1.0;
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_1 : f32 = f32();
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol : f32 = 1.0;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol_1 : f32 = f32();
   let x : f32 = (tint_symbol + tint_symbol_1);
 }
 )";
@@ -252,8 +252,8 @@
     auto* expect = R"(
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32 = 1.0;
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol_1 : f32 = f32();
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol : f32 = 1.0;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol_1 : f32 = f32();
   let x : f32 = (tint_symbol + tint_symbol_1);
 }
 )";
@@ -280,8 +280,8 @@
     auto* expect = R"(
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32;
-  @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_1 : f32;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol : f32;
+  @internal(disable_validation__ignore_address_space) var<workgroup> tint_symbol_1 : f32;
   let p_ptr : ptr<private, f32> = &(tint_symbol);
   let w_ptr : ptr<workgroup, f32> = &(tint_symbol_1);
   let x : f32 = (*(p_ptr) + *(w_ptr));
@@ -311,8 +311,8 @@
     auto* expect = R"(
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32;
-  @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_1 : f32;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol : f32;
+  @internal(disable_validation__ignore_address_space) var<workgroup> tint_symbol_1 : f32;
   let p_ptr : ptr<private, f32> = &(tint_symbol);
   let w_ptr : ptr<workgroup, f32> = &(tint_symbol_1);
   let x : f32 = (*(p_ptr) + *(w_ptr));
@@ -348,13 +348,13 @@
   *(p) = 0.0;
 }
 
-fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<workgroup, f32>) {
+fn foo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<workgroup, f32>) {
   bar(tint_symbol);
 }
 
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_1 : f32;
+  @internal(disable_validation__ignore_address_space) var<workgroup> tint_symbol_1 : f32;
   foo(&(tint_symbol_1));
 }
 )";
@@ -385,11 +385,11 @@
     auto* expect = R"(
 @compute @workgroup_size(1)
 fn main() {
-  @internal(disable_validation__ignore_storage_class) var<workgroup> tint_symbol_1 : f32;
+  @internal(disable_validation__ignore_address_space) var<workgroup> tint_symbol_1 : f32;
   foo(&(tint_symbol_1));
 }
 
-fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<workgroup, f32>) {
+fn foo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<workgroup, f32>) {
   bar(tint_symbol);
 }
 
@@ -427,7 +427,7 @@
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_1 : ptr<storage, S>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, S>) {
   _ = *(tint_symbol);
   _ = *(tint_symbol_1);
 }
@@ -457,7 +457,7 @@
 
     auto* expect = R"(
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_1 : ptr<storage, S>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, S>) {
   _ = *(tint_symbol);
   _ = *(tint_symbol_1);
 }
@@ -489,7 +489,7 @@
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
   _ = (*(tint_symbol)).arr[0];
 }
 )";
@@ -516,7 +516,7 @@
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
   _ = (*(tint_symbol)).arr[0];
 }
 )";
@@ -546,12 +546,12 @@
   arr : array<f32>,
 }
 
-fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>>) {
+fn foo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>>) {
   _ = (*(tint_symbol))[0];
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_1 : ptr<storage, tint_symbol_2>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, tint_symbol_2>) {
   foo(&((*(tint_symbol_1)).arr));
 }
 )";
@@ -581,11 +581,11 @@
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_1 : ptr<storage, tint_symbol_2>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_1 : ptr<storage, tint_symbol_2>) {
   foo(&((*(tint_symbol_1)).arr));
 }
 
-fn foo(@internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>>) {
+fn foo(@internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<storage, array<f32>>) {
   _ = (*(tint_symbol))[0];
 }
 )";
@@ -616,7 +616,7 @@
 type myarray = array<f32>;
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
   _ = (*(tint_symbol)).arr[0];
 }
 )";
@@ -644,7 +644,7 @@
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
   _ = (*(tint_symbol)).arr[0];
 }
 
@@ -681,7 +681,7 @@
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
   _ = (*(tint_symbol)).arr[0];
 }
 )";
@@ -715,7 +715,7 @@
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol : ptr<storage, tint_symbol_1>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol : ptr<storage, tint_symbol_1>) {
   _ = (*(tint_symbol)).arr[0];
 }
 )";
@@ -765,12 +765,12 @@
 fn no_uses() {
 }
 
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S>) {
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S>) {
   _ = *(tint_symbol);
   _ = *(tint_symbol_1);
 }
 
-fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S>) {
+fn foo(a : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S>) {
   let b : f32 = 2.0;
   _ = *(tint_symbol_2);
   bar(a, b, tint_symbol_2, tint_symbol_3);
@@ -778,7 +778,7 @@
 }
 
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_5 : ptr<storage, S>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_5 : ptr<storage, S>) {
   foo(1.0, tint_symbol_4, tint_symbol_5);
 }
 )";
@@ -822,11 +822,11 @@
 
     auto* expect = R"(
 @compute @workgroup_size(1)
-fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_storage_class) tint_symbol_5 : ptr<storage, S>) {
+fn main(@group(0) @binding(0) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_4 : ptr<uniform, S>, @group(0) @binding(1) @internal(disable_validation__entry_point_parameter) @internal(disable_validation__ignore_address_space) tint_symbol_5 : ptr<storage, S>) {
   foo(1.0, tint_symbol_4, tint_symbol_5);
 }
 
-fn foo(a : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S>) {
+fn foo(a : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_2 : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_3 : ptr<storage, S>) {
   let b : f32 = 2.0;
   _ = *(tint_symbol_2);
   bar(a, b, tint_symbol_2, tint_symbol_3);
@@ -836,7 +836,7 @@
 fn no_uses() {
 }
 
-fn bar(a : f32, b : f32, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_storage_class) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S>) {
+fn bar(a : f32, b : f32, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol : ptr<uniform, S>, @internal(disable_validation__ignore_address_space) @internal(disable_validation__ignore_invalid_pointer_argument) tint_symbol_1 : ptr<storage, S>) {
   _ = *(tint_symbol);
   _ = *(tint_symbol_1);
 }
@@ -1192,7 +1192,7 @@
 
     auto* expect = R"(
 fn foo(a : f32) -> f32 {
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol : f32;
   let x = tint_symbol;
   tint_symbol = (x * a);
   return tint_symbol;
@@ -1235,7 +1235,7 @@
 }
 
 fn foo(a : f32) -> f32 {
-  @internal(disable_validation__ignore_storage_class) var<private> tint_symbol : f32;
+  @internal(disable_validation__ignore_address_space) var<private> tint_symbol : f32;
   let x = tint_symbol;
   tint_symbol = (x * a);
   return tint_symbol;
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index d75e7a2..83ca3bd 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -133,7 +133,7 @@
                         b.Group(AInt(bps.plane_1.group)), b.Binding(AInt(bps.plane_1.binding)));
             syms.params = b.Symbols().New("ext_tex_params");
             b.GlobalVar(syms.params, b.ty.type_name("ExternalTextureParams"),
-                        ast::StorageClass::kUniform, b.Group(AInt(bps.params.group)),
+                        ast::AddressSpace::kUniform, b.Group(AInt(bps.params.group)),
                         b.Binding(AInt(bps.params.binding)));
 
             // Replace the original texture_external binding with a texture_2d<f32> binding.
diff --git a/src/tint/transform/num_workgroups_from_uniform.cc b/src/tint/transform/num_workgroups_from_uniform.cc
index b96a2ee..2122f07 100644
--- a/src/tint/transform/num_workgroups_from_uniform.cc
+++ b/src/tint/transform/num_workgroups_from_uniform.cc
@@ -149,7 +149,7 @@
             }
 
             num_workgroups_ubo = ctx.dst->GlobalVar(
-                ctx.dst->Sym(), ctx.dst->ty.Of(num_workgroups_struct), ast::StorageClass::kUniform,
+                ctx.dst->Sym(), ctx.dst->ty.Of(num_workgroups_struct), ast::AddressSpace::kUniform,
                 ctx.dst->Group(AInt(group)), ctx.dst->Binding(AInt(binding)));
         }
         return num_workgroups_ubo;
diff --git a/src/tint/transform/pad_structs.cc b/src/tint/transform/pad_structs.cc
index 0c5da5c..34aee11 100644
--- a/src/tint/transform/pad_structs.cc
+++ b/src/tint/transform/pad_structs.cc
@@ -78,7 +78,7 @@
             new_members.Push(ctx.dst->Member(name, type));
 
             uint32_t size = ty->Size();
-            if (ty->Is<sem::Struct>() && str->UsedAs(ast::StorageClass::kUniform)) {
+            if (ty->Is<sem::Struct>() && str->UsedAs(ast::AddressSpace::kUniform)) {
                 // std140 structs should be padded out to 16 bytes.
                 size = utils::RoundUp(16u, size);
             } else if (auto* array_ty = ty->As<sem::Array>()) {
@@ -91,7 +91,7 @@
 
         // Add any required padding after the last member, if it's not a runtime-sized array.
         uint32_t struct_size = str->Size();
-        if (str->UsedAs(ast::StorageClass::kUniform)) {
+        if (str->UsedAs(ast::AddressSpace::kUniform)) {
             struct_size = utils::RoundUp(16u, struct_size);
         }
         if (offset < struct_size && !has_runtime_sized_array) {
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index b9b6c5e..bac4344 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -38,8 +38,8 @@
     /// The clone context
     CloneContext& ctx;
 
-    /// Set of storage classes to not apply the transform to
-    std::unordered_set<ast::StorageClass> omitted_classes;
+    /// Set of address spacees to not apply the transform to
+    std::unordered_set<ast::AddressSpace> omitted_classes;
 
     /// Applies the transformation state to `ctx`.
     void Transform() {
@@ -57,7 +57,7 @@
         auto* ret_type = sem->Type();
 
         auto* ref = ret_type->As<sem::Reference>();
-        if (ref && omitted_classes.count(ref->StorageClass()) != 0) {
+        if (ref && omitted_classes.count(ref->AddressSpace()) != 0) {
             return nullptr;
         }
 
@@ -229,14 +229,14 @@
         cfg = *cfg_data;
     }
 
-    std::unordered_set<ast::StorageClass> omitted_classes;
+    std::unordered_set<ast::AddressSpace> omitted_classes;
     for (auto sc : cfg.omitted_classes) {
         switch (sc) {
-            case StorageClass::kUniform:
-                omitted_classes.insert(ast::StorageClass::kUniform);
+            case AddressSpace::kUniform:
+                omitted_classes.insert(ast::AddressSpace::kUniform);
                 break;
-            case StorageClass::kStorage:
-                omitted_classes.insert(ast::StorageClass::kStorage);
+            case AddressSpace::kStorage:
+                omitted_classes.insert(ast::AddressSpace::kStorage);
                 break;
         }
     }
diff --git a/src/tint/transform/robustness.h b/src/tint/transform/robustness.h
index 549b666..21a7ff9 100644
--- a/src/tint/transform/robustness.h
+++ b/src/tint/transform/robustness.h
@@ -33,8 +33,8 @@
 /// (array length - 1).
 class Robustness final : public Castable<Robustness, Transform> {
   public:
-    /// Storage class to be skipped in the transform
-    enum class StorageClass {
+    /// Address space to be skipped in the transform
+    enum class AddressSpace {
         kUniform,
         kStorage,
     };
@@ -54,9 +54,9 @@
         /// @returns this Config
         Config& operator=(const Config&);
 
-        /// Storage classes to omit from apply the transform to.
+        /// Address spacees to omit from apply the transform to.
         /// This allows for optimizing on hardware that provide safe accesses.
-        std::unordered_set<StorageClass> omitted_classes;
+        std::unordered_set<AddressSpace> omitted_classes;
     };
 
     /// Constructor
diff --git a/src/tint/transform/robustness_test.cc b/src/tint/transform/robustness_test.cc
index 4cd4604..dd02d99 100644
--- a/src/tint/transform/robustness_test.cc
+++ b/src/tint/transform/robustness_test.cc
@@ -1203,7 +1203,7 @@
 )";
 
     Robustness::Config cfg;
-    cfg.omitted_classes.insert(Robustness::StorageClass::kStorage);
+    cfg.omitted_classes.insert(Robustness::AddressSpace::kStorage);
 
     DataMap data;
     data.Add<Robustness::Config>(cfg);
@@ -1254,7 +1254,7 @@
 )";
 
     Robustness::Config cfg;
-    cfg.omitted_classes.insert(Robustness::StorageClass::kUniform);
+    cfg.omitted_classes.insert(Robustness::AddressSpace::kUniform);
 
     DataMap data;
     data.Add<Robustness::Config>(cfg);
@@ -1305,8 +1305,8 @@
 )";
 
     Robustness::Config cfg;
-    cfg.omitted_classes.insert(Robustness::StorageClass::kStorage);
-    cfg.omitted_classes.insert(Robustness::StorageClass::kUniform);
+    cfg.omitted_classes.insert(Robustness::AddressSpace::kStorage);
+    cfg.omitted_classes.insert(Robustness::AddressSpace::kUniform);
 
     DataMap data;
     data.Add<Robustness::Config>(cfg);
diff --git a/src/tint/transform/spirv_atomic.cc b/src/tint/transform/spirv_atomic.cc
index e815633..cafb74c 100644
--- a/src/tint/transform/spirv_atomic.cc
+++ b/src/tint/transform/spirv_atomic.cc
@@ -206,7 +206,7 @@
                 return b.ty.array(AtomicTypeFor(arr->ElemType()), u32(count.value()));
             },
             [&](const sem::Pointer* ptr) {
-                return b.ty.pointer(AtomicTypeFor(ptr->StoreType()), ptr->StorageClass(),
+                return b.ty.pointer(AtomicTypeFor(ptr->StoreType()), ptr->AddressSpace(),
                                     ptr->Access());
             },
             [&](const sem::Reference* ref) { return AtomicTypeFor(ref->StoreType()); },
diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc
index 66857bc..17f5a5b 100644
--- a/src/tint/transform/std140.cc
+++ b/src/tint/transform/std140.cc
@@ -137,7 +137,7 @@
         // Scan structures for members that need forking
         for (auto* ty : program->Types()) {
             if (auto* str = ty->As<sem::Struct>()) {
-                if (str->UsedAs(ast::StorageClass::kUniform)) {
+                if (str->UsedAs(ast::AddressSpace::kUniform)) {
                     for (auto* member : str->Members()) {
                         if (needs_fork(member->Type())) {
                             return true;
@@ -150,7 +150,7 @@
         // Scan uniform variables that have types that need forking
         for (auto* decl : program->AST().GlobalVariables()) {
             auto* global = program->Sem().Get(decl);
-            if (global->StorageClass() == ast::StorageClass::kUniform) {
+            if (global->AddressSpace() == ast::AddressSpace::kUniform) {
                 if (needs_fork(global->Type()->UnwrapRef())) {
                     return true;
                 }
@@ -269,7 +269,7 @@
         for (auto* global : ctx.src->Sem().Module()->DependencyOrderedDeclarations()) {
             // Check to see if this is a structure used by a uniform buffer...
             auto* str = sem.Get<sem::Struct>(global);
-            if (str && str->UsedAs(ast::StorageClass::kUniform)) {
+            if (str && str->UsedAs(ast::AddressSpace::kUniform)) {
                 // Should this uniform buffer be forked for std140 usage?
                 bool fork_std140 = false;
                 utils::Vector<const ast::StructMember*, 8> members;
@@ -339,7 +339,7 @@
     void ReplaceUniformVarTypes() {
         for (auto* global : ctx.src->AST().GlobalVariables()) {
             if (auto* var = global->As<ast::Var>()) {
-                if (var->declared_storage_class == ast::StorageClass::kUniform) {
+                if (var->declared_address_space == ast::AddressSpace::kUniform) {
                     auto* v = sem.Get(var);
                     if (auto* std140_ty = Std140Type(v->Type()->UnwrapRef())) {
                         ctx.Replace(global->type, std140_ty);
diff --git a/src/tint/transform/std140.h b/src/tint/transform/std140.h
index f41b1e3..ec5cad5 100644
--- a/src/tint/transform/std140.h
+++ b/src/tint/transform/std140.h
@@ -19,7 +19,7 @@
 
 namespace tint::transform {
 
-/// Std140 is a transform that forks types used in the uniform storage class that contain
+/// Std140 is a transform that forks types used in the uniform address space that contain
 /// `matNx2<f32>` matrices into `N`x`vec2<f32>` column vectors. Types that transitively use these
 /// forked types are also forked. `var<uniform>` variables will use these forked types, and
 /// expressions loading from these variables will do appropriate conversions to the regular WGSL
diff --git a/src/tint/transform/unshadow.cc b/src/tint/transform/unshadow.cc
index 952a88b..1746441 100644
--- a/src/tint/transform/unshadow.cc
+++ b/src/tint/transform/unshadow.cc
@@ -57,7 +57,7 @@
             return Switch(
                 decl,  //
                 [&](const ast::Var* var) {
-                    return ctx.dst->Var(source, symbol, type, var->declared_storage_class,
+                    return ctx.dst->Var(source, symbol, type, var->declared_address_space,
                                         var->declared_access, constructor, attributes);
                 },
                 [&](const ast::Let*) {
diff --git a/src/tint/transform/unwind_discard_functions.cc b/src/tint/transform/unwind_discard_functions.cc
index f94f549..7d24e7c 100644
--- a/src/tint/transform/unwind_discard_functions.cc
+++ b/src/tint/transform/unwind_discard_functions.cc
@@ -55,7 +55,7 @@
         if (!module_discard_var_name.IsValid()) {
             module_discard_var_name = b.Symbols().New("tint_discard");
             ctx.dst->GlobalVar(module_discard_var_name, b.ty.bool_(), b.Expr(false),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
         }
         return module_discard_var_name;
     }
diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc
index 3c0dce9..2ec12d5 100644
--- a/src/tint/transform/vertex_pulling.cc
+++ b/src/tint/transform/vertex_pulling.cc
@@ -260,7 +260,7 @@
         for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
             // The decorated variable with struct type
             ctx.dst->GlobalVar(GetVertexBufferName(i), ctx.dst->ty.Of(struct_type),
-                               ast::StorageClass::kStorage, ast::Access::kRead,
+                               ast::AddressSpace::kStorage, ast::Access::kRead,
                                ctx.dst->Binding(AInt(i)), ctx.dst->Group(AInt(cfg.pulling_group)));
         }
     }
diff --git a/src/tint/transform/zero_init_workgroup_memory.cc b/src/tint/transform/zero_init_workgroup_memory.cc
index 0d3ed98..47a5b99 100644
--- a/src/tint/transform/zero_init_workgroup_memory.cc
+++ b/src/tint/transform/zero_init_workgroup_memory.cc
@@ -122,7 +122,7 @@
         // workgroup storage variables used by `fn`. This will populate #statements.
         auto* func = sem.Get(fn);
         for (auto* var : func->TransitivelyReferencedGlobals()) {
-            if (var->StorageClass() == ast::StorageClass::kWorkgroup) {
+            if (var->AddressSpace() == ast::AddressSpace::kWorkgroup) {
                 BuildZeroingStatements(var->Type()->UnwrapRef(), [&](uint32_t num_values) {
                     auto var_name = ctx.Clone(var->Declaration()->symbol);
                     return Expression{b.Expr(var_name), num_values, ArrayIndices{}};
@@ -427,7 +427,7 @@
 bool ZeroInitWorkgroupMemory::ShouldRun(const Program* program, const DataMap&) const {
     for (auto* global : program->AST().GlobalVariables()) {
         if (auto* var = global->As<ast::Var>()) {
-            if (var->declared_storage_class == ast::StorageClass::kWorkgroup) {
+            if (var->declared_address_space == ast::AddressSpace::kWorkgroup) {
                 return true;
             }
         }
diff --git a/src/tint/writer/append_vector.cc b/src/tint/writer/append_vector.cc
index 527560e..edf9132 100644
--- a/src/tint/writer/append_vector.cc
+++ b/src/tint/writer/append_vector.cc
@@ -137,7 +137,7 @@
         auto* scalar_cast_target = b->create<sem::TypeConversion>(
             packed_el_sem_ty,
             b->create<sem::Parameter>(nullptr, 0u, scalar_sem->Type()->UnwrapRef(),
-                                      ast::StorageClass::kNone, ast::Access::kUndefined),
+                                      ast::AddressSpace::kNone, ast::Access::kUndefined),
             sem::EvaluationStage::kRuntime);
         auto* scalar_cast_sem = b->create<sem::Call>(
             scalar_cast_ast, scalar_cast_target, sem::EvaluationStage::kRuntime,
@@ -158,7 +158,7 @@
                          [&](const tint::sem::Expression* arg, size_t i) -> const sem::Parameter* {
                              return b->create<sem::Parameter>(
                                  nullptr, static_cast<uint32_t>(i), arg->Type()->UnwrapRef(),
-                                 ast::StorageClass::kNone, ast::Access::kUndefined);
+                                 ast::AddressSpace::kNone, ast::Access::kUndefined);
                          }),
         sem::EvaluationStage::kRuntime);
     auto* constructor_sem =
diff --git a/src/tint/writer/append_vector_test.cc b/src/tint/writer/append_vector_test.cc
index a8608f9..9b78b57 100644
--- a/src/tint/writer/append_vector_test.cc
+++ b/src/tint/writer/append_vector_test.cc
@@ -250,7 +250,7 @@
 
 // AppendVector(vec_12, 3) -> vec3<i32>(vec_12, 3)
 TEST_F(AppendVectorTest, Vec2i32Var_i32) {
-    GlobalVar("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
+    GlobalVar("vec_12", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
     auto* vec_12 = Expr("vec_12");
     auto* scalar_3 = Expr(3_i);
     WrapInFunction(vec_12, scalar_3);
@@ -286,7 +286,7 @@
 
 // AppendVector(1, 2, scalar_3) -> vec3<i32>(1, 2, scalar_3)
 TEST_F(AppendVectorTest, Vec2i32_i32Var) {
-    GlobalVar("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("scalar_3", ty.i32(), ast::AddressSpace::kPrivate);
     auto* scalar_1 = Expr(1_i);
     auto* scalar_2 = Expr(2_i);
     auto* scalar_3 = Expr("scalar_3");
@@ -327,8 +327,8 @@
 
 // AppendVector(vec_12, scalar_3) -> vec3<i32>(vec_12, scalar_3)
 TEST_F(AppendVectorTest, Vec2i32Var_i32Var) {
-    GlobalVar("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
-    GlobalVar("scalar_3", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("vec_12", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("scalar_3", ty.i32(), ast::AddressSpace::kPrivate);
     auto* vec_12 = Expr("vec_12");
     auto* scalar_3 = Expr("scalar_3");
     WrapInFunction(vec_12, scalar_3);
@@ -364,8 +364,8 @@
 
 // AppendVector(vec_12, scalar_3) -> vec3<i32>(vec_12, i32(scalar_3))
 TEST_F(AppendVectorTest, Vec2i32Var_f32Var) {
-    GlobalVar("vec_12", ty.vec2<i32>(), ast::StorageClass::kPrivate);
-    GlobalVar("scalar_3", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("vec_12", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("scalar_3", ty.f32(), ast::AddressSpace::kPrivate);
     auto* vec_12 = Expr("vec_12");
     auto* scalar_3 = Expr("scalar_3");
     WrapInFunction(vec_12, scalar_3);
@@ -405,8 +405,8 @@
 
 // AppendVector(vec_12, scalar_3) -> vec3<bool>(vec_12, scalar_3)
 TEST_F(AppendVectorTest, Vec2boolVar_boolVar) {
-    GlobalVar("vec_12", ty.vec2<bool>(), ast::StorageClass::kPrivate);
-    GlobalVar("scalar_3", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("vec_12", ty.vec2<bool>(), ast::AddressSpace::kPrivate);
+    GlobalVar("scalar_3", ty.bool_(), ast::AddressSpace::kPrivate);
     auto* vec_12 = Expr("vec_12");
     auto* scalar_3 = Expr("scalar_3");
     WrapInFunction(vec_12, scalar_3);
diff --git a/src/tint/writer/flatten_bindings_test.cc b/src/tint/writer/flatten_bindings_test.cc
index 64c775f..48d765f 100644
--- a/src/tint/writer/flatten_bindings_test.cc
+++ b/src/tint/writer/flatten_bindings_test.cc
@@ -38,9 +38,9 @@
 
 TEST_F(FlattenBindingsTest, AlreadyFlat) {
     ProgramBuilder b;
-    b.GlobalVar("a", b.ty.i32(), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(0_a));
-    b.GlobalVar("b", b.ty.i32(), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(1_a));
-    b.GlobalVar("c", b.ty.i32(), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(2_a));
+    b.GlobalVar("a", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("b", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(1_a));
+    b.GlobalVar("c", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(2_a));
 
     Program program(std::move(b));
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
@@ -51,9 +51,9 @@
 
 TEST_F(FlattenBindingsTest, NotFlat_SingleNamespace) {
     ProgramBuilder b;
-    b.GlobalVar("a", b.ty.i32(), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(0_a));
-    b.GlobalVar("b", b.ty.i32(), ast::StorageClass::kUniform, b.Group(1_a), b.Binding(1_a));
-    b.GlobalVar("c", b.ty.i32(), ast::StorageClass::kUniform, b.Group(2_a), b.Binding(2_a));
+    b.GlobalVar("a", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("b", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(1_a), b.Binding(1_a));
+    b.GlobalVar("c", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(2_a), b.Binding(2_a));
     b.WrapInFunction(b.Expr("a"), b.Expr("b"), b.Expr("c"));
 
     Program program(std::move(b));
@@ -84,9 +84,9 @@
     ProgramBuilder b;
 
     const size_t num_buffers = 3;
-    b.GlobalVar("buffer1", b.ty.i32(), ast::StorageClass::kUniform, b.Group(0_a), b.Binding(0_a));
-    b.GlobalVar("buffer2", b.ty.i32(), ast::StorageClass::kStorage, b.Group(1_a), b.Binding(1_a));
-    b.GlobalVar("buffer3", b.ty.i32(), ast::StorageClass::kStorage, ast::Access::kRead,
+    b.GlobalVar("buffer1", b.ty.i32(), ast::AddressSpace::kUniform, b.Group(0_a), b.Binding(0_a));
+    b.GlobalVar("buffer2", b.ty.i32(), ast::AddressSpace::kStorage, b.Group(1_a), b.Binding(1_a));
+    b.GlobalVar("buffer3", b.ty.i32(), ast::AddressSpace::kStorage, ast::Access::kRead,
                 b.Group(2_a), b.Binding(2_a));
 
     const size_t num_samplers = 2;
diff --git a/src/tint/writer/generate_external_texture_bindings_test.cc b/src/tint/writer/generate_external_texture_bindings_test.cc
index 718ab43..4fc1934 100644
--- a/src/tint/writer/generate_external_texture_bindings_test.cc
+++ b/src/tint/writer/generate_external_texture_bindings_test.cc
@@ -23,7 +23,7 @@
 
 using namespace tint::number_suffixes;  // NOLINT
 
-constexpr auto kUniform = ast::StorageClass::kUniform;
+constexpr auto kUniform = ast::AddressSpace::kUniform;
 
 class GenerateExternalTextureBindingsTest : public ::testing::Test {};
 
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index 16513a9..fabbf9a 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -393,7 +393,7 @@
     } else if (src_type->is_unsigned_scalar_or_vector() && dst_type->is_float_scalar_or_vector()) {
         out << "uintBitsToFloat";
     } else {
-        if (!EmitType(out, dst_type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+        if (!EmitType(out, dst_type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
             return false;
         }
     }
@@ -456,12 +456,12 @@
     auto* uint_type = BoolTypeToUint(bool_type);
 
     // Cast result to bool scalar or vector type.
-    if (!EmitType(out, bool_type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, bool_type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
         return false;
     }
     ScopedParen outerCastParen(out);
     // Cast LHS to uint scalar or vector type.
-    if (!EmitType(out, uint_type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, uint_type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
         return false;
     }
     {
@@ -481,7 +481,7 @@
         return false;
     }
     // Cast RHS to uint scalar or vector type.
-    if (!EmitType(out, uint_type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, uint_type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
         return false;
     }
     {
@@ -508,20 +508,20 @@
                                 std::vector<std::string> parameter_names;
                                 {
                                     auto decl = line(&b);
-                                    if (!EmitTypeAndName(decl, ret_ty, ast::StorageClass::kNone,
+                                    if (!EmitTypeAndName(decl, ret_ty, ast::AddressSpace::kNone,
                                                          ast::Access::kUndefined, fn_name)) {
                                         return "";
                                     }
                                     {
                                         ScopedParen sp(decl);
                                         const auto* ty = TypeOf(expr->lhs)->UnwrapRef();
-                                        if (!EmitTypeAndName(decl, ty, ast::StorageClass::kNone,
+                                        if (!EmitTypeAndName(decl, ty, ast::AddressSpace::kNone,
                                                              ast::Access::kUndefined, "lhs")) {
                                             return "";
                                         }
                                         decl << ", ";
                                         ty = TypeOf(expr->rhs)->UnwrapRef();
-                                        if (!EmitTypeAndName(decl, ty, ast::StorageClass::kNone,
+                                        if (!EmitTypeAndName(decl, ty, ast::AddressSpace::kNone,
                                                              ast::Access::kUndefined, "rhs")) {
                                             return "";
                                         }
@@ -839,7 +839,7 @@
 bool GeneratorImpl::EmitTypeConversion(std::ostream& out,
                                        const sem::Call* call,
                                        const sem::TypeConversion* conv) {
-    if (!EmitType(out, conv->Target(), ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, conv->Target(), ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
         return false;
     }
     ScopedParen sp(out);
@@ -862,7 +862,7 @@
         return EmitZeroValue(out, type);
     }
 
-    if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
         return false;
     }
     ScopedParen sp(out);
@@ -934,7 +934,7 @@
 
             {
                 auto pre = line();
-                if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::StorageClass::kNone,
+                if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, result)) {
                     return false;
                 }
@@ -1072,7 +1072,7 @@
 bool GeneratorImpl::EmitCountOneBitsCall(std::ostream& out, const ast::CallExpression* expr) {
     // GLSL's bitCount returns an integer type, so cast it to the appropriate
     // unsigned type.
-    if (!EmitType(out, TypeOf(expr)->UnwrapRef(), ast::StorageClass::kNone, ast::Access::kReadWrite,
+    if (!EmitType(out, TypeOf(expr)->UnwrapRef(), ast::AddressSpace::kNone, ast::Access::kReadWrite,
                   "")) {
         return false;
     }
@@ -1144,7 +1144,7 @@
             std::string v;
             {
                 std::stringstream s;
-                if (!EmitType(s, vec_ty->type(), ast::StorageClass::kNone, ast::Access::kRead,
+                if (!EmitType(s, vec_ty->type(), ast::AddressSpace::kNone, ast::Access::kRead,
                               "")) {
                     return "";
                 }
@@ -1152,16 +1152,16 @@
             }
             {  // (u)int tint_int_dot([i|u]vecN a, [i|u]vecN b) {
                 auto l = line(&b);
-                if (!EmitType(l, vec_ty->type(), ast::StorageClass::kNone, ast::Access::kRead,
+                if (!EmitType(l, vec_ty->type(), ast::AddressSpace::kNone, ast::Access::kRead,
                               "")) {
                     return "";
                 }
                 l << " " << fn_name << "(";
-                if (!EmitType(l, vec_ty, ast::StorageClass::kNone, ast::Access::kRead, "")) {
+                if (!EmitType(l, vec_ty, ast::AddressSpace::kNone, ast::Access::kRead, "")) {
                     return "";
                 }
                 l << " a, ";
-                if (!EmitType(l, vec_ty, ast::StorageClass::kNone, ast::Access::kRead, "")) {
+                if (!EmitType(l, vec_ty, ast::AddressSpace::kNone, ast::Access::kRead, "")) {
                     return "";
                 }
                 l << " b) {";
@@ -1212,7 +1212,7 @@
 
             {
                 auto l = line(b);
-                if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
+                if (!EmitType(l, builtin->ReturnType(), ast::AddressSpace::kNone,
                               ast::Access::kUndefined, "")) {
                     return false;
                 }
@@ -1238,7 +1238,7 @@
 
             {
                 auto l = line(b);
-                if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
+                if (!EmitType(l, builtin->ReturnType(), ast::AddressSpace::kNone,
                               ast::Access::kUndefined, "")) {
                     return false;
                 }
@@ -1802,7 +1802,7 @@
     {
         auto out = line();
         auto name = builder_.Symbols().NameFor(func->symbol);
-        if (!EmitType(out, sem->ReturnType(), ast::StorageClass::kNone, ast::Access::kReadWrite,
+        if (!EmitType(out, sem->ReturnType(), ast::AddressSpace::kNone, ast::Access::kReadWrite,
                       "")) {
             return false;
         }
@@ -1828,13 +1828,13 @@
                 type = ptr->StoreType();
             }
 
-            // Note: WGSL only allows for StorageClass::kNone on parameters, however
+            // Note: WGSL only allows for AddressSpace::kNone on parameters, however
             // the sanitizer transforms generates load / store functions for storage
             // or uniform buffers. These functions have a buffer parameter with
-            // StorageClass::kStorage or StorageClass::kUniform. This is required to
+            // AddressSpace::kStorage or AddressSpace::kUniform. This is required to
             // correctly translate the parameter to a [RW]ByteAddressBuffer for
             // storage buffers and a uint4[N] for uniform buffers.
-            if (!EmitTypeAndName(out, type, v->StorageClass(), v->Access(),
+            if (!EmitTypeAndName(out, type, v->AddressSpace(), v->Access(),
                                  builder_.Symbols().NameFor(v->Declaration()->symbol))) {
                 return false;
             }
@@ -1857,28 +1857,28 @@
         global,  //
         [&](const ast::Var* var) {
             auto* sem = builder_.Sem().Get<sem::GlobalVariable>(global);
-            switch (sem->StorageClass()) {
-                case ast::StorageClass::kUniform:
+            switch (sem->AddressSpace()) {
+                case ast::AddressSpace::kUniform:
                     return EmitUniformVariable(var, sem);
-                case ast::StorageClass::kStorage:
+                case ast::AddressSpace::kStorage:
                     return EmitStorageVariable(var, sem);
-                case ast::StorageClass::kHandle:
+                case ast::AddressSpace::kHandle:
                     return EmitHandleVariable(var, sem);
-                case ast::StorageClass::kPrivate:
+                case ast::AddressSpace::kPrivate:
                     return EmitPrivateVariable(sem);
-                case ast::StorageClass::kWorkgroup:
+                case ast::AddressSpace::kWorkgroup:
                     return EmitWorkgroupVariable(sem);
-                case ast::StorageClass::kIn:
-                case ast::StorageClass::kOut:
+                case ast::AddressSpace::kIn:
+                case ast::AddressSpace::kOut:
                     return EmitIOVariable(sem);
-                case ast::StorageClass::kPushConstant:
+                case ast::AddressSpace::kPushConstant:
                     diagnostics_.add_error(
                         diag::System::Writer,
-                        "unhandled storage class " + utils::ToString(sem->StorageClass()));
+                        "unhandled address space " + utils::ToString(sem->AddressSpace()));
                     return false;
                 default: {
                     TINT_ICE(Writer, diagnostics_)
-                        << "unhandled storage class " << sem->StorageClass();
+                        << "unhandled address space " << sem->AddressSpace();
                     return false;
                 }
             }
@@ -1952,7 +1952,7 @@
     if (auto* storage = type->As<sem::StorageTexture>()) {
         out << "layout(" << convert_texel_format_to_glsl(storage->texel_format()) << ") ";
     }
-    if (!EmitTypeAndName(out, type, sem->StorageClass(), sem->Access(), name)) {
+    if (!EmitTypeAndName(out, type, sem->AddressSpace(), sem->Access(), name)) {
         return false;
     }
 
@@ -1966,7 +1966,7 @@
 
     auto name = builder_.Symbols().NameFor(decl->symbol);
     auto* type = var->Type()->UnwrapRef();
-    if (!EmitTypeAndName(out, type, var->StorageClass(), var->Access(), name)) {
+    if (!EmitTypeAndName(out, type, var->AddressSpace(), var->Access(), name)) {
         return false;
     }
 
@@ -1993,7 +1993,7 @@
 
     auto name = builder_.Symbols().NameFor(decl->symbol);
     auto* type = var->Type()->UnwrapRef();
-    if (!EmitTypeAndName(out, type, var->StorageClass(), var->Access(), name)) {
+    if (!EmitTypeAndName(out, type, var->AddressSpace(), var->Access(), name)) {
         return false;
     }
 
@@ -2026,7 +2026,7 @@
 
     auto name = builder_.Symbols().NameFor(decl->symbol);
     auto* type = var->Type()->UnwrapRef();
-    if (!EmitTypeAndName(out, type, var->StorageClass(), var->Access(), name)) {
+    if (!EmitTypeAndName(out, type, var->AddressSpace(), var->Access(), name)) {
         return false;
     }
 
@@ -2140,7 +2140,7 @@
             }
             first = false;
 
-            if (!EmitTypeAndName(out, type, sem->StorageClass(), sem->Access(),
+            if (!EmitTypeAndName(out, type, sem->AddressSpace(), sem->Access(),
                                  builder_.Symbols().NameFor(var->symbol))) {
                 return false;
             }
@@ -2197,7 +2197,7 @@
             return true;
         },
         [&](const sem::Vector* v) {
-            if (!EmitType(out, v, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, v, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -2218,7 +2218,7 @@
             return true;
         },
         [&](const sem::Matrix* m) {
-            if (!EmitType(out, m, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, m, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -2235,7 +2235,7 @@
             return true;
         },
         [&](const sem::Array* a) {
-            if (!EmitType(out, a, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, a, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -2259,7 +2259,7 @@
             return true;
         },
         [&](const sem::Struct* s) {
-            if (!EmitType(out, s, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, s, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -2324,7 +2324,7 @@
     } else if (type->Is<sem::U32>()) {
         out << "0u";
     } else if (auto* vec = type->As<sem::Vector>()) {
-        if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
             return false;
         }
         ScopedParen sp(out);
@@ -2337,7 +2337,7 @@
             }
         }
     } else if (auto* mat = type->As<sem::Matrix>()) {
-        if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
             return false;
         }
         ScopedParen sp(out);
@@ -2350,7 +2350,7 @@
             }
         }
     } else if (auto* str = type->As<sem::Struct>()) {
-        if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
             return false;
         }
         bool first = true;
@@ -2364,7 +2364,7 @@
             EmitZeroValue(out, member->Type());
         }
     } else if (auto* arr = type->As<sem::Array>()) {
-        if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
             return false;
         }
         ScopedParen sp(out);
@@ -2682,24 +2682,24 @@
 
 bool GeneratorImpl::EmitType(std::ostream& out,
                              const sem::Type* type,
-                             ast::StorageClass storage_class,
+                             ast::AddressSpace address_space,
                              ast::Access access,
                              const std::string& name,
                              bool* name_printed /* = nullptr */) {
     if (name_printed) {
         *name_printed = false;
     }
-    switch (storage_class) {
-        case ast::StorageClass::kIn: {
+    switch (address_space) {
+        case ast::AddressSpace::kIn: {
             out << "in ";
             break;
         }
-        case ast::StorageClass::kOut: {
+        case ast::AddressSpace::kOut: {
             out << "out ";
             break;
         }
-        case ast::StorageClass::kUniform:
-        case ast::StorageClass::kHandle: {
+        case ast::AddressSpace::kUniform:
+        case ast::AddressSpace::kHandle: {
             out << "uniform ";
             break;
         }
@@ -2725,7 +2725,7 @@
 
             base_type = arr->ElemType();
         }
-        if (!EmitType(out, base_type, storage_class, access, "")) {
+        if (!EmitType(out, base_type, address_space, access, "")) {
             return false;
         }
         if (!name.empty()) {
@@ -2842,13 +2842,13 @@
             out << "bvec" << width;
         } else {
             out << "vector<";
-            if (!EmitType(out, vec->type(), storage_class, access, "")) {
+            if (!EmitType(out, vec->type(), address_space, access, "")) {
                 return false;
             }
             out << ", " << width << ">";
         }
     } else if (auto* atomic = type->As<sem::Atomic>()) {
-        if (!EmitType(out, atomic->Type(), storage_class, access, name)) {
+        if (!EmitType(out, atomic->Type(), address_space, access, name)) {
             return false;
         }
     } else if (type->Is<sem::Void>()) {
@@ -2863,11 +2863,11 @@
 
 bool GeneratorImpl::EmitTypeAndName(std::ostream& out,
                                     const sem::Type* type,
-                                    ast::StorageClass storage_class,
+                                    ast::AddressSpace address_space,
                                     ast::Access access,
                                     const std::string& name) {
     bool printed_name = false;
-    if (!EmitType(out, type, storage_class, access, name, &printed_name)) {
+    if (!EmitType(out, type, address_space, access, name, &printed_name)) {
         return false;
     }
     if (!name.empty() && !printed_name) {
@@ -2877,7 +2877,7 @@
 }
 
 bool GeneratorImpl::EmitStructType(TextBuffer* b, const sem::Struct* str) {
-    auto storage_class_uses = str->StorageClassUsage();
+    auto address_space_uses = str->AddressSpaceUsage();
     line(b) << "struct " << StructName(str) << " {";
     EmitStructMembers(b, str);
     line(b) << "};";
@@ -2903,7 +2903,7 @@
 
         auto out = line(b);
 
-        if (!EmitTypeAndName(out, ty, ast::StorageClass::kNone, ast::Access::kReadWrite, name)) {
+        if (!EmitTypeAndName(out, ty, ast::AddressSpace::kNone, ast::Access::kReadWrite, name)) {
             return false;
         }
         out << ";";
@@ -2944,7 +2944,7 @@
     auto* type = sem->Type()->UnwrapRef();
 
     auto out = line();
-    if (!EmitTypeAndName(out, type, sem->StorageClass(), sem->Access(),
+    if (!EmitTypeAndName(out, type, sem->AddressSpace(), sem->Access(),
                          builder_.Symbols().NameFor(var->symbol))) {
         return false;
     }
@@ -2971,7 +2971,7 @@
 
     auto out = line();
     // TODO(senorblanco): handle const
-    if (!EmitTypeAndName(out, type, ast::StorageClass::kNone, ast::Access::kUndefined,
+    if (!EmitTypeAndName(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined,
                          builder_.Symbols().NameFor(let->symbol))) {
         return false;
     }
@@ -2993,7 +2993,7 @@
 
     auto out = line();
     out << "const ";
-    if (!EmitTypeAndName(out, type, ast::StorageClass::kNone, ast::Access::kUndefined,
+    if (!EmitTypeAndName(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined,
                          builder_.Symbols().NameFor(var->symbol))) {
         return false;
     }
@@ -3020,7 +3020,7 @@
         std::vector<std::string> parameter_names;
         {
             auto decl = line(&b);
-            if (!EmitTypeAndName(decl, builtin->ReturnType(), ast::StorageClass::kNone,
+            if (!EmitTypeAndName(decl, builtin->ReturnType(), ast::AddressSpace::kNone,
                                  ast::Access::kUndefined, fn_name)) {
                 return "";
             }
@@ -3036,7 +3036,7 @@
                         decl << "inout ";
                         ty = ptr->StoreType();
                     }
-                    if (!EmitTypeAndName(decl, ty, ast::StorageClass::kNone,
+                    if (!EmitTypeAndName(decl, ty, ast::AddressSpace::kNone,
                                          ast::Access::kUndefined, param_name)) {
                         return "";
                     }
diff --git a/src/tint/writer/glsl/generator_impl.h b/src/tint/writer/glsl/generator_impl.h
index 9d1016a..f91775e 100644
--- a/src/tint/writer/glsl/generator_impl.h
+++ b/src/tint/writer/glsl/generator_impl.h
@@ -293,35 +293,35 @@
     /// @returns true on success
     bool EmitGlobalVariable(const ast::Variable* global);
 
-    /// Handles emitting a global variable with the uniform storage class
+    /// Handles emitting a global variable with the uniform address space
     /// @param var the AST node for the 'var'
     /// @param sem the semantic node for the 'var'
     /// @returns true on success
     bool EmitUniformVariable(const ast::Var* var, const sem::Variable* sem);
 
-    /// Handles emitting a global variable with the storage storage class
+    /// Handles emitting a global variable with the storage address space
     /// @param var the AST node for the 'var'
     /// @param sem the semantic node for the 'var'
     /// @returns true on success
     bool EmitStorageVariable(const ast::Var* var, const sem::Variable* sem);
 
-    /// Handles emitting a global variable with the handle storage class
+    /// Handles emitting a global variable with the handle address space
     /// @param var the AST node for the 'var'
     /// @param sem the semantic node for the 'var'
     /// @returns true on success
     bool EmitHandleVariable(const ast::Var* var, const sem::Variable* sem);
 
-    /// Handles emitting a global variable with the private storage class
+    /// Handles emitting a global variable with the private address space
     /// @param var the global variable
     /// @returns true on success
     bool EmitPrivateVariable(const sem::Variable* var);
 
-    /// Handles emitting a global variable with the workgroup storage class
+    /// Handles emitting a global variable with the workgroup address space
     /// @param var the global variable
     /// @returns true on success
     bool EmitWorkgroupVariable(const sem::Variable* var);
 
-    /// Handles emitting a global variable with the input or output storage class
+    /// Handles emitting a global variable with the input or output address space
     /// @param var the global variable
     /// @returns true on success
     bool EmitIOVariable(const sem::GlobalVariable* var);
@@ -394,7 +394,7 @@
     /// Handles generating type
     /// @param out the output stream
     /// @param type the type to generate
-    /// @param storage_class the storage class of the variable
+    /// @param address_space the address space of the variable
     /// @param access the access control type of the variable
     /// @param name the name of the variable, used for array emission.
     /// @param name_printed (optional) if not nullptr and an array was printed
@@ -402,20 +402,20 @@
     /// @returns true if the type is emitted
     bool EmitType(std::ostream& out,
                   const sem::Type* type,
-                  ast::StorageClass storage_class,
+                  ast::AddressSpace address_space,
                   ast::Access access,
                   const std::string& name,
                   bool* name_printed = nullptr);
     /// Handles generating type and name
     /// @param out the output stream
     /// @param type the type to generate
-    /// @param storage_class the storage class of the variable
+    /// @param address_space the address space of the variable
     /// @param access the access control type of the variable
     /// @param name the name to emit
     /// @returns true if the type is emitted
     bool EmitTypeAndName(std::ostream& out,
                          const sem::Type* type,
-                         ast::StorageClass storage_class,
+                         ast::AddressSpace address_space,
                          ast::Access access,
                          const std::string& name);
     /// Handles generating a structure declaration
diff --git a/src/tint/writer/glsl/generator_impl_array_accessor_test.cc b/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
index bbf90fe..bed3dcf 100644
--- a/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
 using GlslGeneratorImplTest_Expression = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Expression, IndexAccessor) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
     auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
diff --git a/src/tint/writer/glsl/generator_impl_assign_test.cc b/src/tint/writer/glsl/generator_impl_assign_test.cc
index 84b6b30..98eae33 100644
--- a/src/tint/writer/glsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/glsl/generator_impl_assign_test.cc
@@ -20,8 +20,8 @@
 using GlslGeneratorImplTest_Assign = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Assign, Emit_Assign) {
-    GlobalVar("lhs", ty.i32(), ast::StorageClass::kPrivate);
-    GlobalVar("rhs", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("lhs", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.i32(), ast::AddressSpace::kPrivate);
     auto* assign = Assign("lhs", "rhs");
     WrapInFunction(assign);
 
diff --git a/src/tint/writer/glsl/generator_impl_binary_test.cc b/src/tint/writer/glsl/generator_impl_binary_test.cc
index 23e2ece..b5e391c 100644
--- a/src/tint/writer/glsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/glsl/generator_impl_binary_test.cc
@@ -43,8 +43,8 @@
         return;
     }
 
-    GlobalVar("left", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("right", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("left", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -71,8 +71,8 @@
 
     Enable(ast::Extension::kF16);
 
-    GlobalVar("left", ty.f16(), ast::StorageClass::kPrivate);
-    GlobalVar("right", ty.f16(), ast::StorageClass::kPrivate);
+    GlobalVar("left", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", ty.f16(), ast::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -90,8 +90,8 @@
 TEST_P(GlslBinaryTest, Emit_u32) {
     auto params = GetParam();
 
-    GlobalVar("left", ty.u32(), ast::StorageClass::kPrivate);
-    GlobalVar("right", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("left", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", ty.u32(), ast::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -114,8 +114,8 @@
         return;
     }
 
-    GlobalVar("left", ty.i32(), ast::StorageClass::kPrivate);
-    GlobalVar("right", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("left", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -151,7 +151,7 @@
                     BinaryData{"(left % right)", ast::BinaryOp::kModulo}));
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorScalar_f32) {
-    GlobalVar("a", vec3<f32>(1_f, 1_f, 1_f), ast::StorageClass::kPrivate);
+    GlobalVar("a", vec3<f32>(1_f, 1_f, 1_f), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("a");
     auto* rhs = Expr(1_f);
 
@@ -169,7 +169,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorScalar_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", vec3<f16>(1_h, 1_h, 1_h), ast::StorageClass::kPrivate);
+    GlobalVar("a", vec3<f16>(1_h, 1_h, 1_h), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("a");
     auto* rhs = Expr(1_h);
 
@@ -185,7 +185,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarVector_f32) {
-    GlobalVar("a", vec3<f32>(1_f, 1_f, 1_f), ast::StorageClass::kPrivate);
+    GlobalVar("a", vec3<f32>(1_f, 1_f, 1_f), ast::AddressSpace::kPrivate);
     auto* lhs = Expr(1_f);
     auto* rhs = Expr("a");
 
@@ -203,7 +203,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarVector_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", vec3<f16>(1_h, 1_h, 1_h), ast::StorageClass::kPrivate);
+    GlobalVar("a", vec3<f16>(1_h, 1_h, 1_h), ast::AddressSpace::kPrivate);
     auto* lhs = Expr(1_h);
     auto* rhs = Expr("a");
 
@@ -219,7 +219,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = Expr(1_f);
 
@@ -236,7 +236,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = Expr(1_h);
 
@@ -251,7 +251,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr(1_f);
     auto* rhs = Expr("mat");
 
@@ -268,7 +268,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr(1_h);
     auto* rhs = Expr("mat");
 
@@ -283,7 +283,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixVector_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = vec3<f32>(1_f, 1_f, 1_f);
 
@@ -300,7 +300,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixVector_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = vec3<f16>(1_h, 1_h, 1_h);
 
@@ -315,7 +315,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* lhs = vec3<f32>(1_f, 1_f, 1_f);
     auto* rhs = Expr("mat");
 
@@ -332,7 +332,7 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* lhs = vec3<f16>(1_h, 1_h, 1_h);
     auto* rhs = Expr("mat");
 
@@ -347,8 +347,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f32) {
-    GlobalVar("lhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("rhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("lhs", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -363,8 +363,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("lhs", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
-    GlobalVar("rhs", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("lhs", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -377,8 +377,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModF32) {
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -393,8 +393,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModF16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.f16(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.f16(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f16(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -407,8 +407,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModVec3F32) {
-    GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -423,8 +423,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModVec3F16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec3<f16>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -437,8 +437,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModVec3F32ScalarF32) {
-    GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -453,8 +453,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModVec3F16ScalarF16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec3<f16>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.f16(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f16(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -467,8 +467,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModScalarF32Vec3F32) {
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -483,8 +483,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModScalarF16Vec3F16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.f16(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -497,8 +497,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, ModMixedVec3ScalarF32) {
-    GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* expr_vec_mod_vec =
         create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("a"));
@@ -541,8 +541,8 @@
 TEST_F(GlslGeneratorImplTest_Binary, ModMixedVec3ScalarF16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec3<f16>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.f16(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f16(), ast::AddressSpace::kPrivate);
 
     auto* expr_vec_mod_vec =
         create<ast::BinaryExpression>(ast::BinaryOp::kModulo, Expr("a"), Expr("a"));
@@ -584,8 +584,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Logical_And) {
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -604,10 +604,10 @@
 
 TEST_F(GlslGeneratorImplTest_Binary, Logical_Multi) {
     // (a && b) || (c || d)
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(
         ast::BinaryOp::kLogicalOr,
@@ -636,8 +636,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Binary, Logical_Or) {
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -663,9 +663,9 @@
     //   return 3i;
     // }
 
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr =
         If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
@@ -700,9 +700,9 @@
 TEST_F(GlslGeneratorImplTest_Binary, Return_WithLogical) {
     // return (a && b) || c;
 
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = Return(create<ast::BinaryExpression>(
         ast::BinaryOp::kLogicalOr,
@@ -728,10 +728,10 @@
 TEST_F(GlslGeneratorImplTest_Binary, Assign_WithLogical) {
     // a = (b || c) && d;
 
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr =
         Assign(Expr("a"),
@@ -759,9 +759,9 @@
 TEST_F(GlslGeneratorImplTest_Binary, Decl_WithLogical) {
     // var a : bool = (b && c) || d;
 
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* var =
         Var("a", ty.bool_(),
@@ -798,10 +798,10 @@
              Param(Sym(), ty.bool_()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
 
     utils::Vector params{
         create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc
index b8161e2..11b6306 100644
--- a/src/tint/writer/glsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc
@@ -198,19 +198,19 @@
     if (param.type == CallParamType::kF16) {
         Enable(ast::Extension::kF16);
 
-        GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("h2", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::AddressSpace::kPrivate);
     }
 
-    GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
-    GlobalVar("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
-    GlobalVar("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
-    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("f2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("f3", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("u2", ty.vec2<u32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("i2", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b2", ty.vec2<bool>(), ast::AddressSpace::kPrivate);
+    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::AddressSpace::kPrivate);
 
     auto* call = GenerateCall(param.builtin, param.type, this);
     ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -342,8 +342,8 @@
 TEST_F(GlslGeneratorImplTest_Builtin, Builtin_Call) {
     auto* call = Call("dot", "param1", "param2");
 
-    GlobalVar("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     WrapInFunction(CallStmt(call));
 
@@ -380,9 +380,9 @@
 TEST_F(GlslGeneratorImplTest_Builtin, FMA_f32) {
     auto* call = Call("fma", "a", "b", "c");
 
-    GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     WrapInFunction(CallStmt(call));
 
@@ -397,9 +397,9 @@
 TEST_F(GlslGeneratorImplTest_Builtin, FMA_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("a", ty.vec3<f16>(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.vec3<f16>(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("fma", "a", "b", "c");
     WrapInFunction(CallStmt(call));
@@ -986,7 +986,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
     auto* call = Call("pack4x8snorm", "p1");
-    GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1004,7 +1004,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack4x8Unorm) {
     auto* call = Call("pack4x8unorm", "p1");
-    GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1022,7 +1022,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Snorm) {
     auto* call = Call("pack2x16snorm", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1040,7 +1040,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Unorm) {
     auto* call = Call("pack2x16unorm", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1058,7 +1058,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Pack2x16Float) {
     auto* call = Call("pack2x16float", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1076,7 +1076,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack4x8Snorm) {
     auto* call = Call("unpack4x8snorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1094,7 +1094,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack4x8Unorm) {
     auto* call = Call("unpack4x8unorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1112,7 +1112,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Snorm) {
     auto* call = Call("unpack2x16snorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1130,7 +1130,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Unorm) {
     auto* call = Call("unpack2x16unorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1148,7 +1148,7 @@
 
 TEST_F(GlslGeneratorImplTest_Builtin, Unpack2x16Float) {
     auto* call = Call("unpack2x16float", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -1211,7 +1211,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, DotI32) {
-    GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    GlobalVar("v", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(Call("dot", "v", "v")));
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -1237,7 +1237,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_Builtin, DotU32) {
-    GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+    GlobalVar("v", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(Call("dot", "v", "v")));
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/glsl/generator_impl_call_test.cc b/src/tint/writer/glsl/generator_impl_call_test.cc
index d264896..adf66d3 100644
--- a/src/tint/writer/glsl/generator_impl_call_test.cc
+++ b/src/tint/writer/glsl/generator_impl_call_test.cc
@@ -42,8 +42,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.f32(), utils::Vector{Return(1.23_f)});
-    GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     WrapInFunction(call);
@@ -62,8 +62,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = CallStmt(Call("my_func", "param1", "param2"));
     WrapInFunction(call);
diff --git a/src/tint/writer/glsl/generator_impl_function_test.cc b/src/tint/writer/glsl/generator_impl_function_test.cc
index 6afac16..1357985 100644
--- a/src/tint/writer/glsl/generator_impl_function_test.cc
+++ b/src/tint/writer/glsl/generator_impl_function_test.cc
@@ -110,7 +110,7 @@
     // fn f(foo : ptr<function, f32>) -> f32 {
     //   return *foo;
     // }
-    Func("f", utils::Vector{Param("foo", ty.pointer<f32>(ast::StorageClass::kFunction))}, ty.f32(),
+    Func("f", utils::Vector{Param("foo", ty.pointer<f32>(ast::AddressSpace::kFunction))}, ty.f32(),
          utils::Vector{Return(Deref("foo"))});
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -352,7 +352,7 @@
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_Uniform) {
     auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
     auto* ubo =
-        GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform, Binding(0_a), Group(1_a));
+        GlobalVar("ubo", ty.Of(ubo_ty), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     Func("sub_func",
          utils::Vector{
@@ -402,7 +402,7 @@
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStruct) {
     auto* s = Structure("Uniforms", utils::Vector{Member("coord", ty.vec4<f32>())});
 
-    GlobalVar("uniforms", ty.Of(s), ast::StorageClass::kUniform, Binding(0_a), Group(1_a));
+    GlobalVar("uniforms", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
 
@@ -442,7 +442,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -485,7 +485,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -529,7 +529,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(1_a));
 
     Func("frag_main", utils::Empty, ty.void_(),
@@ -570,7 +570,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(1_a));
 
     Func("frag_main", utils::Empty, ty.void_(),
@@ -607,7 +607,7 @@
 
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
     auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kUniform, Binding(0_a), Group(1_a));
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     Func("sub_func", utils::Vector{Param("param", ty.f32())}, ty.f32(),
          utils::Vector{
@@ -652,7 +652,7 @@
 
 TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_StorageBuffer) {
     auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(1_a));
 
     Func("sub_func", utils::Vector{Param("param", ty.f32())}, ty.f32(),
@@ -859,7 +859,7 @@
 
     auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
 
-    GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(0_a));
 
     {
diff --git a/src/tint/writer/glsl/generator_impl_identifier_test.cc b/src/tint/writer/glsl/generator_impl_identifier_test.cc
index ff9bc88..76835c1 100644
--- a/src/tint/writer/glsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/glsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
 using GlslGeneratorImplTest_Identifier = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Identifier, EmitIdentifierExpression) {
-    GlobalVar("foo", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("foo", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* i = Expr("foo");
     WrapInFunction(i);
diff --git a/src/tint/writer/glsl/generator_impl_if_test.cc b/src/tint/writer/glsl/generator_impl_if_test.cc
index 82dc307..d2368aa 100644
--- a/src/tint/writer/glsl/generator_impl_if_test.cc
+++ b/src/tint/writer/glsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
 using GlslGeneratorImplTest_If = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_If, Emit_If) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* cond = Expr("cond");
     auto* body = Block(Return());
@@ -38,8 +38,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_If, Emit_IfWithElseIf) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
     auto* else_body = Block(Return());
@@ -65,7 +65,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_If, Emit_IfWithElse) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_body = Block(Return());
 
@@ -88,8 +88,8 @@
 }
 
 TEST_F(GlslGeneratorImplTest_If, Emit_IfWithMultiple) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
 
diff --git a/src/tint/writer/glsl/generator_impl_import_test.cc b/src/tint/writer/glsl/generator_impl_import_test.cc
index 9e988f1..d1395bf 100644
--- a/src/tint/writer/glsl/generator_impl_import_test.cc
+++ b/src/tint/writer/glsl/generator_impl_import_test.cc
@@ -256,7 +256,7 @@
                          testing::Values(GlslImportData{"clamp", "clamp"}));
 
 TEST_F(GlslGeneratorImplTest_Import, GlslImportData_Determinant) {
-    GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call("determinant", "var");
     WrapInFunction(expr);
diff --git a/src/tint/writer/glsl/generator_impl_loop_test.cc b/src/tint/writer/glsl/generator_impl_loop_test.cc
index 1271463..64074ef 100644
--- a/src/tint/writer/glsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/glsl/generator_impl_loop_test.cc
@@ -66,8 +66,8 @@
 TEST_F(GlslGeneratorImplTest_Loop, Emit_LoopNestedWithContinuing) {
     Func("a_statement", {}, ty.void_(), {});
 
-    GlobalVar("lhs", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("lhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* body = Block(create<ast::DiscardStatement>());
     auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -112,7 +112,7 @@
     //   }
     // }
 
-    GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))),  //
                        Decl(Var("other", ty.f32())),             //
diff --git a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
index 43c0d82..a7392cd 100644
--- a/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/glsl/generator_impl_member_accessor_test.cc
@@ -91,7 +91,7 @@
 
         auto* s = b.Structure("Data", members);
 
-        b.GlobalVar("data", b.ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+        b.GlobalVar("data", b.ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
                     b.Group(1_a), b.Binding(0_a));
     }
 
@@ -112,7 +112,7 @@
 
 TEST_F(GlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
     auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
-    GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("str", ty.Of(s), ast::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("str", "mem");
     WrapInFunction(Var("expr", ty.f32(), expr));
diff --git a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
index 2d0d1ce..9c425a8 100644
--- a/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_sanitizer_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(GlslSanitizerTest, Call_ArrayLength) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -66,7 +66,7 @@
                                          Member(0, "z", ty.f32()),
                                          Member(4, "a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -105,7 +105,7 @@
 
 TEST_F(GlslSanitizerTest, Call_ArrayLength_ViaLets) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf("b"));
@@ -230,7 +230,7 @@
     // let p : ptr<function, i32> = &v;
     // let x : i32 = *p;
     auto* v = Var("v", ty.i32());
-    auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(v));
+    auto* p = Let("p", ty.pointer<i32>(ast::AddressSpace::kFunction), AddressOf(v));
     auto* x = Var("x", ty.i32(), Deref(p));
 
     Func("main", utils::Empty, ty.void_(),
@@ -271,11 +271,11 @@
     // let vp : ptr<function, vec4<f32>> = &(*mp)[2i];
     // let v : vec4<f32> = *vp;
     auto* a = Var("a", ty.array(ty.mat4x4<f32>(), 4_u));
-    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), ast::StorageClass::kFunction),
+    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), ast::AddressSpace::kFunction),
                    AddressOf(a));
-    auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), ast::StorageClass::kFunction),
+    auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), ast::AddressSpace::kFunction),
                    AddressOf(IndexAccessor(Deref(ap), 3_i)));
-    auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction),
+    auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction),
                    AddressOf(IndexAccessor(Deref(mp), 2_i)));
     auto* v = Var("v", ty.vec4<f32>(), Deref(vp));
 
diff --git a/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc b/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
index 78d5859..59ae98e 100644
--- a/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_storage_buffer_test.cc
@@ -37,7 +37,7 @@
                        ctx->Member("dewey", ctx->ty.f32(), utils::Vector{ctx->MemberAlign(256_i)}),
                        ctx->Member("louie", ctx->ty.f32(), utils::Vector{ctx->MemberAlign(256_i)}),
                    });
-    ctx->GlobalVar("nephews", ctx->ty.Of(nephews), ast::StorageClass::kStorage, ctx->Binding(0_a),
+    ctx->GlobalVar("nephews", ctx->ty.Of(nephews), ast::AddressSpace::kStorage, ctx->Binding(0_a),
                    ctx->Group(0_a));
 }
 
diff --git a/src/tint/writer/glsl/generator_impl_switch_test.cc b/src/tint/writer/glsl/generator_impl_switch_test.cc
index c2db3b5..7a2c750 100644
--- a/src/tint/writer/glsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/glsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
 using GlslGeneratorImplTest_Switch = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Switch, Emit_Switch) {
-    GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* def_body = Block(create<ast::BreakStatement>());
     auto* def = create<ast::CaseStatement>(utils::Empty, def_body);
diff --git a/src/tint/writer/glsl/generator_impl_test.cc b/src/tint/writer/glsl/generator_impl_test.cc
index 919d684..c06b53e 100644
--- a/src/tint/writer/glsl/generator_impl_test.cc
+++ b/src/tint/writer/glsl/generator_impl_test.cc
@@ -60,9 +60,9 @@
     GlobalVar("gl_SampleID", ty.i32(),
               utils::Vector{
                   Builtin(ast::BuiltinValue::kSampleIndex),
-                  Disable(ast::DisabledValidation::kIgnoreStorageClass),
+                  Disable(ast::DisabledValidation::kIgnoreAddressSpace),
               },
-              ast::StorageClass::kIn);
+              ast::AddressSpace::kIn);
     Func("my_func", utils::Empty, ty.i32(),
          utils::Vector{
              Return(Expr("gl_SampleID")),
@@ -85,9 +85,9 @@
     GlobalVar("gl_SampleID", ty.i32(),
               utils::Vector{
                   Builtin(ast::BuiltinValue::kSampleIndex),
-                  Disable(ast::DisabledValidation::kIgnoreStorageClass),
+                  Disable(ast::DisabledValidation::kIgnoreAddressSpace),
               },
-              ast::StorageClass::kIn);
+              ast::AddressSpace::kIn);
     Func("my_func", utils::Empty, ty.i32(),
          utils::Vector{
              Return(Expr("gl_SampleID")),
diff --git a/src/tint/writer/glsl/generator_impl_type_test.cc b/src/tint/writer/glsl/generator_impl_type_test.cc
index c2d9109..f5733db 100644
--- a/src/tint/writer/glsl/generator_impl_type_test.cc
+++ b/src/tint/writer/glsl/generator_impl_type_test.cc
@@ -33,12 +33,12 @@
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_Array) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[4]");
@@ -46,12 +46,12 @@
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
     auto* arr = ty.array(ty.array<bool, 4>(), 5_u);
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[5][4]");
@@ -59,12 +59,12 @@
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
     auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5_u), 6_u);
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[6][5][4]");
@@ -72,12 +72,12 @@
 
 TEST_F(GlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "bool[4]");
@@ -89,7 +89,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, bool_, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, bool_, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "bool");
 }
@@ -100,7 +100,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, f32, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, f32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float");
 }
@@ -113,7 +113,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, f16, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, f16, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float16_t");
 }
@@ -124,7 +124,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, i32, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, i32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "int");
 }
@@ -137,7 +137,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "mat2x3");
 }
@@ -152,7 +152,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "f16mat2x3");
 }
@@ -162,7 +162,7 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -182,13 +182,13 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, sem_s, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, sem_s, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "S");
 }
@@ -198,7 +198,7 @@
                                  Member("double", ty.i32()),
                                  Member("float", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -215,7 +215,7 @@
                                  Member("a", ty.i32(), utils::Vector{MemberOffset(0_a)}),
                                  Member("b", ty.f32(), utils::Vector{MemberOffset(8_a)}),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -236,7 +236,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, u32, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, u32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "uint");
 }
@@ -248,7 +248,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, vec3, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, vec3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "vec3");
 }
@@ -262,7 +262,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, vec3, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, vec3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "f16vec3");
 }
@@ -273,7 +273,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, void_, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, void_, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "void");
 }
@@ -284,7 +284,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_FALSE(gen.EmitType(out, sampler, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_FALSE(gen.EmitType(out, sampler, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
 }
 
@@ -294,7 +294,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_FALSE(gen.EmitType(out, sampler, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_FALSE(gen.EmitType(out, sampler, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
 }
 
@@ -500,7 +500,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, s, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, s, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "highp sampler2DMS");
 }
diff --git a/src/tint/writer/glsl/generator_impl_unary_op_test.cc b/src/tint/writer/glsl/generator_impl_unary_op_test.cc
index 009d173..ac54b4e 100644
--- a/src/tint/writer/glsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/glsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
 using GlslUnaryOpTest = TestHelper;
 
 TEST_F(GlslUnaryOpTest, AddressOf) {
-    GlobalVar("expr", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.f32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
     WrapInFunction(op);
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(GlslUnaryOpTest, Complement) {
-    GlobalVar("expr", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.u32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
     WrapInFunction(op);
 
@@ -44,7 +44,7 @@
 }
 
 TEST_F(GlslUnaryOpTest, Indirection) {
-    GlobalVar("G", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("G", ty.f32(), ast::AddressSpace::kPrivate);
     auto* p = Let("expr", create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
     WrapInFunction(p, op);
@@ -57,7 +57,7 @@
 }
 
 TEST_F(GlslUnaryOpTest, Not) {
-    GlobalVar("expr", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.bool_(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
     WrapInFunction(op);
 
@@ -69,7 +69,7 @@
 }
 
 TEST_F(GlslUnaryOpTest, Negation) {
-    GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
     WrapInFunction(op);
 
diff --git a/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc b/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
index cae4735..35b1407 100644
--- a/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
+++ b/src/tint/writer/glsl/generator_impl_uniform_buffer_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(GlslGeneratorImplTest_UniformBuffer, Simple) {
     auto* simple = Structure("Simple", utils::Vector{Member("member", ty.f32())});
-    GlobalVar("simple", ty.Of(simple), ast::StorageClass::kUniform, Group(0_a), Binding(0_a));
+    GlobalVar("simple", ty.Of(simple), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     GeneratorImpl& gen = Build();
 
@@ -46,7 +46,7 @@
 
 TEST_F(GlslGeneratorImplTest_UniformBuffer, Simple_Desktop) {
     auto* simple = Structure("Simple", utils::Vector{Member("member", ty.f32())});
-    GlobalVar("simple", ty.Of(simple), ast::StorageClass::kUniform, Group(0_a), Binding(0_a));
+    GlobalVar("simple", ty.Of(simple), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
 
diff --git a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
index 27c5e86..650e2b4 100644
--- a/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/glsl/generator_impl_variable_decl_statement_test.cc
@@ -475,7 +475,7 @@
 }
 
 TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
 
     WrapInFunction(Expr("a"));
 
diff --git a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
index 9b39fda..ef40708 100644
--- a/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/glsl/generator_impl_workgroup_var_test.cc
@@ -27,7 +27,7 @@
 using GlslGeneratorImplTest_WorkgroupVar = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_WorkgroupVar, Basic) {
-    GlobalVar("wg", ty.f32(), ast::StorageClass::kWorkgroup);
+    GlobalVar("wg", ty.f32(), ast::AddressSpace::kWorkgroup);
 
     Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
          utils::Vector{
@@ -43,7 +43,7 @@
 TEST_F(GlslGeneratorImplTest_WorkgroupVar, Aliased) {
     auto* alias = Alias("F32", ty.f32());
 
-    GlobalVar("wg", ty.Of(alias), ast::StorageClass::kWorkgroup);
+    GlobalVar("wg", ty.Of(alias), ast::AddressSpace::kWorkgroup);
 
     Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
          utils::Vector{
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 3edb560..34130d0 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -281,10 +281,10 @@
             },
             [&](const ast::Struct* str) {
                 auto* ty = builder_.Sem().Get(str);
-                auto storage_class_uses = ty->StorageClassUsage();
-                if (storage_class_uses.size() !=
-                    (storage_class_uses.count(ast::StorageClass::kStorage) +
-                     storage_class_uses.count(ast::StorageClass::kUniform))) {
+                auto address_space_uses = ty->AddressSpaceUsage();
+                if (address_space_uses.size() !=
+                    (address_space_uses.count(ast::AddressSpace::kStorage) +
+                     address_space_uses.count(ast::AddressSpace::kUniform))) {
                     // The structure is used as something other than a storage buffer or
                     // uniform buffer, so it needs to be emitted.
                     // Storage buffer are read and written to via a ByteAddressBuffer
@@ -325,7 +325,7 @@
         std::string fn;
         {
             std::ostringstream ss;
-            if (!EmitType(ss, vec, tint::ast::StorageClass::kInvalid, ast::Access::kUndefined,
+            if (!EmitType(ss, vec, tint::ast::AddressSpace::kInvalid, ast::Access::kUndefined,
                           "")) {
                 return "";
             }
@@ -334,12 +334,12 @@
         {
             auto out = line(&helpers_);
             out << "void " << fn << "(inout ";
-            if (!EmitTypeAndName(out, vec, ast::StorageClass::kInvalid, ast::Access::kUndefined,
+            if (!EmitTypeAndName(out, vec, ast::AddressSpace::kInvalid, ast::Access::kUndefined,
                                  "vec")) {
                 return "";
             }
             out << ", int idx, ";
-            if (!EmitTypeAndName(out, vec->type(), ast::StorageClass::kInvalid,
+            if (!EmitTypeAndName(out, vec->type(), ast::AddressSpace::kInvalid,
                                  ast::Access::kUndefined, "val")) {
                 return "";
             }
@@ -399,7 +399,7 @@
         std::string fn;
         {
             std::ostringstream ss;
-            if (!EmitType(ss, mat, tint::ast::StorageClass::kInvalid, ast::Access::kUndefined,
+            if (!EmitType(ss, mat, tint::ast::AddressSpace::kInvalid, ast::Access::kUndefined,
                           "")) {
                 return "";
             }
@@ -408,12 +408,12 @@
         {
             auto out = line(&helpers_);
             out << "void " << fn << "(inout ";
-            if (!EmitTypeAndName(out, mat, ast::StorageClass::kInvalid, ast::Access::kUndefined,
+            if (!EmitTypeAndName(out, mat, ast::AddressSpace::kInvalid, ast::Access::kUndefined,
                                  "mat")) {
                 return "";
             }
             out << ", int col, ";
-            if (!EmitTypeAndName(out, mat->ColumnType(), ast::StorageClass::kInvalid,
+            if (!EmitTypeAndName(out, mat->ColumnType(), ast::AddressSpace::kInvalid,
                                  ast::Access::kUndefined, "val")) {
                 return "";
             }
@@ -468,7 +468,7 @@
         std::string fn;
         {
             std::ostringstream ss;
-            if (!EmitType(ss, mat, tint::ast::StorageClass::kInvalid, ast::Access::kUndefined,
+            if (!EmitType(ss, mat, tint::ast::AddressSpace::kInvalid, ast::Access::kUndefined,
                           "")) {
                 return "";
             }
@@ -477,12 +477,12 @@
         {
             auto out = line(&helpers_);
             out << "void " << fn << "(inout ";
-            if (!EmitTypeAndName(out, mat, ast::StorageClass::kInvalid, ast::Access::kUndefined,
+            if (!EmitTypeAndName(out, mat, ast::AddressSpace::kInvalid, ast::Access::kUndefined,
                                  "mat")) {
                 return "";
             }
             out << ", int col, int row, ";
-            if (!EmitTypeAndName(out, mat->type(), ast::StorageClass::kInvalid,
+            if (!EmitTypeAndName(out, mat->type(), ast::AddressSpace::kInvalid,
                                  ast::Access::kUndefined, "val")) {
                 return "";
             }
@@ -587,7 +587,7 @@
     }
 
     out << "as";
-    if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
         return false;
     }
     out << "(";
@@ -658,7 +658,7 @@
         if (auto* vec = ty->As<sem::Vector>()) {
             auto* elem_ty = vec->type();
 
-            if (!EmitType(out, ty, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, ty, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -723,7 +723,7 @@
         std::string ty_name;
         {
             std::ostringstream ss;
-            if (!EmitType(ss, ty, tint::ast::StorageClass::kInvalid, ast::Access::kUndefined, "")) {
+            if (!EmitType(ss, ty, tint::ast::AddressSpace::kInvalid, ast::Access::kUndefined, "")) {
                 return "";
             }
             ty_name = ss.str();
@@ -965,18 +965,18 @@
 
     if (auto* intrinsic = ast::GetAttribute<transform::DecomposeMemoryAccess::Intrinsic>(
             func->Declaration()->attributes)) {
-        switch (intrinsic->storage_class) {
-            case ast::StorageClass::kUniform:
+        switch (intrinsic->address_space) {
+            case ast::AddressSpace::kUniform:
                 return EmitUniformBufferAccess(out, expr, intrinsic);
-            case ast::StorageClass::kStorage:
+            case ast::AddressSpace::kStorage:
                 if (!intrinsic->IsAtomic()) {
                     return EmitStorageBufferAccess(out, expr, intrinsic);
                 }
                 break;
             default:
                 TINT_UNREACHABLE(Writer, diagnostics_)
-                    << "unsupported DecomposeMemoryAccess::Intrinsic storage class:"
-                    << intrinsic->storage_class;
+                    << "unsupported DecomposeMemoryAccess::Intrinsic address space:"
+                    << intrinsic->address_space;
                 return false;
         }
     }
@@ -1081,7 +1081,7 @@
 bool GeneratorImpl::EmitTypeConversion(std::ostream& out,
                                        const sem::Call* call,
                                        const sem::TypeConversion* conv) {
-    if (!EmitType(out, conv->Target(), ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+    if (!EmitType(out, conv->Target(), ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
         return false;
     }
     out << "(";
@@ -1126,7 +1126,7 @@
     if (brackets) {
         out << "{";
     } else {
-        if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+        if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
             return false;
         }
         out << "(";
@@ -1431,12 +1431,12 @@
     auto rmw = [&](const char* hlsl) -> bool {
         {
             auto fn = line(&buf);
-            if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, ast::Access::kUndefined,
+            if (!EmitTypeAndName(fn, result_ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
                                  name)) {
                 return false;
             }
             fn << "(RWByteAddressBuffer buffer, uint offset, ";
-            if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone, ast::Access::kUndefined,
+            if (!EmitTypeAndName(fn, result_ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
                                  "value")) {
                 return false;
             }
@@ -1452,7 +1452,7 @@
 
         {
             auto l = line(&buf);
-            if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone, ast::Access::kUndefined,
+            if (!EmitTypeAndName(l, result_ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
                                  "original_value")) {
                 return false;
             }
@@ -1501,7 +1501,7 @@
             // InterlockedOr using 0 as the OR value
             {
                 auto fn = line(&buf);
-                if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone,
+                if (!EmitTypeAndName(fn, result_ty, ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, name)) {
                     return false;
                 }
@@ -1517,7 +1517,7 @@
 
             {
                 auto l = line(&buf);
-                if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone,
+                if (!EmitTypeAndName(l, result_ty, ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, "value")) {
                     return false;
                 }
@@ -1535,7 +1535,7 @@
             {
                 auto fn = line(&buf);
                 fn << "void " << name << "(RWByteAddressBuffer buffer, uint offset, ";
-                if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone,
+                if (!EmitTypeAndName(fn, value_ty, ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, "value")) {
                     return false;
                 }
@@ -1551,7 +1551,7 @@
 
             {
                 auto l = line(&buf);
-                if (!EmitTypeAndName(l, value_ty, ast::StorageClass::kNone, ast::Access::kUndefined,
+                if (!EmitTypeAndName(l, value_ty, ast::AddressSpace::kNone, ast::Access::kUndefined,
                                      "ignored")) {
                     return false;
                 }
@@ -1566,17 +1566,17 @@
             auto* value_ty = params[2]->Type()->UnwrapRef();
             {
                 auto fn = line(&buf);
-                if (!EmitTypeAndName(fn, result_ty, ast::StorageClass::kNone,
+                if (!EmitTypeAndName(fn, result_ty, ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, name)) {
                     return false;
                 }
                 fn << "(RWByteAddressBuffer buffer, uint offset, ";
-                if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone,
+                if (!EmitTypeAndName(fn, value_ty, ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, "compare")) {
                     return false;
                 }
                 fn << ", ";
-                if (!EmitTypeAndName(fn, value_ty, ast::StorageClass::kNone,
+                if (!EmitTypeAndName(fn, value_ty, ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, "value")) {
                     return false;
                 }
@@ -1592,7 +1592,7 @@
 
             {  // T result = {0};
                 auto l = line(&buf);
-                if (!EmitTypeAndName(l, result_ty, ast::StorageClass::kNone,
+                if (!EmitTypeAndName(l, result_ty, ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, "result")) {
                     return false;
                 }
@@ -1627,7 +1627,7 @@
 
     if (!builtin->ReturnType()->Is<sem::Void>()) {
         auto pre = line();
-        if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::StorageClass::kNone,
+        if (!EmitTypeAndName(pre, builtin->ReturnType(), ast::AddressSpace::kNone,
                              ast::Access::kUndefined, result)) {
             return false;
         }
@@ -1691,7 +1691,7 @@
             {  // T result = 0;
                 auto pre = line();
                 auto* value_ty = builtin->Parameters()[1]->Type()->UnwrapRef();
-                if (!EmitTypeAndName(pre, value_ty, ast::StorageClass::kNone,
+                if (!EmitTypeAndName(pre, value_ty, ast::AddressSpace::kNone,
                                      ast::Access::kUndefined, result)) {
                     return false;
                 }
@@ -1732,7 +1732,7 @@
             {  // T compare_value = <compare_value>;
                 auto pre = line();
                 if (!EmitTypeAndName(pre, TypeOf(compare_value)->UnwrapRef(),
-                                     ast::StorageClass::kNone, ast::Access::kUndefined, compare)) {
+                                     ast::AddressSpace::kNone, ast::Access::kUndefined, compare)) {
                     return false;
                 }
                 pre << " = ";
@@ -1841,7 +1841,7 @@
 
             {
                 auto l = line(b);
-                if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
+                if (!EmitType(l, builtin->ReturnType(), ast::AddressSpace::kNone,
                               ast::Access::kUndefined, "")) {
                     return false;
                 }
@@ -1883,7 +1883,7 @@
             line(b) << member_type << " sig = frexp(" << in << ", exp);";
             {
                 auto l = line(b);
-                if (!EmitType(l, builtin->ReturnType(), ast::StorageClass::kNone,
+                if (!EmitType(l, builtin->ReturnType(), ast::AddressSpace::kNone,
                               ast::Access::kUndefined, "")) {
                     return false;
                 }
@@ -2674,7 +2674,7 @@
     // Emit storage atomic helpers
     if (auto* intrinsic =
             ast::GetAttribute<transform::DecomposeMemoryAccess::Intrinsic>(func->attributes)) {
-        if (intrinsic->storage_class == ast::StorageClass::kStorage && intrinsic->IsAtomic()) {
+        if (intrinsic->address_space == ast::AddressSpace::kStorage && intrinsic->IsAtomic()) {
             if (!EmitStorageAtomicIntrinsic(func, intrinsic)) {
                 return false;
             }
@@ -2696,14 +2696,14 @@
             auto typedef_name = UniqueIdentifier(name + "_ret");
             auto pre = line();
             pre << "typedef ";
-            if (!EmitTypeAndName(pre, sem->ReturnType(), ast::StorageClass::kNone,
+            if (!EmitTypeAndName(pre, sem->ReturnType(), ast::AddressSpace::kNone,
                                  ast::Access::kReadWrite, typedef_name)) {
                 return false;
             }
             pre << ";";
             out << typedef_name;
         } else {
-            if (!EmitType(out, sem->ReturnType(), ast::StorageClass::kNone, ast::Access::kReadWrite,
+            if (!EmitType(out, sem->ReturnType(), ast::AddressSpace::kNone, ast::Access::kReadWrite,
                           "")) {
                 return false;
             }
@@ -2720,19 +2720,19 @@
             first = false;
 
             auto const* type = v->Type();
-            auto storage_class = ast::StorageClass::kNone;
+            auto address_space = ast::AddressSpace::kNone;
             auto access = ast::Access::kUndefined;
 
             if (auto* ptr = type->As<sem::Pointer>()) {
                 type = ptr->StoreType();
-                switch (ptr->StorageClass()) {
-                    case ast::StorageClass::kStorage:
-                    case ast::StorageClass::kUniform:
+                switch (ptr->AddressSpace()) {
+                    case ast::AddressSpace::kStorage:
+                    case ast::AddressSpace::kUniform:
                         // Not allowed by WGSL, but is used by certain transforms (e.g. DMA) to pass
                         // storage buffers and uniform buffers down into transform-generated
                         // functions. In this situation we want to generate the parameter without an
-                        // 'inout', using the storage class and access from the pointer.
-                        storage_class = ptr->StorageClass();
+                        // 'inout', using the address space and access from the pointer.
+                        address_space = ptr->AddressSpace();
                         access = ptr->Access();
                         break;
                     default:
@@ -2741,13 +2741,13 @@
                 }
             }
 
-            // Note: WGSL only allows for StorageClass::kNone on parameters, however
+            // Note: WGSL only allows for AddressSpace::kNone on parameters, however
             // the sanitizer transforms generates load / store functions for storage
             // or uniform buffers. These functions have a buffer parameter with
-            // StorageClass::kStorage or StorageClass::kUniform. This is required to
+            // AddressSpace::kStorage or AddressSpace::kUniform. This is required to
             // correctly translate the parameter to a [RW]ByteAddressBuffer for
             // storage buffers and a uint4[N] for uniform buffers.
-            if (!EmitTypeAndName(out, type, storage_class, access,
+            if (!EmitTypeAndName(out, type, address_space, access,
                                  builder_.Symbols().NameFor(v->Declaration()->symbol))) {
                 return false;
             }
@@ -2794,7 +2794,7 @@
     auto name = builder_.Symbols().NameFor(builder_.Symbols().New("unused"));
     {
         auto out = line();
-        if (!EmitTypeAndName(out, sem->ReturnType(), ast::StorageClass::kNone,
+        if (!EmitTypeAndName(out, sem->ReturnType(), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, name)) {
             return false;
         }
@@ -2810,25 +2810,25 @@
         global,  //
         [&](const ast::Var* var) {
             auto* sem = builder_.Sem().Get(global);
-            switch (sem->StorageClass()) {
-                case ast::StorageClass::kUniform:
+            switch (sem->AddressSpace()) {
+                case ast::AddressSpace::kUniform:
                     return EmitUniformVariable(var, sem);
-                case ast::StorageClass::kStorage:
+                case ast::AddressSpace::kStorage:
                     return EmitStorageVariable(var, sem);
-                case ast::StorageClass::kHandle:
+                case ast::AddressSpace::kHandle:
                     return EmitHandleVariable(var, sem);
-                case ast::StorageClass::kPrivate:
+                case ast::AddressSpace::kPrivate:
                     return EmitPrivateVariable(sem);
-                case ast::StorageClass::kWorkgroup:
+                case ast::AddressSpace::kWorkgroup:
                     return EmitWorkgroupVariable(sem);
-                case ast::StorageClass::kPushConstant:
+                case ast::AddressSpace::kPushConstant:
                     diagnostics_.add_error(
                         diag::System::Writer,
-                        "unhandled storage class " + utils::ToString(sem->StorageClass()));
+                        "unhandled address space " + utils::ToString(sem->AddressSpace()));
                     return false;
                 default: {
                     TINT_ICE(Writer, diagnostics_)
-                        << "unhandled storage class " << sem->StorageClass();
+                        << "unhandled address space " << sem->AddressSpace();
                     return false;
                 }
             }
@@ -2860,7 +2860,7 @@
     {
         ScopedIndent si(this);
         auto out = line();
-        if (!EmitTypeAndName(out, type, ast::StorageClass::kUniform, sem->Access(), name)) {
+        if (!EmitTypeAndName(out, type, ast::AddressSpace::kUniform, sem->Access(), name)) {
             return false;
         }
         out << ";";
@@ -2874,7 +2874,7 @@
 bool GeneratorImpl::EmitStorageVariable(const ast::Var* var, const sem::Variable* sem) {
     auto* type = sem->Type()->UnwrapRef();
     auto out = line();
-    if (!EmitTypeAndName(out, type, ast::StorageClass::kStorage, sem->Access(),
+    if (!EmitTypeAndName(out, type, ast::AddressSpace::kStorage, sem->Access(),
                          builder_.Symbols().NameFor(var->symbol))) {
         return false;
     }
@@ -2893,7 +2893,7 @@
 
     auto name = builder_.Symbols().NameFor(var->symbol);
     auto* type = sem->Type()->UnwrapRef();
-    if (!EmitTypeAndName(out, type, sem->StorageClass(), sem->Access(), name)) {
+    if (!EmitTypeAndName(out, type, sem->AddressSpace(), sem->Access(), name)) {
         return false;
     }
 
@@ -2925,7 +2925,7 @@
 
     auto name = builder_.Symbols().NameFor(decl->symbol);
     auto* type = var->Type()->UnwrapRef();
-    if (!EmitTypeAndName(out, type, var->StorageClass(), var->Access(), name)) {
+    if (!EmitTypeAndName(out, type, var->AddressSpace(), var->Access(), name)) {
         return false;
     }
 
@@ -2952,7 +2952,7 @@
 
     auto name = builder_.Symbols().NameFor(decl->symbol);
     auto* type = var->Type()->UnwrapRef();
-    if (!EmitTypeAndName(out, type, var->StorageClass(), var->Access(), name)) {
+    if (!EmitTypeAndName(out, type, var->AddressSpace(), var->Access(), name)) {
         return false;
     }
 
@@ -3071,7 +3071,7 @@
             }
             first = false;
 
-            if (!EmitTypeAndName(out, type, sem->StorageClass(), sem->Access(),
+            if (!EmitTypeAndName(out, type, sem->AddressSpace(), sem->Access(),
                                  builder_.Symbols().NameFor(var->symbol))) {
                 return false;
             }
@@ -3141,7 +3141,7 @@
                 return true;
             }
 
-            if (!EmitType(out, v, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, v, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -3158,7 +3158,7 @@
             return true;
         },
         [&](const sem::Matrix* m) {
-            if (!EmitType(out, m, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+            if (!EmitType(out, m, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                 return false;
             }
 
@@ -3177,7 +3177,7 @@
         [&](const sem::Array* a) {
             if (constant->AllZero()) {
                 out << "(";
-                if (!EmitType(out, a, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+                if (!EmitType(out, a, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                     return false;
                 }
                 out << ")0";
@@ -3207,7 +3207,7 @@
         [&](const sem::Struct* s) {
             if (constant->AllZero()) {
                 out << "(";
-                if (!EmitType(out, s, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
+                if (!EmitType(out, s, ast::AddressSpace::kNone, ast::Access::kUndefined, "")) {
                     return false;
                 }
                 out << ")0";
@@ -3296,7 +3296,7 @@
             return true;
         },
         [&](const sem::Vector* vec) {
-            if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+            if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
                 return false;
             }
             ScopedParen sp(out);
@@ -3311,7 +3311,7 @@
             return true;
         },
         [&](const sem::Matrix* mat) {
-            if (!EmitType(out, type, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) {
+            if (!EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kReadWrite, "")) {
                 return false;
             }
             ScopedParen sp(out);
@@ -3328,12 +3328,12 @@
         [&](const sem::Struct*) {
             out << "(";
             TINT_DEFER(out << ")" << value);
-            return EmitType(out, type, ast::StorageClass::kNone, ast::Access::kUndefined, "");
+            return EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined, "");
         },
         [&](const sem::Array*) {
             out << "(";
             TINT_DEFER(out << ")" << value);
-            return EmitType(out, type, ast::StorageClass::kNone, ast::Access::kUndefined, "");
+            return EmitType(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined, "");
         },
         [&](Default) {
             diagnostics_.add_error(
@@ -3698,21 +3698,21 @@
 
 bool GeneratorImpl::EmitType(std::ostream& out,
                              const sem::Type* type,
-                             ast::StorageClass storage_class,
+                             ast::AddressSpace address_space,
                              ast::Access access,
                              const std::string& name,
                              bool* name_printed /* = nullptr */) {
     if (name_printed) {
         *name_printed = false;
     }
-    switch (storage_class) {
-        case ast::StorageClass::kStorage:
+    switch (address_space) {
+        case ast::AddressSpace::kStorage:
             if (access != ast::Access::kRead) {
                 out << "RW";
             }
             out << "ByteAddressBuffer";
             return true;
-        case ast::StorageClass::kUniform: {
+        case ast::AddressSpace::kUniform: {
             auto array_length = (type->Size() + 15) / 16;
             out << "uint4 " << name << "[" << array_length << "]";
             if (name_printed) {
@@ -3746,7 +3746,7 @@
                 sizes.push_back(count.value());
                 base_type = arr->ElemType();
             }
-            if (!EmitType(out, base_type, storage_class, access, "")) {
+            if (!EmitType(out, base_type, address_space, access, "")) {
                 return false;
             }
             if (!name.empty()) {
@@ -3780,13 +3780,13 @@
             if (mat->type()->Is<sem::F16>()) {
                 // Use matrix<type, N, M> for f16 matrix
                 out << "matrix<";
-                if (!EmitType(out, mat->type(), storage_class, access, "")) {
+                if (!EmitType(out, mat->type(), address_space, access, "")) {
                     return false;
                 }
                 out << ", " << mat->columns() << ", " << mat->rows() << ">";
                 return true;
             }
-            if (!EmitType(out, mat->type(), storage_class, access, "")) {
+            if (!EmitType(out, mat->type(), address_space, access, "")) {
                 return false;
             }
             // Note: HLSL's matrices are declared as <type>NxM, where N is the
@@ -3903,7 +3903,7 @@
             } else {
                 // For example, use "vector<float16_t, N>" for f16 vector.
                 out << "vector<";
-                if (!EmitType(out, vec->type(), storage_class, access, "")) {
+                if (!EmitType(out, vec->type(), address_space, access, "")) {
                     return false;
                 }
                 out << ", " << width << ">";
@@ -3911,7 +3911,7 @@
             return true;
         },
         [&](const sem::Atomic* atomic) {
-            return EmitType(out, atomic->Type(), storage_class, access, name);
+            return EmitType(out, atomic->Type(), address_space, access, name);
         },
         [&](const sem::Void*) {
             out << "void";
@@ -3925,11 +3925,11 @@
 
 bool GeneratorImpl::EmitTypeAndName(std::ostream& out,
                                     const sem::Type* type,
-                                    ast::StorageClass storage_class,
+                                    ast::AddressSpace address_space,
                                     ast::Access access,
                                     const std::string& name) {
     bool name_printed = false;
-    if (!EmitType(out, type, storage_class, access, name, &name_printed)) {
+    if (!EmitType(out, type, address_space, access, name, &name_printed)) {
         return false;
     }
     if (!name.empty() && !name_printed) {
@@ -4003,7 +4003,7 @@
             }
 
             out << pre;
-            if (!EmitTypeAndName(out, ty, ast::StorageClass::kNone, ast::Access::kReadWrite,
+            if (!EmitTypeAndName(out, ty, ast::AddressSpace::kNone, ast::Access::kReadWrite,
                                  mem_name)) {
                 return false;
             }
@@ -4054,7 +4054,7 @@
     auto* type = sem->Type()->UnwrapRef();
 
     auto out = line();
-    if (!EmitTypeAndName(out, type, sem->StorageClass(), sem->Access(),
+    if (!EmitTypeAndName(out, type, sem->AddressSpace(), sem->Access(),
                          builder_.Symbols().NameFor(var->symbol))) {
         return false;
     }
@@ -4081,7 +4081,7 @@
 
     auto out = line();
     out << "const ";
-    if (!EmitTypeAndName(out, type, ast::StorageClass::kNone, ast::Access::kUndefined,
+    if (!EmitTypeAndName(out, type, ast::AddressSpace::kNone, ast::Access::kUndefined,
                          builder_.Symbols().NameFor(let->symbol))) {
         return false;
     }
@@ -4108,7 +4108,7 @@
         std::vector<std::string> parameter_names;
         {
             auto decl = line(&b);
-            if (!EmitTypeAndName(decl, builtin->ReturnType(), ast::StorageClass::kNone,
+            if (!EmitTypeAndName(decl, builtin->ReturnType(), ast::AddressSpace::kNone,
                                  ast::Access::kUndefined, fn_name)) {
                 return "";
             }
@@ -4124,7 +4124,7 @@
                         decl << "inout ";
                         ty = ptr->StoreType();
                     }
-                    if (!EmitTypeAndName(decl, ty, ast::StorageClass::kNone,
+                    if (!EmitTypeAndName(decl, ty, ast::AddressSpace::kNone,
                                          ast::Access::kUndefined, param_name)) {
                         return "";
                     }
diff --git a/src/tint/writer/hlsl/generator_impl.h b/src/tint/writer/hlsl/generator_impl.h
index abbf818..0f6a668 100644
--- a/src/tint/writer/hlsl/generator_impl.h
+++ b/src/tint/writer/hlsl/generator_impl.h
@@ -303,30 +303,30 @@
     /// @returns true on success
     bool EmitGlobalVariable(const ast::Variable* global);
 
-    /// Handles emitting a global variable with the uniform storage class
+    /// Handles emitting a global variable with the uniform address space
     /// @param var the AST node for the 'var'
     /// @param sem the semantic node for the 'var'
     /// @returns true on success
     bool EmitUniformVariable(const ast::Var* var, const sem::Variable* sem);
 
-    /// Handles emitting a global variable with the storage storage class
+    /// Handles emitting a global variable with the storage address space
     /// @param var the AST node for the 'var'
     /// @param sem the semantic node for the 'var'
     /// @returns true on success
     bool EmitStorageVariable(const ast::Var* var, const sem::Variable* sem);
 
-    /// Handles emitting a global variable with the handle storage class
+    /// Handles emitting a global variable with the handle address space
     /// @param var the AST node for the 'var'
     /// @param sem the semantic node for the 'var'
     /// @returns true on success
     bool EmitHandleVariable(const ast::Var* var, const sem::Variable* sem);
 
-    /// Handles emitting a global variable with the private storage class
+    /// Handles emitting a global variable with the private address space
     /// @param var the global variable
     /// @returns true on success
     bool EmitPrivateVariable(const sem::Variable* var);
 
-    /// Handles emitting a global variable with the workgroup storage class
+    /// Handles emitting a global variable with the workgroup address space
     /// @param var the global variable
     /// @returns true on success
     bool EmitWorkgroupVariable(const sem::Variable* var);
@@ -390,7 +390,7 @@
     /// Handles generating type
     /// @param out the output stream
     /// @param type the type to generate
-    /// @param storage_class the storage class of the variable
+    /// @param address_space the address space of the variable
     /// @param access the access control type of the variable
     /// @param name the name of the variable, used for array emission.
     /// @param name_printed (optional) if not nullptr and an array was printed
@@ -398,20 +398,20 @@
     /// @returns true if the type is emitted
     bool EmitType(std::ostream& out,
                   const sem::Type* type,
-                  ast::StorageClass storage_class,
+                  ast::AddressSpace address_space,
                   ast::Access access,
                   const std::string& name,
                   bool* name_printed = nullptr);
     /// Handles generating type and name
     /// @param out the output stream
     /// @param type the type to generate
-    /// @param storage_class the storage class of the variable
+    /// @param address_space the address space of the variable
     /// @param access the access control type of the variable
     /// @param name the name to emit
     /// @returns true if the type is emitted
     bool EmitTypeAndName(std::ostream& out,
                          const sem::Type* type,
-                         ast::StorageClass storage_class,
+                         ast::AddressSpace address_space,
                          ast::Access access,
                          const std::string& name);
     /// Handles generating a structure declaration
diff --git a/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
index dfa3d67..0da678a 100644
--- a/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
 using HlslGeneratorImplTest_Expression = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Expression, IndexAccessor) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
     auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
diff --git a/src/tint/writer/hlsl/generator_impl_binary_test.cc b/src/tint/writer/hlsl/generator_impl_binary_test.cc
index 8a87697..1163078 100644
--- a/src/tint/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_binary_test.cc
@@ -50,8 +50,8 @@
         return;
     }
 
-    GlobalVar("left", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("right", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("left", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -82,8 +82,8 @@
 
     Enable(ast::Extension::kF16);
 
-    GlobalVar("left", ty.f16(), ast::StorageClass::kPrivate);
-    GlobalVar("right", ty.f16(), ast::StorageClass::kPrivate);
+    GlobalVar("left", ty.f16(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", ty.f16(), ast::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -105,8 +105,8 @@
         return;
     }
 
-    GlobalVar("left", ty.u32(), ast::StorageClass::kPrivate);
-    GlobalVar("right", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("left", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", ty.u32(), ast::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -133,8 +133,8 @@
         return;
     }
 
-    GlobalVar("left", ty.i32(), ast::StorageClass::kPrivate);
-    GlobalVar("right", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("left", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* left = Expr("left");
     auto* right = Expr("right");
@@ -237,7 +237,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = Expr(1_f);
 
@@ -254,7 +254,7 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixScalar_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = Expr(1_h);
 
@@ -269,7 +269,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr(1_f);
     auto* rhs = Expr("mat");
 
@@ -286,7 +286,7 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_ScalarMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr(1_h);
     auto* rhs = Expr("mat");
 
@@ -301,7 +301,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = vec3<f32>(1_f, 1_f, 1_f);
 
@@ -318,7 +318,7 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixVector_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* lhs = Expr("mat");
     auto* rhs = vec3<f16>(1_h, 1_h, 1_h);
 
@@ -333,7 +333,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f32) {
-    GlobalVar("mat", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* lhs = vec3<f32>(1_f, 1_f, 1_f);
     auto* rhs = Expr("mat");
 
@@ -350,7 +350,7 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_VectorMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("mat", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("mat", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* lhs = vec3<f16>(1_h, 1_h, 1_h);
     auto* rhs = Expr("mat");
 
@@ -365,8 +365,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f32) {
-    GlobalVar("lhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("rhs", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("lhs", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -381,8 +381,8 @@
 TEST_F(HlslGeneratorImplTest_Binary, Multiply_MatrixMatrix_f16) {
     Enable(ast::Extension::kF16);
 
-    GlobalVar("lhs", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
-    GlobalVar("rhs", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    GlobalVar("lhs", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("lhs"), Expr("rhs"));
     WrapInFunction(expr);
@@ -395,8 +395,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_And) {
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -415,10 +415,10 @@
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_Multi) {
     // (a && b) || (c || d)
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(
         ast::BinaryOp::kLogicalOr,
@@ -447,8 +447,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Binary, Logical_Or) {
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
     WrapInFunction(expr);
@@ -474,9 +474,9 @@
     //   return 3i;
     // }
 
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr =
         If(create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
@@ -511,9 +511,9 @@
 TEST_F(HlslGeneratorImplTest_Binary, Return_WithLogical) {
     // return (a && b) || c;
 
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr = Return(create<ast::BinaryExpression>(
         ast::BinaryOp::kLogicalOr,
@@ -539,10 +539,10 @@
 TEST_F(HlslGeneratorImplTest_Binary, Assign_WithLogical) {
     // a = (b || c) && d;
 
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* expr =
         Assign(Expr("a"),
@@ -570,12 +570,12 @@
 TEST_F(HlslGeneratorImplTest_Binary, Decl_WithLogical) {
     // var a : bool = (b && c) || d;
 
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* var =
-        Var("a", ty.bool_(), ast::StorageClass::kNone,
+        Var("a", ty.bool_(), ast::AddressSpace::kNone,
             create<ast::BinaryExpression>(
                 ast::BinaryOp::kLogicalOr,
                 create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("b"), Expr("c")),
@@ -609,10 +609,10 @@
              Param(Sym(), ty.bool_()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("d", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("d", ty.bool_(), ast::AddressSpace::kPrivate);
 
     utils::Vector params{
         create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b")),
diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
index 3f9cfa7..3f0792b 100644
--- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc
@@ -198,19 +198,19 @@
     if (param.type == CallParamType::kF16) {
         Enable(ast::Extension::kF16);
 
-        GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("h2", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::AddressSpace::kPrivate);
     }
 
-    GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
-    GlobalVar("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
-    GlobalVar("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
-    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("f2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("f3", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("u2", ty.vec2<u32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("i2", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b2", ty.vec2<bool>(), ast::AddressSpace::kPrivate);
+    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::AddressSpace::kPrivate);
 
     auto* call = GenerateCall(param.builtin, param.type, this);
     ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -342,8 +342,8 @@
 TEST_F(HlslGeneratorImplTest_Builtin, Builtin_Call) {
     auto* call = Call("dot", "param1", "param2");
 
-    GlobalVar("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     WrapInFunction(CallStmt(call));
 
@@ -767,7 +767,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Snorm) {
     auto* call = Call("pack4x8snorm", "p1");
-    GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -789,7 +789,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack4x8Unorm) {
     auto* call = Call("pack4x8unorm", "p1");
-    GlobalVar("p1", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -811,7 +811,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Snorm) {
     auto* call = Call("pack2x16snorm", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -833,7 +833,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Unorm) {
     auto* call = Call("pack2x16unorm", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -855,7 +855,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Pack2x16Float) {
     auto* call = Call("pack2x16float", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -877,7 +877,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack4x8Snorm) {
     auto* call = Call("unpack4x8snorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -900,7 +900,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack4x8Unorm) {
     auto* call = Call("unpack4x8unorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -923,7 +923,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Snorm) {
     auto* call = Call("unpack2x16snorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -946,7 +946,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Unorm) {
     auto* call = Call("unpack2x16unorm", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
@@ -969,7 +969,7 @@
 
 TEST_F(HlslGeneratorImplTest_Builtin, Unpack2x16Float) {
     auto* call = Call("unpack2x16float", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
     GeneratorImpl& gen = Build();
 
diff --git a/src/tint/writer/hlsl/generator_impl_call_test.cc b/src/tint/writer/hlsl/generator_impl_call_test.cc
index 82fb926..33e0762 100644
--- a/src/tint/writer/hlsl/generator_impl_call_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_call_test.cc
@@ -42,8 +42,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.f32(), utils::Vector{Return(1.23_f)});
-    GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     WrapInFunction(call);
@@ -62,8 +62,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = CallStmt(Call("my_func", "param1", "param2"));
     WrapInFunction(call);
diff --git a/src/tint/writer/hlsl/generator_impl_function_test.cc b/src/tint/writer/hlsl/generator_impl_function_test.cc
index 322b560..1adb852 100644
--- a/src/tint/writer/hlsl/generator_impl_function_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_function_test.cc
@@ -101,7 +101,7 @@
     // fn f(foo : ptr<function, f32>) -> f32 {
     //   return *foo;
     // }
-    Func("f", utils::Vector{Param("foo", ty.pointer<f32>(ast::StorageClass::kFunction))}, ty.f32(),
+    Func("f", utils::Vector{Param("foo", ty.pointer<f32>(ast::AddressSpace::kFunction))}, ty.f32(),
          utils::Vector{Return(Deref("foo"))});
 
     GeneratorImpl& gen = SanitizeAndBuild();
@@ -361,7 +361,7 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_Uniform) {
     auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
     auto* ubo =
-        GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform, Binding(0_a), Group(1_a));
+        GlobalVar("ubo", ty.Of(ubo_ty), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     Func("sub_func",
          utils::Vector{
@@ -404,7 +404,7 @@
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStruct) {
     auto* s = Structure("Uniforms", utils::Vector{Member("coord", ty.vec4<f32>())});
 
-    GlobalVar("uniforms", ty.Of(s), ast::StorageClass::kUniform, Binding(0_a), Group(1_a));
+    GlobalVar("uniforms", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
 
@@ -437,7 +437,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -470,7 +470,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(1_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -503,7 +503,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(1_a));
 
     Func("frag_main", utils::Empty, ty.void_(),
@@ -534,7 +534,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(1_a));
 
     Func("frag_main", utils::Empty, ty.void_(),
@@ -561,7 +561,7 @@
 
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
     auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kUniform, Binding(0_a), Group(1_a));
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kUniform, Binding(0_a), Group(1_a));
 
     Func("sub_func",
          utils::Vector{
@@ -603,7 +603,7 @@
 
 TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_StorageBuffer) {
     auto* s = Structure("S", utils::Vector{Member("x", ty.f32())});
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(1_a));
 
     Func("sub_func",
@@ -831,7 +831,7 @@
 
     auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
 
-    GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(0_a));
 
     {
diff --git a/src/tint/writer/hlsl/generator_impl_identifier_test.cc b/src/tint/writer/hlsl/generator_impl_identifier_test.cc
index d4b645f..b6434d8 100644
--- a/src/tint/writer/hlsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
 using HlslGeneratorImplTest_Identifier = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Identifier, EmitIdentifierExpression) {
-    GlobalVar("foo", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("foo", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* i = Expr("foo");
     WrapInFunction(i);
diff --git a/src/tint/writer/hlsl/generator_impl_if_test.cc b/src/tint/writer/hlsl/generator_impl_if_test.cc
index 3195a06..37c9ea9 100644
--- a/src/tint/writer/hlsl/generator_impl_if_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
 using HlslGeneratorImplTest_If = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_If, Emit_If) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* cond = Expr("cond");
     auto* body = Block(Return());
@@ -38,8 +38,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElseIf) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
     auto* else_body = Block(Return());
@@ -65,7 +65,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithElse) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_body = Block(Return());
 
@@ -88,8 +88,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_If, Emit_IfWithMultiple) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
 
diff --git a/src/tint/writer/hlsl/generator_impl_import_test.cc b/src/tint/writer/hlsl/generator_impl_import_test.cc
index d6fdeac..49799a9 100644
--- a/src/tint/writer/hlsl/generator_impl_import_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_import_test.cc
@@ -259,7 +259,7 @@
                          testing::Values(HlslImportData{"clamp", "clamp"}));
 
 TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
-    GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call("determinant", "var");
     WrapInFunction(expr);
diff --git a/src/tint/writer/hlsl/generator_impl_loop_test.cc b/src/tint/writer/hlsl/generator_impl_loop_test.cc
index 6dbae42..92f966c 100644
--- a/src/tint/writer/hlsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_loop_test.cc
@@ -66,8 +66,8 @@
 TEST_F(HlslGeneratorImplTest_Loop, Emit_LoopNestedWithContinuing) {
     Func("a_statement", {}, ty.void_(), {});
 
-    GlobalVar("lhs", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("lhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* body = Block(create<ast::DiscardStatement>());
     auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -112,7 +112,7 @@
     //   }
     // }
 
-    GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))),  //
                        Decl(Var("other", ty.f32())),             //
diff --git a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
index 9ca2d18..1fbef9b 100644
--- a/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -90,7 +90,7 @@
         ProgramBuilder& b = *this;
         auto* s = b.Structure("Data", members);
 
-        b.GlobalVar("data", b.ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+        b.GlobalVar("data", b.ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
                     b.Group(1_a), b.Binding(0_a));
     }
 
@@ -111,7 +111,7 @@
 
 TEST_F(HlslGeneratorImplTest_MemberAccessor, EmitExpression_MemberAccessor) {
     auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
-    GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("str", ty.Of(s), ast::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("str", "mem");
     WrapInFunction(Var("expr", ty.f32(), expr));
diff --git a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
index b9ebd87..dbe8a51 100644
--- a/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_sanitizer_test.cc
@@ -26,7 +26,7 @@
 
 TEST_F(HlslSanitizerTest, Call_ArrayLength) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -60,7 +60,7 @@
                                          Member(0, "z", ty.f32()),
                                          Member(4, "a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -92,7 +92,7 @@
 
 TEST_F(HlslSanitizerTest, Call_ArrayLength_ViaLets) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf("b"));
@@ -129,9 +129,9 @@
 
 TEST_F(HlslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
-    GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(2_a),
+    GlobalVar("c", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(2_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -239,7 +239,7 @@
     // let p : ptr<function, i32> = &v;
     // let x : i32 = *p;
     auto* v = Var("v", ty.i32());
-    auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(v));
+    auto* p = Let("p", ty.pointer<i32>(ast::AddressSpace::kFunction), AddressOf(v));
     auto* x = Var("x", ty.i32(), Deref(p));
 
     Func("main", utils::Empty, ty.void_(),
@@ -273,11 +273,11 @@
     // let vp : ptr<function, vec4<f32>> = &(*mp)[2i];
     // let v : vec4<f32> = *vp;
     auto* a = Var("a", ty.array(ty.mat4x4<f32>(), 4_u));
-    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), ast::StorageClass::kFunction),
+    auto* ap = Let("ap", ty.pointer(ty.array(ty.mat4x4<f32>(), 4_u), ast::AddressSpace::kFunction),
                    AddressOf(a));
-    auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), ast::StorageClass::kFunction),
+    auto* mp = Let("mp", ty.pointer(ty.mat4x4<f32>(), ast::AddressSpace::kFunction),
                    AddressOf(IndexAccessor(Deref(ap), 3_i)));
-    auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction),
+    auto* vp = Let("vp", ty.pointer(ty.vec4<f32>(), ast::AddressSpace::kFunction),
                    AddressOf(IndexAccessor(Deref(mp), 2_i)));
     auto* v = Var("v", ty.vec4<f32>(), Deref(vp));
 
diff --git a/src/tint/writer/hlsl/generator_impl_switch_test.cc b/src/tint/writer/hlsl/generator_impl_switch_test.cc
index 7d89672..24c17a6 100644
--- a/src/tint/writer/hlsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
 using HlslGeneratorImplTest_Switch = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch) {
-    GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
     auto* s = Switch(                     //
         Expr("cond"),                     //
         Case(Expr(5_i), Block(Break())),  //
@@ -46,8 +46,8 @@
 }
 
 TEST_F(HlslGeneratorImplTest_Switch, Emit_Switch_OnlyDefaultCase) {
-    GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
-    GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
+    GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
     auto* s = Switch(  //
         Expr("cond"),  //
         DefaultCase(Block(Assign(Expr("a"), Expr(42_i)))));
diff --git a/src/tint/writer/hlsl/generator_impl_type_test.cc b/src/tint/writer/hlsl/generator_impl_type_test.cc
index 75dac72..7e50180 100644
--- a/src/tint/writer/hlsl/generator_impl_type_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_type_test.cc
@@ -33,12 +33,12 @@
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Array) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[4]");
@@ -46,12 +46,12 @@
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArray) {
     auto* arr = ty.array(ty.array<bool, 4>(), 5_u);
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[5][4]");
@@ -59,12 +59,12 @@
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_ArrayOfArrayOfArray) {
     auto* arr = ty.array(ty.array(ty.array<bool, 4>(), 5_u), 6_u);
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, "ary"))
         << gen.error();
     EXPECT_EQ(out.str(), "bool ary[6][5][4]");
@@ -72,12 +72,12 @@
 
 TEST_F(HlslGeneratorImplTest_Type, EmitType_Array_WithoutName) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::StorageClass::kNone,
+    ASSERT_TRUE(gen.EmitType(out, program->TypeOf(arr), ast::AddressSpace::kNone,
                              ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "bool[4]");
@@ -89,7 +89,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, bool_, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, bool_, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "bool");
 }
@@ -100,7 +100,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, f16, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, f16, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float16_t");
 }
@@ -111,7 +111,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, f32, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, f32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float");
 }
@@ -122,7 +122,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, i32, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, i32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "int");
 }
@@ -135,7 +135,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "matrix<float16_t, 2, 3>");
 }
@@ -148,7 +148,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float2x3");
 }
@@ -158,7 +158,7 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -177,7 +177,7 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -191,13 +191,13 @@
                                  Member("a", ty.i32()),
                                  Member("b", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
     auto* sem_s = program->TypeOf(s)->As<sem::Struct>();
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, sem_s, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, sem_s, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "S");
 }
@@ -207,7 +207,7 @@
                                  Member("double", ty.i32()),
                                  Member("float", ty.f32()),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = SanitizeAndBuild();
 
@@ -224,7 +224,7 @@
                                  Member("a", ty.i32(), utils::Vector{MemberOffset(0_a)}),
                                  Member("b", ty.f32(), utils::Vector{MemberOffset(8_a)}),
                              });
-    GlobalVar("g", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("g", ty.Of(s), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -244,7 +244,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, u32, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, u32, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "uint");
 }
@@ -256,7 +256,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, vec3, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, vec3, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "float3");
 }
@@ -267,7 +267,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, void_, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, void_, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "void");
 }
@@ -278,7 +278,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, sampler, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, sampler, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "SamplerState");
 }
@@ -289,7 +289,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, sampler, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, sampler, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "SamplerComparisonState");
 }
@@ -499,7 +499,7 @@
     GeneratorImpl& gen = Build();
 
     std::stringstream out;
-    ASSERT_TRUE(gen.EmitType(out, s, ast::StorageClass::kNone, ast::Access::kReadWrite, ""))
+    ASSERT_TRUE(gen.EmitType(out, s, ast::AddressSpace::kNone, ast::Access::kReadWrite, ""))
         << gen.error();
     EXPECT_EQ(out.str(), "Texture2DMS<float4>");
 }
diff --git a/src/tint/writer/hlsl/generator_impl_unary_op_test.cc b/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
index d311061..c7f0336 100644
--- a/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
 using HlslUnaryOpTest = TestHelper;
 
 TEST_F(HlslUnaryOpTest, AddressOf) {
-    GlobalVar("expr", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.f32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
     WrapInFunction(op);
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(HlslUnaryOpTest, Complement) {
-    GlobalVar("expr", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.u32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
     WrapInFunction(op);
 
@@ -44,7 +44,7 @@
 }
 
 TEST_F(HlslUnaryOpTest, Indirection) {
-    GlobalVar("G", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("G", ty.f32(), ast::AddressSpace::kPrivate);
     auto* p = Let("expr", create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
     WrapInFunction(p, op);
@@ -57,7 +57,7 @@
 }
 
 TEST_F(HlslUnaryOpTest, Not) {
-    GlobalVar("expr", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.bool_(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
     WrapInFunction(op);
 
@@ -69,7 +69,7 @@
 }
 
 TEST_F(HlslUnaryOpTest, Negation) {
-    GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
     WrapInFunction(op);
 
diff --git a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
index 4e4643f..5df476a 100644
--- a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc
@@ -357,7 +357,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) {
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
 
     WrapInFunction(Expr("a"));
 
diff --git a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
index 9e8be01..4ec7af2 100644
--- a/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
+++ b/src/tint/writer/hlsl/generator_impl_workgroup_var_test.cc
@@ -27,7 +27,7 @@
 using HlslGeneratorImplTest_WorkgroupVar = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_WorkgroupVar, Basic) {
-    GlobalVar("wg", ty.f32(), ast::StorageClass::kWorkgroup);
+    GlobalVar("wg", ty.f32(), ast::AddressSpace::kWorkgroup);
 
     Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
          utils::Vector{
@@ -43,7 +43,7 @@
 TEST_F(HlslGeneratorImplTest_WorkgroupVar, Aliased) {
     auto* alias = Alias("F32", ty.f32());
 
-    GlobalVar("wg", ty.Of(alias), ast::StorageClass::kWorkgroup);
+    GlobalVar("wg", ty.Of(alias), ast::AddressSpace::kWorkgroup);
 
     Func("main", utils::Empty, ty.void_(), utils::Vector{Assign("wg", 1.2_f)},
          utils::Vector{
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 376d55d..f774315 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -193,7 +193,7 @@
         // Use the SSBO binding numbers as the indices for the buffer size lookups.
         for (auto* var : in->AST().GlobalVariables()) {
             auto* global = in->Sem().Get<sem::GlobalVariable>(var);
-            if (global && global->StorageClass() == ast::StorageClass::kStorage) {
+            if (global && global->AddressSpace() == ast::AddressSpace::kStorage) {
                 array_length_from_uniform_cfg.bindpoint_to_size_index.emplace(
                     global->BindingPoint(), global->BindingPoint().binding);
             }
@@ -880,7 +880,7 @@
 
         case sem::BuiltinType::kAtomicCompareExchangeWeak: {
             auto* ptr_ty = TypeOf(expr->args[0])->UnwrapRef()->As<sem::Pointer>();
-            auto sc = ptr_ty->StorageClass();
+            auto sc = ptr_ty->AddressSpace();
             auto* str = builtin->ReturnType()->As<sem::Struct>();
 
             auto func = utils::GetOrCreate(
@@ -2002,12 +2002,12 @@
                     return false;
                 }
             } else if (auto* ptr = param->type->As<ast::Pointer>()) {
-                auto sc = ptr->storage_class;
-                if (sc == ast::StorageClass::kWorkgroup) {
+                auto sc = ptr->address_space;
+                if (sc == ast::AddressSpace::kWorkgroup) {
                     auto& allocations = workgroup_allocations_[func_name];
                     out << " [[threadgroup(" << allocations.size() << ")]]";
                     allocations.push_back(program_->Sem().Get(ptr->type)->Size());
-                } else if (sc == ast::StorageClass::kStorage || sc == ast::StorageClass::kUniform) {
+                } else if (sc == ast::AddressSpace::kStorage || sc == ast::AddressSpace::kUniform) {
                     uint32_t binding = get_binding_index(param);
                     if (binding == kInvalidBindingIndex) {
                         return false;
@@ -2015,7 +2015,7 @@
                     out << " [[buffer(" << binding << ")]]";
                 } else {
                     TINT_ICE(Writer, diagnostics_)
-                        << "invalid pointer storage class for entry point parameter";
+                        << "invalid pointer address space for entry point parameter";
                     return false;
                 }
             } else {
@@ -2551,7 +2551,7 @@
             if (ptr->Access() == ast::Access::kRead) {
                 out << "const ";
             }
-            if (!EmitStorageClass(out, ptr->StorageClass())) {
+            if (!EmitAddressSpace(out, ptr->AddressSpace())) {
                 return false;
             }
             out << " ";
@@ -2698,26 +2698,26 @@
     return true;
 }
 
-bool GeneratorImpl::EmitStorageClass(std::ostream& out, ast::StorageClass sc) {
+bool GeneratorImpl::EmitAddressSpace(std::ostream& out, ast::AddressSpace sc) {
     switch (sc) {
-        case ast::StorageClass::kFunction:
-        case ast::StorageClass::kPrivate:
-        case ast::StorageClass::kHandle:
+        case ast::AddressSpace::kFunction:
+        case ast::AddressSpace::kPrivate:
+        case ast::AddressSpace::kHandle:
             out << "thread";
             return true;
-        case ast::StorageClass::kWorkgroup:
+        case ast::AddressSpace::kWorkgroup:
             out << "threadgroup";
             return true;
-        case ast::StorageClass::kStorage:
+        case ast::AddressSpace::kStorage:
             out << "device";
             return true;
-        case ast::StorageClass::kUniform:
+        case ast::AddressSpace::kUniform:
             out << "constant";
             return true;
         default:
             break;
     }
-    TINT_ICE(Writer, diagnostics_) << "unhandled storage class: " << sc;
+    TINT_ICE(Writer, diagnostics_) << "unhandled address space: " << sc;
     return false;
 }
 
@@ -2998,19 +2998,19 @@
 
     auto out = line();
 
-    switch (sem->StorageClass()) {
-        case ast::StorageClass::kFunction:
-        case ast::StorageClass::kHandle:
-        case ast::StorageClass::kNone:
+    switch (sem->AddressSpace()) {
+        case ast::AddressSpace::kFunction:
+        case ast::AddressSpace::kHandle:
+        case ast::AddressSpace::kNone:
             break;
-        case ast::StorageClass::kPrivate:
+        case ast::AddressSpace::kPrivate:
             out << "thread ";
             break;
-        case ast::StorageClass::kWorkgroup:
+        case ast::AddressSpace::kWorkgroup:
             out << "threadgroup ";
             break;
         default:
-            TINT_ICE(Writer, diagnostics_) << "unhandled variable storage class";
+            TINT_ICE(Writer, diagnostics_) << "unhandled variable address space";
             return false;
     }
 
@@ -3028,9 +3028,9 @@
         if (!EmitExpression(out, var->constructor)) {
             return false;
         }
-    } else if (sem->StorageClass() == ast::StorageClass::kPrivate ||
-               sem->StorageClass() == ast::StorageClass::kFunction ||
-               sem->StorageClass() == ast::StorageClass::kNone) {
+    } else if (sem->AddressSpace() == ast::AddressSpace::kPrivate ||
+               sem->AddressSpace() == ast::AddressSpace::kFunction ||
+               sem->AddressSpace() == ast::AddressSpace::kNone) {
         out << " = ";
         if (!EmitZeroValue(out, type)) {
             return false;
@@ -3047,19 +3047,19 @@
 
     auto out = line();
 
-    switch (sem->StorageClass()) {
-        case ast::StorageClass::kFunction:
-        case ast::StorageClass::kHandle:
-        case ast::StorageClass::kNone:
+    switch (sem->AddressSpace()) {
+        case ast::AddressSpace::kFunction:
+        case ast::AddressSpace::kHandle:
+        case ast::AddressSpace::kNone:
             break;
-        case ast::StorageClass::kPrivate:
+        case ast::AddressSpace::kPrivate:
             out << "thread ";
             break;
-        case ast::StorageClass::kWorkgroup:
+        case ast::AddressSpace::kWorkgroup:
             out << "threadgroup ";
             break;
         default:
-            TINT_ICE(Writer, diagnostics_) << "unhandled variable storage class";
+            TINT_ICE(Writer, diagnostics_) << "unhandled variable address space";
             return false;
     }
 
diff --git a/src/tint/writer/msl/generator_impl.h b/src/tint/writer/msl/generator_impl.h
index a5948aa..7cd1b6d 100644
--- a/src/tint/writer/msl/generator_impl.h
+++ b/src/tint/writer/msl/generator_impl.h
@@ -319,11 +319,11 @@
     /// @param name the name to emit
     /// @returns true if the type is emitted
     bool EmitTypeAndName(std::ostream& out, const sem::Type* type, const std::string& name);
-    /// Handles generating a storage class
+    /// Handles generating a address space
     /// @param out the output of the type stream
-    /// @param sc the storage class to generate
-    /// @returns true if the storage class is emitted
-    bool EmitStorageClass(std::ostream& out, ast::StorageClass sc);
+    /// @param sc the address space to generate
+    /// @returns true if the address space is emitted
+    bool EmitAddressSpace(std::ostream& out, ast::AddressSpace sc);
     /// Handles generating an MSL-packed storage type.
     /// If the type does not have a packed form, the standard non-packed form is
     /// emitted.
@@ -420,7 +420,7 @@
     /// Name of atomicCompareExchangeWeak() helper for the given pointer storage
     /// class and struct return type
     using ACEWKeyType =
-        utils::UnorderedKeyWrapper<std::tuple<ast::StorageClass, const sem::Struct*>>;
+        utils::UnorderedKeyWrapper<std::tuple<ast::AddressSpace, const sem::Struct*>>;
     std::unordered_map<ACEWKeyType, std::string> atomicCompareExchangeWeak_;
 
     /// Unique name of the 'TINT_INVARIANT' preprocessor define.
diff --git a/src/tint/writer/msl/generator_impl_array_accessor_test.cc b/src/tint/writer/msl/generator_impl_array_accessor_test.cc
index e058ff5..771d537 100644
--- a/src/tint/writer/msl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/msl/generator_impl_array_accessor_test.cc
@@ -34,7 +34,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, IndexAccessor_OfDref) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
 
     auto* p = Let("p", AddressOf("ary"));
     auto* expr = IndexAccessor(Deref("p"), 5_i);
diff --git a/src/tint/writer/msl/generator_impl_builtin_test.cc b/src/tint/writer/msl/generator_impl_builtin_test.cc
index 9f75691..1770d5d 100644
--- a/src/tint/writer/msl/generator_impl_builtin_test.cc
+++ b/src/tint/writer/msl/generator_impl_builtin_test.cc
@@ -216,21 +216,21 @@
     if (param.type == CallParamType::kF16) {
         Enable(ast::Extension::kF16);
 
-        GlobalVar("h2", ty.vec2<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("h3", ty.vec3<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::StorageClass::kPrivate);
-        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::StorageClass::kPrivate);
+        GlobalVar("h2", ty.vec2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("h3", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("hm2x2", ty.mat2x2<f16>(), ast::AddressSpace::kPrivate);
+        GlobalVar("hm3x2", ty.mat3x2<f16>(), ast::AddressSpace::kPrivate);
     }
 
-    GlobalVar("f2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("f3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("f4", ty.vec4<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("u1", ty.u32(), ast::StorageClass::kPrivate);
-    GlobalVar("u2", ty.vec2<u32>(), ast::StorageClass::kPrivate);
-    GlobalVar("i2", ty.vec2<i32>(), ast::StorageClass::kPrivate);
-    GlobalVar("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
-    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("f2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("f3", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("f4", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("u1", ty.u32(), ast::AddressSpace::kPrivate);
+    GlobalVar("u2", ty.vec2<u32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("i2", ty.vec2<i32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("b2", ty.vec2<bool>(), ast::AddressSpace::kPrivate);
+    GlobalVar("m2x2", ty.mat2x2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("m3x2", ty.mat3x2<f32>(), ast::AddressSpace::kPrivate);
 
     auto* call = GenerateCall(param.builtin, param.type, this);
     ASSERT_NE(nullptr, call) << "Unhandled builtin";
@@ -370,8 +370,8 @@
                     "unpack_unorm2x16_to_float"}));
 
 TEST_F(MslGeneratorImplTest, Builtin_Call) {
-    GlobalVar("param1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("dot", "param1", "param2");
     WrapInFunction(CallStmt(call));
@@ -855,7 +855,7 @@
 
 TEST_F(MslGeneratorImplTest, Pack2x16Float) {
     auto* call = Call("pack2x16float", "p1");
-    GlobalVar("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.vec2<f32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
 
     GeneratorImpl& gen = Build();
@@ -867,7 +867,7 @@
 
 TEST_F(MslGeneratorImplTest, Unpack2x16Float) {
     auto* call = Call("unpack2x16float", "p1");
-    GlobalVar("p1", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("p1", ty.u32(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(call));
 
     GeneratorImpl& gen = Build();
@@ -878,7 +878,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, DotI32) {
-    GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    GlobalVar("v", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
     WrapInFunction(CallStmt(Call("dot", "v", "v")));
 
     GeneratorImpl& gen = SanitizeAndBuild();
diff --git a/src/tint/writer/msl/generator_impl_call_test.cc b/src/tint/writer/msl/generator_impl_call_test.cc
index 1011ebd..75504fb 100644
--- a/src/tint/writer/msl/generator_impl_call_test.cc
+++ b/src/tint/writer/msl/generator_impl_call_test.cc
@@ -45,8 +45,8 @@
          utils::Vector{
              Return(1.23_f),
          });
-    GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     WrapInFunction(call);
@@ -65,8 +65,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     auto* stmt = CallStmt(call);
diff --git a/src/tint/writer/msl/generator_impl_function_test.cc b/src/tint/writer/msl/generator_impl_function_test.cc
index addd255..3fa5a21 100644
--- a/src/tint/writer/msl/generator_impl_function_test.cc
+++ b/src/tint/writer/msl/generator_impl_function_test.cc
@@ -342,7 +342,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -381,7 +381,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Group(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Group(0_a),
               Binding(0_a));
 
     auto* var = Var("v", ty.f32(), MemberAccessor("coord", "b"));
@@ -417,7 +417,7 @@
 TEST_F(MslGeneratorImplTest, Emit_Attribute_Called_By_EntryPoint_With_Uniform) {
     auto* ubo_ty = Structure("UBO", utils::Vector{Member("coord", ty.vec4<f32>())});
     auto* ubo =
-        GlobalVar("ubo", ty.Of(ubo_ty), ast::StorageClass::kUniform, Group(0_a), Binding(0_a));
+        GlobalVar("ubo", ty.Of(ubo_ty), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
 
     Func("sub_func",
          utils::Vector{
@@ -467,7 +467,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     Func("sub_func",
@@ -519,7 +519,7 @@
                                     Member("b", ty.f32()),
                                 });
 
-    GlobalVar("coord", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Group(0_a),
+    GlobalVar("coord", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Group(0_a),
               Binding(0_a));
 
     Func("sub_func",
@@ -657,7 +657,7 @@
 
     auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
 
-    GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Group(0_a),
+    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(0_a),
               Binding(0_a));
 
     {
diff --git a/src/tint/writer/msl/generator_impl_import_test.cc b/src/tint/writer/msl/generator_impl_import_test.cc
index 7b79569..4a81130 100644
--- a/src/tint/writer/msl/generator_impl_import_test.cc
+++ b/src/tint/writer/msl/generator_impl_import_test.cc
@@ -234,7 +234,7 @@
                                          MslImportData{"clamp", "clamp"}));
 
 TEST_F(MslGeneratorImplTest, MslImportData_Determinant) {
-    GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = Call("determinant", "var");
 
diff --git a/src/tint/writer/msl/generator_impl_loop_test.cc b/src/tint/writer/msl/generator_impl_loop_test.cc
index 7c84db0..41017ff 100644
--- a/src/tint/writer/msl/generator_impl_loop_test.cc
+++ b/src/tint/writer/msl/generator_impl_loop_test.cc
@@ -64,8 +64,8 @@
 TEST_F(MslGeneratorImplTest, Emit_LoopNestedWithContinuing) {
     Func("a_statement", {}, ty.void_(), utils::Empty);
 
-    GlobalVar("lhs", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("lhs", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* body = Block(create<ast::DiscardStatement>());
     auto* continuing = Block(CallStmt(Call("a_statement")));
@@ -107,7 +107,7 @@
     // }
     //
 
-    GlobalVar("rhs", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("rhs", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4_f))),  //
                        Decl(Var("other", ty.f32())),             //
@@ -184,7 +184,7 @@
     Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-    GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
     auto* multi_stmt = Block(f(1_i), f(2_i));
     auto* loop = For(multi_stmt, nullptr, nullptr,  //
                      Block(Return()));
@@ -260,7 +260,7 @@
     Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-    GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
     auto* multi_stmt = Block(f(1_i), f(2_i));
     auto* loop = For(nullptr, nullptr, multi_stmt,  //
                      Block(Return()));
@@ -315,7 +315,7 @@
     Func("f", utils::Vector{Param("i", ty.i32())}, ty.void_(), utils::Empty);
     auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-    GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
     auto* multi_stmt_a = Block(f(1_i), f(2_i));
     auto* multi_stmt_b = Block(f(3_i), f(4_i));
     auto* loop = For(multi_stmt_a, Expr(true), multi_stmt_b,  //
diff --git a/src/tint/writer/msl/generator_impl_member_accessor_test.cc b/src/tint/writer/msl/generator_impl_member_accessor_test.cc
index e189910..2f16f4a 100644
--- a/src/tint/writer/msl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/msl/generator_impl_member_accessor_test.cc
@@ -21,7 +21,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor) {
     GlobalVar("str", ty.Of(Structure("my_str", utils::Vector{Member("mem", ty.f32())})),
-              ast::StorageClass::kPrivate);
+              ast::AddressSpace::kPrivate);
     auto* expr = MemberAccessor("str", "mem");
     WrapInFunction(expr);
 
@@ -33,7 +33,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor_Swizzle_xyz) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("my_vec", "xyz");
     WrapInFunction(expr);
@@ -45,7 +45,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, EmitExpression_MemberAccessor_Swizzle_gbr) {
-    GlobalVar("my_vec", ty.vec4<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("my_vec", ty.vec4<f32>(), ast::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("my_vec", "gbr");
     WrapInFunction(expr);
diff --git a/src/tint/writer/msl/generator_impl_sanitizer_test.cc b/src/tint/writer/msl/generator_impl_sanitizer_test.cc
index f96a1c9..71fe1f6 100644
--- a/src/tint/writer/msl/generator_impl_sanitizer_test.cc
+++ b/src/tint/writer/msl/generator_impl_sanitizer_test.cc
@@ -28,7 +28,7 @@
 
 TEST_F(MslSanitizerTest, Call_ArrayLength) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -82,7 +82,7 @@
                                          Member(0, "z", ty.f32()),
                                          Member(4, "a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -135,7 +135,7 @@
 
 TEST_F(MslSanitizerTest, Call_ArrayLength_ViaLets) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf("b"));
@@ -192,9 +192,9 @@
 
 TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(0_a));
-    GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(2_a),
+    GlobalVar("c", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(2_a),
               Group(0_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -251,9 +251,9 @@
 
 TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniformMissingBinding) {
     auto* s = Structure("my_struct", utils::Vector{Member(0, "a", ty.array<f32>(4))});
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(0_a));
-    GlobalVar("c", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(2_a),
+    GlobalVar("c", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(2_a),
               Group(0_a));
 
     Func("a_func", utils::Empty, ty.void_(),
diff --git a/src/tint/writer/msl/generator_impl_test.cc b/src/tint/writer/msl/generator_impl_test.cc
index 9b3d0bc..bff94b0 100644
--- a/src/tint/writer/msl/generator_impl_test.cc
+++ b/src/tint/writer/msl/generator_impl_test.cc
@@ -154,7 +154,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, WorkgroupMatrix) {
-    GlobalVar("m", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("m", ty.mat2x2<f32>(), ast::AddressSpace::kWorkgroup);
     Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", Expr("m")))},
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -194,7 +194,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, WorkgroupMatrixInArray) {
-    GlobalVar("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::StorageClass::kWorkgroup);
+    GlobalVar("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::AddressSpace::kWorkgroup);
     Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", Expr("m")))},
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -255,7 +255,7 @@
     Structure("S2", utils::Vector{
                         Member("s", ty.type_name("S1")),
                     });
-    GlobalVar("s", ty.type_name("S2"), ast::StorageClass::kWorkgroup);
+    GlobalVar("s", ty.type_name("S2"), ast::AddressSpace::kWorkgroup);
     Func("comp_main", utils::Empty, ty.void_(), utils::Vector{Decl(Let("x", Expr("s")))},
          utils::Vector{
              Stage(ast::PipelineStage::kCompute),
@@ -305,15 +305,15 @@
 }
 
 TEST_F(MslGeneratorImplTest, WorkgroupMatrix_Multiples) {
-    GlobalVar("m1", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("m2", ty.mat2x3<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("m3", ty.mat2x4<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("m4", ty.mat3x2<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("m5", ty.mat3x3<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("m6", ty.mat3x4<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("m7", ty.mat4x2<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("m8", ty.mat4x3<f32>(), ast::StorageClass::kWorkgroup);
-    GlobalVar("m9", ty.mat4x4<f32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("m1", ty.mat2x2<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m2", ty.mat2x3<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m3", ty.mat2x4<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m4", ty.mat3x2<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m5", ty.mat3x3<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m6", ty.mat3x4<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m7", ty.mat4x2<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m8", ty.mat4x3<f32>(), ast::AddressSpace::kWorkgroup);
+    GlobalVar("m9", ty.mat4x4<f32>(), ast::AddressSpace::kWorkgroup);
     Func("main1", utils::Empty, ty.void_(),
          utils::Vector{
              Decl(Let("a1", Expr("m1"))),
diff --git a/src/tint/writer/msl/generator_impl_type_test.cc b/src/tint/writer/msl/generator_impl_type_test.cc
index a8d9fc6..bc9767a 100644
--- a/src/tint/writer/msl/generator_impl_type_test.cc
+++ b/src/tint/writer/msl/generator_impl_type_test.cc
@@ -89,7 +89,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_Array) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -101,7 +101,7 @@
 TEST_F(MslGeneratorImplTest, EmitType_ArrayOfArray) {
     auto* a = ty.array<bool, 4>();
     auto* b = ty.array(a, 5_u);
-    GlobalVar("G", b, ast::StorageClass::kPrivate);
+    GlobalVar("G", b, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -114,7 +114,7 @@
     auto* a = ty.array<bool, 4>();
     auto* b = ty.array(a, 5_u);
     auto* c = ty.array(b, 6_u);
-    GlobalVar("G", c, ast::StorageClass::kPrivate);
+    GlobalVar("G", c, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -125,7 +125,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_Array_WithoutName) {
     auto* arr = ty.array<bool, 4>();
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -136,7 +136,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_RuntimeArray) {
     auto* arr = ty.array<bool, 1>();
-    GlobalVar("G", arr, ast::StorageClass::kPrivate);
+    GlobalVar("G", arr, ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -211,7 +211,7 @@
 
 TEST_F(MslGeneratorImplTest, EmitType_Pointer) {
     auto* f32 = create<sem::F32>();
-    auto* p = create<sem::Pointer>(f32, ast::StorageClass::kWorkgroup, ast::Access::kReadWrite);
+    auto* p = create<sem::Pointer>(f32, ast::AddressSpace::kWorkgroup, ast::Access::kReadWrite);
 
     GeneratorImpl& gen = Build();
 
@@ -282,7 +282,7 @@
                  Member("z", ty.f32()),
              });
 
-    GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -390,7 +390,7 @@
                                  Member("e", ty.f32()),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -481,7 +481,7 @@
                                  Member("f", array_z),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -564,7 +564,7 @@
                                  Member("c", ty.i32()),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -625,7 +625,7 @@
                                  Member("tint_pad_21", ty.f32()),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -683,7 +683,7 @@
                                  Member("b", ty.f32()),
                              });
 
-    GlobalVar("G", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("G", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/msl/generator_impl_unary_op_test.cc b/src/tint/writer/msl/generator_impl_unary_op_test.cc
index 5f86bb5..0c234df 100644
--- a/src/tint/writer/msl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/msl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
 using MslUnaryOpTest = TestHelper;
 
 TEST_F(MslUnaryOpTest, AddressOf) {
-    GlobalVar("expr", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.f32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
     WrapInFunction(op);
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(MslUnaryOpTest, Complement) {
-    GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
     WrapInFunction(op);
 
@@ -44,7 +44,7 @@
 }
 
 TEST_F(MslUnaryOpTest, Indirection) {
-    GlobalVar("G", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("G", ty.f32(), ast::AddressSpace::kPrivate);
     auto* p = Let("expr", create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
     WrapInFunction(p, op);
@@ -57,7 +57,7 @@
 }
 
 TEST_F(MslUnaryOpTest, Not) {
-    GlobalVar("expr", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.bool_(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
     WrapInFunction(op);
 
@@ -69,7 +69,7 @@
 }
 
 TEST_F(MslUnaryOpTest, Negation) {
-    GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
     WrapInFunction(op);
 
diff --git a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
index 3152f6c..b57a39f 100644
--- a/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/tint/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -518,7 +518,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) {
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
 
     WrapInFunction(Expr("a"));
 
@@ -531,7 +531,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Workgroup) {
-    GlobalVar("a", ty.f32(), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kWorkgroup);
 
     WrapInFunction(Expr("a"));
 
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index 70d16a6..874e0b5 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -477,8 +477,8 @@
     for (const auto* var : func_sem->TransitivelyReferencedGlobals()) {
         // For SPIR-V 1.3 we only output Input/output variables. If we update to
         // SPIR-V 1.4 or later this should be all variables.
-        if (var->StorageClass() != ast::StorageClass::kIn &&
-            var->StorageClass() != ast::StorageClass::kOut) {
+        if (var->AddressSpace() != ast::AddressSpace::kIn &&
+            var->AddressSpace() != ast::AddressSpace::kOut) {
             continue;
         }
 
@@ -679,7 +679,7 @@
 
     auto result = result_op();
     auto var_id = std::get<uint32_t>(result);
-    auto sc = ast::StorageClass::kFunction;
+    auto sc = ast::AddressSpace::kFunction;
     auto* type = sem->Type();
     auto type_id = GenerateTypeIfNeeded(type);
     if (type_id == 0) {
@@ -695,7 +695,7 @@
         return 0;
     }
     push_function_var(
-        {Operand(type_id), result, U32Operand(ConvertStorageClass(sc)), Operand(null_id)});
+        {Operand(type_id), result, U32Operand(ConvertAddressSpace(sc)), Operand(null_id)});
 
     if (v->constructor) {
         if (!GenerateStore(var_id, init_id)) {
@@ -738,8 +738,8 @@
     auto result = result_op();
     auto var_id = std::get<uint32_t>(result);
 
-    auto sc = sem->StorageClass() == ast::StorageClass::kNone ? ast::StorageClass::kPrivate
-                                                              : sem->StorageClass();
+    auto sc = sem->AddressSpace() == ast::AddressSpace::kNone ? ast::AddressSpace::kPrivate
+                                                              : sem->AddressSpace();
 
     auto type_id = GenerateTypeIfNeeded(sem->Type());
     if (type_id == 0) {
@@ -748,7 +748,7 @@
 
     push_debug(spv::Op::OpName, {Operand(var_id), Operand(builder_.Symbols().NameFor(v->symbol))});
 
-    OperandList ops = {Operand(type_id), result, U32Operand(ConvertStorageClass(sc))};
+    OperandList ops = {Operand(type_id), result, U32Operand(ConvertAddressSpace(sc))};
 
     if (v->constructor) {
         ops.push_back(Operand(init_id));
@@ -777,10 +777,10 @@
             // If we're a Workgroup variable, and the
             // VK_KHR_zero_initialize_workgroup_memory extension is enabled, we should
             // also zero-initialize.
-            if (sem->StorageClass() == ast::StorageClass::kPrivate ||
-                sem->StorageClass() == ast::StorageClass::kOut ||
+            if (sem->AddressSpace() == ast::AddressSpace::kPrivate ||
+                sem->AddressSpace() == ast::AddressSpace::kOut ||
                 (zero_initialize_workgroup_memory_ &&
-                 sem->StorageClass() == ast::StorageClass::kWorkgroup)) {
+                 sem->AddressSpace() == ast::AddressSpace::kWorkgroup)) {
                 init_id = GenerateConstantNullIfNeeded(type);
                 if (init_id == 0) {
                     return 0;
@@ -798,7 +798,7 @@
             [&](const ast::BuiltinAttribute* builtin) {
                 push_annot(spv::Op::OpDecorate,
                            {Operand(var_id), U32Operand(SpvDecorationBuiltIn),
-                            U32Operand(ConvertBuiltin(builtin->builtin, sem->StorageClass()))});
+                            U32Operand(ConvertBuiltin(builtin->builtin, sem->AddressSpace()))});
                 return true;
             },
             [&](const ast::LocationAttribute*) {
@@ -1875,10 +1875,10 @@
 uint32_t Builder::GenerateSplat(uint32_t scalar_id, const sem::Type* vec_type) {
     // Create a new vector to splat scalar into
     auto splat_vector = result_op();
-    auto* splat_vector_type = builder_.create<sem::Pointer>(vec_type, ast::StorageClass::kFunction,
+    auto* splat_vector_type = builder_.create<sem::Pointer>(vec_type, ast::AddressSpace::kFunction,
                                                             ast::Access::kReadWrite);
     push_function_var({Operand(GenerateTypeIfNeeded(splat_vector_type)), splat_vector,
-                       U32Operand(ConvertStorageClass(ast::StorageClass::kFunction)),
+                       U32Operand(ConvertAddressSpace(ast::AddressSpace::kFunction)),
                        Operand(GenerateConstantNullIfNeeded(vec_type))});
 
     // Splat scalar into vector
@@ -3041,21 +3041,21 @@
                                     Operand result_id) {
     auto is_value_signed = [&] { return builtin->Parameters()[1]->Type()->Is<sem::I32>(); };
 
-    auto storage_class = builtin->Parameters()[0]->Type()->As<sem::Pointer>()->StorageClass();
+    auto address_space = builtin->Parameters()[0]->Type()->As<sem::Pointer>()->AddressSpace();
 
     uint32_t memory_id = 0;
-    switch (builtin->Parameters()[0]->Type()->As<sem::Pointer>()->StorageClass()) {
-        case ast::StorageClass::kWorkgroup:
+    switch (builtin->Parameters()[0]->Type()->As<sem::Pointer>()->AddressSpace()) {
+        case ast::AddressSpace::kWorkgroup:
             memory_id = GenerateConstantIfNeeded(
                 ScalarConstant::U32(static_cast<uint32_t>(spv::Scope::Workgroup)));
             break;
-        case ast::StorageClass::kStorage:
+        case ast::AddressSpace::kStorage:
             memory_id = GenerateConstantIfNeeded(
                 ScalarConstant::U32(static_cast<uint32_t>(spv::Scope::Device)));
             break;
         default:
             TINT_UNREACHABLE(Writer, builder_.Diagnostics())
-                << "unhandled atomic storage class " << storage_class;
+                << "unhandled atomic address space " << address_space;
             return false;
     }
     if (memory_id == 0) {
@@ -3685,10 +3685,10 @@
     // fine.
     if (auto* ptr = type->As<sem::Pointer>()) {
         type =
-            builder_.create<sem::Pointer>(ptr->StoreType(), ptr->StorageClass(), ast::kReadWrite);
+            builder_.create<sem::Pointer>(ptr->StoreType(), ptr->AddressSpace(), ast::kReadWrite);
     } else if (auto* ref = type->As<sem::Reference>()) {
         type =
-            builder_.create<sem::Pointer>(ref->StoreType(), ref->StorageClass(), ast::kReadWrite);
+            builder_.create<sem::Pointer>(ref->StoreType(), ref->AddressSpace(), ast::kReadWrite);
     }
 
     return utils::GetOrCreate(type_to_id_, type, [&]() -> uint32_t {
@@ -3905,9 +3905,9 @@
         return false;
     }
 
-    auto stg_class = ConvertStorageClass(ptr->StorageClass());
+    auto stg_class = ConvertAddressSpace(ptr->AddressSpace());
     if (stg_class == SpvStorageClassMax) {
-        error_ = "invalid storage class for pointer";
+        error_ = "invalid address space for pointer";
         return false;
     }
 
@@ -3922,9 +3922,9 @@
         return false;
     }
 
-    auto stg_class = ConvertStorageClass(ref->StorageClass());
+    auto stg_class = ConvertAddressSpace(ref->AddressSpace());
     if (stg_class == SpvStorageClassMax) {
-        error_ = "invalid storage class for reference";
+        error_ = "invalid address space for reference";
         return false;
     }
 
@@ -4007,43 +4007,43 @@
     return true;
 }
 
-SpvStorageClass Builder::ConvertStorageClass(ast::StorageClass klass) const {
+SpvStorageClass Builder::ConvertAddressSpace(ast::AddressSpace klass) const {
     switch (klass) {
-        case ast::StorageClass::kInvalid:
+        case ast::AddressSpace::kInvalid:
             return SpvStorageClassMax;
-        case ast::StorageClass::kIn:
+        case ast::AddressSpace::kIn:
             return SpvStorageClassInput;
-        case ast::StorageClass::kOut:
+        case ast::AddressSpace::kOut:
             return SpvStorageClassOutput;
-        case ast::StorageClass::kUniform:
+        case ast::AddressSpace::kUniform:
             return SpvStorageClassUniform;
-        case ast::StorageClass::kWorkgroup:
+        case ast::AddressSpace::kWorkgroup:
             return SpvStorageClassWorkgroup;
-        case ast::StorageClass::kPushConstant:
+        case ast::AddressSpace::kPushConstant:
             return SpvStorageClassPushConstant;
-        case ast::StorageClass::kHandle:
+        case ast::AddressSpace::kHandle:
             return SpvStorageClassUniformConstant;
-        case ast::StorageClass::kStorage:
+        case ast::AddressSpace::kStorage:
             return SpvStorageClassStorageBuffer;
-        case ast::StorageClass::kPrivate:
+        case ast::AddressSpace::kPrivate:
             return SpvStorageClassPrivate;
-        case ast::StorageClass::kFunction:
+        case ast::AddressSpace::kFunction:
             return SpvStorageClassFunction;
-        case ast::StorageClass::kNone:
+        case ast::AddressSpace::kNone:
             break;
     }
     return SpvStorageClassMax;
 }
 
-SpvBuiltIn Builder::ConvertBuiltin(ast::BuiltinValue builtin, ast::StorageClass storage) {
+SpvBuiltIn Builder::ConvertBuiltin(ast::BuiltinValue builtin, ast::AddressSpace storage) {
     switch (builtin) {
         case ast::BuiltinValue::kPosition:
-            if (storage == ast::StorageClass::kIn) {
+            if (storage == ast::AddressSpace::kIn) {
                 return SpvBuiltInFragCoord;
-            } else if (storage == ast::StorageClass::kOut) {
+            } else if (storage == ast::AddressSpace::kOut) {
                 return SpvBuiltInPosition;
             } else {
-                TINT_ICE(Writer, builder_.Diagnostics()) << "invalid storage class for builtin";
+                TINT_ICE(Writer, builder_.Diagnostics()) << "invalid address space for builtin";
                 break;
             }
         case ast::BuiltinValue::kVertexIndex:
diff --git a/src/tint/writer/spirv/builder.h b/src/tint/writer/spirv/builder.h
index ba88443..e081d31 100644
--- a/src/tint/writer/spirv/builder.h
+++ b/src/tint/writer/spirv/builder.h
@@ -76,7 +76,7 @@
     /// Constructor
     /// @param program the program
     /// @param zero_initialize_workgroup_memory `true` to initialize all the
-    /// variables in the Workgroup storage class with OpConstantNull
+    /// variables in the Workgroup address space with OpConstantNull
     explicit Builder(const Program* program, bool zero_initialize_workgroup_memory = false);
     ~Builder();
 
@@ -203,15 +203,15 @@
     /// inside a basic block.
     bool InsideBasicBlock() const;
 
-    /// Converts a storage class to a SPIR-V storage class.
-    /// @param klass the storage class to convert
-    /// @returns the SPIR-V storage class or SpvStorageClassMax on error.
-    SpvStorageClass ConvertStorageClass(ast::StorageClass klass) const;
+    /// Converts a address space to a SPIR-V address space.
+    /// @param klass the address space to convert
+    /// @returns the SPIR-V address space or SpvStorageClassMax on error.
+    SpvStorageClass ConvertAddressSpace(ast::AddressSpace klass) const;
     /// Converts a builtin to a SPIR-V builtin and pushes a capability if needed.
     /// @param builtin the builtin to convert
-    /// @param storage the storage class that this builtin is being used with
+    /// @param storage the address space that this builtin is being used with
     /// @returns the SPIR-V builtin or SpvBuiltInMax on error.
-    SpvBuiltIn ConvertBuiltin(ast::BuiltinValue builtin, ast::StorageClass storage);
+    SpvBuiltIn ConvertBuiltin(ast::BuiltinValue builtin, ast::AddressSpace storage);
 
     /// Converts an interpolate attribute to SPIR-V decorations and pushes a
     /// capability if needed.
diff --git a/src/tint/writer/spirv/builder_assign_test.cc b/src/tint/writer/spirv/builder_assign_test.cc
index 963e680..d43fbbe 100644
--- a/src/tint/writer/spirv/builder_assign_test.cc
+++ b/src/tint/writer/spirv/builder_assign_test.cc
@@ -23,7 +23,7 @@
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, Assign_Var) {
-    auto* v = GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* assign = Assign("var", 1_f);
 
@@ -51,7 +51,7 @@
 }
 
 TEST_F(BuilderTest, Assign_Var_OutsideFunction_IsError) {
-    auto* v = GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* assign = Assign("var", Expr(1_f));
 
@@ -70,7 +70,7 @@
 }
 
 TEST_F(BuilderTest, Assign_Var_ZeroConstructor) {
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* val = vec3<f32>();
     auto* assign = Assign("var", val);
@@ -101,7 +101,7 @@
 TEST_F(BuilderTest, Assign_Var_Complex_ConstructorNestedVector) {
     auto* init = vec3<f32>(vec2<f32>(1_f, 2_f), 3_f);
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* assign = Assign("var", init);
 
@@ -134,7 +134,7 @@
 TEST_F(BuilderTest, Assign_Var_Complex_Constructor) {
     auto* init = vec3<f32>(1_f, 2_f, 3_f);
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* assign = Assign("var", init);
 
@@ -209,7 +209,7 @@
 }
 
 TEST_F(BuilderTest, Assign_Vector) {
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* val = vec3<f32>(1_f, 1_f, 3_f);
     auto* assign = Assign("var", val);
@@ -243,7 +243,7 @@
 TEST_F(BuilderTest, Assign_Vector_MemberByName) {
     // var.y = 1
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* assign = Assign(MemberAccessor("var", "y"), Expr(1_f));
 
@@ -278,7 +278,7 @@
 TEST_F(BuilderTest, Assign_Vector_MemberByIndex) {
     // var[1] = 1
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* assign = Assign(IndexAccessor("var", 1_i), Expr(1_f));
 
diff --git a/src/tint/writer/spirv/builder_binary_expression_test.cc b/src/tint/writer/spirv/builder_binary_expression_test.cc
index fd9a64a..e7237fa 100644
--- a/src/tint/writer/spirv/builder_binary_expression_test.cc
+++ b/src/tint/writer/spirv/builder_binary_expression_test.cc
@@ -1031,8 +1031,8 @@
 }
 
 TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
-    auto* a_var = GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate, Expr(true));
-    auto* b_var = GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate, Expr(false));
+    auto* a_var = GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate, Expr(true));
+    auto* b_var = GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate, Expr(false));
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd, Expr("a"), Expr("b"));
 
     WrapInFunction(expr);
@@ -1197,8 +1197,8 @@
 }
 
 TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
-    auto* a_var = GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate, Expr(true));
-    auto* b_var = GlobalVar("b", ty.bool_(), ast::StorageClass::kPrivate, Expr(false));
+    auto* a_var = GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate, Expr(true));
+    auto* b_var = GlobalVar("b", ty.bool_(), ast::AddressSpace::kPrivate, Expr(false));
 
     auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr, Expr("a"), Expr("b"));
 
@@ -1241,19 +1241,19 @@
     switch (type) {
         case Type::f32:
             builder->GlobalVar(name, builder->ty.vec3<f32>(), builder->vec3<f32>(1_f, 1_f, 1_f),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
         case Type::f16:
             builder->GlobalVar(name, builder->ty.vec3<f16>(), builder->vec3<f16>(1_h, 1_h, 1_h),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
         case Type::i32:
             builder->GlobalVar(name, builder->ty.vec3<i32>(), builder->vec3<i32>(1_i, 1_i, 1_i),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
         case Type::u32:
             builder->GlobalVar(name, builder->ty.vec3<u32>(), builder->vec3<u32>(1_u, 1_u, 1_u),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
     }
     return builder->Expr(name);
@@ -1263,19 +1263,19 @@
     switch (type) {
         case Type::f32:
             builder->GlobalVar(name, builder->ty.f32(), builder->Expr(1_f),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
         case Type::f16:
             builder->GlobalVar(name, builder->ty.f16(), builder->Expr(1_h),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
         case Type::i32:
             builder->GlobalVar(name, builder->ty.i32(), builder->Expr(1_i),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
         case Type::u32:
             builder->GlobalVar(name, builder->ty.u32(), builder->Expr(1_u),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
     }
     return builder->Expr(name);
@@ -1570,11 +1570,11 @@
     switch (type) {
         case Type::f32:
             builder->GlobalVar(name, builder->ty.mat3x4<f32>(), builder->mat3x4<f32>(),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
         case Type::f16:
             builder->GlobalVar(name, builder->ty.mat3x4<f16>(), builder->mat3x4<f16>(),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
     }
     return builder->Expr(name);
@@ -1584,11 +1584,11 @@
     switch (type) {
         case Type::f32:
             builder->GlobalVar(name, builder->ty.mat4x3<f32>(), builder->mat4x3<f32>(),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
             break;
         case Type::f16:
             builder->GlobalVar(name, builder->ty.mat4x3<f16>(), builder->mat4x3<f16>(),
-                               ast::StorageClass::kPrivate);
+                               ast::AddressSpace::kPrivate);
     }
     return builder->Expr(name);
 }
diff --git a/src/tint/writer/spirv/builder_builtin_test.cc b/src/tint/writer/spirv/builder_builtin_test.cc
index cfb85d9..dddc475 100644
--- a/src/tint/writer/spirv/builder_builtin_test.cc
+++ b/src/tint/writer/spirv/builder_builtin_test.cc
@@ -97,7 +97,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad_f32) {
-    auto* var = GlobalVar("ident", ty.f32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("ident", ty.f32(), ast::AddressSpace::kPrivate);
     auto* expr = Call("round", "ident");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -133,7 +133,7 @@
 TEST_F(BuiltinBuilderTest, Call_GLSLMethod_WithLoad_f16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("ident", ty.f16(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("ident", ty.f16(), ast::AddressSpace::kPrivate);
     auto* expr = Call("round", "ident");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -172,7 +172,7 @@
 using BuiltinBoolTest = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(BuiltinBoolTest, Call_Bool_Scalar) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.bool_(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.bool_(), ast::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -198,7 +198,7 @@
 
 TEST_P(BuiltinBoolTest, Call_Bool_Vector) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -231,9 +231,9 @@
                          testing::Values(BuiltinData{"any", "OpAny"}, BuiltinData{"all", "OpAll"}));
 
 TEST_F(BuiltinBuilderTest, Call_Select) {
-    auto* v3 = GlobalVar("v3", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* v3 = GlobalVar("v3", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
-    auto* bool_v3 = GlobalVar("bool_v3", ty.vec3<bool>(), ast::StorageClass::kPrivate);
+    auto* bool_v3 = GlobalVar("bool_v3", ty.vec3<bool>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("select", "v3", "v3", "bool_v3");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -277,7 +277,7 @@
     auto* s = Structure("my_struct", utils::Vector{
                                          Member("a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
     auto* expr = Call("arrayLength", AddressOf(MemberAccessor("b", "a")));
 
@@ -321,7 +321,7 @@
                                          Member("z", ty.f32()),
                                          Member(4, "a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
     auto* expr = Call("arrayLength", AddressOf(MemberAccessor("b", "a")));
 
@@ -364,7 +364,7 @@
     auto* s = Structure("my_struct", utils::Vector{
                                          Member("a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf("b"));
@@ -423,7 +423,7 @@
     auto* s = Structure("my_struct", utils::Vector{
                                          Member("a", ty.array<f32>(4)),
                                      });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(1_a),
               Group(2_a));
 
     auto* p = Let("p", AddressOf(Deref(AddressOf("b"))));
@@ -1862,7 +1862,7 @@
 using BuiltinIntTest = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(BuiltinIntTest, Call_SInt_Scalar) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -1892,7 +1892,7 @@
 
 TEST_P(BuiltinIntTest, Call_SInt_Vector) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -1923,7 +1923,7 @@
 
 TEST_P(BuiltinIntTest, Call_UInt_Scalar) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.u32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.u32(), ast::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -1953,7 +1953,7 @@
 
 TEST_P(BuiltinIntTest, Call_UInt_Vector) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -2824,7 +2824,7 @@
 namespace matrix_builtin_tests {
 
 TEST_F(BuiltinBuilderTest, Call_Determinant_f32) {
-    auto* var = GlobalVar("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("var", ty.mat3x3<f32>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("determinant", "var");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -2861,7 +2861,7 @@
 TEST_F(BuiltinBuilderTest, Call_Determinant_f16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("var", ty.mat3x3<f16>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("var", ty.mat3x3<f16>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("determinant", "var");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -2896,7 +2896,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_Transpose_f32) {
-    auto* var = GlobalVar("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("var", ty.mat2x3<f32>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("transpose", "var");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -2934,7 +2934,7 @@
 TEST_F(BuiltinBuilderTest, Call_Transpose_f16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("var", ty.mat2x3<f16>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("var", ty.mat2x3<f16>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("transpose", "var");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -2975,7 +2975,7 @@
 namespace vector_builtin_tests {
 
 TEST_F(BuiltinBuilderTest, Call_Dot_F32) {
-    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("dot", "v", "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3006,7 +3006,7 @@
 TEST_F(BuiltinBuilderTest, Call_Dot_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("v", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("dot", "v", "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3035,7 +3035,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_Dot_U32) {
-    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("dot", "v", "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3074,7 +3074,7 @@
 }
 
 TEST_F(BuiltinBuilderTest, Call_Dot_I32) {
-    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
     auto* expr = Call("dot", "v", "v");
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3120,7 +3120,7 @@
 using BuiltinDeriveTest = BuiltinBuilderTestWithParam<BuiltinData>;
 TEST_P(BuiltinDeriveTest, Call_Derivative_Scalar) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.f32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.f32(), ast::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3153,7 +3153,7 @@
 
 TEST_P(BuiltinDeriveTest, Call_Derivative_Vector) {
     auto param = GetParam();
-    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
     auto* expr = Call(param.name, "v");
     auto* func = Func("func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -3223,7 +3223,7 @@
                                  Member("u", ty.atomic<u32>()),
                                  Member("i", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3286,7 +3286,7 @@
                                  Member("u", ty.atomic<u32>()),
                                  Member("i", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3357,7 +3357,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("v", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3429,7 +3429,7 @@
     auto* s = Structure("S", utils::Vector{
                                  Member("v", ty.atomic<u32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3503,7 +3503,7 @@
                                  Member("u", ty.atomic<u32>()),
                                  Member("i", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
@@ -3578,7 +3578,7 @@
                                  Member("u", ty.atomic<u32>()),
                                  Member("i", ty.atomic<i32>()),
                              });
-    GlobalVar("b", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(1_a),
+    GlobalVar("b", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(1_a),
               Group(2_a));
 
     Func("a_func", utils::Empty, ty.void_(),
diff --git a/src/tint/writer/spirv/builder_constructor_expression_test.cc b/src/tint/writer/spirv/builder_constructor_expression_test.cc
index cb8dd4f..cabbd18 100644
--- a/src/tint/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/tint/writer/spirv/builder_constructor_expression_test.cc
@@ -24,7 +24,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Const) {
     auto* c = Expr(42.2_f);
-    auto* g = GlobalVar("g", ty.f32(), c, ast::StorageClass::kPrivate);
+    auto* g = GlobalVar("g", ty.f32(), c, ast::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -1935,7 +1935,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_F32_With_F32) {
     auto* ctor = Construct<f32>(2_f);
-    GlobalVar("g", ty.f32(), ast::StorageClass::kPrivate, ctor);
+    GlobalVar("g", ty.f32(), ast::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -1954,7 +1954,7 @@
     Enable(ast::Extension::kF16);
 
     auto* ctor = Construct<f16>(2_h);
-    GlobalVar("g", ty.f16(), ast::StorageClass::kPrivate, ctor);
+    GlobalVar("g", ty.f16(), ast::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2015,7 +2015,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_U32_With_F32) {
     auto* ctor = Construct<u32>(1.5_f);
-    GlobalVar("g", ty.u32(), ast::StorageClass::kPrivate, ctor);
+    GlobalVar("g", ty.u32(), ast::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2034,7 +2034,7 @@
     Enable(ast::Extension::kF16);
 
     auto* ctor = Construct<u32>(1.5_h);
-    GlobalVar("g", ty.u32(), ast::StorageClass::kPrivate, ctor);
+    GlobalVar("g", ty.u32(), ast::AddressSpace::kPrivate, ctor);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2099,7 +2099,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec2_With_F32) {
     auto* cast = vec2<f32>(2_f);
-    auto* g = GlobalVar("g", ty.vec2<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec2<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2117,7 +2117,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec2<f16>(2_h);
-    auto* g = GlobalVar("g", ty.vec2<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec2<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2181,7 +2181,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec2_F32_With_Vec2) {
     auto* cast = vec2<f32>(vec2<f32>(2_f, 2_f));
-    GlobalVar("a", ty.vec2<f32>(), ast::StorageClass::kPrivate, cast);
+    GlobalVar("a", ty.vec2<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2203,7 +2203,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec2<f16>(vec2<f16>(2_h, 2_h));
-    GlobalVar("a", ty.vec2<f16>(), ast::StorageClass::kPrivate, cast);
+    GlobalVar("a", ty.vec2<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2271,7 +2271,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_F32_With_Vec3) {
     auto* cast = vec3<f32>(vec3<f32>(2_f, 2_f, 2_f));
-    GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
+    GlobalVar("a", ty.vec3<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2293,7 +2293,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec3<f16>(vec3<f16>(2_h, 2_h, 2_h));
-    GlobalVar("a", ty.vec3<f16>(), ast::StorageClass::kPrivate, cast);
+    GlobalVar("a", ty.vec3<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2361,7 +2361,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_F32_With_Vec4) {
     auto* cast = vec4<f32>(vec4<f32>(2_f, 2_f, 2_f, 2_f));
-    GlobalVar("a", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+    GlobalVar("a", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2383,7 +2383,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(vec4<f16>(2_h, 2_h, 2_h, 2_h));
-    GlobalVar("a", ty.vec4<f16>(), ast::StorageClass::kPrivate, cast);
+    GlobalVar("a", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = SanitizeAndBuild();
     ASSERT_TRUE(b.Build());
@@ -2451,7 +2451,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_F32) {
     auto* cast = vec3<f32>(2_f);
-    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2469,7 +2469,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec3<f16>(2_h);
-    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2533,7 +2533,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_F32_Vec2) {
     auto* cast = vec3<f32>(2_f, vec2<f32>(2_f, 2_f));
-    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2551,7 +2551,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec3<f16>(2_h, vec2<f16>(2_h, 2_h));
-    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2615,7 +2615,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_Vec2_F32) {
     auto* cast = vec3<f32>(vec2<f32>(2_f, 2_f), 2_f);
-    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2633,7 +2633,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec3<f16>(vec2<f16>(2_h, 2_h), 2_h);
-    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec3<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2697,7 +2697,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32) {
     auto* cast = vec4<f32>(2_f);
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2715,7 +2715,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(2_h);
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2779,7 +2779,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_F32_Vec2) {
     auto* cast = vec4<f32>(2_f, 2_f, vec2<f32>(2_f, 2_f));
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2797,7 +2797,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(2_h, 2_h, vec2<f16>(2_h, 2_h));
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2861,7 +2861,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_Vec2_F32) {
     auto* cast = vec4<f32>(2_f, vec2<f32>(2_f, 2_f), 2_f);
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2879,7 +2879,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(2_h, vec2<f16>(2_h, 2_h), 2_h);
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2943,7 +2943,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec2_F32_F32) {
     auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), 2_f, 2_f);
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -2961,7 +2961,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(vec2<f16>(2_h, 2_h), 2_h, 2_h);
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3025,7 +3025,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_F32_With_Vec2_Vec2) {
     auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3043,7 +3043,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(vec2<f16>(2_h, 2_h), vec2<f16>(2_h, 2_h));
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3082,7 +3082,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_Vec3) {
     auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3100,7 +3100,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(2_h, vec3<f16>(2_h, 2_h, 2_h));
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3164,7 +3164,7 @@
 
 TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec3_F32) {
     auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
-    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f32>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -3182,7 +3182,7 @@
     Enable(ast::Extension::kF16);
 
     auto* cast = vec4<f16>(vec3<f16>(2_h, 2_h, 2_h), 2_h);
-    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::StorageClass::kPrivate, cast);
+    auto* g = GlobalVar("g", ty.vec4<f16>(), ast::AddressSpace::kPrivate, cast);
 
     spirv::Builder& b = Build();
 
@@ -4204,7 +4204,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_U32_to_I32) {
-    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<i32>("i");
     WrapInFunction(cast);
@@ -4230,7 +4230,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F32_to_I32) {
-    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<i32>("i");
     WrapInFunction(cast);
@@ -4258,7 +4258,7 @@
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F16_to_I32) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<i32>("i");
     WrapInFunction(cast);
@@ -4284,7 +4284,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_I32_to_U32) {
-    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<u32>("i");
     WrapInFunction(cast);
@@ -4310,7 +4310,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F32_to_U32) {
-    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<u32>("i");
     WrapInFunction(cast);
@@ -4338,7 +4338,7 @@
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F16_to_U32) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<u32>("i");
     WrapInFunction(cast);
@@ -4364,7 +4364,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_I32_to_F32) {
-    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<f32>("i");
     WrapInFunction(cast);
@@ -4390,7 +4390,7 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_U32_to_F32) {
-    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<f32>("i");
     WrapInFunction(cast);
@@ -4418,7 +4418,7 @@
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F16_to_F32) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f16>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<f32>("i");
     WrapInFunction(cast);
@@ -4446,7 +4446,7 @@
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_I32_to_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<i32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<f16>("i");
     WrapInFunction(cast);
@@ -4474,7 +4474,7 @@
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_U32_to_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<u32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<f16>("i");
     WrapInFunction(cast);
@@ -4502,7 +4502,7 @@
 TEST_F(SpvBuilderConstructorTest, Type_Convert_Vectors_F32_to_F16) {
     Enable(ast::Extension::kF16);
 
-    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("i", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* cast = vec3<f16>("i");
     WrapInFunction(cast);
@@ -4590,9 +4590,9 @@
 TEST_F(SpvBuilderConstructorTest, IsConstructorConst_Vector_WithIdent) {
     // vec3<f32>(a, b, c)  -> false
 
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("c", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("c", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* t = vec3<f32>("a", "b", "c");
     WrapInFunction(t);
@@ -4662,8 +4662,8 @@
                                          Member("b", ty.vec3<f32>()),
                                      });
 
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("b", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("b", ty.vec3<f32>(), ast::AddressSpace::kPrivate);
 
     auto* t = Construct(ty.Of(s), "a", "b");
     WrapInFunction(t);
diff --git a/src/tint/writer/spirv/builder_entry_point_test.cc b/src/tint/writer/spirv/builder_entry_point_test.cc
index a4128c1..4cdebf2 100644
--- a/src/tint/writer/spirv/builder_entry_point_test.cc
+++ b/src/tint/writer/spirv/builder_entry_point_test.cc
@@ -15,12 +15,12 @@
 #include <memory>
 
 #include "gtest/gtest.h"
+#include "src/tint/ast/address_space.h"
 #include "src/tint/ast/builtin_attribute.h"
 #include "src/tint/ast/builtin_value.h"
 #include "src/tint/ast/location_attribute.h"
 #include "src/tint/ast/return_statement.h"
 #include "src/tint/ast/stage_attribute.h"
-#include "src/tint/ast/storage_class.h"
 #include "src/tint/ast/variable.h"
 #include "src/tint/program.h"
 #include "src/tint/sem/f32.h"
@@ -62,7 +62,7 @@
     ASSERT_TRUE(b.Build());
 
     // Test that "coord" and "loc1" get hoisted out to global variables with the
-    // Input storage class, retaining their decorations.
+    // Input address space, retaining their decorations.
     EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
 OpMemoryModel Logical GLSL450
 OpEntryPoint Fragment %19 "frag_main" %1 %5
@@ -142,7 +142,7 @@
     ASSERT_TRUE(b.Build());
 
     // Test that the return value gets hoisted out to a global variable with the
-    // Output storage class, and the return statements are replaced with stores.
+    // Output address space, and the return statements are replaced with stores.
     EXPECT_EQ(DumpBuilder(b), R"(OpCapability Shader
 OpMemoryModel Logical GLSL450
 OpEntryPoint Fragment %21 "frag_main" %1 %4
diff --git a/src/tint/writer/spirv/builder_function_test.cc b/src/tint/writer/spirv/builder_function_test.cc
index 449f937..b28817c 100644
--- a/src/tint/writer/spirv/builder_function_test.cc
+++ b/src/tint/writer/spirv/builder_function_test.cc
@@ -61,7 +61,7 @@
 }
 
 TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
 
     Func("a_func", utils::Empty, ty.f32(), utils::Vector{Return("a")}, utils::Empty);
 
@@ -198,7 +198,7 @@
 
     auto* s = Structure("Data", utils::Vector{Member("d", ty.f32())});
 
-    GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(0_a));
 
     {
diff --git a/src/tint/writer/spirv/builder_function_variable_test.cc b/src/tint/writer/spirv/builder_function_variable_test.cc
index 40bc85d..2738634 100644
--- a/src/tint/writer/spirv/builder_function_variable_test.cc
+++ b/src/tint/writer/spirv/builder_function_variable_test.cc
@@ -22,8 +22,8 @@
 
 using BuilderTest = TestHelper;
 
-TEST_F(BuilderTest, FunctionVar_NoStorageClass) {
-    auto* v = Var("var", ty.f32(), ast::StorageClass::kFunction);
+TEST_F(BuilderTest, FunctionVar_NoAddressSpace) {
+    auto* v = Var("var", ty.f32(), ast::AddressSpace::kFunction);
     WrapInFunction(v);
 
     spirv::Builder& b = Build();
@@ -45,7 +45,7 @@
 
 TEST_F(BuilderTest, FunctionVar_WithConstantConstructor) {
     auto* init = vec3<f32>(1_f, 1_f, 3_f);
-    auto* v = Var("var", ty.vec3<f32>(), ast::StorageClass::kFunction, init);
+    auto* v = Var("var", ty.vec3<f32>(), ast::AddressSpace::kFunction, init);
     WrapInFunction(v);
 
     spirv::Builder& b = Build();
diff --git a/src/tint/writer/spirv/builder_global_variable_test.cc b/src/tint/writer/spirv/builder_global_variable_test.cc
index 2c53023..6231d88 100644
--- a/src/tint/writer/spirv/builder_global_variable_test.cc
+++ b/src/tint/writer/spirv/builder_global_variable_test.cc
@@ -24,8 +24,8 @@
 
 using BuilderTest = TestHelper;
 
-TEST_F(BuilderTest, GlobalVar_WithStorageClass) {
-    auto* v = GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
+TEST_F(BuilderTest, GlobalVar_WithAddressSpace) {
+    auto* v = GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -42,7 +42,7 @@
 TEST_F(BuilderTest, GlobalVar_WithConstructor) {
     auto* init = vec3<f32>(1_f, 1_f, 3_f);
 
-    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::StorageClass::kPrivate, init);
+    auto* v = GlobalVar("var", ty.vec3<f32>(), ast::AddressSpace::kPrivate, init);
 
     spirv::Builder& b = Build();
 
@@ -66,7 +66,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", Expr(42_a));
-    GlobalVar("v", ast::StorageClass::kPrivate, Expr(c));
+    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -91,7 +91,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", vec3<f32>(1_f, 2_f, 3_f));
-    GlobalVar("v", ast::StorageClass::kPrivate, Expr(c));
+    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -121,7 +121,7 @@
     Enable(ast::Extension::kF16);
 
     auto* c = GlobalConst("c", vec3<f16>(1_h, 2_h, 3_h));
-    GlobalVar("v", ast::StorageClass::kPrivate, Expr(c));
+    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -150,7 +150,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
-    GlobalVar("v", ast::StorageClass::kPrivate, Expr(c));
+    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -179,7 +179,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
-    GlobalVar("v", ast::StorageClass::kPrivate, Expr(c));
+    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -208,7 +208,7 @@
     // var v = c;
 
     auto* c = GlobalConst("c", vec3<f32>(vec2<f32>(1_f, 2_f), 3_f));
-    GlobalVar("v", ast::StorageClass::kPrivate, Expr(c));
+    GlobalVar("v", ast::AddressSpace::kPrivate, Expr(c));
 
     spirv::Builder& b = SanitizeAndBuild();
 
@@ -251,7 +251,7 @@
 
 struct BuiltinData {
     ast::BuiltinValue builtin;
-    ast::StorageClass storage;
+    ast::AddressSpace storage;
     SpvBuiltIn result;
 };
 inline std::ostream& operator<<(std::ostream& out, BuiltinData data) {
@@ -270,30 +270,30 @@
     BuilderTest_Type,
     BuiltinDataTest,
     testing::Values(
-        BuiltinData{ast::BuiltinValue::kInvalid, ast::StorageClass::kNone, SpvBuiltInMax},
-        BuiltinData{ast::BuiltinValue::kPosition, ast::StorageClass::kIn, SpvBuiltInFragCoord},
-        BuiltinData{ast::BuiltinValue::kPosition, ast::StorageClass::kOut, SpvBuiltInPosition},
+        BuiltinData{ast::BuiltinValue::kInvalid, ast::AddressSpace::kNone, SpvBuiltInMax},
+        BuiltinData{ast::BuiltinValue::kPosition, ast::AddressSpace::kIn, SpvBuiltInFragCoord},
+        BuiltinData{ast::BuiltinValue::kPosition, ast::AddressSpace::kOut, SpvBuiltInPosition},
         BuiltinData{
             ast::BuiltinValue::kVertexIndex,
-            ast::StorageClass::kIn,
+            ast::AddressSpace::kIn,
             SpvBuiltInVertexIndex,
         },
-        BuiltinData{ast::BuiltinValue::kInstanceIndex, ast::StorageClass::kIn,
+        BuiltinData{ast::BuiltinValue::kInstanceIndex, ast::AddressSpace::kIn,
                     SpvBuiltInInstanceIndex},
-        BuiltinData{ast::BuiltinValue::kFrontFacing, ast::StorageClass::kIn, SpvBuiltInFrontFacing},
-        BuiltinData{ast::BuiltinValue::kFragDepth, ast::StorageClass::kOut, SpvBuiltInFragDepth},
-        BuiltinData{ast::BuiltinValue::kLocalInvocationId, ast::StorageClass::kIn,
+        BuiltinData{ast::BuiltinValue::kFrontFacing, ast::AddressSpace::kIn, SpvBuiltInFrontFacing},
+        BuiltinData{ast::BuiltinValue::kFragDepth, ast::AddressSpace::kOut, SpvBuiltInFragDepth},
+        BuiltinData{ast::BuiltinValue::kLocalInvocationId, ast::AddressSpace::kIn,
                     SpvBuiltInLocalInvocationId},
-        BuiltinData{ast::BuiltinValue::kLocalInvocationIndex, ast::StorageClass::kIn,
+        BuiltinData{ast::BuiltinValue::kLocalInvocationIndex, ast::AddressSpace::kIn,
                     SpvBuiltInLocalInvocationIndex},
-        BuiltinData{ast::BuiltinValue::kGlobalInvocationId, ast::StorageClass::kIn,
+        BuiltinData{ast::BuiltinValue::kGlobalInvocationId, ast::AddressSpace::kIn,
                     SpvBuiltInGlobalInvocationId},
-        BuiltinData{ast::BuiltinValue::kWorkgroupId, ast::StorageClass::kIn, SpvBuiltInWorkgroupId},
-        BuiltinData{ast::BuiltinValue::kNumWorkgroups, ast::StorageClass::kIn,
+        BuiltinData{ast::BuiltinValue::kWorkgroupId, ast::AddressSpace::kIn, SpvBuiltInWorkgroupId},
+        BuiltinData{ast::BuiltinValue::kNumWorkgroups, ast::AddressSpace::kIn,
                     SpvBuiltInNumWorkgroups},
-        BuiltinData{ast::BuiltinValue::kSampleIndex, ast::StorageClass::kIn, SpvBuiltInSampleId},
-        BuiltinData{ast::BuiltinValue::kSampleMask, ast::StorageClass::kIn, SpvBuiltInSampleMask},
-        BuiltinData{ast::BuiltinValue::kSampleMask, ast::StorageClass::kOut,
+        BuiltinData{ast::BuiltinValue::kSampleIndex, ast::AddressSpace::kIn, SpvBuiltInSampleId},
+        BuiltinData{ast::BuiltinValue::kSampleMask, ast::AddressSpace::kIn, SpvBuiltInSampleMask},
+        BuiltinData{ast::BuiltinValue::kSampleMask, ast::AddressSpace::kOut,
                     SpvBuiltInSampleMask}));
 
 TEST_F(BuilderTest, GlobalVar_DeclReadOnly) {
@@ -307,7 +307,7 @@
                                  Member("b", ty.i32()),
                              });
 
-    GlobalVar("b", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("b", ty.Of(A), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -345,7 +345,7 @@
 
     auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
     auto* B = Alias("B", ty.Of(A));
-    GlobalVar("b", ty.Of(B), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("b", ty.Of(B), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -381,7 +381,7 @@
 
     auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
     auto* B = Alias("B", ty.Of(A));
-    GlobalVar("b", ty.Of(B), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("b", ty.Of(B), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -416,9 +416,9 @@
     // var<storage, read_write> c : A
 
     auto* A = Structure("A", utils::Vector{Member("a", ty.i32())});
-    GlobalVar("b", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kRead, Group(0_a),
+    GlobalVar("b", ty.Of(A), ast::AddressSpace::kStorage, ast::Access::kRead, Group(0_a),
               Binding(0_a));
-    GlobalVar("c", ty.Of(A), ast::StorageClass::kStorage, ast::Access::kReadWrite, Group(1_a),
+    GlobalVar("c", ty.Of(A), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Group(1_a),
               Binding(0_a));
 
     spirv::Builder& b = SanitizeAndBuild();
@@ -514,16 +514,16 @@
 
 TEST_F(BuilderTest, GlobalVar_WorkgroupWithZeroInit) {
     auto* type_scalar = ty.i32();
-    auto* var_scalar = GlobalVar("a", type_scalar, ast::StorageClass::kWorkgroup);
+    auto* var_scalar = GlobalVar("a", type_scalar, ast::AddressSpace::kWorkgroup);
 
     auto* type_array = ty.array<f32, 16>();
-    auto* var_array = GlobalVar("b", type_array, ast::StorageClass::kWorkgroup);
+    auto* var_array = GlobalVar("b", type_array, ast::AddressSpace::kWorkgroup);
 
     auto* type_struct = Structure("C", utils::Vector{
                                            Member("a", ty.i32()),
                                            Member("b", ty.i32()),
                                        });
-    auto* var_struct = GlobalVar("c", ty.Of(type_struct), ast::StorageClass::kWorkgroup);
+    auto* var_struct = GlobalVar("c", ty.Of(type_struct), ast::AddressSpace::kWorkgroup);
 
     program = std::make_unique<Program>(std::move(*this));
 
diff --git a/src/tint/writer/spirv/builder_ident_expression_test.cc b/src/tint/writer/spirv/builder_ident_expression_test.cc
index 0f24146..5d01db3 100644
--- a/src/tint/writer/spirv/builder_ident_expression_test.cc
+++ b/src/tint/writer/spirv/builder_ident_expression_test.cc
@@ -41,7 +41,7 @@
 }
 
 TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
-    auto* v = GlobalVar("var", ty.f32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("var", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* expr = Expr("var");
     WrapInFunction(expr);
@@ -85,7 +85,7 @@
 }
 
 TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
-    auto* v = Var("var", ty.f32(), ast::StorageClass::kFunction);
+    auto* v = Var("var", ty.f32(), ast::AddressSpace::kFunction);
     auto* expr = Expr("var");
     WrapInFunction(v, expr);
 
@@ -109,7 +109,7 @@
 }
 
 TEST_F(BuilderTest, IdentifierExpression_Load) {
-    auto* var = GlobalVar("var", ty.i32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("var", ty.i32(), ast::AddressSpace::kPrivate);
     auto* expr = Add("var", "var");
     WrapInFunction(expr);
 
diff --git a/src/tint/writer/spirv/builder_if_test.cc b/src/tint/writer/spirv/builder_if_test.cc
index 6705cce..a83b0cf 100644
--- a/src/tint/writer/spirv/builder_if_test.cc
+++ b/src/tint/writer/spirv/builder_if_test.cc
@@ -68,7 +68,7 @@
     //   v = 2;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i));
     auto* expr = If(true, body);
     WrapInFunction(expr);
@@ -104,7 +104,7 @@
     //   v = 3i;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i));
     auto* else_body = Block(Assign("v", 3_i));
 
@@ -146,7 +146,7 @@
     //   v = 3i;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i));
     auto* else_body = Block(Assign("v", 3_i));
 
@@ -197,7 +197,7 @@
     //   v = 5i;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i));
     auto* elseif_1_body = Block(Assign("v", 3_i));
     auto* elseif_2_body = Block(Assign("v", 4_i));
@@ -562,7 +562,7 @@
     // if (a) {
     // }
 
-    auto* var = GlobalVar("a", ty.bool_(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("a", ty.bool_(), ast::AddressSpace::kPrivate);
     auto* fn = Func("f", utils::Empty, ty.void_(),
                     utils::Vector{
                         If("a", Block()),
diff --git a/src/tint/writer/spirv/builder_loop_test.cc b/src/tint/writer/spirv/builder_loop_test.cc
index 7e7f327..3ab27ef 100644
--- a/src/tint/writer/spirv/builder_loop_test.cc
+++ b/src/tint/writer/spirv/builder_loop_test.cc
@@ -54,7 +54,7 @@
     //   break;
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i),  //
                        Break());
 
@@ -96,7 +96,7 @@
     //   }
     // }
 
-    auto* var = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
+    auto* var = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
     auto* body = Block(Assign("v", 2_i),  //
                        Break());
     auto* continuing = Block(Assign("v", 3_i));
diff --git a/src/tint/writer/spirv/builder_switch_test.cc b/src/tint/writer/spirv/builder_switch_test.cc
index c2f526e..4ee8f39 100644
--- a/src/tint/writer/spirv/builder_switch_test.cc
+++ b/src/tint/writer/spirv/builder_switch_test.cc
@@ -57,8 +57,8 @@
     //   default: {}
     // }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -114,8 +114,8 @@
     //   default: {}
     // }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* a = GlobalVar("a", ty.u32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.u32(), ast::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -171,8 +171,8 @@
     //     v = 1i;
     //  }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -221,8 +221,8 @@
     //      v = 3i;
     //  }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -284,8 +284,8 @@
     //      v = 3i;
     //  }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
@@ -346,8 +346,8 @@
     //   default: {}
     // }
 
-    auto* v = GlobalVar("v", ty.i32(), ast::StorageClass::kPrivate);
-    auto* a = GlobalVar("a", ty.i32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("v", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* a = GlobalVar("a", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* func = Func("a_func", utils::Empty, ty.void_(),
                       utils::Vector{
diff --git a/src/tint/writer/spirv/builder_type_test.cc b/src/tint/writer/spirv/builder_type_test.cc
index ea530d2..a17dcb5 100644
--- a/src/tint/writer/spirv/builder_type_test.cc
+++ b/src/tint/writer/spirv/builder_type_test.cc
@@ -28,7 +28,7 @@
 TEST_F(BuilderTest_Type, GenerateRuntimeArray) {
     auto* ary = ty.array(ty.i32());
     auto* str = Structure("S", utils::Vector{Member("x", ary)});
-    GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("a", ty.Of(str), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = Build();
@@ -45,7 +45,7 @@
 TEST_F(BuilderTest_Type, ReturnsGeneratedRuntimeArray) {
     auto* ary = ty.array(ty.i32());
     auto* str = Structure("S", utils::Vector{Member("x", ary)});
-    GlobalVar("a", ty.Of(str), ast::StorageClass::kStorage, ast::Access::kRead, Binding(0_a),
+    GlobalVar("a", ty.Of(str), ast::AddressSpace::kStorage, ast::Access::kRead, Binding(0_a),
               Group(0_a));
 
     spirv::Builder& b = Build();
@@ -61,7 +61,7 @@
 
 TEST_F(BuilderTest_Type, GenerateArray) {
     auto* ary = ty.array(ty.i32(), 4_u);
-    GlobalVar("a", ary, ast::StorageClass::kPrivate);
+    GlobalVar("a", ary, ast::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -78,7 +78,7 @@
 
 TEST_F(BuilderTest_Type, GenerateArray_WithStride) {
     auto* ary = ty.array(ty.i32(), 4_u, 16u);
-    GlobalVar("a", ary, ast::StorageClass::kPrivate);
+    GlobalVar("a", ary, ast::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -98,7 +98,7 @@
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedArray) {
     auto* ary = ty.array(ty.i32(), 4_u);
-    GlobalVar("a", ary, ast::StorageClass::kPrivate);
+    GlobalVar("a", ary, ast::AddressSpace::kPrivate);
 
     spirv::Builder& b = Build();
 
@@ -293,7 +293,7 @@
 
 TEST_F(BuilderTest_Type, GeneratePtr) {
     auto* i32 = create<sem::I32>();
-    auto* ptr = create<sem::Pointer>(i32, ast::StorageClass::kOut, ast::Access::kReadWrite);
+    auto* ptr = create<sem::Pointer>(i32, ast::AddressSpace::kOut, ast::Access::kReadWrite);
 
     spirv::Builder& b = Build();
 
@@ -308,7 +308,7 @@
 
 TEST_F(BuilderTest_Type, ReturnsGeneratedPtr) {
     auto* i32 = create<sem::I32>();
-    auto* ptr = create<sem::Pointer>(i32, ast::StorageClass::kOut, ast::Access::kReadWrite);
+    auto* ptr = create<sem::Pointer>(i32, ast::AddressSpace::kOut, ast::Access::kReadWrite);
 
     spirv::Builder& b = Build();
 
@@ -576,7 +576,7 @@
 }
 
 struct PtrData {
-    ast::StorageClass ast_class;
+    ast::AddressSpace ast_class;
     SpvStorageClass result;
 };
 inline std::ostream& operator<<(std::ostream& out, PtrData data) {
@@ -584,25 +584,25 @@
     return out;
 }
 using PtrDataTest = TestParamHelper<PtrData>;
-TEST_P(PtrDataTest, ConvertStorageClass) {
+TEST_P(PtrDataTest, ConvertAddressSpace) {
     auto params = GetParam();
 
     spirv::Builder& b = Build();
 
-    EXPECT_EQ(b.ConvertStorageClass(params.ast_class), params.result);
+    EXPECT_EQ(b.ConvertAddressSpace(params.ast_class), params.result);
 }
 INSTANTIATE_TEST_SUITE_P(
     BuilderTest_Type,
     PtrDataTest,
-    testing::Values(PtrData{ast::StorageClass::kNone, SpvStorageClassMax},
-                    PtrData{ast::StorageClass::kIn, SpvStorageClassInput},
-                    PtrData{ast::StorageClass::kOut, SpvStorageClassOutput},
-                    PtrData{ast::StorageClass::kUniform, SpvStorageClassUniform},
-                    PtrData{ast::StorageClass::kWorkgroup, SpvStorageClassWorkgroup},
-                    PtrData{ast::StorageClass::kHandle, SpvStorageClassUniformConstant},
-                    PtrData{ast::StorageClass::kStorage, SpvStorageClassStorageBuffer},
-                    PtrData{ast::StorageClass::kPrivate, SpvStorageClassPrivate},
-                    PtrData{ast::StorageClass::kFunction, SpvStorageClassFunction}));
+    testing::Values(PtrData{ast::AddressSpace::kNone, SpvStorageClassMax},
+                    PtrData{ast::AddressSpace::kIn, SpvStorageClassInput},
+                    PtrData{ast::AddressSpace::kOut, SpvStorageClassOutput},
+                    PtrData{ast::AddressSpace::kUniform, SpvStorageClassUniform},
+                    PtrData{ast::AddressSpace::kWorkgroup, SpvStorageClassWorkgroup},
+                    PtrData{ast::AddressSpace::kHandle, SpvStorageClassUniformConstant},
+                    PtrData{ast::AddressSpace::kStorage, SpvStorageClassStorageBuffer},
+                    PtrData{ast::AddressSpace::kPrivate, SpvStorageClassPrivate},
+                    PtrData{ast::AddressSpace::kFunction, SpvStorageClassFunction}));
 
 TEST_F(BuilderTest_Type, DepthTexture_Generate_2d) {
     auto* two_d = create<sem::DepthTexture>(ast::TextureDimension::k2d);
diff --git a/src/tint/writer/spirv/generator_impl.h b/src/tint/writer/spirv/generator_impl.h
index 106e2f8..c83f144 100644
--- a/src/tint/writer/spirv/generator_impl.h
+++ b/src/tint/writer/spirv/generator_impl.h
@@ -42,7 +42,7 @@
     /// Constructor
     /// @param program the program to generate
     /// @param zero_initialize_workgroup_memory `true` to initialize all the
-    /// variables in the Workgroup storage class with OpConstantNull
+    /// variables in the Workgroup address space with OpConstantNull
     GeneratorImpl(const Program* program, bool zero_initialize_workgroup_memory);
 
     /// @returns true on successful generation; false otherwise
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index 83a96d9..05f1a5a 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -429,7 +429,7 @@
             return true;
         },
         [&](const ast::Pointer* ptr) {
-            out << "ptr<" << ptr->storage_class << ", ";
+            out << "ptr<" << ptr->address_space << ", ";
             if (!EmitType(out, ptr->type)) {
                 return false;
             }
@@ -654,10 +654,10 @@
         v,  //
         [&](const ast::Var* var) {
             out << "var";
-            auto sc = var->declared_storage_class;
+            auto address_space = var->declared_address_space;
             auto ac = var->declared_access;
-            if (sc != ast::StorageClass::kNone || ac != ast::Access::kUndefined) {
-                out << "<" << sc;
+            if (address_space != ast::AddressSpace::kNone || ac != ast::Access::kUndefined) {
+                out << "<" << address_space;
                 if (ac != ast::Access::kUndefined) {
                     out << ", ";
                     if (!EmitAccess(out, ac)) {
diff --git a/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc b/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
index 0b28ae9..652f598 100644
--- a/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, IndexAccessor) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
     auto* expr = IndexAccessor("ary", 5_i);
     WrapInFunction(expr);
 
@@ -34,7 +34,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, IndexAccessor_OfDref) {
-    GlobalVar("ary", ty.array<i32, 10>(), ast::StorageClass::kPrivate);
+    GlobalVar("ary", ty.array<i32, 10>(), ast::AddressSpace::kPrivate);
 
     auto* p = Let("p", AddressOf("ary"));
     auto* expr = IndexAccessor(Deref("p"), 5_i);
diff --git a/src/tint/writer/wgsl/generator_impl_assign_test.cc b/src/tint/writer/wgsl/generator_impl_assign_test.cc
index e390d2f..85d4d90 100644
--- a/src/tint/writer/wgsl/generator_impl_assign_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_assign_test.cc
@@ -20,8 +20,8 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Assign) {
-    auto* lhs = GlobalVar("lhs", ty.i32(), ast::StorageClass::kPrivate);
-    auto* rhs = GlobalVar("rhs", ty.i32(), ast::StorageClass::kPrivate);
+    auto* lhs = GlobalVar("lhs", ty.i32(), ast::AddressSpace::kPrivate);
+    auto* rhs = GlobalVar("rhs", ty.i32(), ast::AddressSpace::kPrivate);
     auto* assign = Assign(lhs, rhs);
     WrapInFunction(assign);
 
diff --git a/src/tint/writer/wgsl/generator_impl_binary_test.cc b/src/tint/writer/wgsl/generator_impl_binary_test.cc
index 682c001..d069fe6 100644
--- a/src/tint/writer/wgsl/generator_impl_binary_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_binary_test.cc
@@ -37,8 +37,8 @@
         }
     };
 
-    GlobalVar("left", op_ty(), ast::StorageClass::kPrivate);
-    GlobalVar("right", op_ty(), ast::StorageClass::kPrivate);
+    GlobalVar("left", op_ty(), ast::AddressSpace::kPrivate);
+    GlobalVar("right", op_ty(), ast::AddressSpace::kPrivate);
     auto* left = Expr("left");
     auto* right = Expr("right");
 
diff --git a/src/tint/writer/wgsl/generator_impl_call_test.cc b/src/tint/writer/wgsl/generator_impl_call_test.cc
index 4746be2..6b22d2a 100644
--- a/src/tint/writer/wgsl/generator_impl_call_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_call_test.cc
@@ -48,8 +48,8 @@
          utils::Vector{
              Return(1.23_f),
          });
-    GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     WrapInFunction(call);
@@ -68,8 +68,8 @@
              Param(Sym(), ty.f32()),
          },
          ty.void_(), utils::Empty, utils::Empty);
-    GlobalVar("param1", ty.f32(), ast::StorageClass::kPrivate);
-    GlobalVar("param2", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("param1", ty.f32(), ast::AddressSpace::kPrivate);
+    GlobalVar("param2", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* call = Call("my_func", "param1", "param2");
     auto* stmt = CallStmt(call);
diff --git a/src/tint/writer/wgsl/generator_impl_function_test.cc b/src/tint/writer/wgsl/generator_impl_function_test.cc
index af09a13..e785520 100644
--- a/src/tint/writer/wgsl/generator_impl_function_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_function_test.cc
@@ -179,7 +179,7 @@
                                     Member("d", ty.f32()),
                                 });
 
-    GlobalVar("data", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite, Binding(0_a),
+    GlobalVar("data", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite, Binding(0_a),
               Group(0_a));
 
     {
diff --git a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
index bc77623..db45e79 100644
--- a/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_global_decl_test.cc
@@ -28,7 +28,7 @@
     auto* func_var = Var("a", ty.f32());
     WrapInFunction(func_var);
 
-    GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -45,7 +45,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
-    GlobalVar("a0", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a0", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* s0 = Structure("S0", utils::Vector{
                                    Member("a", ty.i32()),
@@ -57,7 +57,7 @@
          },
          utils::Empty);
 
-    GlobalVar("a1", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("a1", ty.f32(), ast::AddressSpace::kPrivate);
 
     auto* s1 = Structure("S1", utils::Vector{
                                    Member("a", ty.i32()),
diff --git a/src/tint/writer/wgsl/generator_impl_identifier_test.cc b/src/tint/writer/wgsl/generator_impl_identifier_test.cc
index 2e20d4c..25e2a7a 100644
--- a/src/tint/writer/wgsl/generator_impl_identifier_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_identifier_test.cc
@@ -20,7 +20,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitIdentifierExpression_Single) {
-    GlobalVar("glsl", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("glsl", ty.f32(), ast::AddressSpace::kPrivate);
     auto* i = Expr("glsl");
     WrapInFunction(i);
 
diff --git a/src/tint/writer/wgsl/generator_impl_if_test.cc b/src/tint/writer/wgsl/generator_impl_if_test.cc
index 88f6aba..eeaa75f 100644
--- a/src/tint/writer/wgsl/generator_impl_if_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_if_test.cc
@@ -20,7 +20,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_If) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* cond = Expr("cond");
     auto* body = Block(Return());
@@ -39,8 +39,8 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElseIf) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
     auto* else_body = Block(Return());
@@ -64,7 +64,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_body = Block(Return());
 
@@ -87,8 +87,8 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithMultiple) {
-    GlobalVar("cond", ty.bool_(), ast::StorageClass::kPrivate);
-    GlobalVar("else_cond", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.bool_(), ast::AddressSpace::kPrivate);
+    GlobalVar("else_cond", ty.bool_(), ast::AddressSpace::kPrivate);
 
     auto* else_cond = Expr("else_cond");
 
diff --git a/src/tint/writer/wgsl/generator_impl_loop_test.cc b/src/tint/writer/wgsl/generator_impl_loop_test.cc
index 3570957..f4b6898 100644
--- a/src/tint/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_loop_test.cc
@@ -68,7 +68,7 @@
     // for({ignore(1i); ignore(2i);}; ; ) {
     //   return;
     // }
-    GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
     auto* multi_stmt = Block(Ignore(1_i), Ignore(2_i));
     auto* f = For(multi_stmt, nullptr, nullptr, Block(Return()));
     WrapInFunction(f);
@@ -132,7 +132,7 @@
     //   return;
     // }
 
-    GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
     auto* multi_stmt = Block(Ignore(1_i), Ignore(2_i));
     auto* f = For(nullptr, nullptr, multi_stmt, Block(Return()));
     WrapInFunction(f);
@@ -175,7 +175,7 @@
     // for({ ignore(1i); ignore(2i); }; true; { ignore(3i); ignore(4i); }) {
     //   return;
     // }
-    GlobalVar("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
+    GlobalVar("a", ty.atomic<i32>(), ast::AddressSpace::kWorkgroup);
     auto* multi_stmt_a = Block(Ignore(1_i), Ignore(2_i));
     auto* multi_stmt_b = Block(Ignore(3_i), Ignore(4_i));
     auto* f = For(multi_stmt_a, Expr(true), multi_stmt_b, Block(Return()));
diff --git a/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc b/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
index 849f018..9bb695d 100644
--- a/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_member_accessor_test.cc
@@ -21,7 +21,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor) {
     auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
-    GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("str", ty.Of(s), ast::AddressSpace::kPrivate);
 
     auto* expr = MemberAccessor("str", "mem");
     WrapInFunction(expr);
@@ -35,7 +35,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitExpression_MemberAccessor_OfDref) {
     auto* s = Structure("Data", utils::Vector{Member("mem", ty.f32())});
-    GlobalVar("str", ty.Of(s), ast::StorageClass::kPrivate);
+    GlobalVar("str", ty.Of(s), ast::AddressSpace::kPrivate);
 
     auto* p = Let("p", AddressOf("str"));
     auto* expr = MemberAccessor(Deref("p"), "mem");
diff --git a/src/tint/writer/wgsl/generator_impl_switch_test.cc b/src/tint/writer/wgsl/generator_impl_switch_test.cc
index 491660e..5cf0ed2 100644
--- a/src/tint/writer/wgsl/generator_impl_switch_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Switch) {
-    GlobalVar("cond", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("cond", ty.i32(), ast::AddressSpace::kPrivate);
 
     auto* def_body = Block(create<ast::BreakStatement>());
     auto* def = create<ast::CaseStatement>(utils::Empty, def_body);
diff --git a/src/tint/writer/wgsl/generator_impl_type_test.cc b/src/tint/writer/wgsl/generator_impl_type_test.cc
index f6f39d4..13c8411 100644
--- a/src/tint/writer/wgsl/generator_impl_type_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_type_test.cc
@@ -140,7 +140,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_Pointer) {
-    auto* p = ty.pointer<f32>(ast::StorageClass::kWorkgroup);
+    auto* p = ty.pointer<f32>(ast::AddressSpace::kWorkgroup);
     Alias("make_type_reachable", p);
 
     GeneratorImpl& gen = Build();
@@ -151,7 +151,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitType_PointerAccessMode) {
-    auto* p = ty.pointer<f32>(ast::StorageClass::kStorage, ast::Access::kReadWrite);
+    auto* p = ty.pointer<f32>(ast::AddressSpace::kStorage, ast::Access::kReadWrite);
     Alias("make_type_reachable", p);
 
     GeneratorImpl& gen = Build();
diff --git a/src/tint/writer/wgsl/generator_impl_unary_op_test.cc b/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
index dadcede..0d5edd5 100644
--- a/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_unary_op_test.cc
@@ -20,7 +20,7 @@
 using WgslUnaryOpTest = TestHelper;
 
 TEST_F(WgslUnaryOpTest, AddressOf) {
-    GlobalVar("expr", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.f32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("expr"));
     WrapInFunction(op);
 
@@ -32,7 +32,7 @@
 }
 
 TEST_F(WgslUnaryOpTest, Complement) {
-    GlobalVar("expr", ty.u32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.u32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kComplement, Expr("expr"));
     WrapInFunction(op);
 
@@ -44,7 +44,7 @@
 }
 
 TEST_F(WgslUnaryOpTest, Indirection) {
-    GlobalVar("G", ty.f32(), ast::StorageClass::kPrivate);
+    GlobalVar("G", ty.f32(), ast::AddressSpace::kPrivate);
     auto* p = Let("expr", create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf, Expr("G")));
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection, Expr("expr"));
     WrapInFunction(p, op);
@@ -57,7 +57,7 @@
 }
 
 TEST_F(WgslUnaryOpTest, Not) {
-    GlobalVar("expr", ty.bool_(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.bool_(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNot, Expr("expr"));
     WrapInFunction(op);
 
@@ -69,7 +69,7 @@
 }
 
 TEST_F(WgslUnaryOpTest, Negation) {
-    GlobalVar("expr", ty.i32(), ast::StorageClass::kPrivate);
+    GlobalVar("expr", ty.i32(), ast::AddressSpace::kPrivate);
     auto* op = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("expr"));
     WrapInFunction(op);
 
diff --git a/src/tint/writer/wgsl/generator_impl_variable_test.cc b/src/tint/writer/wgsl/generator_impl_variable_test.cc
index f1ac216..b7c894e 100644
--- a/src/tint/writer/wgsl/generator_impl_variable_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_variable_test.cc
@@ -22,7 +22,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, EmitVariable) {
-    auto* v = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+    auto* v = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -31,8 +31,8 @@
     EXPECT_EQ(out.str(), R"(var<private> a : f32;)");
 }
 
-TEST_F(WgslGeneratorImplTest, EmitVariable_StorageClass) {
-    auto* v = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate);
+TEST_F(WgslGeneratorImplTest, EmitVariable_AddressSpace) {
+    auto* v = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
 
     GeneratorImpl& gen = Build();
 
@@ -43,7 +43,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Access_Read) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.i32())});
-    auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kRead,
+    auto* v = GlobalVar("a", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kRead,
                         Binding(0_a), Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -55,7 +55,7 @@
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Access_ReadWrite) {
     auto* s = Structure("S", utils::Vector{Member("a", ty.i32())});
-    auto* v = GlobalVar("a", ty.Of(s), ast::StorageClass::kStorage, ast::Access::kReadWrite,
+    auto* v = GlobalVar("a", ty.Of(s), ast::AddressSpace::kStorage, ast::Access::kReadWrite,
                         Binding(0_a), Group(0_a));
 
     GeneratorImpl& gen = Build();
@@ -76,7 +76,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, EmitVariable_Constructor) {
-    auto* v = GlobalVar("a", ty.f32(), ast::StorageClass::kPrivate, Expr(1_f));
+    auto* v = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate, Expr(1_f));
 
     GeneratorImpl& gen = Build();
 
diff --git a/test/tint/array/assign_to_function_var.wgsl b/test/tint/array/assign_to_function_var.wgsl
index 0d9e9c8..968ca92 100644
--- a/test/tint/array/assign_to_function_var.wgsl
+++ b/test/tint/array/assign_to_function_var.wgsl
@@ -35,12 +35,12 @@
   let src_let : ArrayType = ArrayType();
   dst = src_let;
 
-  // Assign from var, various storage classes.
+  // Assign from var, various address spaces.
   dst = src_function;
   dst = src_private;
   dst = src_workgroup;
 
-  // Assign from struct.arr, various storage classes.
+  // Assign from struct.arr, various address spaces.
   dst = ret_struct_arr().arr;
   dst = src_uniform.arr;
   dst = src_storage.arr;
diff --git a/test/tint/array/assign_to_private_var.wgsl b/test/tint/array/assign_to_private_var.wgsl
index 87a6ac4..6a32874 100644
--- a/test/tint/array/assign_to_private_var.wgsl
+++ b/test/tint/array/assign_to_private_var.wgsl
@@ -36,12 +36,12 @@
   let src_let : ArrayType = ArrayType();
   dst = src_let;
 
-  // Assign from var, various storage classes.
+  // Assign from var, various address spaces.
   dst = src_function;
   dst = src_private;
   dst = src_workgroup;
 
-  // Assign from struct.arr, various storage classes.
+  // Assign from struct.arr, various address spaces.
   dst = ret_struct_arr().arr;
   dst = src_uniform.arr;
   dst = src_storage.arr;
diff --git a/test/tint/array/assign_to_storage_var.wgsl b/test/tint/array/assign_to_storage_var.wgsl
index 63d835f..879219d 100644
--- a/test/tint/array/assign_to_storage_var.wgsl
+++ b/test/tint/array/assign_to_storage_var.wgsl
@@ -40,12 +40,12 @@
   let src_let : ArrayType = ArrayType();
   dst.arr = src_let;
 
-  // Assign from var, various storage classes.
+  // Assign from var, various address spaces.
   dst.arr = src_function;
   dst.arr = src_private;
   dst.arr = src_workgroup;
 
-  // Assign from struct.arr, various storage classes.
+  // Assign from struct.arr, various address spaces.
   dst.arr = ret_struct_arr().arr;
   dst.arr = src_uniform.arr;
   dst.arr = src_storage.arr;
diff --git a/test/tint/array/assign_to_workgroup_var.wgsl b/test/tint/array/assign_to_workgroup_var.wgsl
index 8c9d2bf..aae2e7d 100644
--- a/test/tint/array/assign_to_workgroup_var.wgsl
+++ b/test/tint/array/assign_to_workgroup_var.wgsl
@@ -36,12 +36,12 @@
   let src_let : ArrayType = ArrayType();
   dst = src_let;
 
-  // Assign from var, various storage classes.
+  // Assign from var, various address spaces.
   dst = src_function;
   dst = src_private;
   dst = src_workgroup;
 
-  // Assign from struct.arr, various storage classes.
+  // Assign from struct.arr, various address spaces.
   dst = ret_struct_arr().arr;
   dst = src_uniform.arr;
   dst = src_storage.arr;
diff --git a/test/tint/builtins/gen/gen.wgsl.tmpl b/test/tint/builtins/gen/gen.wgsl.tmpl
index 25e174e..c896623 100644
--- a/test/tint/builtins/gen/gen.wgsl.tmpl
+++ b/test/tint/builtins/gen/gen.wgsl.tmpl
@@ -81,7 +81,7 @@
 
 {{- /* Generate module-scoped handle variables */ -}}
 {{-   range $i, $p := $overload.Parameters  }}
-{{-     $class := Eval "StorageClass" $p.Type -}}
+{{-     $class := Eval "AddressSpace" $p.Type -}}
 {{-     if eq "ptr" $p.Type.Target.Name -}}
 {{-       $el_type := Eval "Type" (index $p.Type.TemplateArguments 1)}}
 {{-       if eq "handle" $class -}}
@@ -115,7 +115,7 @@
 fn {{$permutation}}() {
 {{/* Build the parameters either as 'var' or inline values */ -}}
 {{-   range $i, $p := $overload.Parameters -}}
-{{-     $class       := Eval "StorageClass" $p.Type -}}
+{{-     $class       := Eval "AddressSpace" $p.Type -}}
 {{-     $is_abstract := DeepestElementType $p.Type | IsAbstract -}}
 {{-     if eq "function" $class -}}
 {{-       if eq "ptr" $p.Type.Target.Name -}}
@@ -193,12 +193,12 @@
 
 {{- /* ------------------------------------------------------------------ */ -}}
 {{-                       define "EmitBufferFields"                          -}}
-{{- /* Emits a struct with the fields that match the given storage class  */ -}}
+{{- /* Emits a struct with the fields that match the given address space  */ -}}
 {{- /* and access.                                                        */ -}}
 {{- /* Argument is a map with the following expected keys:                */ -}}
 {{- /*  'overload' - the current overload                                 */ -}}
 {{- /*  'var_name' - name of the variable of the structure type           */ -}}
-{{- /*  'storage'  - filtered storage class                               */ -}}
+{{- /*  'storage'  - filtered address space                               */ -}}
 {{- /*  'access'   - filtered access                                      */ -}}
 {{- /*  'args'     - argument map that's populated with the fields        */ -}}
 {{- /* ------------------------------------------------------------------ */ -}}
@@ -208,9 +208,9 @@
 {{- $filter_access  := .Get "access"   -}}
 {{- $args           := .Get "args"     -}}
 {{-   range $i, $p := $overload.Parameters  }}
-{{-     $storage := Eval "StorageClass" $p.Type -}}
+{{-     $address_space := Eval "AddressSpace" $p.Type -}}
 {{-     $access  := Eval "Access"       $p.Type -}}
-{{-     if and (eq $filter_storage $storage) (eq $filter_access $access) }}
+{{-     if and (eq $filter_storage $address_space) (eq $filter_access $access) }}
 {{-       if eq "ptr" $p.Type.Target.Name  }}
   arg_{{$i}}: {{template "Type" (index $p.Type.TemplateArguments 1)}},
 {{          $args.Put $i (printf "&%v.arg_%v" $var_name $i) -}}
@@ -224,8 +224,8 @@
 
 
 {{- /* ------------------------------------------------------------------ */ -}}
-{{-                           define "StorageClass"                          -}}
-{{- /* Returns the storage class for the given Fully Qualified Name       */ -}}
+{{-                           define "AddressSpace"                          -}}
+{{- /* Returns the address space for the given Fully Qualified Name       */ -}}
 {{- /* ------------------------------------------------------------------ */ -}}
 {{-   $name := .Target.Name -}}
 {{-   if             eq $name "array"   -}}storage
@@ -244,15 +244,15 @@
 {{-   $name := .Target.Name -}}
 {{-   if eq $name "ptr"     -}}{{(index .TemplateArguments 2).Target.Name}}
 {{-   else -}}
-{{- /*  Emit the default for the storage class */ -}}
+{{- /*  Emit the default for the address space */ -}}
 {{- /*  https://gpuweb.github.io/gpuweb/wgsl/#storage-class */ -}}
-{{-     $storage := Eval "StorageClass" . -}}
-{{-          if eq $storage "function"  -}}read_write
-{{-     else if eq $storage "private"   -}}read_write
-{{-     else if eq $storage "workgroup" -}}read_write
-{{-     else if eq $storage "uniform"   -}}read
-{{-     else if eq $storage "storage"   -}}read
-{{-     else if eq $storage "handle"    -}}read
+{{-     $address_space := Eval "AddressSpace" . -}}
+{{-          if eq $address_space "function"  -}}read_write
+{{-     else if eq $address_space "private"   -}}read_write
+{{-     else if eq $address_space "workgroup" -}}read_write
+{{-     else if eq $address_space "uniform"   -}}read
+{{-     else if eq $address_space "storage"   -}}read
+{{-     else if eq $address_space "handle"    -}}read
 {{-     end -}}
 {{-   end -}}
 {{- end -}}
@@ -325,4 +325,4 @@
 {{-    end -}}
 >
 {{-   end -}}
-{{- end -}}
\ No newline at end of file
+{{- end -}}
diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.dxc.hlsl
index 233c92b..48c064b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.fxc.hlsl
index 233c92b..48c064b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.glsl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.glsl
index 51547d9..87e0902 100644
--- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-builtins/gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+builtins/gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.msl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.msl
index 233c92b..48c064b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.spvasm
index 233c92b..48c064b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.wgsl
index 233c92b..48c064b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.wgsl
+++ b/test/tint/builtins/gen/literal/arrayLength/8421b9.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl
index e0a5253..c1ff94b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl
index e0a5253..c1ff94b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.glsl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.glsl
index ba9a68b..7849c68 100644
--- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+builtins/gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.msl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.msl
index e0a5253..c1ff94b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.spvasm b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.spvasm
index e0a5253..c1ff94b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.wgsl b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.wgsl
index e0a5253..c1ff94b 100644
--- a/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.wgsl
+++ b/test/tint/builtins/gen/literal/arrayLength/cbd6b5.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/literal/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.dxc.hlsl
index 58ecc49..af8f59a 100644
--- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.fxc.hlsl
index 58ecc49..af8f59a 100644
--- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.glsl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.glsl
index c34cb64..fc94710 100644
--- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-builtins/gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+builtins/gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.msl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.msl
index 58ecc49..af8f59a 100644
--- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.spvasm b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.spvasm
index 58ecc49..af8f59a 100644
--- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.wgsl b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.wgsl
index 58ecc49..af8f59a 100644
--- a/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.wgsl
+++ b/test/tint/builtins/gen/var/arrayLength/8421b9.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/8421b9.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl
index 07baca0..ec22a8b 100644
--- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl
+++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl
index 07baca0..ec22a8b 100644
--- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl
+++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.glsl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.glsl
index 2819fce..f19d93a 100644
--- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.glsl
+++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-builtins/gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+builtins/gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.msl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.msl
index 07baca0..ec22a8b 100644
--- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.msl
+++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.spvasm b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.spvasm
index 07baca0..ec22a8b 100644
--- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.spvasm
+++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.wgsl b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.wgsl
index 07baca0..ec22a8b 100644
--- a/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.wgsl
+++ b/test/tint/builtins/gen/var/arrayLength/cbd6b5.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' storage class is not implemented yet
+gen/var/arrayLength/cbd6b5.wgsl:26:10 error: using f16 types in 'storage' address space is not implemented yet
   arg_0: array<f16>,
          ^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.dxc.hlsl
index 729d8e0..ae79b76 100644
--- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x2<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.fxc.hlsl
index 729d8e0..ae79b76 100644
--- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x2<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.glsl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.glsl
index 51aef61..b949b92 100644
--- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.glsl
+++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-expressions/binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+expressions/binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x2<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.msl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.msl
index 729d8e0..ae79b76 100644
--- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.msl
+++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x2<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.spvasm b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.spvasm
index 729d8e0..ae79b76 100644
--- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.spvasm
+++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x2<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.wgsl b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.wgsl
index 729d8e0..ae79b76 100644
--- a/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.wgsl
+++ b/test/tint/expressions/binary/mul/mat3x2-vec3/f16.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x2-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x2<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.dxc.hlsl
index fe18486..57a21b5 100644
--- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.fxc.hlsl
index fe18486..57a21b5 100644
--- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.glsl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.glsl
index 0b83b52..07caac0 100644
--- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.glsl
+++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-expressions/binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+expressions/binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.msl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.msl
index fe18486..57a21b5 100644
--- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.msl
+++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.spvasm b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.spvasm
index fe18486..57a21b5 100644
--- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.spvasm
+++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.wgsl b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.wgsl
index fe18486..57a21b5 100644
--- a/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.wgsl
+++ b/test/tint/expressions/binary/mul/mat3x3-vec3/f16.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/mat3x3-vec3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.dxc.hlsl
index da8a0b2..df85ef6 100644
--- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.fxc.hlsl
index da8a0b2..df85ef6 100644
--- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.glsl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.glsl
index e34358b..33e1cf0 100644
--- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.glsl
+++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-expressions/binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+expressions/binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.msl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.msl
index da8a0b2..df85ef6 100644
--- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.msl
+++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.spvasm b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.spvasm
index da8a0b2..df85ef6 100644
--- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.spvasm
+++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.wgsl b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.wgsl
index da8a0b2..df85ef6 100644
--- a/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.wgsl
+++ b/test/tint/expressions/binary/mul/vec3-mat3x3/f16.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat3x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat3x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.dxc.hlsl
index 4b075b5..6f70109 100644
--- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat4x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.fxc.hlsl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.fxc.hlsl
index 4b075b5..6f70109 100644
--- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat4x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.glsl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.glsl
index 367b08c..9f92e39 100644
--- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.glsl
+++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-expressions/binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+expressions/binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat4x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.msl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.msl
index 4b075b5..6f70109 100644
--- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.msl
+++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat4x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.spvasm b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.spvasm
index 4b075b5..6f70109 100644
--- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.spvasm
+++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat4x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.wgsl b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.wgsl
index 4b075b5..6f70109 100644
--- a/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.wgsl
+++ b/test/tint/expressions/binary/mul/vec3-mat4x3/f16.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' storage class is not implemented yet
+binary/mul/vec3-mat4x3/f16.wgsl:3:14 error: using f16 types in 'uniform' address space is not implemented yet
     matrix : mat4x3<f16>,
              ^^^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.dxc.hlsl
index 77452b8..6c8063b2 100644
--- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' storage class is not implemented yet
+swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.fxc.hlsl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.fxc.hlsl
index 77452b8..6c8063b2 100644
--- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' storage class is not implemented yet
+swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.glsl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.glsl
index 713d1a6..a5570c5 100644
--- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.glsl
+++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-expressions/swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' storage class is not implemented yet
+expressions/swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.msl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.msl
index 77452b8..6c8063b2 100644
--- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.msl
+++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' storage class is not implemented yet
+swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.spvasm b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.spvasm
index 77452b8..6c8063b2 100644
--- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.spvasm
+++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' storage class is not implemented yet
+swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.wgsl b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.wgsl
index 77452b8..6c8063b2 100644
--- a/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.wgsl
+++ b/test/tint/expressions/swizzle/read/packed_vec3/f16.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' storage class is not implemented yet
+swizzle/read/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'uniform' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.dxc.hlsl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.dxc.hlsl
index f7fb998..4053a55 100644
--- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.dxc.hlsl
+++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.dxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' storage class is not implemented yet
+swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.fxc.hlsl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.fxc.hlsl
index f7fb998..4053a55 100644
--- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.fxc.hlsl
+++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.fxc.hlsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' storage class is not implemented yet
+swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.glsl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.glsl
index 03372ef..cb935a3 100644
--- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.glsl
+++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.glsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-expressions/swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' storage class is not implemented yet
+expressions/swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.msl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.msl
index f7fb998..4053a55 100644
--- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.msl
+++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.msl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' storage class is not implemented yet
+swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.spvasm b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.spvasm
index f7fb998..4053a55 100644
--- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.spvasm
+++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.spvasm
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' storage class is not implemented yet
+swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.wgsl b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.wgsl
index f7fb998..4053a55 100644
--- a/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.wgsl
+++ b/test/tint/expressions/swizzle/write/packed_vec3/f16.wgsl.expected.wgsl
@@ -1,6 +1,6 @@
 SKIP: FAILED
 
-swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' storage class is not implemented yet
+swizzle/write/packed_vec3/f16.wgsl:3:8 error: using f16 types in 'storage' address space is not implemented yet
     v: vec3<f16>,
        ^^^^^^^^^
 
diff --git a/test/tint/var/uses/push_constant.wgsl.expected.dxc.hlsl b/test/tint/var/uses/push_constant.wgsl.expected.dxc.hlsl
index 895f24e..f5927fa 100644
--- a/test/tint/var/uses/push_constant.wgsl.expected.dxc.hlsl
+++ b/test/tint/var/uses/push_constant.wgsl.expected.dxc.hlsl
@@ -40,4 +40,4 @@
 fn main4() {
 }
 
-Failed to generate: error: unhandled storage class push_constant
+Failed to generate: error: unhandled address space push_constant
diff --git a/test/tint/var/uses/push_constant.wgsl.expected.fxc.hlsl b/test/tint/var/uses/push_constant.wgsl.expected.fxc.hlsl
index 895f24e..f5927fa 100644
--- a/test/tint/var/uses/push_constant.wgsl.expected.fxc.hlsl
+++ b/test/tint/var/uses/push_constant.wgsl.expected.fxc.hlsl
@@ -40,4 +40,4 @@
 fn main4() {
 }
 
-Failed to generate: error: unhandled storage class push_constant
+Failed to generate: error: unhandled address space push_constant
diff --git a/test/tint/var/uses/push_constant.wgsl.expected.glsl b/test/tint/var/uses/push_constant.wgsl.expected.glsl
index b341469..00e2f76 100644
--- a/test/tint/var/uses/push_constant.wgsl.expected.glsl
+++ b/test/tint/var/uses/push_constant.wgsl.expected.glsl
@@ -40,7 +40,7 @@
 fn main4() {
 }
 
-Failed to generate: error: unhandled storage class push_constant
+Failed to generate: error: unhandled address space push_constant
 
 enable chromium_experimental_push_constant;
 
@@ -81,7 +81,7 @@
 fn main4() {
 }
 
-Failed to generate: error: unhandled storage class push_constant
+Failed to generate: error: unhandled address space push_constant
 
 enable chromium_experimental_push_constant;
 
@@ -122,7 +122,7 @@
 fn main4() {
 }
 
-Failed to generate: error: unhandled storage class push_constant
+Failed to generate: error: unhandled address space push_constant
 #version 310 es
 
 void main4() {
diff --git a/test/tint/var/uses/push_constant.wgsl.expected.msl b/test/tint/var/uses/push_constant.wgsl.expected.msl
index 273a21c..925fc2a 100644
--- a/test/tint/var/uses/push_constant.wgsl.expected.msl
+++ b/test/tint/var/uses/push_constant.wgsl.expected.msl
@@ -40,9 +40,9 @@
 fn main4() {
 }
 
-Failed to generate: error: unhandled module-scope storage class (push_constant)
-error: unhandled module-scope storage class (push_constant)
-error: unhandled module-scope storage class (push_constant)
-error: unhandled module-scope storage class (push_constant)
-error: unhandled module-scope storage class (push_constant)
-error: unhandled module-scope storage class (push_constant)
+Failed to generate: error: unhandled module-scope address space (push_constant)
+error: unhandled module-scope address space (push_constant)
+error: unhandled module-scope address space (push_constant)
+error: unhandled module-scope address space (push_constant)
+error: unhandled module-scope address space (push_constant)
+error: unhandled module-scope address space (push_constant)
diff --git a/tools/src/tint/intrinsic/gen/permutate.go b/tools/src/tint/intrinsic/gen/permutate.go
index 525e1e1..df5f1d2 100644
--- a/tools/src/tint/intrinsic/gen/permutate.go
+++ b/tools/src/tint/intrinsic/gen/permutate.go
@@ -340,10 +340,10 @@
 			return false // Abstract types are not typeable
 		}
 	case "ptr":
-		// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
+		// https://gpuweb.github.io/gpuweb/wgsl/#address-space
 		access := fqn.TemplateArguments[2].(sem.FullyQualifiedName).Target.(*sem.EnumEntry).Name
-		storageClass := fqn.TemplateArguments[0].(sem.FullyQualifiedName).Target.(*sem.EnumEntry).Name
-		switch storageClass {
+		addressSpace := fqn.TemplateArguments[0].(sem.FullyQualifiedName).Target.(*sem.EnumEntry).Name
+		switch addressSpace {
 		case "function", "private":
 			if access != "read_write" {
 				return false