Use StorageClass::kNone for ast local var decls

To declare a local variable, we write `var name : type`, not `var<function> name : type`.
This change fixes all the places where we were feeding StorageClass::kFunction into variable declarations.

Note that the resolved, semantic variable correctly infers the `kFunction` StorageClass.

Change-Id: I6221fabae1de0435044f29b9a91808421d5cace6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50821
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Commit-Queue: David Neto <dneto@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc
index 23e004e..59827a8 100644
--- a/src/inspector/inspector_test.cc
+++ b/src/inspector/inspector_test.cc
@@ -291,8 +291,7 @@
       std::tie(member_idx, member_type) = member;
       std::string member_name = StructMemberName(member_idx, member_type);
 
-      stmts.emplace_back(Decl(
-          Var("local" + member_name, member_type, ast::StorageClass::kNone)));
+      stmts.emplace_back(Decl(Var("local" + member_name, member_type)));
     }
 
     for (auto member : members) {
@@ -414,8 +413,7 @@
     std::string result_name = "sampler_result";
 
     ast::StatementList stmts;
-    stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4),
-                                ast::StorageClass::kFunction)));
+    stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4))));
 
     stmts.emplace_back(
         Assign("sampler_result",
@@ -446,8 +444,7 @@
 
     ast::StatementList stmts;
 
-    stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4),
-                                ast::StorageClass::kFunction)));
+    stmts.emplace_back(Decl(Var("sampler_result", ty.vec(base_type, 4))));
 
     stmts.emplace_back(
         Assign("sampler_result", Call("textureSample", texture_name,
@@ -479,8 +476,7 @@
 
     ast::StatementList stmts;
 
-    stmts.emplace_back(
-        Decl(Var("sampler_result", base_type, ast::StorageClass::kFunction)));
+    stmts.emplace_back(Decl(Var("sampler_result", base_type)));
     stmts.emplace_back(
         Assign("sampler_result", Call("textureSampleCompare", texture_name,
                                       sampler_name, coords_name, depth_name)));
@@ -581,8 +577,7 @@
       ast::DecorationList decorations) {
     ast::StatementList stmts;
 
-    stmts.emplace_back(
-        Decl(Var("dim", dim_type, ast::StorageClass::kFunction)));
+    stmts.emplace_back(Decl(Var("dim", dim_type)));
     stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name)));
     stmts.emplace_back(Return());
 
diff --git a/src/program_builder.h b/src/program_builder.h
index acefa08..7c8d5ba 100644
--- a/src/program_builder.h
+++ b/src/program_builder.h
@@ -1189,7 +1189,7 @@
   template <typename NAME>
   ast::Variable* Var(NAME&& name,
                      ast::Type* type,
-                     ast::StorageClass storage,
+                     ast::StorageClass storage = ast::StorageClass::kNone,
                      ast::Expression* constructor = nullptr,
                      ast::DecorationList decorations = {}) {
     type = ty.MaybeCreateTypename(type);
@@ -1208,7 +1208,7 @@
   ast::Variable* Var(const Source& source,
                      NAME&& name,
                      ast::Type* type,
-                     ast::StorageClass storage,
+                     ast::StorageClass storage = ast::StorageClass::kNone,
                      ast::Expression* constructor = nullptr,
                      ast::DecorationList decorations = {}) {
     type = ty.MaybeCreateTypename(type);
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 16217bb..db5c51d 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -2022,7 +2022,7 @@
               .expr;
     }
     auto* var = parser_impl_.MakeVariable(
-        inst.result_id(), ast::StorageClass::kFunction, var_store_type, false,
+        inst.result_id(), ast::StorageClass::kNone, var_store_type, false,
         constructor, ast::DecorationList{});
     auto* var_decl_stmt = create<ast::VariableDeclStatement>(Source{}, var);
     AddStatement(var_decl_stmt);
@@ -2352,7 +2352,7 @@
     // Declare the guard variable just before the "if", initialized to true.
     auto* guard_var =
         create<ast::Variable>(Source{}, builder_.Symbols().Register(guard_name),
-                              ast::StorageClass::kFunction, builder_.ty.bool_(),
+                              ast::StorageClass::kNone, builder_.ty.bool_(),
                               false, MakeTrue(Source{}), ast::DecorationList{});
     auto* guard_decl = create<ast::VariableDeclStatement>(Source{}, guard_var);
     AddStatement(guard_decl);
@@ -2900,8 +2900,8 @@
         RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
     AddStatement(create<ast::VariableDeclStatement>(
         Source{},
-        parser_impl_.MakeVariable(id, ast::StorageClass::kFunction, ast_type,
-                                  false, nullptr, ast::DecorationList{})));
+        parser_impl_.MakeVariable(id, ast::StorageClass::kNone, ast_type, false,
+                                  nullptr, ast::DecorationList{})));
     // Save this as an already-named value.
     identifier_values_.insert(id);
   }
@@ -2913,7 +2913,7 @@
     TINT_ASSERT(!phi_var_name.empty());
     auto* var = create<ast::Variable>(
         Source{}, builder_.Symbols().Register(phi_var_name),
-        ast::StorageClass::kFunction,
+        ast::StorageClass::kNone,
         parser_impl_.ConvertType(def_inst->type_id())->Build(builder_), false,
         nullptr, ast::DecorationList{});
     AddStatement(create<ast::VariableDeclStatement>(Source{}, var));
@@ -5134,7 +5134,7 @@
   auto registered_temp_name = builder_.Symbols().Register(temp_name);
 
   auto* temp_var = create<ast::Variable>(
-      Source{}, registered_temp_name, ast::StorageClass::kFunction,
+      Source{}, registered_temp_name, ast::StorageClass::kNone,
       ast_type->Build(builder_), false, src_vector.expr, ast::DecorationList{});
   AddStatement(create<ast::VariableDeclStatement>(Source{}, temp_var));
 
@@ -5179,10 +5179,10 @@
   auto temp_name = namer_.MakeDerivedName(result_name);
   auto registered_temp_name = builder_.Symbols().Register(temp_name);
 
-  auto* temp_var = create<ast::Variable>(
-      Source{}, registered_temp_name, ast::StorageClass::kFunction,
-      ast_type->Build(builder_), false, src_composite.expr,
-      ast::DecorationList{});
+  auto* temp_var =
+      create<ast::Variable>(Source{}, registered_temp_name,
+                            ast::StorageClass::kNone, ast_type->Build(builder_),
+                            false, src_composite.expr, ast::DecorationList{});
   AddStatement(create<ast::VariableDeclStatement>(Source{}, temp_var));
 
   TypedExpression seed_expr{ast_type, create<ast::IdentifierExpression>(
diff --git a/src/reader/spirv/function_call_test.cc b/src/reader/spirv/function_call_test.cc
index 0206f1d..c9ec4fc 100644
--- a/src/reader/spirv/function_call_test.cc
+++ b/src/reader/spirv/function_call_test.cc
@@ -147,7 +147,7 @@
                 HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_10
-    function
+    none
     __u32
   }
 }
diff --git a/src/reader/spirv/function_cfg_test.cc b/src/reader/spirv/function_cfg_test.cc
index 700b81a..ca042cf 100644
--- a/src/reader/spirv/function_cfg_test.cc
+++ b/src/reader/spirv/function_cfg_test.cc
@@ -7909,7 +7909,7 @@
 VariableDeclStatement{
   Variable{
     guard10
-    function
+    none
     __bool
     {
       ScalarConstructor[not set]{true}
@@ -8021,7 +8021,7 @@
 VariableDeclStatement{
   Variable{
     guard10
-    function
+    none
     __bool
     {
       ScalarConstructor[not set]{true}
@@ -8148,7 +8148,7 @@
 VariableDeclStatement{
   Variable{
     guard10
-    function
+    none
     __bool
     {
       ScalarConstructor[not set]{true}
diff --git a/src/reader/spirv/function_composite_test.cc b/src/reader/spirv/function_composite_test.cc
index 437e72b..2724fd5 100644
--- a/src/reader/spirv/function_composite_test.cc
+++ b/src/reader/spirv/function_composite_test.cc
@@ -581,7 +581,7 @@
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_1_1
-    function
+    none
     __vec_2__f32
     {
       TypeConstructor[not set]{
@@ -647,7 +647,7 @@
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_2_1
-    function
+    none
     __mat_2_3__f32
     {
       Identifier[not set]{x_1}
@@ -717,7 +717,7 @@
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_2_1
-    function
+    none
     __mat_2_3__f32
     {
       Identifier[not set]{x_1}
@@ -767,7 +767,7 @@
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_2_1
-    function
+    none
     __array__u32_5
     {
       Identifier[not set]{x_1}
@@ -834,7 +834,7 @@
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_35
-    function
+    none
     __type_name_S
   }
 }
@@ -851,7 +851,7 @@
 VariableDeclStatement{
   Variable{
     x_2_1
-    function
+    none
     __type_name_S
     {
       Identifier[not set]{x_1}
@@ -908,14 +908,14 @@
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_40
-    function
+    none
     __type_name_S_2
   }
 }
 VariableDeclStatement{
   Variable{
     x_41
-    function
+    none
     __type_name_S_2
   }
 }
@@ -932,7 +932,7 @@
 VariableDeclStatement{
   Variable{
     x_2_1
-    function
+    none
     __type_name_S_1
     {
       Identifier[not set]{x_1}
@@ -969,7 +969,7 @@
 VariableDeclStatement{
   Variable{
     x_4_1
-    function
+    none
     __type_name_S_2
     {
       Identifier[not set]{x_3}
@@ -997,7 +997,7 @@
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_4_1
-    function
+    none
     __type_name_S_2
     {
       Identifier[not set]{x_3}
@@ -1065,7 +1065,7 @@
   EXPECT_THAT(body_str, HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_37
-    function
+    none
     __type_name_S_1
   }
 }
@@ -1082,7 +1082,7 @@
 VariableDeclStatement{
   Variable{
     x_2_1
-    function
+    none
     __type_name_S_1
     {
       Identifier[not set]{x_1}
@@ -1431,7 +1431,7 @@
 VariableDeclStatement{
   Variable{
     x_10_1
-    function
+    none
     __vec_2__u32
     {
       Identifier[not set]{x_1}
diff --git a/src/reader/spirv/function_memory_test.cc b/src/reader/spirv/function_memory_test.cc
index 696e09f..a26a065 100644
--- a/src/reader/spirv/function_memory_test.cc
+++ b/src/reader/spirv/function_memory_test.cc
@@ -1043,7 +1043,7 @@
             R"(VariableDeclStatement{
   Variable{
     x_2
-    function
+    none
     __ptr_storage__u32
   }
 }
diff --git a/src/reader/spirv/function_var_test.cc b/src/reader/spirv/function_var_test.cc
index 2a4b201..8bacfad 100644
--- a/src/reader/spirv/function_var_test.cc
+++ b/src/reader/spirv/function_var_test.cc
@@ -107,21 +107,21 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_1
-    function
+    none
     __u32
   }
 }
 VariableDeclStatement{
   Variable{
     x_2
-    function
+    none
     __u32
   }
 }
 VariableDeclStatement{
   Variable{
     x_3
-    function
+    none
     __u32
   }
 }
@@ -146,21 +146,21 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     a
-    function
+    none
     __u32
   }
 }
 VariableDeclStatement{
   Variable{
     b
-    function
+    none
     __u32
   }
 }
 VariableDeclStatement{
   Variable{
     c
-    function
+    none
     __u32
   }
 }
@@ -185,21 +185,21 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     a
-    function
+    none
     __u32
   }
 }
 VariableDeclStatement{
   Variable{
     b
-    function
+    none
     __i32
   }
 }
 VariableDeclStatement{
   Variable{
     c
-    function
+    none
     __f32
   }
 }
@@ -226,7 +226,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     a
-    function
+    none
     __bool
     {
       ScalarConstructor[not set]{true}
@@ -236,7 +236,7 @@
 VariableDeclStatement{
   Variable{
     b
-    function
+    none
     __bool
     {
       ScalarConstructor[not set]{false}
@@ -246,7 +246,7 @@
 VariableDeclStatement{
   Variable{
     c
-    function
+    none
     __i32
     {
       ScalarConstructor[not set]{-1}
@@ -256,7 +256,7 @@
 VariableDeclStatement{
   Variable{
     d
-    function
+    none
     __u32
     {
       ScalarConstructor[not set]{1u}
@@ -266,7 +266,7 @@
 VariableDeclStatement{
   Variable{
     e
-    function
+    none
     __f32
     {
       ScalarConstructor[not set]{1.500000}
@@ -300,7 +300,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     a
-    function
+    none
     __bool
     {
       ScalarConstructor[not set]{false}
@@ -310,7 +310,7 @@
 VariableDeclStatement{
   Variable{
     b
-    function
+    none
     __i32
     {
       ScalarConstructor[not set]{0}
@@ -320,7 +320,7 @@
 VariableDeclStatement{
   Variable{
     c
-    function
+    none
     __u32
     {
       ScalarConstructor[not set]{0u}
@@ -330,7 +330,7 @@
 VariableDeclStatement{
   Variable{
     d
-    function
+    none
     __f32
     {
       ScalarConstructor[not set]{0.000000}
@@ -360,7 +360,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_200
-    function
+    none
     __vec_2__f32
     {
       TypeConstructor[not set]{
@@ -399,7 +399,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_200
-    function
+    none
     __mat_2_3__f32
     {
       TypeConstructor[not set]{
@@ -446,7 +446,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_200
-    function
+    none
     __array__u32_2
     {
       TypeConstructor[not set]{
@@ -485,7 +485,7 @@
   const char* expect = R"(VariableDeclStatement{
   Variable{
     x_200
-    function
+    none
     __type_name_Arr
     {
       TypeConstructor[not set]{
@@ -520,7 +520,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_200
-    function
+    none
     __array__u32_2
     {
       TypeConstructor[not set]{
@@ -560,7 +560,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_200
-    function
+    none
     __type_name_Arr
     {
       TypeConstructor[not set]{
@@ -595,7 +595,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_200
-    function
+    none
     __type_name_S
     {
       TypeConstructor[not set]{
@@ -635,7 +635,7 @@
               HasSubstr(R"(VariableDeclStatement{
   Variable{
     x_200
-    function
+    none
     __type_name_S
     {
       TypeConstructor[not set]{
@@ -681,7 +681,7 @@
       R"(VariableDeclStatement{
   Variable{
     x_25
-    function
+    none
     __u32
   }
 }
@@ -729,7 +729,7 @@
   auto* expect = R"(VariableDeclStatement{
   Variable{
     x_25
-    function
+    none
     __u32
   }
 }
@@ -801,7 +801,7 @@
   auto* expect = R"(VariableDeclStatement{
   Variable{
     x_25
-    function
+    none
     __u32
   }
 }
@@ -905,7 +905,7 @@
   VariableDeclStatement{
     Variable{
       x_2
-      function
+      none
       __u32
     }
   }
@@ -1351,14 +1351,14 @@
   VariableDeclStatement{
     Variable{
       x_2_phi
-      function
+      none
       __u32
     }
   }
   VariableDeclStatement{
     Variable{
       x_3_phi
-      function
+      none
       __u32
     }
   }
@@ -1498,14 +1498,14 @@
   VariableDeclStatement{
     Variable{
       x_2_phi
-      function
+      none
       __u32
     }
   }
   VariableDeclStatement{
     Variable{
       x_3_phi
-      function
+      none
       __u32
     }
   }
@@ -1549,7 +1549,7 @@
     VariableDeclStatement{
       Variable{
         x_4
-        function
+        none
         __u32
       }
     }
@@ -1670,14 +1670,14 @@
   VariableDeclStatement{
     Variable{
       x_2_phi
-      function
+      none
       __u32
     }
   }
   VariableDeclStatement{
     Variable{
       x_5_phi
-      function
+      none
       __u32
     }
   }
@@ -1693,7 +1693,7 @@
     VariableDeclStatement{
       Variable{
         x_7
-        function
+        none
         __u32
       }
     }
@@ -1852,7 +1852,7 @@
   VariableDeclStatement{
     Variable{
       x_2_phi
-      function
+      none
       __u32
     }
   }
@@ -1978,7 +1978,7 @@
   VariableDeclStatement{
     Variable{
       x_2_phi
-      function
+      none
       __u32
     }
   }
@@ -2083,7 +2083,7 @@
   auto* expect = R"(VariableDeclStatement{
   Variable{
     x_35_phi
-    function
+    none
     __u32
   }
 }
@@ -2173,7 +2173,7 @@
   auto* expect = R"(VariableDeclStatement{
   Variable{
     x_101_phi
-    function
+    none
     __bool
   }
 }
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index 11c492e..296bc5c 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -5947,7 +5947,7 @@
   auto* expect = R"(VariableDeclStatement{
   Variable{
     var_1
-    function
+    none
     __vec_4__f32
   }
 }
@@ -6003,7 +6003,7 @@
 }
 Return{}
 )";
-  ASSERT_EQ(expect, got) << got;
+  ASSERT_EQ(expect, got);
 }
 
 }  // namespace
diff --git a/src/resolver/builtins_validation_test.cc b/src/resolver/builtins_validation_test.cc
index 9a1fdd4..363b35a 100644
--- a/src/resolver/builtins_validation_test.cc
+++ b/src/resolver/builtins_validation_test.cc
@@ -107,7 +107,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Frexp_Scalar) {
-  auto* a = Var("a", ty.i32(), ast::StorageClass::kFunction);
+  auto* a = Var("a", ty.i32());
   auto* builtin = Call("frexp", 1.0f, Expr("a"));
   WrapInFunction(Decl(a), builtin);
 
@@ -117,7 +117,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec2) {
-  auto* a = Var("a", ty.vec2<int>(), ast::StorageClass::kFunction);
+  auto* a = Var("a", ty.vec2<int>());
   auto* b = Const("b", ty.pointer(ty.vec2<i32>(), ast::StorageClass::kFunction),
                   Expr("a"), {});
   auto* builtin = Call("frexp", vec2<f32>(1.0f, 1.0f), Expr("b"));
@@ -129,7 +129,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec3) {
-  auto* a = Var("a", ty.vec3<int>(), ast::StorageClass::kFunction);
+  auto* a = Var("a", ty.vec3<int>());
   auto* b = Const("b", ty.pointer(ty.vec3<i32>(), ast::StorageClass::kFunction),
                   Expr("a"), {});
   auto* builtin = Call("frexp", vec3<f32>(1.0f, 1.0f, 1.0f), Expr("b"));
@@ -141,7 +141,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Frexp_Vec4) {
-  auto* a = Var("a", ty.vec4<int>(), ast::StorageClass::kFunction);
+  auto* a = Var("a", ty.vec4<int>());
   auto* b = Const("b", ty.pointer(ty.vec4<i32>(), ast::StorageClass::kFunction),
                   Expr("a"), {});
   auto* builtin = Call("frexp", vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f), Expr("b"));
@@ -153,7 +153,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Modf_Scalar) {
-  auto* a = Var("a", ty.f32(), ast::StorageClass::kFunction);
+  auto* a = Var("a", ty.f32());
   auto* b =
       Const("b", ty.pointer<f32>(ast::StorageClass::kFunction), Expr("a"), {});
   auto* builtin = Call("modf", 1.0f, Expr("b"));
@@ -165,7 +165,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Modf_Vec2) {
-  auto* a = Var("a", ty.vec2<f32>(), ast::StorageClass::kFunction);
+  auto* a = Var("a", ty.vec2<f32>());
   auto* b = Const("b", ty.pointer(ty.vec2<f32>(), ast::StorageClass::kFunction),
                   Expr("a"), {});
   auto* builtin = Call("modf", vec2<f32>(1.0f, 1.0f), Expr("b"));
@@ -177,7 +177,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Modf_Vec3) {
-  auto* a = Var("a", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* a = Var("a", ty.vec3<f32>());
   auto* b = Const("b", ty.pointer(ty.vec3<f32>(), ast::StorageClass::kFunction),
                   Expr("a"), {});
   auto* builtin = Call("modf", vec3<f32>(1.0f, 1.0f, 1.0f), Expr("b"));
@@ -189,7 +189,7 @@
 }
 
 TEST_F(ResolverBuiltinsValidationTest, Modf_Vec4) {
-  auto* a = Var("a", ty.vec4<f32>(), ast::StorageClass::kFunction);
+  auto* a = Var("a", ty.vec4<f32>());
   auto* b = Const("b", ty.pointer(ty.vec4<f32>(), ast::StorageClass::kFunction),
                   Expr("a"), {});
   auto* builtin = Call("modf", vec4<f32>(1.0f, 1.0f, 1.0f, 1.0f), Expr("b"));
diff --git a/src/resolver/decoration_validation_test.cc b/src/resolver/decoration_validation_test.cc
index f894498..adcaeab 100644
--- a/src/resolver/decoration_validation_test.cc
+++ b/src/resolver/decoration_validation_test.cc
@@ -596,9 +596,9 @@
 
   Func("F", {}, ty.void_(),
        {
-           Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kFunction,
+           Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kNone,
                     Call("textureLoad", "A", vec2<i32>(1, 2), 0))),
-           Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kFunction,
+           Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
                     Call("textureLoad", "B", vec2<i32>(1, 2), 0))),
        },
        {Stage(ast::PipelineStage::kFragment)});
@@ -628,13 +628,13 @@
 
   Func("F_A", {}, ty.void_(),
        {
-           Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kFunction,
+           Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kNone,
                     Call("textureLoad", "A", vec2<i32>(1, 2), 0))),
        },
        {Stage(ast::PipelineStage::kFragment)});
   Func("F_B", {}, ty.void_(),
        {
-           Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kFunction,
+           Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
                     Call("textureLoad", "B", vec2<i32>(1, 2), 0))),
        },
        {Stage(ast::PipelineStage::kFragment)});
diff --git a/src/resolver/function_validation_test.cc b/src/resolver/function_validation_test.cc
index ab2d2c7..423270b 100644
--- a/src/resolver/function_validation_test.cc
+++ b/src/resolver/function_validation_test.cc
@@ -222,7 +222,7 @@
   // }
 
   auto* bar = Param("bar", ty.f32());
-  auto* baz = Var("baz", ty.f32(), ast::StorageClass::kFunction, Expr("bar"));
+  auto* baz = Var("baz", ty.f32(), ast::StorageClass::kNone, Expr("bar"));
 
   Func("foo", ast::VariableList{bar}, ty.void_(), ast::StatementList{Decl(baz)},
        ast::DecorationList{});
diff --git a/src/resolver/intrinsic_test.cc b/src/resolver/intrinsic_test.cc
index a821551..caaa2c9 100644
--- a/src/resolver/intrinsic_test.cc
+++ b/src/resolver/intrinsic_test.cc
@@ -1609,7 +1609,7 @@
                     IntrinsicData{"max", IntrinsicType::kMax}));
 
 TEST_F(ResolverIntrinsicTest, Determinant_2x2) {
-  Global("var", ty.mat2x2<f32>(), ast::StorageClass::kFunction);
+  Global("var", ty.mat2x2<f32>(), ast::StorageClass::kPrivate);
 
   auto* call = Call("determinant", "var");
   WrapInFunction(call);
@@ -1621,7 +1621,7 @@
 }
 
 TEST_F(ResolverIntrinsicTest, Determinant_3x3) {
-  Global("var", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
+  Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
 
   auto* call = Call("determinant", "var");
   WrapInFunction(call);
@@ -1633,7 +1633,7 @@
 }
 
 TEST_F(ResolverIntrinsicTest, Determinant_4x4) {
-  Global("var", ty.mat4x4<f32>(), ast::StorageClass::kFunction);
+  Global("var", ty.mat4x4<f32>(), ast::StorageClass::kPrivate);
 
   auto* call = Call("determinant", "var");
   WrapInFunction(call);
@@ -1645,7 +1645,7 @@
 }
 
 TEST_F(ResolverIntrinsicTest, Determinant_NotSquare) {
-  Global("var", ty.mat2x3<f32>(), ast::StorageClass::kFunction);
+  Global("var", ty.mat2x3<f32>(), ast::StorageClass::kPrivate);
 
   auto* call = Call("determinant", "var");
   WrapInFunction(call);
@@ -1654,13 +1654,13 @@
 
   EXPECT_EQ(
       r()->error(),
-      "error: no matching call to determinant(ptr<function, mat2x3<f32>>)\n\n"
+      "error: no matching call to determinant(ptr<private, mat2x3<f32>>)\n\n"
       "1 candidate function:\n"
       "  determinant(matNxN<f32>) -> f32\n");
 }
 
 TEST_F(ResolverIntrinsicTest, Determinant_NotMatrix) {
-  Global("var", ty.f32(), ast::StorageClass::kFunction);
+  Global("var", ty.f32(), ast::StorageClass::kPrivate);
 
   auto* call = Call("determinant", "var");
   WrapInFunction(call);
@@ -1668,7 +1668,7 @@
   EXPECT_FALSE(r()->Resolve());
 
   EXPECT_EQ(r()->error(),
-            "error: no matching call to determinant(ptr<function, f32>)\n\n"
+            "error: no matching call to determinant(ptr<private, f32>)\n\n"
             "1 candidate function:\n"
             "  determinant(matNxN<f32>) -> f32\n");
 }
diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc
index 5464105..3b42646 100644
--- a/src/resolver/resolver_test.cc
+++ b/src/resolver/resolver_test.cc
@@ -55,7 +55,7 @@
 using Op = ast::BinaryOp;
 
 TEST_F(ResolverTest, Stmt_Assign) {
-  auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
+  auto* v = Var("v", ty.f32());
   auto* lhs = Expr("v");
   auto* rhs = Expr(2.3f);
 
@@ -74,7 +74,7 @@
 }
 
 TEST_F(ResolverTest, Stmt_Case) {
-  auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
+  auto* v = Var("v", ty.f32());
   auto* lhs = Expr("v");
   auto* rhs = Expr(2.3f);
 
@@ -83,7 +83,7 @@
   ast::CaseSelectorList lit;
   lit.push_back(create<ast::SintLiteral>(3));
   auto* cse = create<ast::CaseStatement>(lit, block);
-  auto* cond_var = Var("c", ty.i32(), ast::StorageClass::kFunction);
+  auto* cond_var = Var("c", ty.i32());
   auto* sw = Switch(cond_var, cse, DefaultCase());
   WrapInFunction(v, cond_var, sw);
 
@@ -99,7 +99,7 @@
 }
 
 TEST_F(ResolverTest, Stmt_Block) {
-  auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
+  auto* v = Var("v", ty.f32());
   auto* lhs = Expr("v");
   auto* rhs = Expr(2.3f);
 
@@ -121,7 +121,7 @@
 }
 
 TEST_F(ResolverTest, Stmt_If) {
-  auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
+  auto* v = Var("v", ty.f32());
   auto* else_lhs = Expr("v");
   auto* else_rhs = Expr(2.3f);
 
@@ -163,7 +163,7 @@
 }
 
 TEST_F(ResolverTest, Stmt_Loop) {
-  auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
+  auto* v = Var("v", ty.f32());
   auto* body_lhs = Expr("v");
   auto* body_rhs = Expr(2.3f);
 
@@ -211,7 +211,7 @@
 }
 
 TEST_F(ResolverTest, Stmt_Switch) {
-  auto* v = Var("v", ty.f32(), ast::StorageClass::kFunction);
+  auto* v = Var("v", ty.f32());
   auto* lhs = Expr("v");
   auto* rhs = Expr(2.3f);
   auto* case_block = Block(Assign(lhs, rhs));
@@ -233,8 +233,7 @@
 
 TEST_F(ResolverTest, Stmt_Call) {
   ast::VariableList params;
-  Func("my_func", params, ty.f32(), ast::StatementList{Return(0.0f)},
-       ast::DecorationList{});
+  Func("my_func", params, ty.f32(), {Return(0.0f)}, ast::DecorationList{});
 
   auto* expr = Call("my_func");
 
@@ -321,8 +320,7 @@
   auto* bar_f32_init = bar_f32->constructor();
   auto* bar_f32_decl = Decl(bar_f32);
 
-  Func("func", params, ty.void_(),
-       ast::StatementList{inner, foo_f32_decl, bar_f32_decl},
+  Func("func", params, ty.void_(), {inner, foo_f32_decl, bar_f32_decl},
        ast::DecorationList{});
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -358,11 +356,10 @@
   ast::VariableList params;
 
   // Declare i32 "foo" inside a function
-  auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kFunction, Expr(2));
+  auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2));
   auto* fn_i32_init = fn_i32->constructor();
   auto* fn_i32_decl = Decl(fn_i32);
-  Func("func_i32", params, ty.void_(), ast::StatementList{fn_i32_decl},
-       ast::DecorationList{});
+  Func("func_i32", params, ty.void_(), {fn_i32_decl}, ast::DecorationList{});
 
   // Declare f32 "foo" at module scope
   auto* mod_f32 = Var("foo", ty.f32(), ast::StorageClass::kInput, Expr(2.f));
@@ -370,12 +367,10 @@
   AST().AddGlobalVariable(mod_f32);
 
   // Reference "foo" in another function
-  auto* fn_f32 =
-      Var("bar", ty.f32(), ast::StorageClass::kFunction, Expr("foo"));
+  auto* fn_f32 = Var("bar", ty.f32(), ast::StorageClass::kNone, Expr("foo"));
   auto* fn_f32_init = fn_f32->constructor();
   auto* fn_f32_decl = Decl(fn_f32);
-  Func("func_f32", params, ty.void_(), ast::StatementList{fn_f32_decl},
-       ast::DecorationList{});
+  Func("func_f32", params, ty.void_(), {fn_f32_decl}, ast::DecorationList{});
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
   ASSERT_NE(TypeOf(mod_init), nullptr);
@@ -395,7 +390,7 @@
 
 TEST_F(ResolverTest, Expr_ArrayAccessor_Array) {
   auto* idx = Expr(2);
-  Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kFunction);
+  Global("my_var", ty.array<f32, 3>(), ast::StorageClass::kPrivate);
 
   auto* acc = IndexAccessor("my_var", idx);
   WrapInFunction(acc);
@@ -413,7 +408,7 @@
   auto* aary = ty.alias("myarrty", ty.array<f32, 3>());
   AST().AddConstructedType(aary);
 
-  Global("my_var", aary, ast::StorageClass::kFunction);
+  Global("my_var", aary, ast::StorageClass::kPrivate);
 
   auto* acc = IndexAccessor("my_var", 2);
   WrapInFunction(acc);
@@ -499,8 +494,7 @@
 
 TEST_F(ResolverTest, Expr_Call) {
   ast::VariableList params;
-  Func("my_func", params, ty.f32(), ast::StatementList{Return(0.0f)},
-       ast::DecorationList{});
+  Func("my_func", params, ty.f32(), {Return(0.0f)}, ast::DecorationList{});
 
   auto* call = Call("my_func");
   WrapInFunction(call);
@@ -513,8 +507,7 @@
 
 TEST_F(ResolverTest, Expr_Call_InBinaryOp) {
   ast::VariableList params;
-  Func("func", params, ty.f32(), ast::StatementList{Return(0.0f)},
-       ast::DecorationList{});
+  Func("func", params, ty.f32(), {Return(0.0f)}, ast::DecorationList{});
 
   auto* expr = Add(Call("func"), Call("func"));
   WrapInFunction(expr);
@@ -527,8 +520,7 @@
 
 TEST_F(ResolverTest, Expr_Call_WithParams) {
   ast::VariableList params;
-  Func("my_func", params, ty.void_(), ast::StatementList{},
-       ast::DecorationList{});
+  Func("my_func", params, ty.void_(), {}, ast::DecorationList{});
 
   auto* param = Expr(2.4f);
 
@@ -643,10 +635,10 @@
 TEST_F(ResolverTest, Expr_Identifier_FunctionVariable_Const) {
   auto* my_var_a = Expr("my_var");
   auto* var = Const("my_var", ty.f32(), Construct(ty.f32()));
-  auto* decl = Decl(Var("b", ty.f32(), ast::StorageClass::kFunction, my_var_a));
+  auto* decl = Decl(Var("b", ty.f32(), ast::StorageClass::kNone, my_var_a));
 
   Func("my_func", ast::VariableList{}, ty.void_(),
-       ast::StatementList{
+       {
            Decl(var),
            decl,
        },
@@ -674,7 +666,7 @@
                   });
 
   Func("my_func", ast::VariableList{}, ty.void_(),
-       ast::StatementList{
+       {
            Decl(var),
            assign,
        },
@@ -703,9 +695,8 @@
   auto* assign = Assign(my_var_a, my_var_b);
 
   Func("my_func", ast::VariableList{}, ty.void_(),
-       ast::StatementList{
-           Decl(Var("my_var", ty.pointer<f32>(ast::StorageClass::kFunction),
-                    ast::StorageClass::kNone)),
+       {
+           Decl(Var("my_var", ty.pointer<f32>(ast::StorageClass::kFunction))),
            assign,
        },
        ast::DecorationList{});
@@ -723,8 +714,8 @@
 }
 
 TEST_F(ResolverTest, Expr_Call_Function) {
-  Func("my_func", ast::VariableList{}, ty.f32(),
-       ast::StatementList{Return(0.0f)}, ast::DecorationList{});
+  Func("my_func", ast::VariableList{}, ty.f32(), {Return(0.0f)},
+       ast::DecorationList{});
 
   auto* call = Call("my_func");
   WrapInFunction(call);
@@ -785,13 +776,12 @@
   auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
 
   auto* func = Func("my_func", ast::VariableList{}, ty.void_(),
-                    ast::StatementList{
+                    {
                         Assign("out_var", "in_var"),
                         Assign("wg_var", "wg_var"),
                         Assign("sb_var", "sb_var"),
                         Assign("priv_var", "priv_var"),
-                    },
-                    ast::DecorationList{});
+                    });
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -824,15 +814,14 @@
   auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
   auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
 
-  Func(
-      "my_func", ast::VariableList{}, ty.f32(),
-      ast::StatementList{Assign("out_var", "in_var"),
-                         Assign("wg_var", "wg_var"), Assign("sb_var", "sb_var"),
-                         Assign("priv_var", "priv_var"), Return(0.0f)},
-      ast::DecorationList{});
+  Func("my_func", ast::VariableList{}, ty.f32(),
+       {Assign("out_var", "in_var"), Assign("wg_var", "wg_var"),
+        Assign("sb_var", "sb_var"), Assign("priv_var", "priv_var"),
+        Return(0.0f)},
+       ast::DecorationList{});
 
   auto* func2 = Func("func", ast::VariableList{}, ty.void_(),
-                     ast::StatementList{
+                     {
                          Assign("out_var", Call("my_func")),
                      },
                      ast::DecorationList{});
@@ -853,15 +842,11 @@
 }
 
 TEST_F(ResolverTest, Function_NotRegisterFunctionVariable) {
-  auto* var = Var("in_var", ty.f32(), ast::StorageClass::kFunction);
-  Global("var", ty.f32(), ast::StorageClass::kFunction);
-
   auto* func = Func("my_func", ast::VariableList{}, ty.void_(),
-                    ast::StatementList{
-                        Decl(var),
+                    {
+                        Decl(Var("var", ty.f32())),
                         Assign("var", 1.f),
-                    },
-                    ast::DecorationList{});
+                    });
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -873,17 +858,16 @@
 }
 
 TEST_F(ResolverTest, Function_ReturnStatements) {
-  auto* var = Var("foo", ty.f32(), ast::StorageClass::kFunction);
+  auto* var = Var("foo", ty.f32());
 
   auto* ret_1 = Return(1.f);
   auto* ret_foo = Return("foo");
   auto* func = Func("my_func", ast::VariableList{}, ty.f32(),
-                    ast::StatementList{
+                    {
                         Decl(var),
                         If(true, Block(ret_1)),
                         ret_foo,
-                    },
-                    ast::DecorationList{});
+                    });
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -1468,8 +1452,7 @@
                   });
 
   auto* stmt = Decl(var);
-  Func("func", ast::VariableList{}, ty.void_(), ast::StatementList{stmt},
-       ast::DecorationList{});
+  Func("func", ast::VariableList{}, ty.void_(), {stmt}, ast::DecorationList{});
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -1508,8 +1491,7 @@
 TEST_F(ResolverTest, StorageClass_DoesNotSetOnConst) {
   auto* var = Const("var", ty.i32(), Construct(ty.i32()));
   auto* stmt = Decl(var);
-  Func("func", ast::VariableList{}, ty.void_(), ast::StatementList{stmt},
-       ast::DecorationList{});
+  Func("func", ast::VariableList{}, ty.void_(), {stmt}, ast::DecorationList{});
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 
@@ -1536,20 +1518,18 @@
   Global("call_c", ty.f32(), ast::StorageClass::kPrivate);
 
   ast::VariableList params;
-  auto* func_b = Func("b", params, ty.f32(), ast::StatementList{Return(0.0f)},
-                      ast::DecorationList{});
+  auto* func_b =
+      Func("b", params, ty.f32(), {Return(0.0f)}, ast::DecorationList{});
   auto* func_c =
-      Func("c", params, ty.f32(),
-           ast::StatementList{Assign("second", Call("b")), Return(0.0f)},
+      Func("c", params, ty.f32(), {Assign("second", Call("b")), Return(0.0f)},
            ast::DecorationList{});
 
   auto* func_a =
-      Func("a", params, ty.f32(),
-           ast::StatementList{Assign("first", Call("c")), Return(0.0f)},
+      Func("a", params, ty.f32(), {Assign("first", Call("c")), Return(0.0f)},
            ast::DecorationList{});
 
   auto* ep_1 = Func("ep_1", params, ty.void_(),
-                    ast::StatementList{
+                    {
                         Assign("call_a", Call("a")),
                         Assign("call_b", Call("b")),
                     },
@@ -1558,7 +1538,7 @@
                     });
 
   auto* ep_2 = Func("ep_2", params, ty.void_(),
-                    ast::StatementList{
+                    {
                         Assign("call_c", Call("c")),
                     },
                     ast::DecorationList{
diff --git a/src/resolver/struct_storage_class_use_test.cc b/src/resolver/struct_storage_class_use_test.cc
index 89f58bd..1003eba 100644
--- a/src/resolver/struct_storage_class_use_test.cc
+++ b/src/resolver/struct_storage_class_use_test.cc
@@ -119,7 +119,7 @@
 TEST_F(ResolverStorageClassUseTest, StructReachableFromLocal) {
   auto* s = Structure("S", {Member("a", ty.f32())});
 
-  WrapInFunction(Var("g", s, ast::StorageClass::kFunction));
+  WrapInFunction(Var("g", s));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
 
@@ -133,7 +133,7 @@
   auto* s = Structure("S", {Member("a", ty.f32())});
   auto* a = ty.alias("A", s);
   AST().AddConstructedType(a);
-  WrapInFunction(Var("g", a, ast::StorageClass::kFunction));
+  WrapInFunction(Var("g", a));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
 
@@ -146,7 +146,7 @@
 TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalStruct) {
   auto* s = Structure("S", {Member("a", ty.f32())});
   auto* o = Structure("O", {Member("a", s)});
-  WrapInFunction(Var("g", o, ast::StorageClass::kFunction));
+  WrapInFunction(Var("g", o));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
 
@@ -159,7 +159,7 @@
 TEST_F(ResolverStorageClassUseTest, StructReachableViaLocalArray) {
   auto* s = Structure("S", {Member("a", ty.f32())});
   auto* a = ty.array(s, 3);
-  WrapInFunction(Var("g", a, ast::StorageClass::kFunction));
+  WrapInFunction(Var("g", a));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
 
@@ -183,7 +183,7 @@
              create<ast::BindingDecoration>(1),
              create<ast::GroupDecoration>(0),
          });
-  WrapInFunction(Var("g", s, ast::StorageClass::kFunction));
+  WrapInFunction(Var("g", s));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
 
diff --git a/src/resolver/type_constructor_validation_test.cc b/src/resolver/type_constructor_validation_test.cc
index 055464e..e5d06d0 100644
--- a/src/resolver/type_constructor_validation_test.cc
+++ b/src/resolver/type_constructor_validation_test.cc
@@ -46,17 +46,18 @@
 TEST_F(ResolverTypeConstructorValidationTest, InferTypeTest_Simple) {
   // var a = 1;
   // var b = a;
-  auto sc = ast::StorageClass::kFunction;
-  auto* a = Var("a", nullptr, sc, Expr(1));
-  auto* b = Var("b", nullptr, sc, Expr("a"));
+  auto* a = Var("a", nullptr, ast::StorageClass::kNone, Expr(1));
+  auto* b = Var("b", nullptr, ast::StorageClass::kNone, Expr("a"));
   auto* a_ident = Expr("a");
   auto* b_ident = Expr("b");
 
   WrapInFunction(Decl(a), Decl(b), Assign(a_ident, "a"), Assign(b_ident, "b"));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
-  ASSERT_EQ(TypeOf(a_ident), ty.pointer(ty.i32(), sc));
-  ASSERT_EQ(TypeOf(b_ident), ty.pointer(ty.i32(), sc));
+  ASSERT_EQ(TypeOf(a_ident),
+            ty.pointer(ty.i32(), ast::StorageClass::kFunction));
+  ASSERT_EQ(TypeOf(b_ident),
+            ty.pointer(ty.i32(), ast::StorageClass::kFunction));
 }
 
 using InferTypeTest_FromConstructorExpression = ResolverTestWithParam<Params>;
@@ -70,8 +71,7 @@
   auto* rhs_type = params.create_rhs_ast_type(ty);
   auto* constructor_expr = ConstructValueFilledWith(rhs_type, 0);
 
-  auto sc = ast::StorageClass::kFunction;
-  auto* a = Var("a", nullptr, sc, constructor_expr);
+  auto* a = Var("a", nullptr, ast::StorageClass::kNone, constructor_expr);
   // Self-assign 'a' to force the expression to be resolved so we can test its
   // type below
   auto* a_ident = Expr("a");
@@ -79,7 +79,9 @@
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
   auto* got = TypeOf(a_ident);
-  auto* expected = ty.pointer(params.create_rhs_sem_type(ty), sc).sem;
+  auto* expected =
+      ty.pointer(params.create_rhs_sem_type(ty), ast::StorageClass::kFunction)
+          .sem;
   ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                            << "expected: " << FriendlyName(expected) << "\n";
 }
@@ -124,8 +126,7 @@
   auto* arith_rhs_expr = ConstructValueFilledWith(ElementTypeOf(rhs_type), 3);
   auto* constructor_expr = Mul(arith_lhs_expr, arith_rhs_expr);
 
-  auto sc = ast::StorageClass::kFunction;
-  auto* a = Var("a", nullptr, sc, constructor_expr);
+  auto* a = Var("a", nullptr, ast::StorageClass::kNone, constructor_expr);
   // Self-assign 'a' to force the expression to be resolved so we can test its
   // type below
   auto* a_ident = Expr("a");
@@ -133,7 +134,9 @@
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
   auto* got = TypeOf(a_ident);
-  auto* expected = ty.pointer(params.create_rhs_sem_type(ty), sc).sem;
+  auto* expected =
+      ty.pointer(params.create_rhs_sem_type(ty), ast::StorageClass::kFunction)
+          .sem;
   ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                            << "expected: " << FriendlyName(expected) << "\n";
 }
@@ -173,8 +176,7 @@
        {Return(ConstructValueFilledWith(params.create_rhs_ast_type(ty), 0))},
        {});
 
-  auto sc = ast::StorageClass::kFunction;
-  auto* a = Var("a", nullptr, sc, Call(Expr("foo")));
+  auto* a = Var("a", nullptr, ast::StorageClass::kNone, Call(Expr("foo")));
   // Self-assign 'a' to force the expression to be resolved so we can test its
   // type below
   auto* a_ident = Expr("a");
@@ -182,7 +184,9 @@
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
   auto* got = TypeOf(a_ident);
-  auto* expected = ty.pointer(params.create_rhs_sem_type(ty), sc).sem;
+  auto* expected =
+      ty.pointer(params.create_rhs_sem_type(ty), ast::StorageClass::kFunction)
+          .sem;
   ASSERT_EQ(got, expected) << "got:      " << FriendlyName(got) << "\n"
                            << "expected: " << FriendlyName(expected) << "\n";
 }
diff --git a/src/resolver/type_validation_test.cc b/src/resolver/type_validation_test.cc
index a97d677..0c1a01a 100644
--- a/src/resolver/type_validation_test.cc
+++ b/src/resolver/type_validation_test.cc
@@ -385,8 +385,7 @@
 }
 
 TEST_F(ResolverTypeValidationTest, RuntimeArrayAsLocalVariable) {
-  auto* v =
-      Var(Source{{56, 78}}, "g", ty.array<i32>(), ast::StorageClass::kFunction);
+  auto* v = Var(Source{{56, 78}}, "g", ty.array<i32>());
   WrapInFunction(v);
 
   ASSERT_FALSE(r()->Resolve());
@@ -515,7 +514,7 @@
 
   auto* type = params.create_ast_type(ty);
 
-  auto* var = Var("v", type, ast::StorageClass::kFunction);
+  auto* var = Var("v", type);
   auto* expr = Expr("v");
   WrapInFunction(var, expr);
 
diff --git a/src/transform/calculate_array_length.cc b/src/transform/calculate_array_length.cc
index 22407a4..fbaef80 100644
--- a/src/transform/calculate_array_length.cc
+++ b/src/transform/calculate_array_length.cc
@@ -181,9 +181,9 @@
 
                 // Construct the variable that'll hold the result of
                 // RWByteAddressBuffer.GetDimensions()
-                auto* buffer_size_result = ctx.dst->Decl(ctx.dst->Var(
-                    ctx.dst->Sym(), ctx.dst->ty.u32(),
-                    ast::StorageClass::kFunction, ctx.dst->Expr(0u)));
+                auto* buffer_size_result = ctx.dst->Decl(
+                    ctx.dst->Var(ctx.dst->Sym(), ctx.dst->ty.u32(),
+                                 ast::StorageClass::kNone, ctx.dst->Expr(0u)));
 
                 // Call storage_buffer.GetDimensions(buffer_size_result)
                 auto* call_get_dims =
diff --git a/src/transform/vertex_pulling.cc b/src/transform/vertex_pulling.cc
index fb2a84d..df33fa3 100644
--- a/src/transform/vertex_pulling.cc
+++ b/src/transform/vertex_pulling.cc
@@ -234,9 +234,8 @@
     ast::StatementList stmts;
 
     // Declare the pulling position variable in the shader
-    stmts.emplace_back(
-        ctx.dst->Decl(ctx.dst->Var(GetPullingPositionName(), ctx.dst->ty.u32(),
-                                   ast::StorageClass::kFunction)));
+    stmts.emplace_back(ctx.dst->Decl(
+        ctx.dst->Var(GetPullingPositionName(), ctx.dst->ty.u32())));
 
     for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
       const VertexBufferLayoutDescriptor& buffer_layout = cfg.vertex_state[i];
@@ -396,8 +395,7 @@
       // Create a function-scope variable to replace the parameter.
       auto func_var_sym = ctx.Clone(param->symbol());
       auto* func_var_type = ctx.Clone(param->type());
-      auto* func_var = ctx.dst->Var(func_var_sym, func_var_type,
-                                    ast::StorageClass::kFunction);
+      auto* func_var = ctx.dst->Var(func_var_sym, func_var_type);
       ctx.InsertBefore(func->body()->statements(), *func->body()->begin(),
                        ctx.dst->Decl(func_var));
       // Capture mapping from location to the new variable.
@@ -471,8 +469,7 @@
     }
 
     // Create a function-scope variable to replace the parameter.
-    auto* func_var = ctx.dst->Var(param_sym, ctx.Clone(param->type()),
-                                  ast::StorageClass::kFunction);
+    auto* func_var = ctx.dst->Var(param_sym, ctx.Clone(param->type()));
     ctx.InsertBefore(func->body()->statements(), *func->body()->begin(),
                      ctx.dst->Decl(func_var));
 
diff --git a/src/writer/hlsl/generator_impl_binary_test.cc b/src/writer/hlsl/generator_impl_binary_test.cc
index ec55d81..610e517 100644
--- a/src/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/writer/hlsl/generator_impl_binary_test.cc
@@ -44,8 +44,8 @@
     return;
   }
 
-  Global("left", ty.f32(), ast::StorageClass::kFunction);
-  Global("right", ty.f32(), ast::StorageClass::kFunction);
+  Global("left", ty.f32(), ast::StorageClass::kPrivate);
+  Global("right", ty.f32(), ast::StorageClass::kPrivate);
 
   auto* left = Expr("left");
   auto* right = Expr("right");
@@ -62,8 +62,8 @@
 TEST_P(HlslBinaryTest, Emit_u32) {
   auto params = GetParam();
 
-  Global("left", ty.u32(), ast::StorageClass::kFunction);
-  Global("right", ty.u32(), ast::StorageClass::kFunction);
+  Global("left", ty.u32(), ast::StorageClass::kPrivate);
+  Global("right", ty.u32(), ast::StorageClass::kPrivate);
 
   auto* left = Expr("left");
   auto* right = Expr("right");
@@ -86,8 +86,8 @@
     return;
   }
 
-  Global("left", ty.i32(), ast::StorageClass::kFunction);
-  Global("right", ty.i32(), ast::StorageClass::kFunction);
+  Global("left", ty.i32(), ast::StorageClass::kPrivate);
+  Global("right", ty.i32(), ast::StorageClass::kPrivate);
 
   auto* left = Expr("left");
   auto* right = Expr("right");
@@ -426,7 +426,7 @@
   Global("c", ty.bool_(), ast::StorageClass::kPrivate);
   Global("d", ty.bool_(), ast::StorageClass::kPrivate);
 
-  auto* var = Var("a", ty.bool_(), ast::StorageClass::kFunction,
+  auto* var = Var("a", ty.bool_(), ast::StorageClass::kNone,
                   create<ast::BinaryExpression>(
                       ast::BinaryOp::kLogicalOr,
                       create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
diff --git a/src/writer/hlsl/generator_impl_function_test.cc b/src/writer/hlsl/generator_impl_function_test.cc
index 7551484..cad1739 100644
--- a/src/writer/hlsl/generator_impl_function_test.cc
+++ b/src/writer/hlsl/generator_impl_function_test.cc
@@ -323,7 +323,7 @@
        });
 
   auto* var =
-      Var("v", ty.f32(), ast::StorageClass::kFunction, Call("sub_func", 1.0f));
+      Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1.0f));
 
   Func("frag_main", {}, ty.void_(),
        {
@@ -368,7 +368,7 @@
              create<ast::GroupDecoration>(1),
          });
 
-  auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+  auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                   MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
@@ -416,7 +416,7 @@
              create<ast::GroupDecoration>(1),
          });
 
-  auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+  auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                   MemberAccessor("coord", "b"));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
@@ -462,7 +462,7 @@
              create<ast::GroupDecoration>(1),
          });
 
-  auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+  auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                   MemberAccessor("coord", "b"));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
@@ -756,7 +756,7 @@
        });
 
   auto* var =
-      Var("v", ty.f32(), ast::StorageClass::kFunction, Call("sub_func", 1.0f));
+      Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1.0f));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
        {
@@ -807,7 +807,7 @@
        });
 
   auto* var =
-      Var("v", ty.f32(), ast::StorageClass::kFunction, Call("sub_func", 1.0f));
+      Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1.0f));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
        {
@@ -993,7 +993,7 @@
          });
 
   {
-    auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+    auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                     MemberAccessor("data", "d"));
 
     Func("a", ast::VariableList{}, ty.void_(),
@@ -1007,7 +1007,7 @@
   }
 
   {
-    auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+    auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                     MemberAccessor("data", "d"));
 
     Func("b", ast::VariableList{}, ty.void_(),
diff --git a/src/writer/hlsl/generator_impl_import_test.cc b/src/writer/hlsl/generator_impl_import_test.cc
index 459396b..cec626f 100644
--- a/src/writer/hlsl/generator_impl_import_test.cc
+++ b/src/writer/hlsl/generator_impl_import_test.cc
@@ -226,7 +226,7 @@
                          testing::Values(HlslImportData{"clamp", "clamp"}));
 
 TEST_F(HlslGeneratorImplTest_Import, HlslImportData_Determinant) {
-  Global("var", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
+  Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
 
   auto* expr = Call("determinant", "var");
   WrapInFunction(expr);
diff --git a/src/writer/hlsl/generator_impl_intrinsic_test.cc b/src/writer/hlsl/generator_impl_intrinsic_test.cc
index bb8e198..e6f3966 100644
--- a/src/writer/hlsl/generator_impl_intrinsic_test.cc
+++ b/src/writer/hlsl/generator_impl_intrinsic_test.cc
@@ -155,11 +155,11 @@
 TEST_P(HlslIntrinsicTest, Emit) {
   auto param = GetParam();
 
-  Global("f2", ty.vec2<float>(), ast::StorageClass::kFunction);
-  Global("f3", ty.vec3<float>(), ast::StorageClass::kFunction);
-  Global("u2", ty.vec2<unsigned int>(), ast::StorageClass::kFunction);
-  Global("b2", ty.vec2<bool>(), ast::StorageClass::kFunction);
-  Global("m2x2", ty.mat2x2<float>(), ast::StorageClass::kFunction);
+  Global("f2", ty.vec2<float>(), ast::StorageClass::kPrivate);
+  Global("f3", ty.vec3<float>(), ast::StorageClass::kPrivate);
+  Global("u2", ty.vec2<unsigned int>(), ast::StorageClass::kPrivate);
+  Global("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
+  Global("m2x2", ty.mat2x2<float>(), ast::StorageClass::kPrivate);
 
   auto* call = GenerateCall(param.intrinsic, param.type, this);
   ASSERT_NE(nullptr, call) << "Unhandled intrinsic";
@@ -259,8 +259,8 @@
 TEST_F(HlslGeneratorImplTest_Intrinsic, Intrinsic_Call) {
   auto* call = Call("dot", "param1", "param2");
 
-  Global("param1", ty.vec3<f32>(), ast::StorageClass::kFunction);
-  Global("param2", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  Global("param1", ty.vec3<f32>(), ast::StorageClass::kPrivate);
+  Global("param2", ty.vec3<f32>(), ast::StorageClass::kPrivate);
 
   WrapInFunction(call);
 
diff --git a/src/writer/hlsl/generator_impl_loop_test.cc b/src/writer/hlsl/generator_impl_loop_test.cc
index 3b205ac..7563001 100644
--- a/src/writer/hlsl/generator_impl_loop_test.cc
+++ b/src/writer/hlsl/generator_impl_loop_test.cc
@@ -137,10 +137,9 @@
 
   Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
 
-  auto* var = Var("lhs", ty.f32(), ast::StorageClass::kFunction, Expr(2.4f));
+  auto* var = Var("lhs", ty.f32(), ast::StorageClass::kNone, Expr(2.4f));
 
-  auto* body = Block(
-      Decl(var), Decl(Var("other", ty.f32(), ast::StorageClass::kFunction)));
+  auto* body = Block(Decl(var), Decl(Var("other", ty.f32())));
 
   auto* lhs = Expr("lhs");
   auto* rhs = Expr("rhs");
diff --git a/src/writer/hlsl/generator_impl_member_accessor_test.cc b/src/writer/hlsl/generator_impl_member_accessor_test.cc
index 9343a20..92e1375 100644
--- a/src/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -182,7 +182,7 @@
   });
 
   SetupFunction({
-      Decl(Var("x", nullptr, ast::StorageClass::kFunction,
+      Decl(Var("x", nullptr, ast::StorageClass::kNone,
                MemberAccessor("data", "b"))),
   });
 
@@ -256,7 +256,7 @@
   });
 
   SetupFunction({
-      Decl(Var("value", p.member_type(ty), ast::StorageClass::kFunction,
+      Decl(Var("value", p.member_type(ty), ast::StorageClass::kNone,
                Construct(p.member_type(ty)))),
       Assign(MemberAccessor("data", "b"), Expr("value")),
   });
@@ -387,7 +387,7 @@
 
   SetupFunction({
       Decl(
-          Var("x", nullptr, ast::StorageClass::kFunction,
+          Var("x", nullptr, ast::StorageClass::kNone,
               IndexAccessor(IndexAccessor(MemberAccessor("data", "a"), 2), 1))),
   });
 
@@ -423,7 +423,7 @@
   });
 
   SetupFunction({
-      Decl(Var("x", nullptr, ast::StorageClass::kFunction,
+      Decl(Var("x", nullptr, ast::StorageClass::kNone,
                IndexAccessor(MemberAccessor("data", "a"), 2))),
   });
 
@@ -457,7 +457,7 @@
   });
 
   SetupFunction({
-      Decl(Var("x", nullptr, ast::StorageClass::kFunction,
+      Decl(Var("x", nullptr, ast::StorageClass::kNone,
                IndexAccessor(MemberAccessor("data", "a"),
                              Sub(Add(2, Expr(4)), Expr(3))))),
   });
@@ -533,7 +533,7 @@
 
   SetupFunction({
       Decl(Var(
-          "x", nullptr, ast::StorageClass::kFunction,
+          "x", nullptr, ast::StorageClass::kNone,
           MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2), "b"))),
   });
 
@@ -578,7 +578,7 @@
   });
 
   SetupFunction({
-      Decl(Var("x", nullptr, ast::StorageClass::kFunction,
+      Decl(Var("x", nullptr, ast::StorageClass::kNone,
                MemberAccessor(
                    MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2),
                                   "b"),
@@ -626,7 +626,7 @@
   });
 
   SetupFunction({
-      Decl(Var("x", nullptr, ast::StorageClass::kFunction,
+      Decl(Var("x", nullptr, ast::StorageClass::kNone,
                MemberAccessor(
                    MemberAccessor(IndexAccessor(MemberAccessor("data", "c"), 2),
                                   "b"),
@@ -675,7 +675,7 @@
 
   SetupFunction({
       Decl(Var(
-          "x", nullptr, ast::StorageClass::kFunction,
+          "x", nullptr, ast::StorageClass::kNone,
           IndexAccessor(MemberAccessor(
                             IndexAccessor(MemberAccessor("data", "c"), 2), "b"),
                         1))),
@@ -792,7 +792,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_MemberAccessor, Swizzle_xyz) {
-  auto* var = Var("my_vec", ty.vec4<f32>(), ast::StorageClass::kFunction,
+  auto* var = Var("my_vec", ty.vec4<f32>(), ast::StorageClass::kNone,
                   vec4<f32>(1.f, 2.f, 3.f, 4.f));
   auto* expr = MemberAccessor("my_vec", "xyz");
   WrapInFunction(var, expr);
@@ -805,7 +805,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_MemberAccessor, Swizzle_gbr) {
-  auto* var = Var("my_vec", ty.vec4<f32>(), ast::StorageClass::kFunction,
+  auto* var = Var("my_vec", ty.vec4<f32>(), ast::StorageClass::kNone,
                   vec4<f32>(1.f, 2.f, 3.f, 4.f));
   auto* expr = MemberAccessor("my_vec", "gbr");
   WrapInFunction(var, expr);
diff --git a/src/writer/hlsl/generator_impl_sanitizer_test.cc b/src/writer/hlsl/generator_impl_sanitizer_test.cc
index 6100f9f..107eded 100644
--- a/src/writer/hlsl/generator_impl_sanitizer_test.cc
+++ b/src/writer/hlsl/generator_impl_sanitizer_test.cc
@@ -44,7 +44,7 @@
 
   Func("main", ast::VariableList{}, ty.void_(),
        ast::StatementList{
-           Decl(Var("len", ty.u32(), ast::StorageClass::kFunction,
+           Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
                     Call("arrayLength", MemberAccessor("sb", "arr")))),
        },
        ast::DecorationList{
@@ -74,7 +74,7 @@
 TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
   auto* array_init = array<i32, 4>(1, 2, 3, 4);
   auto* array_index = IndexAccessor(array_init, 3);
-  auto* pos = Var("pos", ty.i32(), ast::StorageClass::kFunction, array_index);
+  auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
 
   Func("main", ast::VariableList{}, ty.void_(),
        ast::StatementList{
@@ -108,7 +108,7 @@
   auto* struct_init = Construct(str, 1, vec3<f32>(2.f, 3.f, 4.f), 4);
   auto* struct_access = MemberAccessor(struct_init, "b");
   auto* pos =
-      Var("pos", ty.vec3<f32>(), ast::StorageClass::kFunction, struct_access);
+      Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
 
   Func("main", ast::VariableList{}, ty.void_(),
        ast::StatementList{
diff --git a/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
index e6904ec..62431b8 100644
--- a/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/hlsl/generator_impl_variable_decl_statement_test.cc
@@ -26,7 +26,7 @@
 using HlslGeneratorImplTest_VariableDecl = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
-  auto* var = Var("a", ty.f32(), ast::StorageClass::kFunction);
+  auto* var = Var("a", ty.f32());
   auto* stmt = Decl(var);
   WrapInFunction(stmt);
 
@@ -52,7 +52,7 @@
 }
 
 TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) {
-  auto* var = Var("a", ty.array<f32, 5>(), ast::StorageClass::kFunction);
+  auto* var = Var("a", ty.array<f32, 5>());
 
   WrapInFunction(var, Expr("a"));
 
@@ -93,8 +93,7 @@
 
 TEST_F(HlslGeneratorImplTest_VariableDecl,
        Emit_VariableDeclStatement_Initializer_ZeroVec) {
-  auto* var =
-      Var("a", ty.vec3<f32>(), ast::StorageClass::kFunction, vec3<f32>());
+  auto* var = Var("a", ty.vec3<f32>(), ast::StorageClass::kNone, vec3<f32>());
 
   auto* stmt = Decl(var);
   WrapInFunction(stmt);
@@ -109,7 +108,7 @@
 TEST_F(HlslGeneratorImplTest_VariableDecl,
        Emit_VariableDeclStatement_Initializer_ZeroMat) {
   auto* var =
-      Var("a", ty.mat2x3<f32>(), ast::StorageClass::kFunction, mat2x3<f32>());
+      Var("a", ty.mat2x3<f32>(), ast::StorageClass::kNone, mat2x3<f32>());
 
   auto* stmt = Decl(var);
   WrapInFunction(stmt);
diff --git a/src/writer/msl/generator_impl_array_accessor_test.cc b/src/writer/msl/generator_impl_array_accessor_test.cc
index d61cd60..0c3c67b 100644
--- a/src/writer/msl/generator_impl_array_accessor_test.cc
+++ b/src/writer/msl/generator_impl_array_accessor_test.cc
@@ -22,7 +22,7 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, ArrayAccessor) {
-  auto* ary = Var("ary", ty.array<i32, 10>(), ast::StorageClass::kFunction);
+  auto* ary = Var("ary", ty.array<i32, 10>());
   auto* expr = IndexAccessor("ary", 5);
   WrapInFunction(ary, expr);
 
diff --git a/src/writer/msl/generator_impl_assign_test.cc b/src/writer/msl/generator_impl_assign_test.cc
index 2c11f82..3e635fa 100644
--- a/src/writer/msl/generator_impl_assign_test.cc
+++ b/src/writer/msl/generator_impl_assign_test.cc
@@ -22,8 +22,8 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_Assign) {
-  auto* lhs = Var("lhs", ty.i32(), ast::StorageClass::kFunction);
-  auto* rhs = Var("rhs", ty.i32(), ast::StorageClass::kFunction);
+  auto* lhs = Var("lhs", ty.i32());
+  auto* rhs = Var("rhs", ty.i32());
   auto* assign = Assign(lhs, rhs);
   WrapInFunction(lhs, rhs, assign);
 
diff --git a/src/writer/msl/generator_impl_binary_test.cc b/src/writer/msl/generator_impl_binary_test.cc
index ae11182..f1099cd 100644
--- a/src/writer/msl/generator_impl_binary_test.cc
+++ b/src/writer/msl/generator_impl_binary_test.cc
@@ -38,8 +38,8 @@
                : static_cast<ast::Type*>(ty.u32());
   };
 
-  auto* left = Var("left", type(), ast::StorageClass::kFunction);
-  auto* right = Var("right", type(), ast::StorageClass::kFunction);
+  auto* left = Var("left", type());
+  auto* right = Var("right", type());
 
   auto* expr =
       create<ast::BinaryExpression>(params.op, Expr("left"), Expr("right"));
diff --git a/src/writer/msl/generator_impl_function_test.cc b/src/writer/msl/generator_impl_function_test.cc
index 1848625..aab8226 100644
--- a/src/writer/msl/generator_impl_function_test.cc
+++ b/src/writer/msl/generator_impl_function_test.cc
@@ -312,7 +312,7 @@
   Global("coord", ac, ast::StorageClass::kStorage, nullptr,
          {create<ast::BindingDecoration>(0), create<ast::GroupDecoration>(1)});
 
-  auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+  auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                   MemberAccessor("coord", "b"));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
@@ -357,7 +357,7 @@
   Global("coord", ac, ast::StorageClass::kStorage, nullptr,
          {create<ast::BindingDecoration>(0), create<ast::GroupDecoration>(1)});
 
-  auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+  auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                   MemberAccessor("coord", "b"));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
@@ -566,7 +566,7 @@
        });
 
   auto* var =
-      Var("v", ty.f32(), ast::StorageClass::kFunction, Call("sub_func", 1.0f));
+      Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1.0f));
 
   Func("frag_main", {}, ty.void_(),
        {
@@ -621,7 +621,7 @@
   Func("sub_func", params, ty.f32(), body, {});
 
   auto* var =
-      Var("v", ty.f32(), ast::StorageClass::kFunction, Call("sub_func", 1.0f));
+      Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1.0f));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
        ast::StatementList{
@@ -677,7 +677,7 @@
   Func("sub_func", params, ty.f32(), body, {});
 
   auto* var =
-      Var("v", ty.f32(), ast::StorageClass::kFunction, Call("sub_func", 1.0f));
+      Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1.0f));
 
   Func("frag_main", ast::VariableList{}, ty.void_(),
        ast::StatementList{
@@ -805,7 +805,7 @@
          {create<ast::BindingDecoration>(0), create<ast::GroupDecoration>(0)});
 
   {
-    auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+    auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                     MemberAccessor("data", "d"));
 
     Func("a", ast::VariableList{}, ty.void_(),
@@ -819,7 +819,7 @@
   }
 
   {
-    auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+    auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                     MemberAccessor("data", "d"));
 
     Func("b", ast::VariableList{}, ty.void_(),
diff --git a/src/writer/msl/generator_impl_identifier_test.cc b/src/writer/msl/generator_impl_identifier_test.cc
index d0df37f..13b739e 100644
--- a/src/writer/msl/generator_impl_identifier_test.cc
+++ b/src/writer/msl/generator_impl_identifier_test.cc
@@ -22,7 +22,7 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, EmitIdentifierExpression) {
-  auto* foo = Var("foo", ty.i32(), ast::StorageClass::kFunction);
+  auto* foo = Var("foo", ty.i32());
 
   auto* i = Expr("foo");
   WrapInFunction(foo, i);
diff --git a/src/writer/msl/generator_impl_if_test.cc b/src/writer/msl/generator_impl_if_test.cc
index b7f1f35..9840b23 100644
--- a/src/writer/msl/generator_impl_if_test.cc
+++ b/src/writer/msl/generator_impl_if_test.cc
@@ -22,7 +22,7 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_If) {
-  auto* cond = Var("cond", ty.bool_(), ast::StorageClass::kFunction);
+  auto* cond = Var("cond", ty.bool_());
   auto* i = If(cond, Block(Return()));
   WrapInFunction(cond, i);
 
@@ -38,8 +38,8 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_IfWithElseIf) {
-  auto* cond = Var("cond", ty.bool_(), ast::StorageClass::kFunction);
-  auto* else_cond = Var("else_cond", ty.bool_(), ast::StorageClass::kFunction);
+  auto* cond = Var("cond", ty.bool_());
+  auto* else_cond = Var("else_cond", ty.bool_());
   auto* i = If(cond, Block(Return()), Else(else_cond, Block(Return())));
   WrapInFunction(cond, else_cond, i);
 
@@ -57,7 +57,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_IfWithElse) {
-  auto* cond = Var("cond", ty.bool_(), ast::StorageClass::kFunction);
+  auto* cond = Var("cond", ty.bool_());
   auto* i = If(cond, Block(Return()), Else(nullptr, Block(Return())));
   WrapInFunction(cond, i);
 
@@ -75,8 +75,8 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_IfWithMultiple) {
-  auto* cond = Var("cond", ty.bool_(), ast::StorageClass::kFunction);
-  auto* else_cond = Var("else_cond", ty.bool_(), ast::StorageClass::kFunction);
+  auto* cond = Var("cond", ty.bool_());
+  auto* else_cond = Var("else_cond", ty.bool_());
   auto* i = If(cond, Block(Return()), Else(else_cond, Block(Return())),
                Else(nullptr, Block(Return())));
   WrapInFunction(cond, else_cond, i);
diff --git a/src/writer/msl/generator_impl_import_test.cc b/src/writer/msl/generator_impl_import_test.cc
index 8b93b5f..6b756dc 100644
--- a/src/writer/msl/generator_impl_import_test.cc
+++ b/src/writer/msl/generator_impl_import_test.cc
@@ -182,7 +182,7 @@
                                          MslImportData{"clamp", "clamp"}));
 
 TEST_F(MslGeneratorImplTest, MslImportData_Determinant) {
-  Global("var", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
+  Global("var", ty.mat3x3<f32>(), ast::StorageClass::kPrivate);
 
   auto* expr = Call("determinant", "var");
 
diff --git a/src/writer/msl/generator_impl_intrinsic_test.cc b/src/writer/msl/generator_impl_intrinsic_test.cc
index 6088319..5d818f4 100644
--- a/src/writer/msl/generator_impl_intrinsic_test.cc
+++ b/src/writer/msl/generator_impl_intrinsic_test.cc
@@ -166,13 +166,13 @@
 TEST_P(MslIntrinsicTest, Emit) {
   auto param = GetParam();
 
-  Global("f2", ty.vec2<float>(), ast::StorageClass::kFunction);
-  Global("f3", ty.vec3<float>(), ast::StorageClass::kFunction);
-  Global("f4", ty.vec4<float>(), ast::StorageClass::kFunction);
-  Global("u1", ty.u32(), ast::StorageClass::kFunction);
-  Global("u2", ty.vec2<unsigned int>(), ast::StorageClass::kFunction);
-  Global("b2", ty.vec2<bool>(), ast::StorageClass::kFunction);
-  Global("m2x2", ty.mat2x2<float>(), ast::StorageClass::kFunction);
+  Global("f2", ty.vec2<float>(), ast::StorageClass::kPrivate);
+  Global("f3", ty.vec3<float>(), ast::StorageClass::kPrivate);
+  Global("f4", ty.vec4<float>(), ast::StorageClass::kPrivate);
+  Global("u1", ty.u32(), ast::StorageClass::kPrivate);
+  Global("u2", ty.vec2<unsigned int>(), ast::StorageClass::kPrivate);
+  Global("b2", ty.vec2<bool>(), ast::StorageClass::kPrivate);
+  Global("m2x2", ty.mat2x2<float>(), ast::StorageClass::kPrivate);
 
   auto* call = GenerateCall(param.intrinsic, param.type, this);
   ASSERT_NE(nullptr, call) << "Unhandled intrinsic";
@@ -277,8 +277,8 @@
                       "unpack_unorm2x16_to_float"}));
 
 TEST_F(MslGeneratorImplTest, Intrinsic_Call) {
-  Global("param1", ty.vec2<f32>(), ast::StorageClass::kFunction);
-  Global("param2", ty.vec2<f32>(), ast::StorageClass::kFunction);
+  Global("param1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
+  Global("param2", ty.vec2<f32>(), ast::StorageClass::kPrivate);
 
   auto* call = Call("dot", "param1", "param2");
   WrapInFunction(call);
@@ -314,7 +314,7 @@
 
 TEST_F(MslGeneratorImplTest, Pack2x16Float) {
   auto* call = Call("pack2x16float", "p1");
-  Global("p1", ty.vec2<f32>(), ast::StorageClass::kFunction);
+  Global("p1", ty.vec2<f32>(), ast::StorageClass::kPrivate);
   WrapInFunction(call);
 
   GeneratorImpl& gen = Build();
@@ -326,7 +326,7 @@
 
 TEST_F(MslGeneratorImplTest, Unpack2x16Float) {
   auto* call = Call("unpack2x16float", "p1");
-  Global("p1", ty.u32(), ast::StorageClass::kFunction);
+  Global("p1", ty.u32(), ast::StorageClass::kPrivate);
   WrapInFunction(call);
 
   GeneratorImpl& gen = Build();
diff --git a/src/writer/msl/generator_impl_loop_test.cc b/src/writer/msl/generator_impl_loop_test.cc
index db4814e..8db7a81 100644
--- a/src/writer/msl/generator_impl_loop_test.cc
+++ b/src/writer/msl/generator_impl_loop_test.cc
@@ -132,10 +132,9 @@
 
   Global("rhs", ty.f32(), ast::StorageClass::kInput);
 
-  auto* var = Var("lhs", ty.f32(), ast::StorageClass::kFunction, Expr(2.4f));
+  auto* var = Var("lhs", ty.f32(), ast::StorageClass::kNone, Expr(2.4f));
 
-  auto* body = Block(
-      Decl(var), Decl(Var("other", ty.f32(), ast::StorageClass::kFunction)));
+  auto* body = Block(Decl(var), Decl(Var("other", ty.f32())));
 
   auto* continuing = Block(Assign("lhs", "rhs"));
 
diff --git a/src/writer/msl/generator_impl_switch_test.cc b/src/writer/msl/generator_impl_switch_test.cc
index a901967..e707eb9 100644
--- a/src/writer/msl/generator_impl_switch_test.cc
+++ b/src/writer/msl/generator_impl_switch_test.cc
@@ -22,7 +22,7 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_Switch) {
-  auto* cond = Var("cond", ty.i32(), ast::StorageClass::kFunction);
+  auto* cond = Var("cond", ty.i32());
 
   auto* def_body = Block(create<ast::BreakStatement>());
   auto* def = create<ast::CaseStatement>(ast::CaseSelectorList{}, def_body);
diff --git a/src/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/writer/msl/generator_impl_variable_decl_statement_test.cc
index 64fa23f..04e7e34 100644
--- a/src/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -84,7 +84,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Vector) {
-  auto* var = Var("a", ty.vec2<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("a", ty.vec2<f32>());
   auto* stmt = Decl(var);
   WrapInFunction(stmt);
 
@@ -97,7 +97,7 @@
 }
 
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) {
-  auto* var = Var("a", ty.mat3x2<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("a", ty.mat3x2<f32>());
 
   auto* stmt = Decl(var);
   WrapInFunction(stmt);
@@ -143,7 +143,7 @@
 TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_ZeroVec) {
   auto* zero_vec = vec3<f32>();
 
-  auto* var = Var("a", ty.vec3<f32>(), ast::StorageClass::kFunction, zero_vec);
+  auto* var = Var("a", ty.vec3<f32>(), ast::StorageClass::kNone, zero_vec);
   auto* stmt = Decl(var);
   WrapInFunction(stmt);
 
diff --git a/src/writer/spirv/builder_accessor_expression_test.cc b/src/writer/spirv/builder_accessor_expression_test.cc
index 2c5303b..6962231 100644
--- a/src/writer/spirv/builder_accessor_expression_test.cc
+++ b/src/writer/spirv/builder_accessor_expression_test.cc
@@ -26,13 +26,13 @@
   // vec3<f32> ary;
   // ary[1]  -> ptr<f32>
 
-  auto* var = Global("ary", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("ary", ty.vec3<f32>());
 
   auto* ary = Expr("ary");
   auto* idx_expr = Expr(1);
 
   auto* expr = IndexAccessor(ary, idx_expr);
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -62,14 +62,14 @@
   // idx : i32;
   // ary[idx]  -> ptr<f32>
 
-  auto* var = Global("ary", ty.vec3<f32>(), ast::StorageClass::kFunction);
-  auto* idx = Global("idx", ty.i32(), ast::StorageClass::kFunction);
+  auto* var = Var("ary", ty.vec3<f32>());
+  auto* idx = Var("idx", ty.i32());
 
   auto* ary = Expr("ary");
   auto* idx_expr = Expr("idx");
 
   auto* expr = IndexAccessor(ary, idx_expr);
-  WrapInFunction(expr);
+  WrapInFunction(var, idx, expr);
 
   spirv::Builder& b = Build();
 
@@ -102,12 +102,12 @@
   // vec3<f32> ary;
   // ary[1 + 2]  -> ptr<f32>
 
-  auto* var = Global("ary", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("ary", ty.vec3<f32>());
 
   auto* ary = Expr("ary");
 
   auto* expr = IndexAccessor(ary, Add(1, 2));
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -140,10 +140,10 @@
   // ary = array<vec3<f32>, 4>
   // ary[3][2];
 
-  auto* var = Global("ary", ary4, ast::StorageClass::kFunction);
+  auto* var = Var("ary", ary4);
 
   auto* expr = IndexAccessor(IndexAccessor("ary", 3), 2);
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -178,10 +178,10 @@
   // var a : array<vec3<f32>, 4>;
   // a[2].xy;
 
-  auto* var = Global("ary", ary4, ast::StorageClass::kFunction);
+  auto* var = Var("ary", ary4);
 
   auto* expr = MemberAccessor(IndexAccessor("ary", 2), "xy");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -224,10 +224,10 @@
                                        Member("b", ty.f32()),
                                    });
 
-  auto* var = Global("ident", s, ast::StorageClass::kFunction);
+  auto* var = Var("ident", s);
 
   auto* expr = MemberAccessor("ident", "b");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -270,9 +270,9 @@
 
   auto* s_type = Structure("my_struct", {Member("inner", inner_struct)});
 
-  auto* var = Global("ident", s_type, ast::StorageClass::kFunction);
+  auto* var = Var("ident", s_type);
   auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -312,10 +312,10 @@
                                        Member("b", ty.f32()),
                                    });
 
-  auto* var = GlobalConst("ident", s, Construct(s, 0.f, 0.f));
+  auto* var = Const("ident", s, Construct(s, 0.f, 0.f));
 
   auto* expr = MemberAccessor("ident", "b");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -352,10 +352,10 @@
 
   auto* s_type = Structure("my_struct", {Member("inner", inner_struct)});
 
-  auto* var = GlobalConst("ident", s_type,
-                          Construct(s_type, Construct(inner_struct, 0.f, 0.f)));
+  auto* var = Const("ident", s_type,
+                    Construct(s_type, Construct(inner_struct, 0.f, 0.f)));
   auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "b");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -396,9 +396,9 @@
   auto* alias = ty.alias("Inner", inner_struct);
   auto* s_type = Structure("Outer", {Member("inner", alias)});
 
-  auto* var = Global("ident", s_type, ast::StorageClass::kFunction);
+  auto* var = Var("ident", s_type);
   auto* expr = MemberAccessor(MemberAccessor("ident", "inner"), "a");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -441,10 +441,10 @@
 
   auto* s_type = Structure("my_struct", {Member("inner", inner_struct)});
 
-  auto* var = Global("ident", s_type, ast::StorageClass::kFunction);
+  auto* var = Var("ident", s_type);
   auto* expr =
       Assign(MemberAccessor(MemberAccessor("ident", "inner"), "a"), Expr(2.0f));
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -490,12 +490,12 @@
 
   auto* s_type = Structure("my_struct", {Member("inner", inner_struct)});
 
-  auto* var = Global("ident", s_type, ast::StorageClass::kFunction);
-  auto* store = Global("store", ty.f32(), ast::StorageClass::kFunction);
+  auto* var = Var("ident", s_type);
+  auto* store = Var("store", ty.f32());
 
   auto* rhs = MemberAccessor(MemberAccessor("ident", "inner"), "a");
   auto* expr = Assign("store", rhs);
-  WrapInFunction(expr);
+  WrapInFunction(var, store, expr);
 
   spirv::Builder& b = Build();
 
@@ -529,10 +529,10 @@
 TEST_F(BuilderTest, MemberAccessor_Swizzle_Single) {
   // ident.y
 
-  auto* var = Global("ident", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("ident", ty.vec3<f32>());
 
   auto* expr = MemberAccessor("ident", "y");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -560,10 +560,10 @@
 TEST_F(BuilderTest, MemberAccessor_Swizzle_MultipleNames) {
   // ident.yx
 
-  auto* var = Global("ident", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("ident", ty.vec3<f32>());
 
   auto* expr = MemberAccessor("ident", "yx");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -590,10 +590,10 @@
 TEST_F(BuilderTest, MemberAccessor_Swizzle_of_Swizzle) {
   // ident.yxz.xz
 
-  auto* var = Global("ident", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("ident", ty.vec3<f32>());
 
   auto* expr = MemberAccessor(MemberAccessor("ident", "yxz"), "xz");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -621,10 +621,10 @@
 TEST_F(BuilderTest, MemberAccessor_Member_of_Swizzle) {
   // ident.yxz.x
 
-  auto* var = Global("ident", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("ident", ty.vec3<f32>());
 
   auto* expr = MemberAccessor(MemberAccessor("ident", "yxz"), "x");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -651,10 +651,10 @@
 TEST_F(BuilderTest, MemberAccessor_Array_of_Swizzle) {
   // index.yxz[1]
 
-  auto* var = Global("ident", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("ident", ty.vec3<f32>());
 
   auto* expr = IndexAccessor(MemberAccessor("ident", "yxz"), 1);
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -700,7 +700,7 @@
   auto* a_type = Structure("A", {Member("foo", b_ary_type)});
 
   auto* a_ary_type = ty.array(a_type, 2);
-  auto* var = Global("index", a_ary_type, ast::StorageClass::kFunction);
+  auto* var = Var("index", a_ary_type);
   auto* expr = MemberAccessor(
       MemberAccessor(
           MemberAccessor(
@@ -709,7 +709,7 @@
               "bar"),
           "baz"),
       "yx");
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -755,12 +755,12 @@
   // pos[1]
 
   auto* var =
-      GlobalConst("pos", ty.array(ty.vec2<f32>(), 3),
-                  Construct(ty.array(ty.vec2<f32>(), 3), vec2<f32>(0.0f, 0.5f),
-                            vec2<f32>(-0.5f, -0.5f), vec2<f32>(0.5f, -0.5f)));
+      Const("pos", ty.array(ty.vec2<f32>(), 3),
+            Construct(ty.array(ty.vec2<f32>(), 3), vec2<f32>(0.0f, 0.5f),
+                      vec2<f32>(-0.5f, -0.5f), vec2<f32>(0.5f, -0.5f)));
 
   auto* expr = IndexAccessor("pos", 1u);
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -798,10 +798,10 @@
   // let pos : vec2<f32> = vec2<f32>(0.0, 0.5);
   // pos[1]
 
-  auto* var = GlobalConst("pos", ty.vec2<f32>(), vec2<f32>(0.0f, 0.5f));
+  auto* var = Const("pos", ty.vec2<f32>(), vec2<f32>(0.0f, 0.5f));
 
   auto* expr = IndexAccessor("pos", 1u);
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -828,15 +828,11 @@
   // idx : i32
   // pos[idx]
 
-  auto* var = GlobalConst("pos", ty.vec2<f32>(), vec2<f32>(0.0f, 0.5f));
-
-  auto* idx = Var("idx", ty.i32(), ast::StorageClass::kFunction);
+  auto* var = Const("pos", ty.vec2<f32>(), vec2<f32>(0.0f, 0.5f));
+  auto* idx = Var("idx", ty.i32());
   auto* expr = IndexAccessor("pos", idx);
 
-  ast::StatementList body;
-  body.push_back(WrapInStatement(idx));
-  body.push_back(WrapInStatement(expr));
-  WrapInFunction(body);
+  WrapInFunction(var, idx, expr);
 
   spirv::Builder& b = Build();
 
@@ -867,10 +863,10 @@
   // let a : array<f32, 3>;
   // a[2]
 
-  auto* var = GlobalConst("a", ty.array<f32, 3>(),
-                          Construct(ty.array<f32, 3>(), 0.0f, 0.5f, 1.0f));
+  auto* var = Const("a", ty.array<f32, 3>(),
+                    Construct(ty.array<f32, 3>(), 0.0f, 0.5f, 1.0f));
   auto* expr = IndexAccessor("a", 2);
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -900,16 +896,13 @@
   // idx : i32
   // a[idx]
 
-  auto* var = GlobalConst("a", ty.array<f32, 3>(),
-                          Construct(ty.array<f32, 3>(), 0.0f, 0.5f, 1.0f));
+  auto* var = Const("a", ty.array<f32, 3>(),
+                    Construct(ty.array<f32, 3>(), 0.0f, 0.5f, 1.0f));
 
-  auto* idx = Var("idx", ty.i32(), ast::StorageClass::kFunction);
+  auto* idx = Var("idx", ty.i32());
   auto* expr = IndexAccessor("a", idx);
 
-  ast::StatementList body;
-  body.push_back(WrapInStatement(idx));
-  body.push_back(WrapInStatement(expr));
-  WrapInFunction(body);
+  WrapInFunction(var, idx, expr);
 
   spirv::Builder& b = Build();
 
diff --git a/src/writer/spirv/builder_assign_test.cc b/src/writer/spirv/builder_assign_test.cc
index c3facfe..4dbf765 100644
--- a/src/writer/spirv/builder_assign_test.cc
+++ b/src/writer/spirv/builder_assign_test.cc
@@ -181,11 +181,11 @@
                                        Member("b", ty.f32()),
                                    });
 
-  auto* v = Global("ident", s, ast::StorageClass::kFunction);
+  auto* v = Var("ident", s);
 
   auto* assign = Assign(MemberAccessor("ident", "b"), Expr(4.f));
 
-  WrapInFunction(assign);
+  WrapInFunction(v, assign);
 
   spirv::Builder& b = Build();
 
diff --git a/src/writer/spirv/builder_binary_expression_test.cc b/src/writer/spirv/builder_binary_expression_test.cc
index 55000ce..bdf19a2 100644
--- a/src/writer/spirv/builder_binary_expression_test.cc
+++ b/src/writer/spirv/builder_binary_expression_test.cc
@@ -87,11 +87,11 @@
 TEST_P(BinaryArithSignedIntegerTest, Scalar_Loads) {
   auto param = GetParam();
 
-  auto* var = Global("param", ty.i32(), ast::StorageClass::kFunction);
+  auto* var = Var("param", ty.i32());
   auto* expr =
       create<ast::BinaryExpression>(param.op, Expr("param"), Expr("param"));
 
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -482,12 +482,12 @@
 }
 
 TEST_F(BuilderTest, Binary_Multiply_MatrixScalar) {
-  auto* var = Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("mat", ty.mat3x3<f32>());
 
   auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply,
                                              Expr("mat"), Expr(1.f));
 
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -510,12 +510,12 @@
 }
 
 TEST_F(BuilderTest, Binary_Multiply_ScalarMatrix) {
-  auto* var = Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("mat", ty.mat3x3<f32>());
 
   auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply,
                                              Expr(1.f), Expr("mat"));
 
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -538,13 +538,13 @@
 }
 
 TEST_F(BuilderTest, Binary_Multiply_MatrixVector) {
-  auto* var = Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("mat", ty.mat3x3<f32>());
   auto* rhs = vec3<f32>(1.f, 1.f, 1.f);
 
   auto* expr =
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, Expr("mat"), rhs);
 
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -568,13 +568,13 @@
 }
 
 TEST_F(BuilderTest, Binary_Multiply_VectorMatrix) {
-  auto* var = Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("mat", ty.mat3x3<f32>());
   auto* lhs = vec3<f32>(1.f, 1.f, 1.f);
 
   auto* expr =
       create<ast::BinaryExpression>(ast::BinaryOp::kMultiply, lhs, Expr("mat"));
 
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -598,12 +598,12 @@
 }
 
 TEST_F(BuilderTest, Binary_Multiply_MatrixMatrix) {
-  auto* var = Global("mat", ty.mat3x3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("mat", ty.mat3x3<f32>());
 
   auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kMultiply,
                                              Expr("mat"), Expr("mat"));
 
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
@@ -666,9 +666,9 @@
 
 TEST_F(BuilderTest, Binary_LogicalAnd_WithLoads) {
   auto* a_var =
-      Global("a", ty.bool_(), ast::StorageClass::kFunction, Expr(true));
+      Global("a", ty.bool_(), ast::StorageClass::kPrivate, Expr(true));
   auto* b_var =
-      Global("b", ty.bool_(), ast::StorageClass::kFunction, Expr(false));
+      Global("b", ty.bool_(), ast::StorageClass::kPrivate, Expr(false));
 
   auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                              Expr("a"), Expr("b"));
@@ -686,10 +686,10 @@
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
 %3 = OpConstantTrue %2
-%5 = OpTypePointer Function %2
-%4 = OpVariable %5 Function %3
+%5 = OpTypePointer Private %2
+%4 = OpVariable %5 Private %3
 %6 = OpConstantFalse %2
-%7 = OpVariable %5 Function %6
+%7 = OpVariable %5 Private %6
 )");
   EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
             R"(%1 = OpLabel
@@ -825,9 +825,9 @@
 
 TEST_F(BuilderTest, Binary_LogicalOr_WithLoads) {
   auto* a_var =
-      Global("a", ty.bool_(), ast::StorageClass::kFunction, Expr(true));
+      Global("a", ty.bool_(), ast::StorageClass::kPrivate, Expr(true));
   auto* b_var =
-      Global("b", ty.bool_(), ast::StorageClass::kFunction, Expr(false));
+      Global("b", ty.bool_(), ast::StorageClass::kPrivate, Expr(false));
 
   auto* expr = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalOr,
                                              Expr("a"), Expr("b"));
@@ -845,10 +845,10 @@
   EXPECT_EQ(b.GenerateBinaryExpression(expr), 12u) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeBool
 %3 = OpConstantTrue %2
-%5 = OpTypePointer Function %2
-%4 = OpVariable %5 Function %3
+%5 = OpTypePointer Private %2
+%4 = OpVariable %5 Private %3
 %6 = OpConstantFalse %2
-%7 = OpVariable %5 Function %6
+%7 = OpVariable %5 Private %6
 )");
   EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
             R"(%1 = OpLabel
diff --git a/src/writer/spirv/builder_block_test.cc b/src/writer/spirv/builder_block_test.cc
index 206cb6a..e0cad3c 100644
--- a/src/writer/spirv/builder_block_test.cc
+++ b/src/writer/spirv/builder_block_test.cc
@@ -27,9 +27,9 @@
 TEST_F(BuilderTest, DISABLED_Block) {
   // Note, this test uses shadow variables which aren't allowed in WGSL but
   // serves to prove the block code is pushing new scopes as needed.
-  auto* inner = Block(Decl(Var("var", ty.f32(), ast::StorageClass::kFunction)),
+  auto* inner = Block(Decl(Var("var", ty.f32(), ast::StorageClass::kNone)),
                       Assign("var", 2.f));
-  auto* outer = Block(Decl(Var("var", ty.f32(), ast::StorageClass::kFunction)),
+  auto* outer = Block(Decl(Var("var", ty.f32(), ast::StorageClass::kNone)),
                       Assign("var", 1.f), inner, Assign("var", 3.f));
 
   WrapInFunction(outer);
diff --git a/src/writer/spirv/builder_constructor_expression_test.cc b/src/writer/spirv/builder_constructor_expression_test.cc
index 3b69501..2669331 100644
--- a/src/writer/spirv/builder_constructor_expression_test.cc
+++ b/src/writer/spirv/builder_constructor_expression_test.cc
@@ -113,10 +113,10 @@
 }
 
 TEST_F(SpvBuilderConstructorTest, Type_IdentifierExpression_Param) {
-  auto* var = Global("ident", ty.f32(), ast::StorageClass::kFunction);
+  auto* var = Var("ident", ty.f32());
 
   auto* t = vec2<f32>(1.0f, "ident");
-  WrapInFunction(t);
+  WrapInFunction(var, t);
 
   spirv::Builder& b = Build();
 
diff --git a/src/writer/spirv/builder_entry_point_test.cc b/src/writer/spirv/builder_entry_point_test.cc
index b76d0c5..fd98a76 100644
--- a/src/writer/spirv/builder_entry_point_test.cc
+++ b/src/writer/spirv/builder_entry_point_test.cc
@@ -46,7 +46,7 @@
       Param("coord", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
   auto* loc1 = Param("loc1", ty.f32(), {Location(1u)});
   auto* mul = Mul(Expr(MemberAccessor("coord", "x")), Expr("loc1"));
-  auto* col = Var("col", ty.f32(), ast::StorageClass::kFunction, mul, {});
+  auto* col = Var("col", ty.f32(), ast::StorageClass::kNone, mul);
   Func("frag_main", ast::VariableList{coord, loc1}, ty.void_(),
        ast::StatementList{WrapInStatement(col)},
        ast::DecorationList{
diff --git a/src/writer/spirv/builder_function_test.cc b/src/writer/spirv/builder_function_test.cc
index ac8a5be..a2da8e5 100644
--- a/src/writer/spirv/builder_function_test.cc
+++ b/src/writer/spirv/builder_function_test.cc
@@ -213,7 +213,7 @@
          });
 
   {
-    auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+    auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                     MemberAccessor("data", "d"));
 
     Func("a", ast::VariableList{}, ty.void_(),
@@ -227,7 +227,7 @@
   }
 
   {
-    auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+    auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                     MemberAccessor("data", "d"));
 
     Func("b", ast::VariableList{}, ty.void_(),
diff --git a/src/writer/spirv/builder_function_variable_test.cc b/src/writer/spirv/builder_function_variable_test.cc
index 7fae8b3..1ef5deb 100644
--- a/src/writer/spirv/builder_function_variable_test.cc
+++ b/src/writer/spirv/builder_function_variable_test.cc
@@ -23,7 +23,8 @@
 using BuilderTest = TestHelper;
 
 TEST_F(BuilderTest, FunctionVar_NoStorageClass) {
-  auto* v = Global("var", ty.f32(), ast::StorageClass::kInput);
+  auto* v = Var("var", ty.f32(), ast::StorageClass::kFunction);
+  WrapInFunction(v);
 
   spirv::Builder& b = Build();
 
@@ -44,8 +45,8 @@
 
 TEST_F(BuilderTest, FunctionVar_WithConstantConstructor) {
   auto* init = vec3<f32>(1.f, 1.f, 3.f);
-
-  auto* v = Global("var", ty.vec3<f32>(), ast::StorageClass::kOutput, init);
+  auto* v = Var("var", ty.vec3<f32>(), ast::StorageClass::kFunction, init);
+  WrapInFunction(v);
 
   spirv::Builder& b = Build();
 
@@ -74,7 +75,8 @@
 TEST_F(BuilderTest, FunctionVar_WithNonConstantConstructor) {
   auto* init = vec2<f32>(1.f, Add(3.f, 3.f));
 
-  auto* v = Global("var", ty.vec2<f32>(), ast::StorageClass::kFunction, init);
+  auto* v = Var("var", ty.vec2<f32>(), ast::StorageClass::kNone, init);
+  WrapInFunction(v);
 
   spirv::Builder& b = Build();
 
@@ -105,9 +107,10 @@
   // var v : f32 = 1.0;
   // var v2 : f32 = v; // Should generate the load and store automatically.
 
-  auto* v = Global("v", ty.f32(), ast::StorageClass::kFunction, Expr(1.f));
+  auto* v = Var("v", ty.f32(), ast::StorageClass::kNone, Expr(1.f));
 
-  auto* v2 = Global("v2", ty.f32(), ast::StorageClass::kFunction, Expr("v"));
+  auto* v2 = Var("v2", ty.f32(), ast::StorageClass::kNone, Expr("v"));
+  WrapInFunction(v, v2);
 
   spirv::Builder& b = Build();
 
@@ -139,9 +142,10 @@
   // var v : f32 = 1.0;
   // let v2 : f32 = v; // Should generate the load
 
-  auto* v = Global("v", ty.f32(), ast::StorageClass::kFunction, Expr(1.f));
+  auto* v = Var("v", ty.f32(), ast::StorageClass::kNone, Expr(1.f));
 
-  auto* v2 = Global("v2", ty.f32(), ast::StorageClass::kFunction, Expr("v"));
+  auto* v2 = Var("v2", ty.f32(), ast::StorageClass::kNone, Expr("v"));
+  WrapInFunction(v, v2);
 
   spirv::Builder& b = Build();
 
diff --git a/src/writer/spirv/builder_if_test.cc b/src/writer/spirv/builder_if_test.cc
index 62eb81d..193c11a 100644
--- a/src/writer/spirv/builder_if_test.cc
+++ b/src/writer/spirv/builder_if_test.cc
@@ -506,7 +506,7 @@
   // if (a) {
   // }
 
-  auto* var = Global("a", ty.bool_(), ast::StorageClass::kFunction);
+  auto* var = Global("a", ty.bool_(), ast::StorageClass::kPrivate);
 
   auto* expr =
       create<ast::IfStatement>(Expr("a"), Block(), ast::ElseStatementList{});
@@ -519,16 +519,17 @@
 
   EXPECT_TRUE(b.GenerateIfStatement(expr)) << b.error();
   EXPECT_EQ(DumpInstructions(b.types()), R"(%3 = OpTypeBool
-%2 = OpTypePointer Function %3
-%1 = OpVariable %2 Function
+%2 = OpTypePointer Private %3
+%4 = OpConstantNull %3
+%1 = OpVariable %2 Private %4
 )");
   EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
-            R"(%4 = OpLoad %3 %1
-OpSelectionMerge %5 None
-OpBranchConditional %4 %6 %5
+            R"(%5 = OpLoad %3 %1
+OpSelectionMerge %6 None
+OpBranchConditional %5 %7 %6
+%7 = OpLabel
+OpBranch %6
 %6 = OpLabel
-OpBranch %5
-%5 = OpLabel
 )");
 }
 
diff --git a/src/writer/spirv/builder_intrinsic_test.cc b/src/writer/spirv/builder_intrinsic_test.cc
index 6ce0797..9b9f4db 100644
--- a/src/writer/spirv/builder_intrinsic_test.cc
+++ b/src/writer/spirv/builder_intrinsic_test.cc
@@ -1261,7 +1261,7 @@
                          testing::Values(IntrinsicData{"clamp", "UClamp"}));
 
 TEST_F(IntrinsicBuilderTest, Call_Modf) {
-  auto* out = Var("out", ty.vec2<f32>(), ast::StorageClass::kFunction);
+  auto* out = Var("out", ty.vec2<f32>());
   auto* expr = Call("modf", vec2<f32>(1.0f, 2.0f), "out");
   Func("a_func", ast::VariableList{}, ty.void_(),
        ast::StatementList{
@@ -1305,7 +1305,7 @@
 }
 
 TEST_F(IntrinsicBuilderTest, Call_Frexp) {
-  auto* out = Var("out", ty.vec2<i32>(), ast::StorageClass::kFunction);
+  auto* out = Var("out", ty.vec2<i32>());
   auto* expr = Call("frexp", vec2<f32>(1.0f, 2.0f), "out");
   Func("a_func", ast::VariableList{}, ty.void_(),
        ast::StatementList{
diff --git a/src/writer/spirv/builder_loop_test.cc b/src/writer/spirv/builder_loop_test.cc
index 2db38a5..690dec0 100644
--- a/src/writer/spirv/builder_loop_test.cc
+++ b/src/writer/spirv/builder_loop_test.cc
@@ -135,7 +135,7 @@
   //   }
   // }
 
-  auto* var = Var("a", ty.i32(), ast::StorageClass::kFunction);
+  auto* var = Var("a", ty.i32());
   auto* var_decl = WrapInStatement(var);
   auto* body = Block(var_decl);
   auto* continuing = Block(Assign("a", 3));
diff --git a/src/writer/spirv/builder_return_test.cc b/src/writer/spirv/builder_return_test.cc
index 738d126..a89a59a 100644
--- a/src/writer/spirv/builder_return_test.cc
+++ b/src/writer/spirv/builder_return_test.cc
@@ -60,10 +60,10 @@
 }
 
 TEST_F(BuilderTest, Return_WithValue_GeneratesLoad) {
-  auto* var = Global("param", ty.f32(), ast::StorageClass::kFunction);
+  auto* var = Var("param", ty.f32());
 
   auto* ret = Return(var);
-  Func("test", {}, ty.f32(), {ret}, {});
+  Func("test", {}, ty.f32(), {Decl(var), ret}, {});
 
   spirv::Builder& b = Build();
 
diff --git a/src/writer/spirv/builder_unary_op_expression_test.cc b/src/writer/spirv/builder_unary_op_expression_test.cc
index 18f9306..2c8e90d 100644
--- a/src/writer/spirv/builder_unary_op_expression_test.cc
+++ b/src/writer/spirv/builder_unary_op_expression_test.cc
@@ -72,11 +72,11 @@
 }
 
 TEST_F(BuilderTest, UnaryOp_LoadRequired) {
-  auto* var = Global("param", ty.vec3<f32>(), ast::StorageClass::kFunction);
+  auto* var = Var("param", ty.vec3<f32>());
 
   auto* expr =
       create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr("param"));
-  WrapInFunction(expr);
+  WrapInFunction(var, expr);
 
   spirv::Builder& b = Build();
 
diff --git a/src/writer/wgsl/generator_impl_function_test.cc b/src/writer/wgsl/generator_impl_function_test.cc
index 5630bb9..6a11f84 100644
--- a/src/writer/wgsl/generator_impl_function_test.cc
+++ b/src/writer/wgsl/generator_impl_function_test.cc
@@ -213,7 +213,7 @@
          });
 
   {
-    auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+    auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                     MemberAccessor("data", "d"));
 
     Func("a", ast::VariableList{}, ty.void_(),
@@ -227,7 +227,7 @@
   }
 
   {
-    auto* var = Var("v", ty.f32(), ast::StorageClass::kFunction,
+    auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
                     MemberAccessor("data", "d"));
 
     Func("b", ast::VariableList{}, ty.void_(),
diff --git a/src/writer/wgsl/generator_impl_global_decl_test.cc b/src/writer/wgsl/generator_impl_global_decl_test.cc
index 14fd4a7..342c358 100644
--- a/src/writer/wgsl/generator_impl_global_decl_test.cc
+++ b/src/writer/wgsl/generator_impl_global_decl_test.cc
@@ -26,7 +26,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_GlobalDeclAfterFunction) {
-  auto* func_var = Var("a", ty.f32(), ast::StorageClass::kFunction);
+  auto* func_var = Var("a", ty.f32());
   WrapInFunction(func_var);
 
   Global("a", ty.f32(), ast::StorageClass::kPrivate);
@@ -62,8 +62,8 @@
 
   Func("main", ast::VariableList{}, ty.void_(),
        ast::StatementList{
-           Decl(Var("s0", s0, ast::StorageClass::kFunction)),
-           Decl(Var("s1", s1, ast::StorageClass::kFunction)),
+           Decl(Var("s0", s0)),
+           Decl(Var("s1", s1)),
            Assign("a1", Call("func")),
        },
        ast::DecorationList{
diff --git a/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc b/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
index 853e137..e7a3f30 100644
--- a/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/wgsl/generator_impl_variable_decl_statement_test.cc
@@ -23,7 +23,7 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement) {
-  auto* var = Var("a", ty.f32(), ast::StorageClass::kFunction);
+  auto* var = Var("a", ty.f32());
 
   auto* stmt = Decl(var);
   WrapInFunction(stmt);
@@ -37,7 +37,7 @@
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_InferredType) {
-  auto* var = Var("a", nullptr, ast::StorageClass::kFunction, Expr(123));
+  auto* var = Var("a", nullptr, ast::StorageClass::kNone, Expr(123));
 
   auto* stmt = Decl(var);
   WrapInFunction(stmt);