tint: Rename SourceVariable() to RootIdentifier()

This is now a well-defined term in the WGSL spec, so we should use it.

Change-Id: Icc46a77f0a465afbfd39cdaec84e506b143c8c0c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/109220
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Auto-Submit: James Price <jrprice@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 39fae60..eb863de 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -1160,7 +1160,7 @@
       "resolver/resolver_test_helper.cc",
       "resolver/resolver_test_helper.h",
       "resolver/side_effects_test.cc",
-      "resolver/source_variable_test.cc",
+      "resolver/root_identifier_test.cc",
       "resolver/static_assert_test.cc",
       "resolver/struct_address_space_use_test.cc",
       "resolver/struct_layout_test.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 1d39243..69712dd 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -885,7 +885,7 @@
     resolver/resolver_test.cc
     resolver/side_effects_test.cc
     resolver/static_assert_test.cc
-    resolver/source_variable_test.cc
+    resolver/root_identifier_test.cc
     resolver/address_space_layout_validation_test.cc
     resolver/address_space_validation_test.cc
     resolver/struct_layout_test.cc
diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc
index 516c1dc..b641f53 100644
--- a/src/tint/inspector/inspector.cc
+++ b/src/tint/inspector/inspector.cc
@@ -892,10 +892,10 @@
     utils::UniqueVector<const ast::CallExpression*, 8> callsites;
 
     for (size_t i = 0; i < N; i++) {
-        const sem::Variable* source_var = sem.Get(exprs[i])->SourceVariable();
-        if (auto* global = source_var->As<sem::GlobalVariable>()) {
+        const sem::Variable* root_ident = sem.Get(exprs[i])->RootIdentifier();
+        if (auto* global = root_ident->As<sem::GlobalVariable>()) {
             globals[i] = global;
-        } else if (auto* param = source_var->As<sem::Parameter>()) {
+        } else if (auto* param = root_ident->As<sem::Parameter>()) {
             auto* func = tint::As<sem::Function>(param->Owner());
             if (func->CallSites().empty()) {
                 // One or more of the expressions is a parameter, but this function
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index cb24955..daec00a 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -1712,7 +1712,7 @@
     bool has_side_effects = idx->HasSideEffects() || obj->HasSideEffects();
     auto* sem = builder_->create<sem::IndexAccessorExpression>(
         expr, ty, stage, obj, idx, current_statement_, std::move(val), has_side_effects,
-        obj->SourceVariable());
+        obj->RootIdentifier());
     sem->Behaviors() = idx->Behaviors() + obj->Behaviors();
     return sem;
 }
@@ -2365,7 +2365,7 @@
     auto* structure = sem_.TypeOf(expr->structure);
     auto* storage_ty = structure->UnwrapRef();
     auto* object = sem_.Get(expr->structure);
-    auto* source_var = object->SourceVariable();
+    auto* root_ident = object->RootIdentifier();
 
     const sem::Type* ty = nullptr;
 
@@ -2404,7 +2404,7 @@
             }
             return builder_->create<sem::StructMemberAccess>(expr, ty, current_statement_,
                                                              val.Get(), object, member,
-                                                             has_side_effects, source_var);
+                                                             has_side_effects, root_ident);
         },
 
         [&](const sem::Vector* vec) -> sem::Expression* {
@@ -2476,7 +2476,7 @@
                 return nullptr;
             }
             return builder_->create<sem::Swizzle>(expr, ty, current_statement_, val.Get(), object,
-                                                  std::move(swizzle), has_side_effects, source_var);
+                                                  std::move(swizzle), has_side_effects, root_ident);
         },
 
         [&](Default) {
@@ -2549,7 +2549,7 @@
     }
 
     const sem::Type* ty = nullptr;
-    const sem::Variable* source_var = nullptr;
+    const sem::Variable* root_ident = nullptr;
     const sem::Constant* value = nullptr;
     auto stage = sem::EvaluationStage::kRuntime;
 
@@ -2573,7 +2573,7 @@
                 ty = builder_->create<sem::Pointer>(ref->StoreType(), ref->AddressSpace(),
                                                     ref->Access());
 
-                source_var = expr->SourceVariable();
+                root_ident = expr->RootIdentifier();
             } else {
                 AddError("cannot take the address of expression", unary->expr->source);
                 return nullptr;
@@ -2584,7 +2584,7 @@
             if (auto* ptr = expr_ty->As<sem::Pointer>()) {
                 ty = builder_->create<sem::Reference>(ptr->StoreType(), ptr->AddressSpace(),
                                                       ptr->Access());
-                source_var = expr->SourceVariable();
+                root_ident = expr->RootIdentifier();
             } else {
                 AddError("cannot dereference expression of type '" + sem_.TypeNameOf(expr_ty) + "'",
                          unary->expr->source);
@@ -2623,7 +2623,7 @@
     }
 
     auto* sem = builder_->create<sem::Expression>(unary, ty, stage, current_statement_, value,
-                                                  expr->HasSideEffects(), source_var);
+                                                  expr->HasSideEffects(), root_ident);
     sem->Behaviors() = expr->Behaviors();
     return sem;
 }
diff --git a/src/tint/resolver/source_variable_test.cc b/src/tint/resolver/root_identifier_test.cc
similarity index 69%
rename from src/tint/resolver/source_variable_test.cc
rename to src/tint/resolver/root_identifier_test.cc
index e662395..934feae 100644
--- a/src/tint/resolver/source_variable_test.cc
+++ b/src/tint/resolver/root_identifier_test.cc
@@ -23,9 +23,9 @@
 namespace tint::resolver {
 namespace {
 
-class ResolverSourceVariableTest : public ResolverTest {};
+class ResolverRootIdentifierTest : public ResolverTest {};
 
-TEST_F(ResolverSourceVariableTest, GlobalPrivateVar) {
+TEST_F(ResolverRootIdentifierTest, GlobalPrivateVar) {
     auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kPrivate);
     auto* expr = Expr(a);
     WrapInFunction(expr);
@@ -33,10 +33,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, GlobalWorkgroupVar) {
+TEST_F(ResolverRootIdentifierTest, GlobalWorkgroupVar) {
     auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kWorkgroup);
     auto* expr = Expr(a);
     WrapInFunction(expr);
@@ -44,10 +44,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, GlobalStorageVar) {
+TEST_F(ResolverRootIdentifierTest, GlobalStorageVar) {
     auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kStorage, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
     WrapInFunction(expr);
@@ -55,10 +55,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, GlobalUniformVar) {
+TEST_F(ResolverRootIdentifierTest, GlobalUniformVar) {
     auto* a = GlobalVar("a", ty.f32(), ast::AddressSpace::kUniform, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
     WrapInFunction(expr);
@@ -66,10 +66,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, GlobalTextureVar) {
+TEST_F(ResolverRootIdentifierTest, GlobalTextureVar) {
     auto* a = GlobalVar("a", ty.sampled_texture(ast::TextureDimension::k2d, ty.f32()),
                         ast::AddressSpace::kNone, Group(0_a), Binding(0_a));
     auto* expr = Expr(a);
@@ -78,10 +78,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, GlobalOverride) {
+TEST_F(ResolverRootIdentifierTest, GlobalOverride) {
     auto* a = Override("a", ty.f32(), Expr(1_f));
     auto* expr = Expr(a);
     WrapInFunction(expr);
@@ -89,10 +89,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, GlobalConst) {
+TEST_F(ResolverRootIdentifierTest, GlobalConst) {
     auto* a = GlobalConst("a", ty.f32(), Expr(1_f));
     auto* expr = Expr(a);
     WrapInFunction(expr);
@@ -100,10 +100,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, FunctionVar) {
+TEST_F(ResolverRootIdentifierTest, FunctionVar) {
     auto* a = Var("a", ty.f32());
     auto* expr = Expr(a);
     WrapInFunction(a, expr);
@@ -111,10 +111,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, FunctionLet) {
+TEST_F(ResolverRootIdentifierTest, FunctionLet) {
     auto* a = Let("a", ty.f32(), Expr(1_f));
     auto* expr = Expr(a);
     WrapInFunction(a, expr);
@@ -122,10 +122,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, Parameter) {
+TEST_F(ResolverRootIdentifierTest, Parameter) {
     auto* a = Param("a", ty.f32());
     auto* expr = Expr(a);
     Func("foo", utils::Vector{a}, ty.void_(), utils::Vector{WrapInStatement(expr)});
@@ -133,10 +133,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, PointerParameter) {
+TEST_F(ResolverRootIdentifierTest, PointerParameter) {
     // fn foo(a : ptr<function, f32>)
     // {
     //   let b = a;
@@ -151,11 +151,11 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_param = Sem().Get(param);
-    EXPECT_EQ(Sem().Get(expr_param)->SourceVariable(), sem_param);
-    EXPECT_EQ(Sem().Get(expr_let)->SourceVariable(), sem_param);
+    EXPECT_EQ(Sem().Get(expr_param)->RootIdentifier(), sem_param);
+    EXPECT_EQ(Sem().Get(expr_let)->RootIdentifier(), sem_param);
 }
 
-TEST_F(ResolverSourceVariableTest, VarCopyVar) {
+TEST_F(ResolverRootIdentifierTest, VarCopyVar) {
     // {
     //   var a : f32;
     //   var b = a;
@@ -170,11 +170,11 @@
 
     auto* sem_a = Sem().Get(a);
     auto* sem_b = Sem().Get(b);
-    EXPECT_EQ(Sem().Get(expr_a)->SourceVariable(), sem_a);
-    EXPECT_EQ(Sem().Get(expr_b)->SourceVariable(), sem_b);
+    EXPECT_EQ(Sem().Get(expr_a)->RootIdentifier(), sem_a);
+    EXPECT_EQ(Sem().Get(expr_b)->RootIdentifier(), sem_b);
 }
 
-TEST_F(ResolverSourceVariableTest, LetCopyVar) {
+TEST_F(ResolverRootIdentifierTest, LetCopyVar) {
     // {
     //   var a : f32;
     //   let b = a;
@@ -189,11 +189,11 @@
 
     auto* sem_a = Sem().Get(a);
     auto* sem_b = Sem().Get(b);
-    EXPECT_EQ(Sem().Get(expr_a)->SourceVariable(), sem_a);
-    EXPECT_EQ(Sem().Get(expr_b)->SourceVariable(), sem_b);
+    EXPECT_EQ(Sem().Get(expr_a)->RootIdentifier(), sem_a);
+    EXPECT_EQ(Sem().Get(expr_b)->RootIdentifier(), sem_b);
 }
 
-TEST_F(ResolverSourceVariableTest, ThroughIndexAccessor) {
+TEST_F(ResolverRootIdentifierTest, ThroughIndexAccessor) {
     // var<private> a : array<f32, 4u>;
     // {
     //   a[2i]
@@ -205,10 +205,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, ThroughMemberAccessor) {
+TEST_F(ResolverRootIdentifierTest, ThroughMemberAccessor) {
     // struct S { f : f32 }
     // var<private> a : S;
     // {
@@ -222,10 +222,10 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, ThroughPointers) {
+TEST_F(ResolverRootIdentifierTest, ThroughPointers) {
     // var<private> a : f32;
     // {
     //   let a_ptr1 = &*&a;
@@ -244,49 +244,49 @@
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
     auto* sem_a = Sem().Get(a);
-    EXPECT_EQ(Sem().Get(address_of_1)->SourceVariable(), sem_a);
-    EXPECT_EQ(Sem().Get(address_of_2)->SourceVariable(), sem_a);
-    EXPECT_EQ(Sem().Get(address_of_3)->SourceVariable(), sem_a);
-    EXPECT_EQ(Sem().Get(deref_1)->SourceVariable(), sem_a);
-    EXPECT_EQ(Sem().Get(deref_2)->SourceVariable(), sem_a);
+    EXPECT_EQ(Sem().Get(address_of_1)->RootIdentifier(), sem_a);
+    EXPECT_EQ(Sem().Get(address_of_2)->RootIdentifier(), sem_a);
+    EXPECT_EQ(Sem().Get(address_of_3)->RootIdentifier(), sem_a);
+    EXPECT_EQ(Sem().Get(deref_1)->RootIdentifier(), sem_a);
+    EXPECT_EQ(Sem().Get(deref_2)->RootIdentifier(), sem_a);
 }
 
-TEST_F(ResolverSourceVariableTest, Literal) {
+TEST_F(ResolverRootIdentifierTest, Literal) {
     auto* expr = Expr(1_f);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), nullptr);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), nullptr);
 }
 
-TEST_F(ResolverSourceVariableTest, FunctionReturnValue) {
+TEST_F(ResolverRootIdentifierTest, FunctionReturnValue) {
     auto* expr = Call("min", 1_f, 2_f);
     WrapInFunction(expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), nullptr);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), nullptr);
 }
 
-TEST_F(ResolverSourceVariableTest, BinaryExpression) {
+TEST_F(ResolverRootIdentifierTest, BinaryExpression) {
     auto* a = Var("a", ty.f32());
     auto* expr = Add(a, Expr(1_f));
     WrapInFunction(a, expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), nullptr);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), nullptr);
 }
 
-TEST_F(ResolverSourceVariableTest, UnaryExpression) {
+TEST_F(ResolverRootIdentifierTest, UnaryExpression) {
     auto* a = Var("a", ty.f32());
     auto* expr = create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, Expr(a));
     WrapInFunction(a, expr);
 
     EXPECT_TRUE(r()->Resolve()) << r()->error();
 
-    EXPECT_EQ(Sem().Get(expr)->SourceVariable(), nullptr);
+    EXPECT_EQ(Sem().Get(expr)->RootIdentifier(), nullptr);
 }
 
 }  // namespace
diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc
index d5ff803..f5389f7 100644
--- a/src/tint/resolver/uniformity.cc
+++ b/src/tint/resolver/uniformity.cc
@@ -1157,8 +1157,8 @@
                 if (u->op == ast::UnaryOp::kIndirection) {
                     // Cut the analysis short, since we only need to know the originating variable
                     // which is being accessed.
-                    auto* source_var = sem_.Get(u)->SourceVariable();
-                    auto* value = current_function_->variables.Get(source_var);
+                    auto* root_ident = sem_.Get(u)->RootIdentifier();
+                    auto* value = current_function_->variables.Get(root_ident);
                     if (!value) {
                         value = cf;
                     }
@@ -1251,10 +1251,10 @@
                 if (u->op == ast::UnaryOp::kIndirection) {
                     // Cut the analysis short, since we only need to know the originating variable
                     // that is being written to.
-                    auto* source_var = sem_.Get(u)->SourceVariable();
-                    auto name = builder_->Symbols().NameFor(source_var->Declaration()->symbol);
+                    auto* root_ident = sem_.Get(u)->RootIdentifier();
+                    auto name = builder_->Symbols().NameFor(root_ident->Declaration()->symbol);
                     auto* deref = CreateNode(name + "_deref");
-                    auto* old_value = current_function_->variables.Set(source_var, deref);
+                    auto* old_value = current_function_->variables.Set(root_ident, deref);
 
                     if (old_value) {
                         // If derefercing a partial reference or partial pointer, we link back to
@@ -1405,9 +1405,9 @@
                     }
 
                     // Update the current stored value for this pointer argument.
-                    auto* source_var = sem_arg->SourceVariable();
-                    TINT_ASSERT(Resolver, source_var);
-                    current_function_->variables.Set(source_var, ptr_result);
+                    auto* root_ident = sem_arg->RootIdentifier();
+                    TINT_ASSERT(Resolver, root_ident);
+                    current_function_->variables.Set(root_ident, ptr_result);
                 }
             } else {
                 // All builtin function parameters are RequiredToBeUniformForReturnValue, as are
diff --git a/src/tint/sem/expression.cc b/src/tint/sem/expression.cc
index cdaa2bc..d7fd255 100644
--- a/src/tint/sem/expression.cc
+++ b/src/tint/sem/expression.cc
@@ -28,9 +28,9 @@
                        const Statement* statement,
                        const Constant* constant,
                        bool has_side_effects,
-                       const Variable* source_var /* = nullptr */)
+                       const Variable* root_ident /* = nullptr */)
     : declaration_(declaration),
-      source_variable_(source_var),
+      root_identifier_(root_ident),
       type_(type),
       stage_(stage),
       statement_(statement),
diff --git a/src/tint/sem/expression.h b/src/tint/sem/expression.h
index 5942a71..cc87031 100644
--- a/src/tint/sem/expression.h
+++ b/src/tint/sem/expression.h
@@ -40,14 +40,14 @@
     /// @param statement the statement that owns this expression
     /// @param constant the constant value of the expression. May be null
     /// @param has_side_effects true if this expression may have side-effects
-    /// @param source_var the (optional) source variable for this expression
+    /// @param root_ident the (optional) root identifier for this expression
     Expression(const ast::Expression* declaration,
                const sem::Type* type,
                EvaluationStage stage,
                const Statement* statement,
                const Constant* constant,
                bool has_side_effects,
-               const Variable* source_var = nullptr);
+               const Variable* root_ident = nullptr);
 
     /// Destructor
     ~Expression() override;
@@ -71,8 +71,8 @@
     /// For reference and pointer expressions, this will either be the originating
     /// variable or a function parameter. For other types of expressions, it will
     /// either be the parameter or constant declaration, or nullptr.
-    /// @return the source variable of this expression, or nullptr
-    const Variable* SourceVariable() const { return source_variable_; }
+    /// @return the root identifier of this expression, or nullptr
+    const Variable* RootIdentifier() const { return root_identifier_; }
 
     /// @return the behaviors of this statement
     const sem::Behaviors& Behaviors() const { return behaviors_; }
@@ -89,8 +89,8 @@
   protected:
     /// The AST expression node for this semantic expression
     const ast::Expression* const declaration_;
-    /// The source variable for this semantic expression, or nullptr
-    const Variable* source_variable_;
+    /// The root identifier for this semantic expression, or nullptr
+    const Variable* root_identifier_;
 
   private:
     const sem::Type* const type_;
diff --git a/src/tint/sem/expression_test.cc b/src/tint/sem/expression_test.cc
index 63e01fb..845b279 100644
--- a/src/tint/sem/expression_test.cc
+++ b/src/tint/sem/expression_test.cc
@@ -46,7 +46,7 @@
     auto* a = create<Expression>(/* declaration */ nullptr, create<I32>(),
                                  sem::EvaluationStage::kRuntime, /* statement */ nullptr,
                                  /* constant_value */ nullptr,
-                                 /* has_side_effects */ false, /* source_var */ nullptr);
+                                 /* has_side_effects */ false, /* root_ident */ nullptr);
     auto* b = create<Materialize>(a, /* statement */ nullptr, &c);
 
     EXPECT_EQ(a, a->UnwrapMaterialize());
diff --git a/src/tint/sem/index_accessor_expression.cc b/src/tint/sem/index_accessor_expression.cc
index 70d1d5f..0565695 100644
--- a/src/tint/sem/index_accessor_expression.cc
+++ b/src/tint/sem/index_accessor_expression.cc
@@ -30,8 +30,8 @@
                                                  const Statement* statement,
                                                  const Constant* constant,
                                                  bool has_side_effects,
-                                                 const Variable* source_var /* = nullptr */)
-    : Base(declaration, type, stage, statement, constant, has_side_effects, source_var),
+                                                 const Variable* root_ident /* = nullptr */)
+    : Base(declaration, type, stage, statement, constant, has_side_effects, root_ident),
       object_(object),
       index_(index) {}
 
diff --git a/src/tint/sem/index_accessor_expression.h b/src/tint/sem/index_accessor_expression.h
index ea93df7..19ae82b 100644
--- a/src/tint/sem/index_accessor_expression.h
+++ b/src/tint/sem/index_accessor_expression.h
@@ -38,7 +38,7 @@
     /// @param statement the statement that owns this expression
     /// @param constant the constant value of the expression. May be null
     /// @param has_side_effects whether this expression may have side effects
-    /// @param source_var the (optional) source variable for this expression
+    /// @param root_ident the (optional) root identifier for this expression
     IndexAccessorExpression(const ast::IndexAccessorExpression* declaration,
                             const sem::Type* type,
                             EvaluationStage stage,
@@ -47,7 +47,7 @@
                             const Statement* statement,
                             const Constant* constant,
                             bool has_side_effects,
-                            const Variable* source_var = nullptr);
+                            const Variable* root_ident = nullptr);
 
     /// Destructor
     ~IndexAccessorExpression() override;
diff --git a/src/tint/sem/materialize.cc b/src/tint/sem/materialize.cc
index 15c31ae..c735f6d 100644
--- a/src/tint/sem/materialize.cc
+++ b/src/tint/sem/materialize.cc
@@ -26,7 +26,7 @@
            /* statement */ statement,
            /* constant */ constant,
            /* has_side_effects */ false,
-           /* source_var */ expr->SourceVariable()),
+           /* root_ident */ expr->RootIdentifier()),
       expr_(expr) {}
 
 Materialize::~Materialize() = default;
diff --git a/src/tint/sem/member_accessor_expression.cc b/src/tint/sem/member_accessor_expression.cc
index 4d194a9..8d08008 100644
--- a/src/tint/sem/member_accessor_expression.cc
+++ b/src/tint/sem/member_accessor_expression.cc
@@ -30,8 +30,8 @@
                                                    const Constant* constant,
                                                    const Expression* object,
                                                    bool has_side_effects,
-                                                   const Variable* source_var /* = nullptr */)
-    : Base(declaration, type, stage, statement, constant, has_side_effects, source_var),
+                                                   const Variable* root_ident /* = nullptr */)
+    : Base(declaration, type, stage, statement, constant, has_side_effects, root_ident),
       object_(object) {}
 
 MemberAccessorExpression::~MemberAccessorExpression() = default;
@@ -43,7 +43,7 @@
                                        const Expression* object,
                                        const StructMember* member,
                                        bool has_side_effects,
-                                       const Variable* source_var /* = nullptr */)
+                                       const Variable* root_ident /* = nullptr */)
     : Base(declaration,
            type,
            object->Stage(),
@@ -51,7 +51,7 @@
            constant,
            object,
            has_side_effects,
-           source_var),
+           root_ident),
       member_(member) {}
 
 StructMemberAccess::~StructMemberAccess() = default;
@@ -63,7 +63,7 @@
                  const Expression* object,
                  utils::VectorRef<uint32_t> indices,
                  bool has_side_effects,
-                 const Variable* source_var /* = nullptr */)
+                 const Variable* root_ident /* = nullptr */)
     : Base(declaration,
            type,
            object->Stage(),
@@ -71,7 +71,7 @@
            constant,
            object,
            has_side_effects,
-           source_var),
+           root_ident),
       indices_(std::move(indices)) {}
 
 Swizzle::~Swizzle() = default;
diff --git a/src/tint/sem/member_accessor_expression.h b/src/tint/sem/member_accessor_expression.h
index 2541f33..5541d1c 100644
--- a/src/tint/sem/member_accessor_expression.h
+++ b/src/tint/sem/member_accessor_expression.h
@@ -48,7 +48,7 @@
     /// @param constant the constant value of the expression. May be null.
     /// @param object the object that holds the member being accessed
     /// @param has_side_effects whether this expression may have side effects
-    /// @param source_var the (optional) source variable for this expression
+    /// @param root_ident the (optional) root identifier for this expression
     MemberAccessorExpression(const ast::MemberAccessorExpression* declaration,
                              const sem::Type* type,
                              EvaluationStage stage,
@@ -56,7 +56,7 @@
                              const Constant* constant,
                              const Expression* object,
                              bool has_side_effects,
-                             const Variable* source_var = nullptr);
+                             const Variable* root_ident = nullptr);
 
   private:
     Expression const* const object_;
@@ -75,7 +75,7 @@
     /// @param object the object that holds the member being accessed
     /// @param member the structure member
     /// @param has_side_effects whether this expression may have side effects
-    /// @param source_var the (optional) source variable for this expression
+    /// @param root_ident the (optional) root identifier for this expression
     StructMemberAccess(const ast::MemberAccessorExpression* declaration,
                        const sem::Type* type,
                        const Statement* statement,
@@ -83,7 +83,7 @@
                        const Expression* object,
                        const StructMember* member,
                        bool has_side_effects,
-                       const Variable* source_var = nullptr);
+                       const Variable* root_ident = nullptr);
 
     /// Destructor
     ~StructMemberAccess() override;
@@ -107,7 +107,7 @@
     /// @param object the object that holds the member being accessed
     /// @param indices the swizzle indices
     /// @param has_side_effects whether this expression may have side effects
-    /// @param source_var the (optional) source variable for this expression
+    /// @param root_ident the (optional) root identifier for this expression
     Swizzle(const ast::MemberAccessorExpression* declaration,
             const sem::Type* type,
             const Statement* statement,
@@ -115,7 +115,7 @@
             const Expression* object,
             utils::VectorRef<uint32_t> indices,
             bool has_side_effects,
-            const Variable* source_var = nullptr);
+            const Variable* root_ident = nullptr);
 
     /// Destructor
     ~Swizzle() override;
diff --git a/src/tint/sem/variable.cc b/src/tint/sem/variable.cc
index 225e308..f83745f 100644
--- a/src/tint/sem/variable.cc
+++ b/src/tint/sem/variable.cc
@@ -97,9 +97,9 @@
       variable_(variable) {
     auto* type = variable->Type();
     if (type->Is<sem::Pointer>() && variable->Initializer()) {
-        source_variable_ = variable->Initializer()->SourceVariable();
+        root_identifier_ = variable->Initializer()->RootIdentifier();
     } else {
-        source_variable_ = variable;
+        root_identifier_ = variable;
     }
 }
 
diff --git a/src/tint/transform/localize_struct_array_assignment.cc b/src/tint/transform/localize_struct_array_assignment.cc
index bfe8865..cb53645 100644
--- a/src/tint/transform/localize_struct_array_assignment.cc
+++ b/src/tint/transform/localize_struct_array_assignment.cc
@@ -174,15 +174,15 @@
     // See https://www.w3.org/TR/WGSL/#originating-variable-section
     std::pair<const sem::Type*, ast::AddressSpace> GetOriginatingTypeAndAddressSpace(
         const ast::AssignmentStatement* assign_stmt) {
-        auto* source_var = src->Sem().Get(assign_stmt->lhs)->SourceVariable();
-        if (!source_var) {
+        auto* root_ident = src->Sem().Get(assign_stmt->lhs)->RootIdentifier();
+        if (!root_ident) {
             TINT_ICE(Transform, b.Diagnostics())
                 << "Unable to determine originating variable for lhs of assignment "
                    "statement";
             return {};
         }
 
-        auto* type = source_var->Type();
+        auto* type = root_ident->Type();
         if (auto* ref = type->As<sem::Reference>()) {
             return {ref->StoreType(), ref->AddressSpace()};
         } else if (auto* ptr = type->As<sem::Pointer>()) {
diff --git a/src/tint/transform/spirv_atomic.cc b/src/tint/transform/spirv_atomic.cc
index eba6681..319975a 100644
--- a/src/tint/transform/spirv_atomic.cc
+++ b/src/tint/transform/spirv_atomic.cc
@@ -97,7 +97,7 @@
                                     b.Call(sem::str(stub->builtin), std::move(out_args)));
                     }
 
-                    // Keep track of this expression. We'll need to modify the source variable /
+                    // Keep track of this expression. We'll need to modify the root identifier /
                     // structure to be atomic.
                     atomic_expressions.Add(ctx.src->Sem().Get(args[0]));
                 }
@@ -230,8 +230,8 @@
     void ReplaceLoadsAndStores() {
         // Returns true if 'e' is a reference to an atomic variable or struct member
         auto is_ref_to_atomic_var = [&](const sem::Expression* e) {
-            if (tint::Is<sem::Reference>(e->Type()) && e->SourceVariable() &&
-                (atomic_variables.count(e->SourceVariable()) != 0)) {
+            if (tint::Is<sem::Reference>(e->Type()) && e->RootIdentifier() &&
+                (atomic_variables.count(e->RootIdentifier()) != 0)) {
                 // If it's a struct member, make sure it's one we marked as atomic
                 if (auto* ma = e->As<sem::StructMemberAccess>()) {
                     auto it = forked_structs.find(ma->Member()->Struct()->Declaration());
diff --git a/src/tint/transform/std140.cc b/src/tint/transform/std140.cc
index 0746bda..2116b0f 100644
--- a/src/tint/transform/std140.cc
+++ b/src/tint/transform/std140.cc
@@ -498,26 +498,26 @@
 
         AccessChain access;
 
-        // Start by looking at the source variable. This must be a std140-forked uniform buffer.
-        access.var = tint::As<sem::GlobalVariable>(expr->SourceVariable());
+        // Start by looking at the root identifier. This must be a std140-forked uniform buffer.
+        access.var = tint::As<sem::GlobalVariable>(expr->RootIdentifier());
         if (!access.var || !std140_uniforms.Contains(access.var)) {
             // Not at std140-forked uniform buffer access chain.
             return std::nullopt;
         }
 
-        // Walk from the outer-most expression, inwards towards the source variable.
+        // Walk from the outer-most expression, inwards towards the root identifier.
         while (true) {
             enum class Action { kStop, kContinue, kError };
             Action action = Switch(
                 expr,  //
                 [&](const sem::VariableUser* user) {
                     if (user->Variable() == access.var) {
-                        // Walked all the way to the source variable. We're done traversing.
+                        // Walked all the way to the root identifier. We're done traversing.
                         access.indices.Push(UniformVariable{});
                         return Action::kStop;
                     }
                     if (user->Variable()->Type()->Is<sem::Pointer>()) {
-                        // Found a pointer. As the source variable is a uniform buffer variable,
+                        // Found a pointer. As the root identifier is a uniform buffer variable,
                         // this must be a pointer-let. Continue traversing from the let
                         // initializer.
                         expr = user->Variable()->Initializer();