Add Source parameter to decoration constructors

Once a `Decoration` has been parsed, it'll be placed into a `DecorationList` and validated later in the parse. In order to create error diagnostics that refer back to the decoration, we need to know its source.

Bug: tint:282
Bug: tint:291
Change-Id: I38de708adbd041601b61d7e0a4d0402e9a2fe526
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/31722
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/array_decoration.cc b/src/ast/array_decoration.cc
index 96da686..8a0753d 100644
--- a/src/ast/array_decoration.cc
+++ b/src/ast/array_decoration.cc
@@ -21,7 +21,8 @@
 namespace tint {
 namespace ast {
 
-ArrayDecoration::ArrayDecoration() : Decoration(Kind) {}
+ArrayDecoration::ArrayDecoration(const Source& source)
+    : Decoration(Kind, source) {}
 
 ArrayDecoration::~ArrayDecoration() = default;
 
diff --git a/src/ast/array_decoration.h b/src/ast/array_decoration.h
index a86a4df..52d9407 100644
--- a/src/ast/array_decoration.h
+++ b/src/ast/array_decoration.h
@@ -45,7 +45,8 @@
 
  protected:
   /// Constructor
-  ArrayDecoration();
+  /// @param source the source of this decoration
+  explicit ArrayDecoration(const Source& source);
 };
 
 /// A list of unique array decorations
diff --git a/src/ast/binding_decoration.cc b/src/ast/binding_decoration.cc
index bcfdf1b..bb237f0 100644
--- a/src/ast/binding_decoration.cc
+++ b/src/ast/binding_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-BindingDecoration::BindingDecoration(uint32_t val) : value_(val) {}
+BindingDecoration::BindingDecoration(uint32_t val, const Source& source)
+    : VariableDecoration(source), value_(val) {}
 
 BindingDecoration::~BindingDecoration() = default;
 
diff --git a/src/ast/binding_decoration.h b/src/ast/binding_decoration.h
index a554aac..20fec89 100644
--- a/src/ast/binding_decoration.h
+++ b/src/ast/binding_decoration.h
@@ -27,7 +27,8 @@
  public:
   /// constructor
   /// @param value the binding value
-  explicit BindingDecoration(uint32_t value);
+  /// @param source the source of this decoration
+  BindingDecoration(uint32_t value, const Source& source);
   ~BindingDecoration() override;
 
   /// @returns true if this is a binding decoration
diff --git a/src/ast/binding_decoration_test.cc b/src/ast/binding_decoration_test.cc
index 740fde3..26f91cf 100644
--- a/src/ast/binding_decoration_test.cc
+++ b/src/ast/binding_decoration_test.cc
@@ -23,12 +23,12 @@
 using BindingDecorationTest = testing::Test;
 
 TEST_F(BindingDecorationTest, Creation) {
-  BindingDecoration d{2};
+  BindingDecoration d{2, Source{}};
   EXPECT_EQ(2u, d.value());
 }
 
 TEST_F(BindingDecorationTest, Is) {
-  BindingDecoration d{2};
+  BindingDecoration d{2, Source{}};
   EXPECT_TRUE(d.IsBinding());
   EXPECT_FALSE(d.IsBuiltin());
   EXPECT_FALSE(d.IsConstantId());
@@ -37,7 +37,7 @@
 }
 
 TEST_F(BindingDecorationTest, ToStr) {
-  BindingDecoration d{2};
+  BindingDecoration d{2, Source{}};
   std::ostringstream out;
   d.to_str(out);
   EXPECT_EQ(out.str(), R"(BindingDecoration{2}
diff --git a/src/ast/builtin_decoration.cc b/src/ast/builtin_decoration.cc
index 50cea89..1ac7155 100644
--- a/src/ast/builtin_decoration.cc
+++ b/src/ast/builtin_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-BuiltinDecoration::BuiltinDecoration(Builtin builtin) : builtin_(builtin) {}
+BuiltinDecoration::BuiltinDecoration(Builtin builtin, const Source& source)
+    : VariableDecoration(source), builtin_(builtin) {}
 
 BuiltinDecoration::~BuiltinDecoration() = default;
 
diff --git a/src/ast/builtin_decoration.h b/src/ast/builtin_decoration.h
index 072f196..30b873c 100644
--- a/src/ast/builtin_decoration.h
+++ b/src/ast/builtin_decoration.h
@@ -26,7 +26,8 @@
  public:
   /// constructor
   /// @param builtin the builtin value
-  explicit BuiltinDecoration(Builtin builtin);
+  /// @param source the source of this decoration
+  BuiltinDecoration(Builtin builtin, const Source& source);
   ~BuiltinDecoration() override;
 
   /// @returns true if this is a builtin decoration
diff --git a/src/ast/builtin_decoration_test.cc b/src/ast/builtin_decoration_test.cc
index 21c2659..37bc260 100644
--- a/src/ast/builtin_decoration_test.cc
+++ b/src/ast/builtin_decoration_test.cc
@@ -23,12 +23,12 @@
 using BuiltinDecorationTest = testing::Test;
 
 TEST_F(BuiltinDecorationTest, Creation) {
-  BuiltinDecoration d{Builtin::kFragDepth};
+  BuiltinDecoration d{Builtin::kFragDepth, Source{}};
   EXPECT_EQ(Builtin::kFragDepth, d.value());
 }
 
 TEST_F(BuiltinDecorationTest, Is) {
-  BuiltinDecoration d{Builtin::kFragDepth};
+  BuiltinDecoration d{Builtin::kFragDepth, Source{}};
   EXPECT_FALSE(d.IsBinding());
   EXPECT_TRUE(d.IsBuiltin());
   EXPECT_FALSE(d.IsConstantId());
@@ -37,7 +37,7 @@
 }
 
 TEST_F(BuiltinDecorationTest, ToStr) {
-  BuiltinDecoration d{Builtin::kFragDepth};
+  BuiltinDecoration d{Builtin::kFragDepth, Source{}};
   std::ostringstream out;
   d.to_str(out);
   EXPECT_EQ(out.str(), R"(BuiltinDecoration{frag_depth}
diff --git a/src/ast/constant_id_decoration.cc b/src/ast/constant_id_decoration.cc
index a5befb6..6afca22 100644
--- a/src/ast/constant_id_decoration.cc
+++ b/src/ast/constant_id_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-ConstantIdDecoration::ConstantIdDecoration(uint32_t val) : value_(val) {}
+ConstantIdDecoration::ConstantIdDecoration(uint32_t val, const Source& source)
+    : VariableDecoration(source), value_(val) {}
 
 ConstantIdDecoration::~ConstantIdDecoration() = default;
 
diff --git a/src/ast/constant_id_decoration.h b/src/ast/constant_id_decoration.h
index c7b2d9a..1bbaeb0 100644
--- a/src/ast/constant_id_decoration.h
+++ b/src/ast/constant_id_decoration.h
@@ -26,7 +26,8 @@
  public:
   /// constructor
   /// @param val the constant_id value
-  explicit ConstantIdDecoration(uint32_t val);
+  /// @param source the source of this decoration
+  ConstantIdDecoration(uint32_t val, const Source& source);
   ~ConstantIdDecoration() override;
 
   /// @returns true if this is a constant_id decoration
diff --git a/src/ast/constant_id_decoration_test.cc b/src/ast/constant_id_decoration_test.cc
index 85eac21..607ef75 100644
--- a/src/ast/constant_id_decoration_test.cc
+++ b/src/ast/constant_id_decoration_test.cc
@@ -23,12 +23,12 @@
 using ConstantIdDecorationTest = testing::Test;
 
 TEST_F(ConstantIdDecorationTest, Creation) {
-  ConstantIdDecoration d{12};
+  ConstantIdDecoration d{12, Source{}};
   EXPECT_EQ(12u, d.value());
 }
 
 TEST_F(ConstantIdDecorationTest, Is) {
-  ConstantIdDecoration d{27};
+  ConstantIdDecoration d{27, Source{}};
   EXPECT_FALSE(d.IsBinding());
   EXPECT_FALSE(d.IsBuiltin());
   EXPECT_TRUE(d.IsConstantId());
@@ -37,7 +37,7 @@
 }
 
 TEST_F(ConstantIdDecorationTest, ToStr) {
-  ConstantIdDecoration d{1200};
+  ConstantIdDecoration d{1200, Source{}};
   std::ostringstream out;
   d.to_str(out);
   EXPECT_EQ(out.str(), R"(ConstantIdDecoration{1200}
diff --git a/src/ast/decorated_variable_test.cc b/src/ast/decorated_variable_test.cc
index c5db5af..b43be2d 100644
--- a/src/ast/decorated_variable_test.cc
+++ b/src/ast/decorated_variable_test.cc
@@ -76,9 +76,10 @@
   DecoratedVariable dv(std::move(var));
 
   VariableDecorationList decos;
-  decos.push_back(std::make_unique<LocationDecoration>(1));
-  decos.push_back(std::make_unique<BuiltinDecoration>(ast::Builtin::kPosition));
-  decos.push_back(std::make_unique<ConstantIdDecoration>(1200));
+  decos.push_back(std::make_unique<LocationDecoration>(1, Source{}));
+  decos.push_back(
+      std::make_unique<BuiltinDecoration>(ast::Builtin::kPosition, Source{}));
+  decos.push_back(std::make_unique<ConstantIdDecoration>(1200, Source{}));
 
   dv.set_decorations(std::move(decos));
 
@@ -93,7 +94,7 @@
   DecoratedVariable dv(std::move(var));
 
   VariableDecorationList decos;
-  decos.push_back(std::make_unique<ConstantIdDecoration>(1200));
+  decos.push_back(std::make_unique<ConstantIdDecoration>(1200, Source{}));
   dv.set_decorations(std::move(decos));
 
   EXPECT_EQ(dv.constant_id(), 1200u);
@@ -118,8 +119,8 @@
   dv.set_constructor(std::make_unique<IdentifierExpression>("expr"));
 
   VariableDecorationList decos;
-  decos.push_back(std::make_unique<BindingDecoration>(2));
-  decos.push_back(std::make_unique<SetDecoration>(1));
+  decos.push_back(std::make_unique<BindingDecoration>(2, Source{}));
+  decos.push_back(std::make_unique<SetDecoration>(1, Source{}));
 
   dv.set_decorations(std::move(decos));
   std::ostringstream out;
diff --git a/src/ast/decoration.h b/src/ast/decoration.h
index 9c58cca..878c31e 100644
--- a/src/ast/decoration.h
+++ b/src/ast/decoration.h
@@ -49,13 +49,19 @@
     return GetKind() == TO::Kind;
   }
 
+  /// @return the source of this decoration
+  const Source& GetSource() { return source_; }
+
  protected:
   /// Constructor
   /// @param kind represents the derived type
-  explicit Decoration(DecorationKind kind) : kind_(kind) {}
+  /// @param source the source of this decoration
+  Decoration(DecorationKind kind, const Source& source)
+      : kind_(kind), source_(source) {}
 
  private:
   DecorationKind const kind_;
+  Source const source_;
 };
 
 /// As dynamically casts |deco| to the target type |TO|.
diff --git a/src/ast/decoration_test.cc b/src/ast/decoration_test.cc
index a800494..aed6aea 100644
--- a/src/ast/decoration_test.cc
+++ b/src/ast/decoration_test.cc
@@ -29,21 +29,21 @@
 using DecorationTest = testing::Test;
 
 TEST_F(DecorationTest, AsCorrectType) {
-  auto* decoration = new ConstantIdDecoration(1);
+  auto* decoration = new ConstantIdDecoration(1, Source{});
   auto upcast = std::unique_ptr<Decoration>(decoration);
   auto downcast = As<VariableDecoration>(std::move(upcast));
   EXPECT_EQ(decoration, downcast.get());
 }
 
 TEST_F(DecorationTest, AsIncorrectType) {
-  auto* decoration = new ConstantIdDecoration(1);
+  auto* decoration = new ConstantIdDecoration(1, Source{});
   auto upcast = std::unique_ptr<Decoration>(decoration);
   auto downcast = As<ArrayDecoration>(std::move(upcast));
   EXPECT_EQ(nullptr, downcast.get());
 }
 
 TEST_F(DecorationTest, Is) {
-  auto decoration = std::make_unique<ConstantIdDecoration>(1);
+  auto decoration = std::make_unique<ConstantIdDecoration>(1, Source{});
   EXPECT_TRUE(decoration->Is<VariableDecoration>());
   EXPECT_FALSE(decoration->Is<ArrayDecoration>());
 }
diff --git a/src/ast/function_decoration.cc b/src/ast/function_decoration.cc
index 15d7eaa..f414c9d 100644
--- a/src/ast/function_decoration.cc
+++ b/src/ast/function_decoration.cc
@@ -22,7 +22,8 @@
 namespace tint {
 namespace ast {
 
-FunctionDecoration::FunctionDecoration() : Decoration(Kind) {}
+FunctionDecoration::FunctionDecoration(const Source& source)
+    : Decoration(Kind, source) {}
 
 FunctionDecoration::~FunctionDecoration() = default;
 
diff --git a/src/ast/function_decoration.h b/src/ast/function_decoration.h
index 101f3a9..8112351 100644
--- a/src/ast/function_decoration.h
+++ b/src/ast/function_decoration.h
@@ -51,7 +51,8 @@
 
  protected:
   /// Constructor
-  FunctionDecoration();
+  /// @param source the source of this decoration
+  explicit FunctionDecoration(const Source& source);
 };
 
 /// A list of unique function decorations
diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc
index ed88269..1410f57 100644
--- a/src/ast/function_test.cc
+++ b/src/ast/function_test.cc
@@ -90,24 +90,24 @@
   VariableDecorationList decos;
   DecoratedVariable loc1(
       std::make_unique<ast::Variable>("loc1", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   loc1.set_decorations(std::move(decos));
 
   DecoratedVariable loc2(
       std::make_unique<ast::Variable>("loc2", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   loc2.set_decorations(std::move(decos));
 
   DecoratedVariable builtin1(
       std::make_unique<ast::Variable>("builtin1", StorageClass::kInput, &i32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kPosition));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kPosition, Source{}));
   builtin1.set_decorations(std::move(decos));
 
   DecoratedVariable builtin2(
       std::make_unique<ast::Variable>("builtin2", StorageClass::kInput, &i32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   builtin2.set_decorations(std::move(decos));
 
   Function f("func", VariableList{}, &void_type);
@@ -133,24 +133,24 @@
   VariableDecorationList decos;
   DecoratedVariable loc1(
       std::make_unique<ast::Variable>("loc1", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   loc1.set_decorations(std::move(decos));
 
   DecoratedVariable loc2(
       std::make_unique<ast::Variable>("loc2", StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   loc2.set_decorations(std::move(decos));
 
   DecoratedVariable builtin1(
       std::make_unique<ast::Variable>("builtin1", StorageClass::kInput, &i32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kPosition));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kPosition, Source{}));
   builtin1.set_decorations(std::move(decos));
 
   DecoratedVariable builtin2(
       std::make_unique<ast::Variable>("builtin2", StorageClass::kInput, &i32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   builtin2.set_decorations(std::move(decos));
 
   Function f("func", VariableList{}, &void_type);
@@ -308,7 +308,7 @@
 
   Function f("func", {}, &void_type);
   f.set_body(std::move(block));
-  f.add_decoration(std::make_unique<WorkgroupDecoration>(2, 4, 6));
+  f.add_decoration(std::make_unique<WorkgroupDecoration>(2, 4, 6, Source{}));
 
   std::ostringstream out;
   f.to_str(out, 2);
@@ -413,7 +413,7 @@
 TEST_F(FunctionTest, WorkgroupSize) {
   type::VoidType void_type;
   Function f("f", {}, &void_type);
-  f.add_decoration(std::make_unique<WorkgroupDecoration>(2u, 4u, 6u));
+  f.add_decoration(std::make_unique<WorkgroupDecoration>(2u, 4u, 6u, Source{}));
 
   uint32_t x = 0;
   uint32_t y = 0;
diff --git a/src/ast/location_decoration.cc b/src/ast/location_decoration.cc
index 1330b77..7e1db78 100644
--- a/src/ast/location_decoration.cc
+++ b/src/ast/location_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-LocationDecoration::LocationDecoration(uint32_t val) : value_(val) {}
+LocationDecoration::LocationDecoration(uint32_t val, const Source& source)
+    : VariableDecoration(source), value_(val) {}
 
 LocationDecoration::~LocationDecoration() = default;
 
diff --git a/src/ast/location_decoration.h b/src/ast/location_decoration.h
index 8eca37f..2e74fd7 100644
--- a/src/ast/location_decoration.h
+++ b/src/ast/location_decoration.h
@@ -27,7 +27,8 @@
  public:
   /// constructor
   /// @param value the location value
-  explicit LocationDecoration(uint32_t value);
+  /// @param source the source of this decoration
+  explicit LocationDecoration(uint32_t value, const Source& source);
   ~LocationDecoration() override;
 
   /// @returns true if this is a location decoration
diff --git a/src/ast/location_decoration_test.cc b/src/ast/location_decoration_test.cc
index 7063e32..900d96c 100644
--- a/src/ast/location_decoration_test.cc
+++ b/src/ast/location_decoration_test.cc
@@ -25,12 +25,12 @@
 using LocationDecorationTest = testing::Test;
 
 TEST_F(LocationDecorationTest, Creation) {
-  LocationDecoration d{2};
+  LocationDecoration d{2, Source{}};
   EXPECT_EQ(2u, d.value());
 }
 
 TEST_F(LocationDecorationTest, Is) {
-  LocationDecoration d{2};
+  LocationDecoration d{2, Source{}};
   EXPECT_FALSE(d.IsBinding());
   EXPECT_FALSE(d.IsBuiltin());
   EXPECT_FALSE(d.IsConstantId());
@@ -39,7 +39,7 @@
 }
 
 TEST_F(LocationDecorationTest, ToStr) {
-  LocationDecoration d{2};
+  LocationDecoration d{2, Source{}};
   std::ostringstream out;
   d.to_str(out);
   EXPECT_EQ(out.str(), R"(LocationDecoration{2}
diff --git a/src/ast/set_decoration.cc b/src/ast/set_decoration.cc
index 5924a00..1a89ac9 100644
--- a/src/ast/set_decoration.cc
+++ b/src/ast/set_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-SetDecoration::SetDecoration(uint32_t val) : value_(val) {}
+SetDecoration::SetDecoration(uint32_t val, const Source& source)
+    : VariableDecoration(source), value_(val) {}
 
 SetDecoration::~SetDecoration() = default;
 
diff --git a/src/ast/set_decoration.h b/src/ast/set_decoration.h
index 41f4d13..e76795d 100644
--- a/src/ast/set_decoration.h
+++ b/src/ast/set_decoration.h
@@ -27,7 +27,8 @@
  public:
   /// constructor
   /// @param value the set value
-  explicit SetDecoration(uint32_t value);
+  /// @param source the source of this decoration
+  SetDecoration(uint32_t value, const Source& source);
   ~SetDecoration() override;
 
   /// @returns true if this is a set decoration
diff --git a/src/ast/set_decoration_test.cc b/src/ast/set_decoration_test.cc
index 1d3d372..5dc88cb 100644
--- a/src/ast/set_decoration_test.cc
+++ b/src/ast/set_decoration_test.cc
@@ -23,12 +23,12 @@
 using SetDecorationTest = testing::Test;
 
 TEST_F(SetDecorationTest, Creation) {
-  SetDecoration d{2};
+  SetDecoration d{2, Source{}};
   EXPECT_EQ(2u, d.value());
 }
 
 TEST_F(SetDecorationTest, Is) {
-  SetDecoration d{2};
+  SetDecoration d{2, Source{}};
   EXPECT_FALSE(d.IsBinding());
   EXPECT_FALSE(d.IsBuiltin());
   EXPECT_FALSE(d.IsConstantId());
@@ -37,7 +37,7 @@
 }
 
 TEST_F(SetDecorationTest, ToStr) {
-  SetDecoration d{2};
+  SetDecoration d{2, Source{}};
   std::ostringstream out;
   d.to_str(out);
   EXPECT_EQ(out.str(), R"(SetDecoration{2}
diff --git a/src/ast/stage_decoration.cc b/src/ast/stage_decoration.cc
index f1882de..e10b48d 100644
--- a/src/ast/stage_decoration.cc
+++ b/src/ast/stage_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-StageDecoration::StageDecoration(ast::PipelineStage stage) : stage_(stage) {}
+StageDecoration::StageDecoration(ast::PipelineStage stage, const Source& source)
+    : FunctionDecoration(source), stage_(stage) {}
 
 StageDecoration::~StageDecoration() = default;
 
diff --git a/src/ast/stage_decoration.h b/src/ast/stage_decoration.h
index 516acb0..3f24ed7 100644
--- a/src/ast/stage_decoration.h
+++ b/src/ast/stage_decoration.h
@@ -26,7 +26,8 @@
  public:
   /// constructor
   /// @param stage the pipeline stage
-  explicit StageDecoration(ast::PipelineStage stage);
+  /// @param source the source of this decoration
+  StageDecoration(ast::PipelineStage stage, const Source& source);
   ~StageDecoration() override;
 
   /// @returns true if this is a stage decoration
diff --git a/src/ast/stage_decoration_test.cc b/src/ast/stage_decoration_test.cc
index ce6f340..b447313 100644
--- a/src/ast/stage_decoration_test.cc
+++ b/src/ast/stage_decoration_test.cc
@@ -25,18 +25,18 @@
 using StageDecorationTest = testing::Test;
 
 TEST_F(StageDecorationTest, Creation_1param) {
-  StageDecoration d{ast::PipelineStage::kFragment};
+  StageDecoration d{ast::PipelineStage::kFragment, Source{}};
   EXPECT_EQ(d.value(), ast::PipelineStage::kFragment);
 }
 
 TEST_F(StageDecorationTest, Is) {
-  StageDecoration d{ast::PipelineStage::kFragment};
+  StageDecoration d{ast::PipelineStage::kFragment, Source{}};
   EXPECT_FALSE(d.IsWorkgroup());
   EXPECT_TRUE(d.IsStage());
 }
 
 TEST_F(StageDecorationTest, ToStr) {
-  StageDecoration d{ast::PipelineStage::kFragment};
+  StageDecoration d{ast::PipelineStage::kFragment, Source{}};
   std::ostringstream out;
   d.to_str(out);
   EXPECT_EQ(out.str(), R"(StageDecoration{fragment}
diff --git a/src/ast/stride_decoration.cc b/src/ast/stride_decoration.cc
index a68cbcd..77a0672 100644
--- a/src/ast/stride_decoration.cc
+++ b/src/ast/stride_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-StrideDecoration::StrideDecoration(uint32_t stride) : stride_(stride) {}
+StrideDecoration::StrideDecoration(uint32_t stride, const Source& source)
+    : ArrayDecoration(source), stride_(stride) {}
 
 bool StrideDecoration::IsStride() const {
   return true;
diff --git a/src/ast/stride_decoration.h b/src/ast/stride_decoration.h
index a8a9cb2..c75ec25 100644
--- a/src/ast/stride_decoration.h
+++ b/src/ast/stride_decoration.h
@@ -29,7 +29,8 @@
  public:
   /// constructor
   /// @param stride the stride value
-  explicit StrideDecoration(uint32_t stride);
+  /// @param source the source of this decoration
+  StrideDecoration(uint32_t stride, const Source& source);
   ~StrideDecoration() override;
 
   /// @returns true if this is a stride decoration
diff --git a/src/ast/stride_decoration_test.cc b/src/ast/stride_decoration_test.cc
index 8209c3d..076802d 100644
--- a/src/ast/stride_decoration_test.cc
+++ b/src/ast/stride_decoration_test.cc
@@ -23,15 +23,24 @@
 using StrideDecorationTest = testing::Test;
 
 TEST_F(StrideDecorationTest, Creation) {
-  StrideDecoration d{2};
+  StrideDecoration d{2, Source{}};
   EXPECT_EQ(2u, d.stride());
 }
 
 TEST_F(StrideDecorationTest, Is) {
-  StrideDecoration d{2};
+  StrideDecoration d{2, Source{}};
   EXPECT_TRUE(d.IsStride());
 }
 
+TEST_F(StrideDecorationTest, Source) {
+  StrideDecoration d{
+      2, Source{Source::Range{Source::Location{1, 2}, Source::Location{3, 4}}}};
+  EXPECT_EQ(d.GetSource().range.begin.line, 1u);
+  EXPECT_EQ(d.GetSource().range.begin.column, 2u);
+  EXPECT_EQ(d.GetSource().range.end.line, 3u);
+  EXPECT_EQ(d.GetSource().range.end.column, 4u);
+}
+
 }  // namespace
 }  // namespace ast
 }  // namespace tint
diff --git a/src/ast/struct_block_decoration.cc b/src/ast/struct_block_decoration.cc
index aac4c21..4d156cf 100644
--- a/src/ast/struct_block_decoration.cc
+++ b/src/ast/struct_block_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-StructBlockDecoration::StructBlockDecoration() = default;
+StructBlockDecoration::StructBlockDecoration(const Source& source)
+    : StructDecoration(source) {}
 
 StructBlockDecoration::~StructBlockDecoration() = default;
 
diff --git a/src/ast/struct_block_decoration.h b/src/ast/struct_block_decoration.h
index e5f4eaf..55cd3d4 100644
--- a/src/ast/struct_block_decoration.h
+++ b/src/ast/struct_block_decoration.h
@@ -28,7 +28,8 @@
 class StructBlockDecoration : public StructDecoration {
  public:
   /// constructor
-  StructBlockDecoration();
+  /// @param source the source of this decoration
+  explicit StructBlockDecoration(const Source& source);
   ~StructBlockDecoration() override;
 
   /// @returns true if this is a block struct
diff --git a/src/ast/struct_decoration.cc b/src/ast/struct_decoration.cc
index f75e16b..99c5cc1 100644
--- a/src/ast/struct_decoration.cc
+++ b/src/ast/struct_decoration.cc
@@ -17,7 +17,8 @@
 namespace tint {
 namespace ast {
 
-StructDecoration::StructDecoration() : Decoration(Kind) {}
+StructDecoration::StructDecoration(const Source& source)
+    : Decoration(Kind, source) {}
 
 StructDecoration::~StructDecoration() = default;
 
diff --git a/src/ast/struct_decoration.h b/src/ast/struct_decoration.h
index 9386e42..ba9f8d4 100644
--- a/src/ast/struct_decoration.h
+++ b/src/ast/struct_decoration.h
@@ -41,7 +41,8 @@
 
  protected:
   /// Constructor
-  StructDecoration();
+  /// @param source the source of this decoration
+  explicit StructDecoration(const Source& source);
 };
 
 /// List of struct decorations
diff --git a/src/ast/struct_member_decoration.cc b/src/ast/struct_member_decoration.cc
index 1e35fd4..aaf8d34 100644
--- a/src/ast/struct_member_decoration.cc
+++ b/src/ast/struct_member_decoration.cc
@@ -21,8 +21,8 @@
 namespace tint {
 namespace ast {
 
-StructMemberDecoration::StructMemberDecoration()
-    : Decoration(DecorationKind::kStructMember) {}
+StructMemberDecoration::StructMemberDecoration(const Source& source)
+    : Decoration(DecorationKind::kStructMember, source) {}
 
 StructMemberDecoration::~StructMemberDecoration() = default;
 
diff --git a/src/ast/struct_member_decoration.h b/src/ast/struct_member_decoration.h
index b8cbb8a..a6c1c74 100644
--- a/src/ast/struct_member_decoration.h
+++ b/src/ast/struct_member_decoration.h
@@ -45,7 +45,8 @@
 
  protected:
   /// Constructor
-  StructMemberDecoration();
+  /// @param source the source of this decoration
+  explicit StructMemberDecoration(const Source& source);
 };
 
 /// A list of unique struct member decorations
diff --git a/src/ast/struct_member_offset_decoration.cc b/src/ast/struct_member_offset_decoration.cc
index 79168c6..98b3ca8 100644
--- a/src/ast/struct_member_offset_decoration.cc
+++ b/src/ast/struct_member_offset_decoration.cc
@@ -17,8 +17,9 @@
 namespace tint {
 namespace ast {
 
-StructMemberOffsetDecoration::StructMemberOffsetDecoration(uint32_t offset)
-    : offset_(offset) {}
+StructMemberOffsetDecoration::StructMemberOffsetDecoration(uint32_t offset,
+                                                           const Source& source)
+    : StructMemberDecoration(source), offset_(offset) {}
 
 bool StructMemberOffsetDecoration::IsOffset() const {
   return true;
diff --git a/src/ast/struct_member_offset_decoration.h b/src/ast/struct_member_offset_decoration.h
index e8140af..3ca6b86 100644
--- a/src/ast/struct_member_offset_decoration.h
+++ b/src/ast/struct_member_offset_decoration.h
@@ -29,7 +29,8 @@
  public:
   /// constructor
   /// @param offset the offset value
-  explicit StructMemberOffsetDecoration(uint32_t offset);
+  /// @param source the source of this decoration
+  StructMemberOffsetDecoration(uint32_t offset, const Source& source);
   ~StructMemberOffsetDecoration() override;
 
   /// @returns true if this is an offset decoration
diff --git a/src/ast/struct_member_offset_decoration_test.cc b/src/ast/struct_member_offset_decoration_test.cc
index 141fbe5..efa4698 100644
--- a/src/ast/struct_member_offset_decoration_test.cc
+++ b/src/ast/struct_member_offset_decoration_test.cc
@@ -23,12 +23,12 @@
 using StructMemberOffsetDecorationTest = testing::Test;
 
 TEST_F(StructMemberOffsetDecorationTest, Creation) {
-  StructMemberOffsetDecoration d{2};
+  StructMemberOffsetDecoration d{2, Source{}};
   EXPECT_EQ(2u, d.offset());
 }
 
 TEST_F(StructMemberOffsetDecorationTest, Is) {
-  StructMemberOffsetDecoration d{2};
+  StructMemberOffsetDecoration d{2, Source{}};
   EXPECT_TRUE(d.IsOffset());
 }
 
diff --git a/src/ast/struct_member_test.cc b/src/ast/struct_member_test.cc
index f74856a..322f52a 100644
--- a/src/ast/struct_member_test.cc
+++ b/src/ast/struct_member_test.cc
@@ -30,7 +30,8 @@
 TEST_F(StructMemberTest, Creation) {
   type::I32Type i32;
   StructMemberDecorationList decorations;
-  decorations.emplace_back(std::make_unique<StructMemberOffsetDecoration>(4));
+  decorations.emplace_back(
+      std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
 
   StructMember st{"a", &i32, std::move(decorations)};
   EXPECT_EQ(st.name(), "a");
@@ -77,7 +78,8 @@
 TEST_F(StructMemberTest, IsValid_Null_Decoration) {
   type::I32Type i32;
   StructMemberDecorationList decorations;
-  decorations.emplace_back(std::make_unique<StructMemberOffsetDecoration>(4));
+  decorations.emplace_back(
+      std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
   decorations.push_back(nullptr);
 
   StructMember st{"a", &i32, std::move(decorations)};
@@ -87,7 +89,8 @@
 TEST_F(StructMemberTest, ToStr) {
   type::I32Type i32;
   StructMemberDecorationList decorations;
-  decorations.emplace_back(std::make_unique<StructMemberOffsetDecoration>(4));
+  decorations.emplace_back(
+      std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
 
   StructMember st{"a", &i32, std::move(decorations)};
   std::ostringstream out;
diff --git a/src/ast/struct_test.cc b/src/ast/struct_test.cc
index 95f8adb..475d6b6 100644
--- a/src/ast/struct_test.cc
+++ b/src/ast/struct_test.cc
@@ -52,7 +52,7 @@
       std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
 
   StructDecorationList decos;
-  decos.push_back(std::make_unique<StructBlockDecoration>());
+  decos.push_back(std::make_unique<StructBlockDecoration>(Source{}));
 
   Struct s{std::move(decos), std::move(members)};
   EXPECT_EQ(s.members().size(), 1u);
@@ -72,7 +72,7 @@
       std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
 
   StructDecorationList decos;
-  decos.push_back(std::make_unique<StructBlockDecoration>());
+  decos.push_back(std::make_unique<StructBlockDecoration>(Source{}));
 
   Struct s{
       Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
@@ -122,7 +122,7 @@
       std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
 
   StructDecorationList decos;
-  decos.push_back(std::make_unique<StructBlockDecoration>());
+  decos.push_back(std::make_unique<StructBlockDecoration>(Source{}));
 
   Struct s{std::move(decos), std::move(members)};
 
diff --git a/src/ast/type/access_control_type_test.cc b/src/ast/type/access_control_type_test.cc
index 6dc716e..907805d 100644
--- a/src/ast/type/access_control_type_test.cc
+++ b/src/ast/type/access_control_type_test.cc
@@ -102,7 +102,7 @@
   U32Type u32;
   ArrayType array(&u32, 4);
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
   array.set_decorations(std::move(decos));
   AccessControlType at{AccessControl::kReadOnly, &array};
   EXPECT_EQ(16u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -112,7 +112,7 @@
   U32Type u32;
   ArrayType array(&u32);
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
   array.set_decorations(std::move(decos));
   AccessControlType at{AccessControl::kReadOnly, &array};
   EXPECT_EQ(4u, at.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -123,12 +123,12 @@
   StructMemberList members;
 
   StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+  deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<StructMember>("foo", &u32, std::move(deco)));
 
   deco = StructMemberDecorationList();
-  deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+  deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<StructMember>("bar", &u32, std::move(deco)));
 
@@ -152,7 +152,7 @@
   U32Type u32;
   ArrayType array(&u32, 4);
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
   array.set_decorations(std::move(decos));
   AccessControlType at{AccessControl::kReadOnly, &array};
   EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer));
@@ -162,7 +162,7 @@
   U32Type u32;
   ArrayType array(&u32);
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
   array.set_decorations(std::move(decos));
   AccessControlType at{AccessControl::kReadOnly, &array};
   EXPECT_EQ(16u, at.BaseAlignment(MemoryLayout::kUniformBuffer));
@@ -174,13 +174,13 @@
 
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
diff --git a/src/ast/type/alias_type_test.cc b/src/ast/type/alias_type_test.cc
index 6266cfb..19015a8 100644
--- a/src/ast/type/alias_type_test.cc
+++ b/src/ast/type/alias_type_test.cc
@@ -165,7 +165,7 @@
   U32Type u32;
   ArrayType array(&u32, 4);
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
   array.set_decorations(std::move(decos));
   AliasType alias{"alias", &array};
   EXPECT_EQ(16u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -175,7 +175,7 @@
   U32Type u32;
   ArrayType array(&u32);
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
   array.set_decorations(std::move(decos));
   AliasType alias{"alias", &array};
   EXPECT_EQ(4u, alias.MinBufferBindingSize(MemoryLayout::kUniformBuffer));
@@ -187,13 +187,13 @@
 
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
@@ -217,7 +217,7 @@
   U32Type u32;
   ArrayType array(&u32, 4);
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
   array.set_decorations(std::move(decos));
   AliasType alias{"alias", &array};
   EXPECT_EQ(16u, alias.BaseAlignment(MemoryLayout::kUniformBuffer));
@@ -227,7 +227,7 @@
   U32Type u32;
   ArrayType array(&u32);
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
   array.set_decorations(std::move(decos));
   AliasType alias{"alias", &array};
   EXPECT_EQ(16u, alias.BaseAlignment(MemoryLayout::kUniformBuffer));
@@ -239,13 +239,13 @@
 
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
diff --git a/src/ast/type/array_type_test.cc b/src/ast/type/array_type_test.cc
index 33cd00e..cf237e7 100644
--- a/src/ast/type/array_type_test.cc
+++ b/src/ast/type/array_type_test.cc
@@ -81,7 +81,7 @@
 TEST_F(ArrayTypeTest, TypeName_WithStride) {
   I32Type i32;
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(16));
+  decos.push_back(std::make_unique<StrideDecoration>(16, Source{}));
 
   ArrayType arr{&i32, 3};
   arr.set_decorations(std::move(decos));
@@ -97,7 +97,7 @@
 TEST_F(ArrayTypeTest, MinBufferBindingSizeArray) {
   U32Type u32;
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
 
   ArrayType arr(&u32, 4);
   arr.set_decorations(std::move(decos));
@@ -107,7 +107,7 @@
 TEST_F(ArrayTypeTest, MinBufferBindingSizeRuntimeArray) {
   U32Type u32;
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
 
   ArrayType arr(&u32);
   arr.set_decorations(std::move(decos));
@@ -117,7 +117,7 @@
 TEST_F(ArrayTypeTest, BaseAlignmentArray) {
   U32Type u32;
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
 
   ArrayType arr(&u32, 4);
   arr.set_decorations(std::move(decos));
@@ -128,7 +128,7 @@
 TEST_F(ArrayTypeTest, BaseAlignmentRuntimeArray) {
   U32Type u32;
   ArrayDecorationList decos;
-  decos.push_back(std::make_unique<StrideDecoration>(4));
+  decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
 
   ArrayType arr(&u32);
   arr.set_decorations(std::move(decos));
diff --git a/src/ast/type/struct_type_test.cc b/src/ast/type/struct_type_test.cc
index 9d98edc..60486e1 100644
--- a/src/ast/type/struct_type_test.cc
+++ b/src/ast/type/struct_type_test.cc
@@ -70,13 +70,13 @@
 
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
@@ -95,26 +95,26 @@
   ArrayType arr(&u32, 4);
   {
     ArrayDecorationList decos;
-    decos.push_back(std::make_unique<StrideDecoration>(4));
+    decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
     arr.set_decorations(std::move(decos));
   }
 
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(8));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(8, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &arr, std::move(deco)));
   }
@@ -134,26 +134,26 @@
   ArrayType arr(&u32);
   {
     ArrayDecorationList decos;
-    decos.push_back(std::make_unique<StrideDecoration>(4));
+    decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
     arr.set_decorations(std::move(decos));
   }
 
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(8));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(8, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
@@ -173,7 +173,7 @@
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &vec2, std::move(deco)));
   }
@@ -194,7 +194,7 @@
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &vec3, std::move(deco)));
   }
@@ -216,7 +216,7 @@
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &vec4, std::move(deco)));
   }
@@ -237,13 +237,13 @@
 
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
@@ -261,26 +261,26 @@
   ArrayType arr(&u32, 4);
   {
     ArrayDecorationList decos;
-    decos.push_back(std::make_unique<StrideDecoration>(4));
+    decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
     arr.set_decorations(std::move(decos));
   }
 
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(8));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(8, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &arr, std::move(deco)));
   }
@@ -298,26 +298,26 @@
   ArrayType arr(&u32);
   {
     ArrayDecorationList decos;
-    decos.push_back(std::make_unique<StrideDecoration>(4));
+    decos.push_back(std::make_unique<StrideDecoration>(4, Source{}));
     arr.set_decorations(std::move(decos));
   }
 
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(4, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(8));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(8, Source{}));
     members.push_back(
         std::make_unique<StructMember>("bar", &u32, std::move(deco)));
   }
@@ -336,7 +336,7 @@
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &vec2, std::move(deco)));
   }
@@ -356,7 +356,7 @@
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &vec3, std::move(deco)));
   }
@@ -376,7 +376,7 @@
   StructMemberList members;
   {
     StructMemberDecorationList deco;
-    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0));
+    deco.push_back(std::make_unique<StructMemberOffsetDecoration>(0, Source{}));
     members.push_back(
         std::make_unique<StructMember>("foo", &vec4, std::move(deco)));
   }
diff --git a/src/ast/variable_decoration.cc b/src/ast/variable_decoration.cc
index 2087e68..da68d27 100644
--- a/src/ast/variable_decoration.cc
+++ b/src/ast/variable_decoration.cc
@@ -25,7 +25,8 @@
 namespace tint {
 namespace ast {
 
-VariableDecoration::VariableDecoration() : Decoration(Kind) {}
+VariableDecoration::VariableDecoration(const Source& source)
+    : Decoration(Kind, source) {}
 
 VariableDecoration::~VariableDecoration() = default;
 
diff --git a/src/ast/variable_decoration.h b/src/ast/variable_decoration.h
index 3a13b68..4cb931b 100644
--- a/src/ast/variable_decoration.h
+++ b/src/ast/variable_decoration.h
@@ -67,7 +67,8 @@
 
  protected:
   /// Constructor
-  VariableDecoration();
+  /// @param source the source of this decoration
+  explicit VariableDecoration(const Source& source);
 };
 
 /// A list of unique variable decorations
diff --git a/src/ast/workgroup_decoration.cc b/src/ast/workgroup_decoration.cc
index fd44db4..1e3b107 100644
--- a/src/ast/workgroup_decoration.cc
+++ b/src/ast/workgroup_decoration.cc
@@ -17,13 +17,19 @@
 namespace tint {
 namespace ast {
 
-WorkgroupDecoration::WorkgroupDecoration(uint32_t x) : x_(x) {}
+WorkgroupDecoration::WorkgroupDecoration(uint32_t x, const Source& source)
+    : FunctionDecoration(source), x_(x) {}
 
-WorkgroupDecoration::WorkgroupDecoration(uint32_t x, uint32_t y)
-    : x_(x), y_(y) {}
+WorkgroupDecoration::WorkgroupDecoration(uint32_t x,
+                                         uint32_t y,
+                                         const Source& source)
+    : FunctionDecoration(source), x_(x), y_(y) {}
 
-WorkgroupDecoration::WorkgroupDecoration(uint32_t x, uint32_t y, uint32_t z)
-    : x_(x), y_(y), z_(z) {}
+WorkgroupDecoration::WorkgroupDecoration(uint32_t x,
+                                         uint32_t y,
+                                         uint32_t z,
+                                         const Source& source)
+    : FunctionDecoration(source), x_(x), y_(y), z_(z) {}
 
 WorkgroupDecoration::~WorkgroupDecoration() = default;
 
diff --git a/src/ast/workgroup_decoration.h b/src/ast/workgroup_decoration.h
index 04678d6..40574fe 100644
--- a/src/ast/workgroup_decoration.h
+++ b/src/ast/workgroup_decoration.h
@@ -29,16 +29,19 @@
  public:
   /// constructor
   /// @param x the workgroup x dimension size
-  explicit WorkgroupDecoration(uint32_t x);
+  /// @param source the source of this decoration
+  WorkgroupDecoration(uint32_t x, const Source& source);
   /// constructor
   /// @param x the workgroup x dimension size
   /// @param y the workgroup x dimension size
-  WorkgroupDecoration(uint32_t x, uint32_t y);
+  /// @param source the source of this decoration
+  WorkgroupDecoration(uint32_t x, uint32_t y, const Source& source);
   /// constructor
   /// @param x the workgroup x dimension size
   /// @param y the workgroup x dimension size
   /// @param z the workgroup x dimension size
-  WorkgroupDecoration(uint32_t x, uint32_t y, uint32_t z);
+  /// @param source the source of this decoration
+  WorkgroupDecoration(uint32_t x, uint32_t y, uint32_t z, const Source& source);
   ~WorkgroupDecoration() override;
 
   /// @returns true if this is a workgroup decoration
diff --git a/src/ast/workgroup_decoration_test.cc b/src/ast/workgroup_decoration_test.cc
index 7b4936b..90c267d 100644
--- a/src/ast/workgroup_decoration_test.cc
+++ b/src/ast/workgroup_decoration_test.cc
@@ -25,7 +25,7 @@
 using WorkgroupDecorationTest = testing::Test;
 
 TEST_F(WorkgroupDecorationTest, Creation_1param) {
-  WorkgroupDecoration d{2};
+  WorkgroupDecoration d{2, Source{}};
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
@@ -35,7 +35,7 @@
   EXPECT_EQ(z, 1u);
 }
 TEST_F(WorkgroupDecorationTest, Creation_2param) {
-  WorkgroupDecoration d{2, 4};
+  WorkgroupDecoration d{2, 4, Source{}};
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
@@ -46,7 +46,7 @@
 }
 
 TEST_F(WorkgroupDecorationTest, Creation_3param) {
-  WorkgroupDecoration d{2, 4, 6};
+  WorkgroupDecoration d{2, 4, 6, Source{}};
   uint32_t x = 0;
   uint32_t y = 0;
   uint32_t z = 0;
@@ -57,13 +57,13 @@
 }
 
 TEST_F(WorkgroupDecorationTest, Is) {
-  WorkgroupDecoration d{2, 4, 6};
+  WorkgroupDecoration d{2, 4, 6, Source{}};
   EXPECT_TRUE(d.IsWorkgroup());
   EXPECT_FALSE(d.IsStage());
 }
 
 TEST_F(WorkgroupDecorationTest, ToStr) {
-  WorkgroupDecoration d{2, 4, 6};
+  WorkgroupDecoration d{2, 4, 6, Source{}};
   std::ostringstream out;
   d.to_str(out);
   EXPECT_EQ(out.str(), R"(WorkgroupDecoration{2 4 6}
diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc
index 97d04f7..f4b69c0 100644
--- a/src/inspector/inspector_test.cc
+++ b/src/inspector/inspector_test.cc
@@ -183,7 +183,7 @@
         std::make_unique<ast::Variable>(name, ast::StorageClass::kNone, type));
     dvar->set_is_const(true);
     ast::VariableDecorationList decos;
-    decos.push_back(std::make_unique<ast::ConstantIdDecoration>(id));
+    decos.push_back(std::make_unique<ast::ConstantIdDecoration>(id, Source{}));
     dvar->set_decorations(std::move(decos));
     if (val) {
       dvar->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
@@ -260,8 +260,8 @@
       std::tie(type, offset) = member_info;
 
       ast::StructMemberDecorationList deco;
-      deco.push_back(
-          std::make_unique<ast::StructMemberOffsetDecoration>(offset));
+      deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(
+          offset, Source{}));
 
       members.push_back(std::make_unique<ast::StructMember>(
           StructMemberName(members.size(), type), type, std::move(deco)));
@@ -269,7 +269,7 @@
 
     ast::StructDecorationList decos;
     if (is_block) {
-      decos.push_back(std::make_unique<ast::StructBlockDecoration>());
+      decos.push_back(std::make_unique<ast::StructBlockDecoration>(Source{}));
     }
 
     auto str =
@@ -315,8 +315,9 @@
         std::make_unique<ast::Variable>(name, storage_class, struct_type));
     ast::VariableDecorationList decorations;
 
-    decorations.push_back(std::make_unique<ast::BindingDecoration>(binding));
-    decorations.push_back(std::make_unique<ast::SetDecoration>(set));
+    decorations.push_back(
+        std::make_unique<ast::BindingDecoration>(binding, Source{}));
+    decorations.push_back(std::make_unique<ast::SetDecoration>(set, Source{}));
     var->set_decorations(std::move(decorations));
 
     mod()->AddGlobalVariable(std::move(var));
@@ -401,7 +402,7 @@
       array_type_memo_[count] =
           std::make_unique<ast::type::ArrayType>(u32_type(), count);
       ast::ArrayDecorationList decos;
-      decos.push_back(std::make_unique<ast::StrideDecoration>(4));
+      decos.push_back(std::make_unique<ast::StrideDecoration>(4, Source{}));
       array_type_memo_[count]->set_decorations(std::move(decos));
     }
     return array_type_memo_[count].get();
@@ -447,8 +448,8 @@
 
 TEST_F(InspectorGetEntryPointTest, OneEntryPoint) {
   auto foo = MakeEmptyBodyFunction("foo");
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   auto result = inspector()->GetEntryPoints();
@@ -461,13 +462,13 @@
 
 TEST_F(InspectorGetEntryPointTest, MultipleEntryPoints) {
   auto foo = MakeEmptyBodyFunction("foo");
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   auto bar = MakeEmptyBodyFunction("bar");
-  bar->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  bar->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   mod()->AddFunction(std::move(bar));
 
   auto result = inspector()->GetEntryPoints();
@@ -485,13 +486,13 @@
   mod()->AddFunction(std::move(func));
 
   auto foo = MakeCallerBodyFunction("foo", "func");
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   auto bar = MakeCallerBodyFunction("bar", "func");
-  bar->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  bar->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   mod()->AddFunction(std::move(bar));
 
   auto result = inspector()->GetEntryPoints();
@@ -506,8 +507,8 @@
 
 TEST_F(InspectorGetEntryPointTest, DefaultWorkgroupSize) {
   auto foo = MakeCallerBodyFunction("foo", "func");
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   auto result = inspector()->GetEntryPoints();
@@ -523,9 +524,10 @@
 
 TEST_F(InspectorGetEntryPointTest, NonDefaultWorkgroupSize) {
   auto foo = MakeEmptyBodyFunction("foo");
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
-  foo->add_decoration(std::make_unique<ast::WorkgroupDecoration>(8u, 2u, 1u));
+      std::make_unique<ast::WorkgroupDecoration>(8u, 2u, 1u, Source{}));
   mod()->AddFunction(std::move(foo));
 
   auto result = inspector()->GetEntryPoints();
@@ -544,8 +546,8 @@
   mod()->AddFunction(std::move(func));
 
   auto foo = MakeCallerBodyFunction("foo", "func");
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   auto result = inspector()->GetEntryPoints();
@@ -560,8 +562,8 @@
   AddInOutVariables({{"in_var", "out_var"}});
 
   auto foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out_var"}});
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -584,8 +586,8 @@
   mod()->AddFunction(std::move(func));
 
   auto foo = MakeCallerBodyFunction("foo", "func");
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -609,8 +611,8 @@
 
   auto foo = MakeInOutVariableCallerBodyFunction("foo", "func",
                                                  {{"in_var", "out_var"}});
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -631,8 +633,8 @@
 
   auto foo = MakeInOutVariableBodyFunction(
       "foo", {{"in_var", "out_var"}, {"in2_var", "out2_var"}});
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -658,8 +660,8 @@
   mod()->AddFunction(std::move(func));
 
   auto foo = MakeCallerBodyFunction("foo", "func");
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -681,13 +683,13 @@
   AddInOutVariables({{"in_var", "out_var"}, {"in2_var", "out2_var"}});
 
   auto foo = MakeInOutVariableBodyFunction("foo", {{"in_var", "out2_var"}});
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   auto bar = MakeInOutVariableBodyFunction("bar", {{"in2_var", "out_var"}});
-  bar->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  bar->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   mod()->AddFunction(std::move(bar));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -718,13 +720,13 @@
 
   auto foo = MakeInOutVariableCallerBodyFunction("foo", "func",
                                                  {{"in_var", "out_var"}});
-  foo->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  foo->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(foo));
 
   auto bar = MakeCallerBodyFunction("bar", "func");
-  bar->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  bar->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   mod()->AddFunction(std::move(bar));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -853,8 +855,8 @@
   mod()->AddFunction(std::move(ub_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -867,7 +869,8 @@
 TEST_F(InspectorGetUniformBufferResourceBindings, MissingBlockDeco) {
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
 
   members.push_back(std::make_unique<ast::StructMember>(
       StructMemberName(members.size(), i32_type()), i32_type(),
@@ -887,8 +890,8 @@
   mod()->AddFunction(std::move(ub_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -907,8 +910,8 @@
   mod()->AddFunction(std::move(ub_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -932,8 +935,8 @@
   mod()->AddFunction(std::move(ub_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -982,8 +985,8 @@
       "ep_func", ast::VariableList(), void_type());
   func->set_body(std::move(body));
 
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -1015,8 +1018,8 @@
   mod()->AddFunction(std::move(ub_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "ub_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -1039,8 +1042,8 @@
   mod()->AddFunction(std::move(sb_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -1064,8 +1067,8 @@
   mod()->AddFunction(std::move(sb_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -1114,8 +1117,8 @@
       "ep_func", ast::VariableList(), void_type());
   func->set_body(std::move(body));
 
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -1147,8 +1150,8 @@
   mod()->AddFunction(std::move(sb_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
@@ -1172,8 +1175,8 @@
   mod()->AddFunction(std::move(sb_func));
 
   auto ep_func = MakeCallerBodyFunction("ep_func", "sb_func");
-  ep_func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(ep_func));
 
   ASSERT_TRUE(td()->Determine()) << td()->error();
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 98b2c83..18f715b 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -635,7 +635,7 @@
 
   if (ep_info_ != nullptr) {
     ast_fn->add_decoration(
-        std::make_unique<ast::StageDecoration>(ep_info_->stage));
+        std::make_unique<ast::StageDecoration>(ep_info_->stage, Source{}));
   }
 
   ast_module_.AddFunction(std::move(ast_fn));
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index ab77baf..c36ec78 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -392,7 +392,8 @@
             << ShowType(struct_type_id);
         return nullptr;
       }
-      return std::make_unique<ast::StructMemberOffsetDecoration>(decoration[1]);
+      return std::make_unique<ast::StructMemberOffsetDecoration>(decoration[1],
+                                                                 Source{});
     case SpvDecorationNonReadable:
       // WGSL doesn't have a member decoration for this.  Silently drop it.
       return nullptr;
@@ -781,7 +782,8 @@
                       << ": multiple ArrayStride decorations";
       }
       ast::ArrayDecorationList decos;
-      decos.push_back(std::make_unique<ast::StrideDecoration>(stride));
+      decos.push_back(
+          std::make_unique<ast::StrideDecoration>(stride, Source{}));
       ast_type->set_decorations(std::move(decos));
     } else {
       return Fail() << "invalid array type ID " << type_id
@@ -804,10 +806,10 @@
     const auto decoration = struct_decorations[0][0];
     if (decoration == SpvDecorationBlock) {
       ast_struct_decorations.push_back(
-          std::make_unique<ast::StructBlockDecoration>());
+          std::make_unique<ast::StructBlockDecoration>(Source{}));
     } else if (decoration == SpvDecorationBufferBlock) {
       ast_struct_decorations.push_back(
-          std::make_unique<ast::StructBlockDecoration>());
+          std::make_unique<ast::StructBlockDecoration>(Source{}));
       remap_buffer_block_type_.insert(type_id);
     } else {
       Fail() << "struct with ID " << type_id
@@ -1006,7 +1008,8 @@
       ast::VariableDecorationList spec_id_decos;
       for (const auto& deco : GetDecorationsFor(inst.result_id())) {
         if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) {
-          auto cid = std::make_unique<ast::ConstantIdDecoration>(deco[1]);
+          auto cid =
+              std::make_unique<ast::ConstantIdDecoration>(deco[1], Source{});
           spec_id_decos.push_back(std::move(cid));
           break;
         }
@@ -1142,8 +1145,8 @@
         enum_converter_.ToStorageClass(builtin_position_.storage_class),
         ConvertType(builtin_position_.member_type_id)));
     ast::VariableDecorationList decos;
-    decos.push_back(
-        std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kPosition));
+    decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+        ast::Builtin::kPosition, Source{}));
     var->set_decorations(std::move(decos));
 
     ast_module_.AddGlobalVariable(std::move(var));
@@ -1188,7 +1191,7 @@
         return nullptr;
       }
       ast_decorations.emplace_back(
-          std::make_unique<ast::BuiltinDecoration>(ast_builtin));
+          std::make_unique<ast::BuiltinDecoration>(ast_builtin, Source{}));
     }
     if (deco[0] == SpvDecorationLocation) {
       if (deco.size() != 2) {
@@ -1197,7 +1200,7 @@
         return nullptr;
       }
       ast_decorations.emplace_back(
-          std::make_unique<ast::LocationDecoration>(deco[1]));
+          std::make_unique<ast::LocationDecoration>(deco[1], Source{}));
     }
     if (deco[0] == SpvDecorationDescriptorSet) {
       if (deco.size() == 1) {
@@ -1206,7 +1209,7 @@
         return nullptr;
       }
       ast_decorations.emplace_back(
-          std::make_unique<ast::SetDecoration>(deco[1]));
+          std::make_unique<ast::SetDecoration>(deco[1], Source{}));
     }
     if (deco[0] == SpvDecorationBinding) {
       if (deco.size() == 1) {
@@ -1215,7 +1218,7 @@
         return nullptr;
       }
       ast_decorations.emplace_back(
-          std::make_unique<ast::BindingDecoration>(deco[1]));
+          std::make_unique<ast::BindingDecoration>(deco[1], Source{}));
     }
   }
   if (!ast_decorations.empty()) {
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index a938eca..583c3ea 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -439,6 +439,7 @@
 //  | SET INT PAREN_LEFT_LITERAL PAREN_RIGHT
 std::unique_ptr<ast::VariableDecoration> ParserImpl::variable_decoration() {
   auto t = peek();
+  auto source = t.source();
   if (t.IsLocation()) {
     next();  // consume the peek
 
@@ -460,7 +461,7 @@
       set_error(t, "missing ) for location decoration");
       return {};
     }
-    return std::make_unique<ast::LocationDecoration>(val);
+    return std::make_unique<ast::LocationDecoration>(val, source);
   }
   if (t.IsBuiltin()) {
     next();  // consume the peek
@@ -488,7 +489,7 @@
       set_error(t, "missing ) for builtin decoration");
       return {};
     }
-    return std::make_unique<ast::BuiltinDecoration>(builtin);
+    return std::make_unique<ast::BuiltinDecoration>(builtin, source);
   }
   if (t.IsBinding()) {
     next();  // consume the peek
@@ -512,7 +513,7 @@
       return {};
     }
 
-    return std::make_unique<ast::BindingDecoration>(val);
+    return std::make_unique<ast::BindingDecoration>(val, source);
   }
   if (t.IsSet()) {
     next();  // consume the peek
@@ -536,7 +537,7 @@
       return {};
     }
 
-    return std::make_unique<ast::SetDecoration>(val);
+    return std::make_unique<ast::SetDecoration>(val, source);
   }
 
   return nullptr;
@@ -1335,6 +1336,9 @@
 
   for (;;) {
     t = next();
+
+    auto source = t.source();
+
     if (!t.IsStride()) {
       set_error(t, "unknown array decoration");
       return false;
@@ -1356,7 +1360,7 @@
       return false;
     }
     uint32_t stride = static_cast<uint32_t>(t.to_i32());
-    decos.push_back(std::make_unique<ast::StrideDecoration>(stride));
+    decos.push_back(std::make_unique<ast::StrideDecoration>(stride, source));
 
     t = next();
     if (!t.IsParenRight()) {
@@ -1546,7 +1550,7 @@
 //  : BLOCK
 std::unique_ptr<ast::StructDecoration> ParserImpl::struct_decoration(Token t) {
   if (t.IsBlock()) {
-    return std::make_unique<ast::StructBlockDecoration>();
+    return std::make_unique<ast::StructBlockDecoration>(t.source());
   }
   return nullptr;
 }
@@ -1677,6 +1681,8 @@
   if (!t.IsOffset())
     return nullptr;
 
+  auto source = t.source();
+
   next();  // Consume the peek
 
   t = next();
@@ -1702,7 +1708,7 @@
     return nullptr;
   }
 
-  return std::make_unique<ast::StructMemberOffsetDecoration>(val);
+  return std::make_unique<ast::StructMemberOffsetDecoration>(val, source);
 }
 
 // function_decl
@@ -1797,6 +1803,7 @@
 //         (COMMA INT_LITERAL (COMMA INT_LITERAL)?)? PAREN_RIGHT
 std::unique_ptr<ast::FunctionDecoration> ParserImpl::function_decoration() {
   auto t = peek();
+  auto source = t.source();
   if (t.IsWorkgroupSize()) {
     next();  // Consume the peek
 
@@ -1858,7 +1865,7 @@
     }
 
     return std::make_unique<ast::WorkgroupDecoration>(uint32_t(x), uint32_t(y),
-                                                      uint32_t(z));
+                                                      uint32_t(z), source);
   }
   if (t.IsStage()) {
     next();  // Consume the peek
@@ -1883,7 +1890,7 @@
       set_error(t, "missing ) for stage decoration");
       return nullptr;
     }
-    return std::make_unique<ast::StageDecoration>(stage);
+    return std::make_unique<ast::StageDecoration>(stage, source);
   }
   return nullptr;
 }
diff --git a/src/transform/vertex_pulling_transform.cc b/src/transform/vertex_pulling_transform.cc
index e8390d7..cec42b8 100644
--- a/src/transform/vertex_pulling_transform.cc
+++ b/src/transform/vertex_pulling_transform.cc
@@ -143,8 +143,8 @@
           vertex_index_name_, ast::StorageClass::kInput, GetI32Type()));
 
   ast::VariableDecorationList decorations;
-  decorations.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kVertexIdx));
+  decorations.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kVertexIdx, Source{}));
 
   var->set_decorations(std::move(decorations));
   mod_->AddGlobalVariable(std::move(var));
@@ -186,8 +186,8 @@
           instance_index_name_, ast::StorageClass::kInput, GetI32Type()));
 
   ast::VariableDecorationList decorations;
-  decorations.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kInstanceIdx));
+  decorations.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kInstanceIdx, Source{}));
 
   var->set_decorations(std::move(decorations));
   mod_->AddGlobalVariable(std::move(var));
@@ -221,7 +221,7 @@
   // The array inside the struct definition
   auto internal_array = std::make_unique<ast::type::ArrayType>(GetU32Type());
   ast::ArrayDecorationList ary_decos;
-  ary_decos.push_back(std::make_unique<ast::StrideDecoration>(4u));
+  ary_decos.push_back(std::make_unique<ast::StrideDecoration>(4u, Source{}));
   internal_array->set_decorations(std::move(ary_decos));
 
   auto* internal_array_type = ctx_->type_mgr().Get(std::move(internal_array));
@@ -229,13 +229,14 @@
   // Creating the struct type
   ast::StructMemberList members;
   ast::StructMemberDecorationList member_dec;
-  member_dec.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0u));
+  member_dec.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0u, Source{}));
 
   members.push_back(std::make_unique<ast::StructMember>(
       kStructBufferName, internal_array_type, std::move(member_dec)));
 
   ast::StructDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructBlockDecoration>());
+  decos.push_back(std::make_unique<ast::StructBlockDecoration>(Source{}));
 
   auto* struct_type =
       ctx_->type_mgr().Get(std::make_unique<ast::type::StructType>(
@@ -251,8 +252,10 @@
 
     // Add decorations
     ast::VariableDecorationList decorations;
-    decorations.push_back(std::make_unique<ast::BindingDecoration>(i));
-    decorations.push_back(std::make_unique<ast::SetDecoration>(pulling_set_));
+    decorations.push_back(
+        std::make_unique<ast::BindingDecoration>(i, Source{}));
+    decorations.push_back(
+        std::make_unique<ast::SetDecoration>(pulling_set_, Source{}));
     var->set_decorations(std::move(decorations));
 
     mod_->AddGlobalVariable(std::move(var));
diff --git a/src/transform/vertex_pulling_transform_test.cc b/src/transform/vertex_pulling_transform_test.cc
index 9d13b98..740c3dc 100644
--- a/src/transform/vertex_pulling_transform_test.cc
+++ b/src/transform/vertex_pulling_transform_test.cc
@@ -44,8 +44,8 @@
     auto func = std::make_unique<ast::Function>(
         "main", ast::VariableList{},
         ctx_.type_mgr().Get(std::make_unique<ast::type::VoidType>()));
-    func->add_decoration(
-        std::make_unique<ast::StageDecoration>(ast::PipelineStage ::kVertex));
+    func->add_decoration(std::make_unique<ast::StageDecoration>(
+        ast::PipelineStage ::kVertex, Source{}));
     mod()->AddFunction(std::move(func));
   }
 
@@ -69,7 +69,8 @@
         std::make_unique<ast::Variable>(name, ast::StorageClass::kInput, type));
 
     ast::VariableDecorationList decorations;
-    decorations.push_back(std::make_unique<ast::LocationDecoration>(location));
+    decorations.push_back(
+        std::make_unique<ast::LocationDecoration>(location, Source{}));
 
     var->set_decorations(std::move(decorations));
     mod_->AddGlobalVariable(std::move(var));
@@ -112,8 +113,8 @@
   auto func = std::make_unique<ast::Function>(
       "main", ast::VariableList{},
       ctx()->type_mgr().Get(std::make_unique<ast::type::VoidType>()));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   mod()->AddFunction(std::move(func));
 
   InitTransform({});
@@ -396,8 +397,8 @@
                                         ast::StorageClass::kInput, &i32));
 
     ast::VariableDecorationList decorations;
-    decorations.push_back(
-        std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kVertexIdx));
+    decorations.push_back(std::make_unique<ast::BuiltinDecoration>(
+        ast::Builtin::kVertexIdx, Source{}));
 
     vertex_index_var->set_decorations(std::move(decorations));
     mod()->AddGlobalVariable(std::move(vertex_index_var));
@@ -409,8 +410,8 @@
                                         ast::StorageClass::kInput, &i32));
 
     ast::VariableDecorationList decorations;
-    decorations.push_back(
-        std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kInstanceIdx));
+    decorations.push_back(std::make_unique<ast::BuiltinDecoration>(
+        ast::Builtin::kInstanceIdx, Source{}));
 
     instance_index_var->set_decorations(std::move(decorations));
     mod()->AddGlobalVariable(std::move(instance_index_var));
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index 81cf17c..9cd3fd0 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -4702,8 +4702,8 @@
   func_a->set_body(std::move(body));
 
   auto ep_1 = std::make_unique<ast::Function>("ep_1", std::move(params), &f32);
-  ep_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   auto* ep_1_ptr = ep_1.get();
 
   body = std::make_unique<ast::BlockStatement>();
@@ -4720,8 +4720,8 @@
   ep_1->set_body(std::move(body));
 
   auto ep_2 = std::make_unique<ast::Function>("ep_2", std::move(params), &f32);
-  ep_2->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  ep_2->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   auto* ep_2_ptr = ep_2.get();
 
   body = std::make_unique<ast::BlockStatement>();
diff --git a/src/validator_function_test.cc b/src/validator_function_test.cc
index d147dcc..3a496f3 100644
--- a/src/validator_function_test.cc
+++ b/src/validator_function_test.cc
@@ -84,8 +84,8 @@
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->DetermineFunctions(mod()->functions())) << td()->error();
@@ -238,8 +238,8 @@
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>(std::move(return_expr)));
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
 
   mod()->AddFunction(std::move(func));
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -262,8 +262,8 @@
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
 
   mod()->AddFunction(std::move(func));
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -285,8 +285,8 @@
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
 
   func = std::make_unique<ast::Function>(Source{Source::Location{12, 34}},
@@ -294,8 +294,8 @@
   body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -317,8 +317,8 @@
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
 
   func = std::make_unique<ast::Function>(Source{Source::Location{12, 34}},
@@ -326,8 +326,8 @@
   body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -344,8 +344,8 @@
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
diff --git a/src/validator_test.cc b/src/validator_test.cc
index 741e432..c234637 100644
--- a/src/validator_test.cc
+++ b/src/validator_test.cc
@@ -344,8 +344,8 @@
       Source{Source::Location{12, 34}}, std::move(lhs), std::move(rhs)));
   body->append(std::make_unique<ast::ReturnStatement>());
   func->set_body(std::move(body));
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   mod()->AddFunction(std::move(func));
 
   EXPECT_TRUE(td()->Determine()) << td()->error();
@@ -674,8 +674,8 @@
       Source{Source::Location{13, 34}}, std::move(var1)));
   body1->append(std::make_unique<ast::ReturnStatement>());
   func1->set_body(std::move(body1));
-  func1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
 
   mod()->AddFunction(std::move(func0));
   mod()->AddFunction(std::move(func1));
diff --git a/src/writer/hlsl/generator_impl_alias_type_test.cc b/src/writer/hlsl/generator_impl_alias_type_test.cc
index e878b44..d50db38 100644
--- a/src/writer/hlsl/generator_impl_alias_type_test.cc
+++ b/src/writer/hlsl/generator_impl_alias_type_test.cc
@@ -56,7 +56,8 @@
       "a", &f32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &i32, std::move(b_deco)));
 
diff --git a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
index c22dfe4..8a81489 100644
--- a/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
+++ b/src/writer/hlsl/generator_impl_function_entry_point_data_test.cc
@@ -56,12 +56,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(foo_var.get());
@@ -73,8 +73,8 @@
   ast::VariableList params;
   auto func =
       std::make_unique<ast::Function>("vtx_main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -115,12 +115,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(foo_var.get());
@@ -132,8 +132,8 @@
   ast::VariableList params;
   auto func =
       std::make_unique<ast::Function>("vtx_main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -174,12 +174,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(foo_var.get());
@@ -190,8 +190,8 @@
 
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -232,12 +232,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(foo_var.get());
@@ -248,8 +248,8 @@
 
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -287,12 +287,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(foo_var.get());
@@ -303,8 +303,8 @@
 
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -337,12 +337,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(foo_var.get());
@@ -353,8 +353,8 @@
 
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -395,15 +395,15 @@
           "coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   auto depth_var =
       std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
           "depth", ast::StorageClass::kOutput, &f32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -415,8 +415,8 @@
   ast::VariableList params;
   auto func =
       std::make_unique<ast::Function>("main", std::move(params), &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
diff --git a/src/writer/hlsl/generator_impl_function_test.cc b/src/writer/hlsl/generator_impl_function_test.cc
index a2a11b6..5edfe2b 100644
--- a/src/writer/hlsl/generator_impl_function_test.cc
+++ b/src/writer/hlsl/generator_impl_function_test.cc
@@ -133,12 +133,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(foo_var.get());
@@ -150,8 +150,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::AssignmentStatement>(
@@ -192,15 +192,15 @@
           "coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   auto depth_var =
       std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
           "depth", ast::StorageClass::kOutput, &f32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -212,8 +212,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::AssignmentStatement>(
@@ -256,8 +256,8 @@
           "coord", ast::StorageClass::kUniform, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -266,8 +266,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto var =
       std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
@@ -318,8 +318,8 @@
   mod()->AddConstructedType(&s);
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -328,8 +328,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto var =
       std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
@@ -370,12 +370,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -390,8 +392,8 @@
           "coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -400,8 +402,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto var =
       std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
@@ -436,12 +438,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -456,8 +460,8 @@
           "coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -466,8 +470,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto var =
       std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
@@ -502,12 +506,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -522,8 +528,8 @@
           "coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -533,8 +539,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto assign = std::make_unique<ast::AssignmentStatement>(
       std::make_unique<ast::MemberAccessorExpression>(
@@ -572,17 +578,17 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   auto val_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("val", ast::StorageClass::kOutput, &f32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   val_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(foo_var.get());
@@ -614,8 +620,8 @@
 
   auto func_1 =
       std::make_unique<ast::Function>("ep_1", std::move(params), &void_type);
-  func_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -669,8 +675,8 @@
           "depth", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(depth_var.get());
@@ -692,8 +698,8 @@
 
   auto func_1 =
       std::make_unique<ast::Function>("ep_1", std::move(params), &void_type);
-  func_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -741,15 +747,15 @@
           "coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   auto depth_var =
       std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
           "depth", ast::StorageClass::kOutput, &f32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -778,8 +784,8 @@
 
   auto func_1 =
       std::make_unique<ast::Function>("ep_1", std::move(params), &void_type);
-  func_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -831,8 +837,8 @@
           "coord", ast::StorageClass::kUniform, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -856,8 +862,8 @@
 
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -905,8 +911,8 @@
           "coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(coord_var.get());
@@ -930,8 +936,8 @@
 
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -975,7 +981,7 @@
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   td().RegisterVariableForTesting(bar_var.get());
@@ -984,8 +990,8 @@
   ast::VariableList params;
   auto func_1 =
       std::make_unique<ast::Function>("ep_1", std::move(params), &void_type);
-  func_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::AssignmentStatement>(
@@ -1034,8 +1040,8 @@
 
   auto func = std::make_unique<ast::Function>("GeometryShader",
                                               ast::VariableList{}, &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   mod()->AddFunction(std::move(func));
 
@@ -1053,8 +1059,8 @@
   ast::VariableList params;
   auto func =
       std::make_unique<ast::Function>("main", std::move(params), &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
@@ -1079,9 +1085,10 @@
   ast::VariableList params;
   auto func =
       std::make_unique<ast::Function>("main", std::move(params), &void_type);
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
-  func->add_decoration(std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u));
+      std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::ReturnStatement>());
diff --git a/src/writer/hlsl/generator_impl_member_accessor_test.cc b/src/writer/hlsl/generator_impl_member_accessor_test.cc
index efdf970..5a345c2 100644
--- a/src/writer/hlsl/generator_impl_member_accessor_test.cc
+++ b/src/writer/hlsl/generator_impl_member_accessor_test.cc
@@ -51,7 +51,8 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("mem", &f32, std::move(deco)));
 
@@ -92,12 +93,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -140,12 +143,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -191,12 +196,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("z", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &mat, std::move(b_deco)));
 
@@ -254,12 +261,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("z", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &mat, std::move(b_deco)));
 
@@ -313,12 +322,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("z", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &mat, std::move(b_deco)));
 
@@ -368,12 +379,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("z", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &mat, std::move(b_deco)));
 
@@ -420,7 +433,8 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &mat, std::move(deco)));
 
@@ -466,12 +480,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("z", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &mat, std::move(b_deco)));
 
@@ -518,12 +534,13 @@
   ast::type::I32Type i32;
   ast::type::ArrayType ary(&i32, 5);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(4));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(4, Source{}));
   ary.set_decorations(std::move(decos));
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ary, std::move(a_deco)));
 
@@ -567,12 +584,13 @@
   ast::type::I32Type i32;
   ast::type::ArrayType ary(&i32, 5);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(4));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(4, Source{}));
   ary.set_decorations(std::move(decos));
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ary, std::move(a_deco)));
 
@@ -627,12 +645,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -678,12 +698,13 @@
   ast::type::I32Type i32;
   ast::type::ArrayType ary(&i32, 5);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(4));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(4, Source{}));
   ary.set_decorations(std::move(decos));
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ary, std::move(a_deco)));
 
@@ -734,12 +755,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -789,12 +812,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ivec3, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec3, std::move(b_deco)));
 
@@ -840,12 +865,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ivec3, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec3, std::move(b_deco)));
 
@@ -913,11 +940,13 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ivec3, std::move(deco)));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec3, std::move(deco)));
 
@@ -928,10 +957,11 @@
 
   ast::type::ArrayType ary(&data, 4);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(32));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(32, Source{}));
   ary.set_decorations(std::move(decos));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &ary, std::move(deco)));
 
@@ -986,11 +1016,13 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ivec3, std::move(deco)));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec3, std::move(deco)));
 
@@ -1001,10 +1033,11 @@
 
   ast::type::ArrayType ary(&data, 4);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(32));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(32, Source{}));
   ary.set_decorations(std::move(decos));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &ary, std::move(deco)));
 
@@ -1062,11 +1095,13 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ivec3, std::move(deco)));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec3, std::move(deco)));
 
@@ -1077,10 +1112,11 @@
 
   ast::type::ArrayType ary(&data, 4);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(32));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(32, Source{}));
   ary.set_decorations(std::move(decos));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &ary, std::move(deco)));
 
@@ -1137,11 +1173,13 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ivec3, std::move(deco)));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec3, std::move(deco)));
 
@@ -1152,10 +1190,11 @@
 
   ast::type::ArrayType ary(&data, 4);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(32));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(32, Source{}));
   ary.set_decorations(std::move(decos));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &ary, std::move(deco)));
 
@@ -1213,11 +1252,13 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ivec3, std::move(deco)));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec3, std::move(deco)));
 
@@ -1228,10 +1269,11 @@
 
   ast::type::ArrayType ary(&data, 4);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(32));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(32, Source{}));
   ary.set_decorations(std::move(decos));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &ary, std::move(deco)));
 
@@ -1305,11 +1347,13 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList deco;
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &ivec3, std::move(deco)));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec3, std::move(deco)));
 
@@ -1320,10 +1364,11 @@
 
   ast::type::ArrayType ary(&data, 4);
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(32));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(32, Source{}));
   ary.set_decorations(std::move(decos));
 
-  deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &ary, std::move(deco)));
 
diff --git a/src/writer/hlsl/generator_impl_module_constant_test.cc b/src/writer/hlsl/generator_impl_module_constant_test.cc
index 94ffb8e..a63b7db 100644
--- a/src/writer/hlsl/generator_impl_module_constant_test.cc
+++ b/src/writer/hlsl/generator_impl_module_constant_test.cc
@@ -62,7 +62,7 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(23));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(23, Source{}));
 
   auto var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("pos", ast::StorageClass::kNone, &f32));
@@ -85,7 +85,7 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(23));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(23, Source{}));
 
   auto var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("pos", ast::StorageClass::kNone, &f32));
diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc
index 274a6be..f91756e 100644
--- a/src/writer/hlsl/generator_impl_type_test.cc
+++ b/src/writer/hlsl/generator_impl_type_test.cc
@@ -173,7 +173,8 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -199,7 +200,8 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -217,17 +219,20 @@
   ast::type::F32Type f32;
 
   ast::StructMemberDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
 
   ast::StructMemberList members;
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(32));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(32, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(128));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(128, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &f32, std::move(decos)));
 
@@ -282,12 +287,13 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
   ast::StructDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructBlockDecoration>());
+  decos.push_back(std::make_unique<ast::StructBlockDecoration>(Source{}));
 
   auto str =
       std::make_unique<ast::Struct>(std::move(decos), std::move(members));
diff --git a/src/writer/msl/generator_impl_alias_type_test.cc b/src/writer/msl/generator_impl_alias_type_test.cc
index 1003694..0525e0a 100644
--- a/src/writer/msl/generator_impl_alias_type_test.cc
+++ b/src/writer/msl/generator_impl_alias_type_test.cc
@@ -61,7 +61,8 @@
       "a", &f32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &i32, std::move(b_deco)));
 
@@ -89,7 +90,8 @@
       "a", &f32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &i32, std::move(b_deco)));
 
diff --git a/src/writer/msl/generator_impl_function_entry_point_data_test.cc b/src/writer/msl/generator_impl_function_entry_point_data_test.cc
index f404627..778da93 100644
--- a/src/writer/msl/generator_impl_function_entry_point_data_test.cc
+++ b/src/writer/msl/generator_impl_function_entry_point_data_test.cc
@@ -55,12 +55,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -75,8 +75,8 @@
   ast::VariableList params;
   auto func =
       std::make_unique<ast::Function>("vtx_main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -118,12 +118,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -138,8 +138,8 @@
   ast::VariableList params;
   auto func =
       std::make_unique<ast::Function>("vtx_main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -181,12 +181,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -200,8 +200,8 @@
 
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -243,12 +243,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -262,8 +262,8 @@
 
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -302,12 +302,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kInput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -321,8 +321,8 @@
 
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -356,12 +356,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &i32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -375,8 +375,8 @@
 
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("main", std::move(params), &f32);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
@@ -417,15 +417,15 @@
           "coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   auto depth_var =
       std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
           "depth", ast::StorageClass::kOutput, &f32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -440,8 +440,8 @@
   ast::VariableList params;
   auto func =
       std::make_unique<ast::Function>("main", std::move(params), &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   auto* func_ptr = func.get();
 
   auto body = std::make_unique<ast::BlockStatement>();
diff --git a/src/writer/msl/generator_impl_function_test.cc b/src/writer/msl/generator_impl_function_test.cc
index 86d2d31..5cbe0d2 100644
--- a/src/writer/msl/generator_impl_function_test.cc
+++ b/src/writer/msl/generator_impl_function_test.cc
@@ -149,12 +149,12 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -169,8 +169,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::AssignmentStatement>(
@@ -215,15 +215,15 @@
           "coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   auto depth_var =
       std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
           "depth", ast::StorageClass::kOutput, &f32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -238,8 +238,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::AssignmentStatement>(
@@ -281,8 +281,8 @@
           "coord", ast::StorageClass::kUniform, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -295,8 +295,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto var =
       std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
@@ -334,12 +334,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -356,8 +358,8 @@
           "coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -369,8 +371,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto var =
       std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
@@ -413,12 +415,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -435,8 +439,8 @@
           "coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -448,8 +452,8 @@
   ast::VariableList params;
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto var =
       std::make_unique<ast::Variable>("v", ast::StorageClass::kFunction, &f32);
@@ -493,17 +497,17 @@
       std::make_unique<ast::Variable>("foo", ast::StorageClass::kInput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   foo_var->set_decorations(std::move(decos));
 
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   auto val_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("val", ast::StorageClass::kOutput, &f32));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(0, Source{}));
   val_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -538,8 +542,8 @@
 
   auto func_1 =
       std::make_unique<ast::Function>("ep_1", std::move(params), &void_type);
-  func_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -597,8 +601,8 @@
           "depth", ast::StorageClass::kOutput, &f32));
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -623,8 +627,8 @@
 
   auto func_1 =
       std::make_unique<ast::Function>("ep_1", std::move(params), &void_type);
-  func_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -676,15 +680,15 @@
           "coord", ast::StorageClass::kInput, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragCoord));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragCoord, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   auto depth_var =
       std::make_unique<ast::DecoratedVariable>(std::make_unique<ast::Variable>(
           "depth", ast::StorageClass::kOutput, &f32));
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kFragDepth, Source{}));
   depth_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -716,8 +720,8 @@
 
   auto func_1 =
       std::make_unique<ast::Function>("ep_1", std::move(params), &void_type);
-  func_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -769,8 +773,8 @@
           "coord", ast::StorageClass::kUniform, &vec4));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -797,8 +801,8 @@
 
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -844,12 +848,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -866,8 +872,8 @@
           "coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -893,8 +899,8 @@
 
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -945,12 +951,14 @@
 
   ast::StructMemberList members;
   ast::StructMemberDecorationList a_deco;
-  a_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(a_deco)));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -967,8 +975,8 @@
           "coord", ast::StorageClass::kStorageBuffer, &ac));
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
   coord_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -994,8 +1002,8 @@
 
   auto func = std::make_unique<ast::Function>("frag_main", std::move(params),
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::ExpressionList expr;
   expr.push_back(std::make_unique<ast::ScalarConstructorExpression>(
@@ -1046,7 +1054,7 @@
   auto bar_var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("bar", ast::StorageClass::kOutput, &f32));
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(1, Source{}));
   bar_var->set_decorations(std::move(decos));
 
   Context ctx;
@@ -1058,8 +1066,8 @@
   ast::VariableList params;
   auto func_1 =
       std::make_unique<ast::Function>("ep_1", std::move(params), &void_type);
-  func_1->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func_1->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::AssignmentStatement>(
@@ -1112,8 +1120,8 @@
 
   auto func =
       std::make_unique<ast::Function>("main", ast::VariableList{}, &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
 
   ast::Module m;
   m.AddFunction(std::move(func));
diff --git a/src/writer/msl/generator_impl_module_constant_test.cc b/src/writer/msl/generator_impl_module_constant_test.cc
index f20aad6..757ed56 100644
--- a/src/writer/msl/generator_impl_module_constant_test.cc
+++ b/src/writer/msl/generator_impl_module_constant_test.cc
@@ -64,7 +64,7 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(23));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(23, Source{}));
 
   auto var = std::make_unique<ast::DecoratedVariable>(
       std::make_unique<ast::Variable>("pos", ast::StorageClass::kNone, &f32));
diff --git a/src/writer/msl/generator_impl_test.cc b/src/writer/msl/generator_impl_test.cc
index 7e21912..c820cc9 100644
--- a/src/writer/msl/generator_impl_test.cc
+++ b/src/writer/msl/generator_impl_test.cc
@@ -52,8 +52,8 @@
 
   auto func = std::make_unique<ast::Function>("my_func", ast::VariableList{},
                                               &void_type);
-  func->add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  func->add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
   m.AddFunction(std::move(func));
 
   GeneratorImpl g(&m);
@@ -185,17 +185,20 @@
   ast::type::F32Type f32;
 
   ast::StructMemberDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
 
   ast::StructMemberList members;
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(32));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(32, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(128));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(128, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &f32, std::move(decos)));
 
@@ -215,17 +218,20 @@
   ast::type::VectorType fvec(&f32, 3);
 
   ast::StructMemberDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
 
   ast::StructMemberList members;
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &fvec, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(32));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(32, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &f32, std::move(decos)));
 
@@ -234,15 +240,18 @@
 
   ast::type::StructType inner_s("Inner", std::move(inner_str));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("d", &f32, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(32));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(32, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("e", &inner_s, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(64));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(64, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("f", &f32, std::move(decos)));
 
diff --git a/src/writer/msl/generator_impl_type_test.cc b/src/writer/msl/generator_impl_type_test.cc
index c3a1205..ccf2d26 100644
--- a/src/writer/msl/generator_impl_type_test.cc
+++ b/src/writer/msl/generator_impl_type_test.cc
@@ -202,7 +202,8 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -226,7 +227,8 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -250,17 +252,20 @@
   ast::type::F32Type f32;
 
   ast::StructMemberDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
 
   ast::StructMemberList members;
   members.push_back(
       std::make_unique<ast::StructMember>("a", &i32, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(32));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(32, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(decos)));
 
-  decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(128));
+  decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(128, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("c", &f32, std::move(decos)));
 
@@ -320,12 +325,13 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
   ast::StructDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructBlockDecoration>());
+  decos.push_back(std::make_unique<ast::StructBlockDecoration>(Source{}));
   auto str =
       std::make_unique<ast::Struct>(std::move(decos), std::move(members));
 
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 50b20f9..66785f1 100644
--- a/src/writer/msl/generator_impl_variable_decl_statement_test.cc
+++ b/src/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -95,7 +95,8 @@
       "a", &f32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
diff --git a/src/writer/spirv/builder_function_decoration_test.cc b/src/writer/spirv/builder_function_decoration_test.cc
index dc8b785..9d57e83 100644
--- a/src/writer/spirv/builder_function_decoration_test.cc
+++ b/src/writer/spirv/builder_function_decoration_test.cc
@@ -42,8 +42,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
 
   ast::Module mod;
   Builder b(&mod);
@@ -67,7 +67,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::StageDecoration>(params.stage));
+  func.add_decoration(
+      std::make_unique<ast::StageDecoration>(params.stage, Source{}));
 
   ast::Module mod;
   Builder b(&mod);
@@ -95,8 +96,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
   auto v_in =
       std::make_unique<ast::Variable>("my_in", ast::StorageClass::kInput, &f32);
   auto v_out = std::make_unique<ast::Variable>(
@@ -141,8 +142,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kVertex));
+  func.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kVertex, Source{}));
 
   auto body = std::make_unique<ast::BlockStatement>();
   body->append(std::make_unique<ast::AssignmentStatement>(
@@ -209,8 +210,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::Module mod;
   Builder b(&mod);
@@ -224,8 +225,8 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+  func.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
 
   ast::Module mod;
   Builder b(&mod);
@@ -239,9 +240,10 @@
   ast::type::VoidType void_type;
 
   ast::Function func("main", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u));
   func.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kCompute));
+      std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
+  func.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kCompute, Source{}));
 
   ast::Module mod;
   Builder b(&mod);
@@ -255,12 +257,12 @@
   ast::type::VoidType void_type;
 
   ast::Function func1("main1", {}, &void_type);
-  func1.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func1.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::Function func2("main2", {}, &void_type);
-  func2.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func2.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
 
   ast::Module mod;
   Builder b(&mod);
diff --git a/src/writer/spirv/builder_global_variable_test.cc b/src/writer/spirv/builder_global_variable_test.cc
index 62e9b16..3b9905f 100644
--- a/src/writer/spirv/builder_global_variable_test.cc
+++ b/src/writer/spirv/builder_global_variable_test.cc
@@ -268,7 +268,7 @@
   auto v =
       std::make_unique<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(5));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(5, Source{}));
 
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
@@ -292,8 +292,8 @@
   auto v =
       std::make_unique<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::BindingDecoration>(2));
-  decos.push_back(std::make_unique<ast::SetDecoration>(3));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(2, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(3, Source{}));
 
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
@@ -318,8 +318,8 @@
   auto v =
       std::make_unique<ast::Variable>("var", ast::StorageClass::kOutput, &f32);
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kPosition));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kPosition, Source{}));
 
   ast::DecoratedVariable dv(std::move(v));
   dv.set_decorations(std::move(decos));
@@ -342,7 +342,7 @@
   ast::type::BoolType bool_type;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(1200));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(1200, Source{}));
 
   ast::DecoratedVariable v(std::make_unique<ast::Variable>(
       "var", ast::StorageClass::kNone, &bool_type));
@@ -368,7 +368,7 @@
   ast::type::BoolType bool_type;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(1200));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(1200, Source{}));
 
   ast::DecoratedVariable v(std::make_unique<ast::Variable>(
       "var", ast::StorageClass::kNone, &bool_type));
@@ -392,7 +392,7 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0, Source{}));
 
   ast::DecoratedVariable v(
       std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &f32));
@@ -418,7 +418,7 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0, Source{}));
 
   ast::DecoratedVariable v(
       std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &f32));
@@ -442,7 +442,7 @@
   ast::type::I32Type i32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0, Source{}));
 
   ast::DecoratedVariable v(
       std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &i32));
@@ -466,7 +466,7 @@
   ast::type::U32Type u32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(0, Source{}));
 
   ast::DecoratedVariable v(
       std::make_unique<ast::Variable>("var", ast::StorageClass::kNone, &u32));
diff --git a/src/writer/spirv/builder_type_test.cc b/src/writer/spirv/builder_type_test.cc
index aef87ed..51211a4 100644
--- a/src/writer/spirv/builder_type_test.cc
+++ b/src/writer/spirv/builder_type_test.cc
@@ -133,7 +133,7 @@
   ast::type::I32Type i32;
 
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(16u));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(16u, Source{}));
 
   ast::type::ArrayType ary(&i32, 4);
   ary.set_decorations(std::move(decos));
@@ -362,7 +362,8 @@
       std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
 
   ast::StructDecorationList struct_decos;
-  struct_decos.push_back(std::make_unique<ast::StructBlockDecoration>());
+  struct_decos.push_back(
+      std::make_unique<ast::StructBlockDecoration>(Source{}));
 
   auto s = std::make_unique<ast::Struct>(std::move(struct_decos),
                                          std::move(members));
@@ -388,9 +389,11 @@
   ast::type::F32Type f32;
 
   ast::StructMemberDecorationList a_decos;
-  a_decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   ast::StructMemberDecorationList b_decos;
-  b_decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(8));
+  b_decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(8, Source{}));
 
   ast::StructMemberList members;
   members.push_back(
@@ -471,11 +474,14 @@
   ast::type::MatrixType glsl_mat4x4(&f32, 4, 4);
 
   ast::StructMemberDecorationList a_decos;
-  a_decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   ast::StructMemberDecorationList b_decos;
-  b_decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  b_decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   ast::StructMemberDecorationList c_decos;
-  c_decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(48));
+  c_decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(48, Source{}));
 
   ast::StructMemberList members;
   members.push_back(std::make_unique<ast::StructMember>("a", &glsl_mat2x2,
@@ -537,11 +543,14 @@
   ast::type::ArrayType rtarr_mat4x4(&glsl_mat4x4);  // Runtime array
 
   ast::StructMemberDecorationList a_decos;
-  a_decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(0));
+  a_decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(0, Source{}));
   ast::StructMemberDecorationList b_decos;
-  b_decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(16));
+  b_decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(16, Source{}));
   ast::StructMemberDecorationList c_decos;
-  c_decos.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(48));
+  c_decos.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(48, Source{}));
 
   ast::StructMemberList members;
   members.push_back(std::make_unique<ast::StructMember>("a", &glsl_mat2x2,
diff --git a/src/writer/wgsl/generator_impl_alias_type_test.cc b/src/writer/wgsl/generator_impl_alias_type_test.cc
index c16d043..0c5e507 100644
--- a/src/writer/wgsl/generator_impl_alias_type_test.cc
+++ b/src/writer/wgsl/generator_impl_alias_type_test.cc
@@ -48,7 +48,8 @@
       "a", &f32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &i32, std::move(b_deco)));
 
@@ -79,7 +80,8 @@
       "a", &f32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &i32, std::move(b_deco)));
 
diff --git a/src/writer/wgsl/generator_impl_function_test.cc b/src/writer/wgsl/generator_impl_function_test.cc
index 95ad844..92f4b626 100644
--- a/src/writer/wgsl/generator_impl_function_test.cc
+++ b/src/writer/wgsl/generator_impl_function_test.cc
@@ -87,7 +87,8 @@
 
   ast::type::VoidType void_type;
   ast::Function func("my_func", {}, &void_type);
-  func.add_decoration(std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u));
+  func.add_decoration(
+      std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
   func.set_body(std::move(body));
 
   GeneratorImpl g;
@@ -109,8 +110,8 @@
 
   ast::type::VoidType void_type;
   ast::Function func("my_func", {}, &void_type);
-  func.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
+  func.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   func.set_body(std::move(body));
 
   GeneratorImpl g;
@@ -132,9 +133,10 @@
 
   ast::type::VoidType void_type;
   ast::Function func("my_func", {}, &void_type);
+  func.add_decoration(std::make_unique<ast::StageDecoration>(
+      ast::PipelineStage::kFragment, Source{}));
   func.add_decoration(
-      std::make_unique<ast::StageDecoration>(ast::PipelineStage::kFragment));
-  func.add_decoration(std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u));
+      std::make_unique<ast::WorkgroupDecoration>(2u, 4u, 6u, Source{}));
   func.set_body(std::move(body));
 
   GeneratorImpl g;
diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc
index 2fc6542..706f332 100644
--- a/src/writer/wgsl/generator_impl_type_test.cc
+++ b/src/writer/wgsl/generator_impl_type_test.cc
@@ -65,7 +65,7 @@
 TEST_F(WgslGeneratorImplTest, EmitType_Array_Decoration) {
   ast::type::BoolType b;
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(16u));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(16u, Source{}));
 
   ast::type::ArrayType a(&b, 4);
   a.set_decorations(std::move(decos));
@@ -78,8 +78,8 @@
 TEST_F(WgslGeneratorImplTest, EmitType_Array_MultipleDecorations) {
   ast::type::BoolType b;
   ast::ArrayDecorationList decos;
-  decos.push_back(std::make_unique<ast::StrideDecoration>(16u));
-  decos.push_back(std::make_unique<ast::StrideDecoration>(32u));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(16u, Source{}));
+  decos.push_back(std::make_unique<ast::StrideDecoration>(32u, Source{}));
 
   ast::type::ArrayType a(&b, 4);
   a.set_decorations(std::move(decos));
@@ -149,7 +149,8 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -172,7 +173,8 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
@@ -200,12 +202,13 @@
       "a", &i32, ast::StructMemberDecorationList{}));
 
   ast::StructMemberDecorationList b_deco;
-  b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4));
+  b_deco.push_back(
+      std::make_unique<ast::StructMemberOffsetDecoration>(4, Source{}));
   members.push_back(
       std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
 
   ast::StructDecorationList decos;
-  decos.push_back(std::make_unique<ast::StructBlockDecoration>());
+  decos.push_back(std::make_unique<ast::StructBlockDecoration>(Source{}));
 
   auto str =
       std::make_unique<ast::Struct>(std::move(decos), std::move(members));
diff --git a/src/writer/wgsl/generator_impl_variable_test.cc b/src/writer/wgsl/generator_impl_variable_test.cc
index 1b72849..053f640 100644
--- a/src/writer/wgsl/generator_impl_variable_test.cc
+++ b/src/writer/wgsl/generator_impl_variable_test.cc
@@ -56,7 +56,7 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(std::make_unique<ast::LocationDecoration>(2));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(2, Source{}));
 
   ast::DecoratedVariable dv;
   dv.set_name("a");
@@ -73,12 +73,12 @@
   ast::type::F32Type f32;
 
   ast::VariableDecorationList decos;
-  decos.push_back(
-      std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kPosition));
-  decos.push_back(std::make_unique<ast::BindingDecoration>(0));
-  decos.push_back(std::make_unique<ast::SetDecoration>(1));
-  decos.push_back(std::make_unique<ast::LocationDecoration>(2));
-  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(42));
+  decos.push_back(std::make_unique<ast::BuiltinDecoration>(
+      ast::Builtin::kPosition, Source{}));
+  decos.push_back(std::make_unique<ast::BindingDecoration>(0, Source{}));
+  decos.push_back(std::make_unique<ast::SetDecoration>(1, Source{}));
+  decos.push_back(std::make_unique<ast::LocationDecoration>(2, Source{}));
+  decos.push_back(std::make_unique<ast::ConstantIdDecoration>(42, Source{}));
 
   ast::DecoratedVariable dv;
   dv.set_name("a");