Selaa lähdekoodia

Distinguish between template constants and symbolic constants. (#3595)

This is accomplished by tracking an extra bit on the ID we store in the
constant values table, and propagating that from subexpressions to the
enclosing expression. This extra bit is not yet computed correctly for
types; that will be addressed in later PRs.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Richard Smith 2 vuotta sitten
vanhempi
sitoutus
a3154356f0
100 muutettua tiedostoa jossa 1304 lisäystä ja 1272 poistoa
  1. 28 10
      toolchain/check/context.cpp
  2. 1 1
      toolchain/check/context.h
  3. 47 36
      toolchain/check/eval.cpp
  4. 2 2
      toolchain/check/eval.h
  5. 4 3
      toolchain/check/handle_call_expr.cpp
  6. 8 6
      toolchain/check/handle_name.cpp
  7. 14 14
      toolchain/check/testdata/array/array_in_place.carbon
  8. 15 15
      toolchain/check/testdata/array/assign_return_value.carbon
  9. 15 15
      toolchain/check/testdata/array/assign_var.carbon
  10. 26 26
      toolchain/check/testdata/array/base.carbon
  11. 4 4
      toolchain/check/testdata/array/fail_bound_overflow.carbon
  12. 11 11
      toolchain/check/testdata/array/fail_incomplete_element.carbon
  13. 7 7
      toolchain/check/testdata/array/fail_invalid_type.carbon
  14. 12 12
      toolchain/check/testdata/array/fail_out_of_bound.carbon
  15. 37 37
      toolchain/check/testdata/array/fail_type_mismatch.carbon
  16. 15 15
      toolchain/check/testdata/array/function_param.carbon
  17. 24 24
      toolchain/check/testdata/array/nine_elements.carbon
  18. 3 3
      toolchain/check/testdata/as/as_type.carbon
  19. 3 3
      toolchain/check/testdata/as/basic.carbon
  20. 7 7
      toolchain/check/testdata/as/fail_no_conversion.carbon
  21. 4 4
      toolchain/check/testdata/as/fail_not_type.carbon
  22. 16 16
      toolchain/check/testdata/as/identity.carbon
  23. 27 27
      toolchain/check/testdata/as/tuple.carbon
  24. 7 7
      toolchain/check/testdata/basics/builtin_types.carbon
  25. 3 3
      toolchain/check/testdata/basics/fail_bad_run.carbon
  26. 1 1
      toolchain/check/testdata/basics/fail_bad_run_2.carbon
  27. 1 1
      toolchain/check/testdata/basics/fail_name_lookup.carbon
  28. 2 2
      toolchain/check/testdata/basics/fail_non_type_as_type.carbon
  29. 2 2
      toolchain/check/testdata/basics/multifile.carbon
  30. 4 4
      toolchain/check/testdata/basics/multifile_raw_and_textual_ir.carbon
  31. 2 2
      toolchain/check/testdata/basics/multifile_raw_ir.carbon
  32. 37 37
      toolchain/check/testdata/basics/numeric_literals.carbon
  33. 4 4
      toolchain/check/testdata/basics/parens.carbon
  34. 17 17
      toolchain/check/testdata/basics/raw_and_textual_ir.carbon
  35. 3 3
      toolchain/check/testdata/basics/raw_identifier.carbon
  36. 9 9
      toolchain/check/testdata/basics/raw_ir.carbon
  37. 1 1
      toolchain/check/testdata/basics/run.carbon
  38. 3 3
      toolchain/check/testdata/basics/run_i32.carbon
  39. 8 8
      toolchain/check/testdata/basics/textual_ir.carbon
  40. 27 27
      toolchain/check/testdata/class/base.carbon
  41. 27 27
      toolchain/check/testdata/class/base_field.carbon
  42. 15 15
      toolchain/check/testdata/class/base_function_unqualified.carbon
  43. 19 19
      toolchain/check/testdata/class/base_method.carbon
  44. 26 26
      toolchain/check/testdata/class/base_method_shadow.carbon
  45. 13 13
      toolchain/check/testdata/class/basic.carbon
  46. 46 46
      toolchain/check/testdata/class/derived_to_base.carbon
  47. 27 27
      toolchain/check/testdata/class/fail_abstract.carbon
  48. 4 4
      toolchain/check/testdata/class/fail_addr_not_self.carbon
  49. 7 7
      toolchain/check/testdata/class/fail_addr_self.carbon
  50. 61 61
      toolchain/check/testdata/class/fail_base_bad_type.carbon
  51. 14 14
      toolchain/check/testdata/class/fail_base_method_define.carbon
  52. 1 1
      toolchain/check/testdata/class/fail_base_misplaced.carbon
  53. 21 21
      toolchain/check/testdata/class/fail_base_modifiers.carbon
  54. 9 9
      toolchain/check/testdata/class/fail_base_no_extend.carbon
  55. 16 16
      toolchain/check/testdata/class/fail_base_repeated.carbon
  56. 12 12
      toolchain/check/testdata/class/fail_base_unbound.carbon
  57. 24 24
      toolchain/check/testdata/class/fail_derived_to_base.carbon
  58. 12 12
      toolchain/check/testdata/class/fail_field_modifiers.carbon
  59. 19 19
      toolchain/check/testdata/class/fail_incomplete.carbon
  60. 28 28
      toolchain/check/testdata/class/fail_init.carbon
  61. 19 19
      toolchain/check/testdata/class/fail_init_as_inplace.carbon
  62. 14 14
      toolchain/check/testdata/class/fail_memaccess_category.carbon
  63. 5 5
      toolchain/check/testdata/class/fail_member_of_let.carbon
  64. 14 14
      toolchain/check/testdata/class/fail_method.carbon
  65. 9 9
      toolchain/check/testdata/class/fail_method_modifiers.carbon
  66. 7 7
      toolchain/check/testdata/class/fail_modifiers.carbon
  67. 3 3
      toolchain/check/testdata/class/fail_out_of_line_decl.carbon
  68. 8 8
      toolchain/check/testdata/class/fail_redeclaration_introducer.carbon
  69. 8 8
      toolchain/check/testdata/class/fail_redeclaration_scope.carbon
  70. 7 7
      toolchain/check/testdata/class/fail_redefinition.carbon
  71. 7 7
      toolchain/check/testdata/class/fail_reorder.carbon
  72. 6 6
      toolchain/check/testdata/class/fail_scope.carbon
  73. 12 12
      toolchain/check/testdata/class/fail_self.carbon
  74. 18 18
      toolchain/check/testdata/class/fail_todo_modifiers.carbon
  75. 10 10
      toolchain/check/testdata/class/fail_unbound_field.carbon
  76. 7 7
      toolchain/check/testdata/class/fail_unknown_member.carbon
  77. 15 15
      toolchain/check/testdata/class/field_access.carbon
  78. 16 16
      toolchain/check/testdata/class/field_access_in_value.carbon
  79. 2 2
      toolchain/check/testdata/class/forward_declared.carbon
  80. 14 14
      toolchain/check/testdata/class/init.carbon
  81. 15 15
      toolchain/check/testdata/class/init_as.carbon
  82. 26 26
      toolchain/check/testdata/class/init_nested.carbon
  83. 23 23
      toolchain/check/testdata/class/method.carbon
  84. 37 37
      toolchain/check/testdata/class/nested.carbon
  85. 13 13
      toolchain/check/testdata/class/nested_name.carbon
  86. 13 13
      toolchain/check/testdata/class/raw_self.carbon
  87. 7 7
      toolchain/check/testdata/class/raw_self_type.carbon
  88. 4 4
      toolchain/check/testdata/class/redeclaration.carbon
  89. 4 4
      toolchain/check/testdata/class/redeclaration_introducer.carbon
  90. 6 6
      toolchain/check/testdata/class/reenter_scope.carbon
  91. 14 14
      toolchain/check/testdata/class/scope.carbon
  92. 10 10
      toolchain/check/testdata/class/self.carbon
  93. 21 21
      toolchain/check/testdata/class/self_conversion.carbon
  94. 10 10
      toolchain/check/testdata/class/self_type.carbon
  95. 8 8
      toolchain/check/testdata/class/static_method.carbon
  96. 1 1
      toolchain/check/testdata/const/collapse.carbon
  97. 1 1
      toolchain/check/testdata/const/fail_collapse.carbon
  98. 13 13
      toolchain/check/testdata/expr_category/in_place_tuple_init.carbon
  99. 8 8
      toolchain/check/testdata/function/call/empty_struct.carbon
  100. 7 7
      toolchain/check/testdata/function/call/empty_tuple.carbon

+ 28 - 10
toolchain/check/context.cpp

@@ -66,8 +66,8 @@ auto Context::AddInst(SemIR::Inst inst) -> SemIR::InstId {
   CARBON_VLOG() << "AddInst: " << inst << "\n";
 
   auto const_id = TryEvalInst(*this, inst_id, inst);
-  if (const_id.is_valid()) {
-    CARBON_VLOG() << "Constant: " << inst << " -> " << insts().Get(const_id)
+  if (const_id.is_constant()) {
+    CARBON_VLOG() << "Constant: " << inst << " -> " << const_id.inst_id()
                   << "\n";
     constant_values().Set(inst_id, const_id);
   }
@@ -75,13 +75,18 @@ auto Context::AddInst(SemIR::Inst inst) -> SemIR::InstId {
   return inst_id;
 }
 
-auto Context::AddConstantInst(SemIR::Inst inst) -> SemIR::InstId {
+auto Context::AddConstant(SemIR::Inst inst, bool is_symbolic)
+    -> SemIR::ConstantId {
   // TODO: Deduplicate constants.
   auto inst_id = insts().AddInNoBlock(inst);
   constants().Add(inst_id);
-  constant_values().Set(inst_id, inst_id);
+
+  auto const_id = is_symbolic ? SemIR::ConstantId::ForSymbolicConstant(inst_id)
+                              : SemIR::ConstantId::ForTemplateConstant(inst_id);
+  constant_values().Set(inst_id, const_id);
+
   CARBON_VLOG() << "AddConstantInst: " << inst << "\n";
-  return inst_id;
+  return const_id;
 }
 
 auto Context::AddInstAndPush(Parse::NodeId parse_node, SemIR::Inst inst)
@@ -203,7 +208,8 @@ auto Context::ResolveIfLazyImportRef(SemIR::InstId inst_id) -> void {
                                Parse::NodeId::Invalid,
                                GetBuiltinType(SemIR::BuiltinKind::FunctionType),
                                function_id});
-      constant_values().Set(inst_id, inst_id);
+      constant_values().Set(inst_id,
+                            SemIR::ConstantId::ForTemplateConstant(inst_id));
       break;
     }
 
@@ -843,7 +849,13 @@ class TypeCompleter {
       if (field_value_rep.type_id != field.field_type_id) {
         same_as_object_rep = false;
         field.field_type_id = field_value_rep.type_id;
-        field_id = context_.AddConstantInst(field);
+        // TODO: Use `TryEvalInst` to form this value.
+        field_id = context_
+                       .AddConstant(field, context_.constant_values()
+                                               .Get(context_.types().GetInstId(
+                                                   field.field_type_id))
+                                               .is_symbolic())
+                       .inst_id();
       }
       value_rep_fields.push_back(field_id);
     }
@@ -1147,7 +1159,10 @@ auto Context::CanonicalizeTypeAndAddInstIfNew(SemIR::Inst inst)
   auto profile_node = [&](llvm::FoldingSetNodeID& canonical_id) {
     return ProfileType(*this, inst, canonical_id);
   };
-  auto make_inst = [&] { return AddConstantInst(inst); };
+  auto make_inst = [&] {
+    // TODO: Properly determine whether types are symbolic.
+    return AddConstant(inst, /*is_symbolic=*/false).inst_id();
+  };
   return CanonicalizeTypeImpl(inst.kind(), profile_node, make_inst);
 }
 
@@ -1186,8 +1201,11 @@ auto Context::CanonicalizeTupleType(Parse::NodeId parse_node,
     return true;
   };
   auto make_tuple_inst = [&] {
-    return AddConstantInst(SemIR::TupleType{parse_node, SemIR::TypeId::TypeType,
-                                            type_blocks().Add(type_ids)});
+    // TODO: Properly determine when types are symbolic.
+    return AddConstant(SemIR::TupleType{parse_node, SemIR::TypeId::TypeType,
+                                        type_blocks().Add(type_ids)},
+                       /*is_symbolic=*/false)
+        .inst_id();
   };
   return CanonicalizeTypeImpl(SemIR::TupleType::Kind, profile_tuple,
                               make_tuple_inst);

+ 1 - 1
toolchain/check/context.h

@@ -60,7 +60,7 @@ class Context {
   auto AddInst(SemIR::Inst inst) -> SemIR::InstId;
 
   // Adds an instruction to the constants block, returning the produced ID.
-  auto AddConstantInst(SemIR::Inst inst) -> SemIR::InstId;
+  auto AddConstant(SemIR::Inst inst, bool is_symbolic) -> SemIR::ConstantId;
 
   // Pushes a parse tree node onto the stack, storing the SemIR::Inst as the
   // result.

+ 47 - 36
toolchain/check/eval.cpp

@@ -13,19 +13,21 @@ namespace Carbon::Check {
 // Overloads are provided for different kinds of ID.
 
 // If the given instruction is constant, returns its constant value.
-static auto GetConstantValue(Context& context, SemIR::InstId inst_id)
-    -> SemIR::InstId {
-  return context.constant_values().Get(inst_id);
+static auto GetConstantValue(Context& context, SemIR::InstId inst_id,
+                             bool* is_symbolic) -> SemIR::InstId {
+  auto const_id = context.constant_values().Get(inst_id);
+  *is_symbolic |= const_id.is_symbolic();
+  return const_id.inst_id();
 }
 
 // If the given instruction block contains only constants, returns a
 // corresponding block of those values.
-static auto GetConstantValue(Context& context, SemIR::InstBlockId inst_block_id)
-    -> SemIR::InstBlockId {
+static auto GetConstantValue(Context& context, SemIR::InstBlockId inst_block_id,
+                             bool* is_symbolic) -> SemIR::InstBlockId {
   auto insts = context.inst_blocks().Get(inst_block_id);
   llvm::SmallVector<SemIR::InstId> const_insts;
   for (auto inst_id : insts) {
-    auto const_inst_id = GetConstantValue(context, inst_id);
+    auto const_inst_id = GetConstantValue(context, inst_id, is_symbolic);
     if (!const_inst_id.is_valid()) {
       return SemIR::InstBlockId::Invalid;
     }
@@ -49,8 +51,9 @@ static auto GetConstantValue(Context& context, SemIR::InstBlockId inst_block_id)
 // has runtime phase.
 template <typename InstT, typename FieldIdT>
 static auto ReplaceFieldWithConstantValue(Context& context, InstT* inst,
-                                          FieldIdT InstT::*field) -> bool {
-  auto unwrapped = GetConstantValue(context, inst->*field);
+                                          FieldIdT InstT::*field,
+                                          bool* is_symbolic) -> bool {
+  auto unwrapped = GetConstantValue(context, inst->*field, is_symbolic);
   if (!unwrapped.is_valid()) {
     return false;
   }
@@ -64,19 +67,21 @@ static auto ReplaceFieldWithConstantValue(Context& context, InstT* inst,
 template <typename InstT, typename... EachFieldIdT>
 static auto RebuildIfFieldsAreConstant(Context& context, SemIR::Inst inst,
                                        EachFieldIdT InstT::*... each_field_id)
-    -> SemIR::InstId {
+    -> SemIR::ConstantId {
   // Build a constant instruction by replacing each non-constant operand with
   // its constant value.
   auto typed_inst = inst.As<InstT>();
-  if ((ReplaceFieldWithConstantValue(context, &typed_inst, each_field_id) &&
+  bool is_symbolic = false;
+  if ((ReplaceFieldWithConstantValue(context, &typed_inst, each_field_id,
+                                     &is_symbolic) &&
        ...)) {
-    return context.AddConstantInst(typed_inst);
+    return context.AddConstant(typed_inst, is_symbolic);
   }
-  return SemIR::InstId::Invalid;
+  return SemIR::ConstantId::NotConstant;
 }
 
 auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
-    -> SemIR::InstId {
+    -> SemIR::ConstantId {
   // TODO: Ensure we have test coverage for each of these cases that can result
   // in a constant, once those situations are all reachable.
 
@@ -110,22 +115,24 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
     case SemIR::ConstType::Kind:
     case SemIR::PointerType::Kind:
     case SemIR::StructType::Kind:
+    case SemIR::StructTypeField::Kind:
     case SemIR::TupleType::Kind:
     case SemIR::UnboundElementType::Kind:
-      return inst_id;
+      // TODO: Propagate symbolic / template nature from operands.
+      return SemIR::ConstantId::ForTemplateConstant(inst_id);
 
     case SemIR::BaseDecl::Kind:
     case SemIR::FieldDecl::Kind:
     case SemIR::FunctionDecl::Kind:
       // TODO: Consider adding a corresponding `Value` inst.
-      return inst_id;
+      return SemIR::ConstantId::ForTemplateConstant(inst_id);
 
     case SemIR::BoolLiteral::Kind:
     case SemIR::IntLiteral::Kind:
     case SemIR::RealLiteral::Kind:
     case SemIR::StringLiteral::Kind:
       // Promote literals to the constant block.
-      return context.AddConstantInst(inst);
+      return context.AddConstant(inst, /*is_symbolic=*/false);
 
     // TODO: These need special handling.
     case SemIR::ArrayIndex::Kind:
@@ -148,33 +155,38 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
     case SemIR::ValueOfInitializer::Kind:
       break;
 
-    case SemIR::BindName::Kind:
     case SemIR::BindSymbolicName::Kind:
-      // TODO: Should we really be looking through runtime and symbolic `let`
-      // bindings?
-      return GetConstantValue(context, inst.As<SemIR::AnyBindName>().value_id);
+      // TODO: Consider forming a constant value here using a de Bruijn index or
+      // similar, so that corresponding symbolic parameters in redeclarations
+      // are treated as the same value.
+      return SemIR::ConstantId::ForSymbolicConstant(inst_id);
+
+    case SemIR::BindName::Kind:
+      // TODO: We need to look through `BindName`s for member accesses naming
+      // fields, where the member name is a `BindName`. Should we really be
+      // creating a `BindName` in that case?
+      return context.constant_values().Get(inst.As<SemIR::BindName>().value_id);
 
     case SemIR::NameRef::Kind:
-      return GetConstantValue(context, inst.As<SemIR::NameRef>().value_id);
+      return context.constant_values().Get(inst.As<SemIR::NameRef>().value_id);
 
     case SemIR::Converted::Kind:
-      return GetConstantValue(context, inst.As<SemIR::Converted>().result_id);
+      return context.constant_values().Get(
+          inst.As<SemIR::Converted>().result_id);
 
     case SemIR::UnaryOperatorNot::Kind: {
-      auto const_id = GetConstantValue(
-          context, inst.As<SemIR::UnaryOperatorNot>().operand_id);
-      if (!const_id.is_valid()) {
+      auto const_id = context.constant_values().Get(
+          inst.As<SemIR::UnaryOperatorNot>().operand_id);
+      if (!const_id.is_template()) {
         break;
       }
-      auto value = context.insts().TryGetAs<SemIR::BoolLiteral>(const_id);
-      if (!value) {
-        // TODO: Can we CHECK this instead?
-        break;
-      }
-      value->value =
-          (value->value == SemIR::BoolValue::False ? SemIR::BoolValue::True
-                                                   : SemIR::BoolValue::False);
-      return context.AddConstantInst(*value);
+      // A template constant of bool type is always a bool literal.
+      auto value =
+          context.insts().GetAs<SemIR::BoolLiteral>(const_id.inst_id());
+      value.value =
+          (value.value == SemIR::BoolValue::False ? SemIR::BoolValue::True
+                                                  : SemIR::BoolValue::False);
+      return context.AddConstant(value, /*is_symbolic=*/false);
     }
 
     // These cases are either not expressions or not constant.
@@ -193,12 +205,11 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
     case SemIR::ReturnExpr::Kind:
     case SemIR::Return::Kind:
     case SemIR::StructLiteral::Kind:
-    case SemIR::StructTypeField::Kind:
     case SemIR::TupleLiteral::Kind:
     case SemIR::VarStorage::Kind:
       break;
   }
-  return SemIR::InstId::Invalid;
+  return SemIR::ConstantId::NotConstant;
 }
 
 }  // namespace Carbon::Check

+ 2 - 2
toolchain/check/eval.h

@@ -13,11 +13,11 @@ namespace Carbon::Check {
 
 // Determines the phase of the instruction `inst`, and returns its constant
 // value if it has constant phase. If it has runtime phase, returns
-// `SemIR::InstId::Invalid`.
+// `SemIR::ConstantId::NotConstant`.
 //
 // TODO: Support symbolic phase.
 auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
-    -> SemIR::InstId;
+    -> SemIR::ConstantId;
 
 }  // namespace Carbon::Check
 

+ 4 - 3
toolchain/check/handle_call_expr.cpp

@@ -57,11 +57,12 @@ auto HandleCallExpr(Context& context, Parse::CallExprId parse_node) -> bool {
 
   // Identify the function we're calling.
   auto function_decl_id = context.constant_values().Get(function_callee_id);
-  if (!function_decl_id.is_valid()) {
+  if (!function_decl_id.is_constant()) {
     return diagnose_not_callable();
   }
-  auto function_decl =
-      context.insts().Get(function_decl_id).TryAs<SemIR::FunctionDecl>();
+  auto function_decl = context.insts()
+                           .Get(function_decl_id.inst_id())
+                           .TryAs<SemIR::FunctionDecl>();
   if (!function_decl) {
     return diagnose_not_callable();
   }

+ 8 - 6
toolchain/check/handle_name.cpp

@@ -155,10 +155,10 @@ auto HandleMemberAccessExpr(Context& context,
         // Find the specified element, which could be either a field or a base
         // class, and build an element access expression.
         auto element_id = context.constant_values().Get(member_id);
-        CARBON_CHECK(element_id.is_valid())
+        CARBON_CHECK(element_id.is_constant())
             << "Non-constant value " << context.insts().Get(member_id)
             << " of unbound element type";
-        auto index = GetClassElementIndex(context, element_id);
+        auto index = GetClassElementIndex(context, element_id.inst_id());
         auto access_id = context.AddInst(SemIR::ClassElementAccess{
             parse_node, unbound_element_type->element_type_id, base_id, index});
         if (SemIR::GetExprCategory(context.sem_ir(), base_id) ==
@@ -179,13 +179,15 @@ auto HandleMemberAccessExpr(Context& context,
           context.GetBuiltinType(SemIR::BuiltinKind::FunctionType)) {
         // Find the named function and check whether it's an instance method.
         auto function_name_id = context.constant_values().Get(member_id);
-        CARBON_CHECK(function_name_id.is_valid())
+        CARBON_CHECK(function_name_id.is_constant())
             << "Non-constant value " << context.insts().Get(member_id)
             << " of function type";
-        auto function_decl =
-            context.insts().Get(function_name_id).TryAs<SemIR::FunctionDecl>();
+        auto function_decl = context.insts()
+                                 .Get(function_name_id.inst_id())
+                                 .TryAs<SemIR::FunctionDecl>();
         CARBON_CHECK(function_decl)
-            << "Unexpected value " << context.insts().Get(function_name_id)
+            << "Unexpected value "
+            << context.insts().Get(function_name_id.inst_id())
             << " of function type";
         if (IsInstanceMethod(context.sem_ir(), function_decl->function_id)) {
           context.AddInstAndPush(

+ 14 - 14
toolchain/check/testdata/array/array_in_place.carbon

@@ -13,19 +13,19 @@ fn G() {
 // CHECK:STDOUT: --- array_in_place.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_25.1: type = tuple_type (type, type, type), const
-// CHECK:STDOUT:   %.loc7_25.2: type = tuple_type (i32, i32, i32), const
-// CHECK:STDOUT:   %.loc7_25.3: type = ptr_type (i32, i32, i32), const
-// CHECK:STDOUT:   %.loc10_28: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc10_29.1: type = array_type %.loc10_28, (i32, i32, i32), const
-// CHECK:STDOUT:   %.loc10_29.2: type = ptr_type [(i32, i32, i32); 2], const
-// CHECK:STDOUT:   %.loc10_42: type = tuple_type ((i32, i32, i32), (i32, i32, i32)), const
+// CHECK:STDOUT:   %.loc7_25.1: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.loc7_25.2: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.loc7_25.3: type = ptr_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.loc10_28: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc10_29.1: type = array_type %.loc10_28, (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.loc10_29.2: type = ptr_type [(i32, i32, i32); 2] [template]
+// CHECK:STDOUT:   %.loc10_42: type = tuple_type ((i32, i32, i32), (i32, i32, i32)) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.F = %F, .G = %G}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> %return: (i32, i32, i32);
@@ -33,18 +33,18 @@ fn G() {
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc10_25: (type, type, type) = tuple_literal (i32, i32, i32)
-// CHECK:STDOUT:   %.loc10_28: i32 = int_literal 2, const = constants.%.loc10_28
-// CHECK:STDOUT:   %.loc7: type = converted %.loc10_25, constants.%.loc7_25.2, const = constants.%.loc7_25.2
-// CHECK:STDOUT:   %.loc10_29: type = array_type %.loc10_28, (i32, i32, i32), const = constants.%.loc10_29.1
+// CHECK:STDOUT:   %.loc10_28: i32 = int_literal 2 [template = constants.%.loc10_28]
+// CHECK:STDOUT:   %.loc7: type = converted %.loc10_25, constants.%.loc7_25.2 [template = constants.%.loc7_25.2]
+// CHECK:STDOUT:   %.loc10_29: type = array_type %.loc10_28, (i32, i32, i32) [template = constants.%.loc10_29.1]
 // CHECK:STDOUT:   %v.var: ref [(i32, i32, i32); 2] = var v
 // CHECK:STDOUT:   %v: ref [(i32, i32, i32); 2] = bind_name v, %v.var
-// CHECK:STDOUT:   %F.ref.loc10_34: <function> = name_ref F, file.%F, const = file.%F
+// CHECK:STDOUT:   %F.ref.loc10_34: <function> = name_ref F, file.%F [template = file.%F]
 // CHECK:STDOUT:   %.loc10_42.3: ref (i32, i32, i32) = splice_block %.loc10_42.2 {
 // CHECK:STDOUT:     %.loc10_42.1: i32 = int_literal 0
 // CHECK:STDOUT:     %.loc10_42.2: ref (i32, i32, i32) = array_index %v.var, %.loc10_42.1
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %.loc10_35: init (i32, i32, i32) = call %F.ref.loc10_34() to %.loc10_42.3
-// CHECK:STDOUT:   %F.ref.loc10_39: <function> = name_ref F, file.%F, const = file.%F
+// CHECK:STDOUT:   %F.ref.loc10_39: <function> = name_ref F, file.%F [template = file.%F]
 // CHECK:STDOUT:   %.loc10_42.6: ref (i32, i32, i32) = splice_block %.loc10_42.5 {
 // CHECK:STDOUT:     %.loc10_42.4: i32 = int_literal 1
 // CHECK:STDOUT:     %.loc10_42.5: ref (i32, i32, i32) = array_index %v.var, %.loc10_42.4

+ 15 - 15
toolchain/check/testdata/array/assign_return_value.carbon

@@ -13,37 +13,37 @@ fn Run() {
 // CHECK:STDOUT: --- assign_return_value.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_16.1: type = tuple_type (type), const
-// CHECK:STDOUT:   %.loc7_16.2: type = tuple_type (i32), const
-// CHECK:STDOUT:   %.loc7_28: i32 = int_literal 0, const
-// CHECK:STDOUT:   %.loc7_30: (i32,) = tuple_value (%.loc7_28), const
-// CHECK:STDOUT:   %.loc10_16: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc10_17.1: type = array_type %.loc10_16, i32, const
-// CHECK:STDOUT:   %.loc10_17.2: type = ptr_type [i32; 1], const
+// CHECK:STDOUT:   %.loc7_16.1: type = tuple_type (type) [template]
+// CHECK:STDOUT:   %.loc7_16.2: type = tuple_type (i32) [template]
+// CHECK:STDOUT:   %.loc7_28: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.loc7_30: (i32,) = tuple_value (%.loc7_28) [template]
+// CHECK:STDOUT:   %.loc10_16: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc10_17.1: type = array_type %.loc10_16, i32 [template]
+// CHECK:STDOUT:   %.loc10_17.2: type = ptr_type [i32; 1] [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.F = %F, .Run = %Run}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> (i32,) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7_28: i32 = int_literal 0, const = constants.%.loc7_28
+// CHECK:STDOUT:   %.loc7_28: i32 = int_literal 0 [template = constants.%.loc7_28]
 // CHECK:STDOUT:   %.loc7_30.1: (i32,) = tuple_literal (%.loc7_28)
-// CHECK:STDOUT:   %.loc7_30.2: (i32,) = tuple_value (%.loc7_28), const = constants.%.loc7_30
-// CHECK:STDOUT:   %.loc7_30.3: (i32,) = converted %.loc7_30.1, %.loc7_30.2, const = constants.%.loc7_30
+// CHECK:STDOUT:   %.loc7_30.2: (i32,) = tuple_value (%.loc7_28) [template = constants.%.loc7_30]
+// CHECK:STDOUT:   %.loc7_30.3: (i32,) = converted %.loc7_30.1, %.loc7_30.2 [template = constants.%.loc7_30]
 // CHECK:STDOUT:   return %.loc7_30.3
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc10_16: i32 = int_literal 1, const = constants.%.loc10_16
-// CHECK:STDOUT:   %.loc10_17: type = array_type %.loc10_16, i32, const = constants.%.loc10_17.1
+// CHECK:STDOUT:   %.loc10_16: i32 = int_literal 1 [template = constants.%.loc10_16]
+// CHECK:STDOUT:   %.loc10_17: type = array_type %.loc10_16, i32 [template = constants.%.loc10_17.1]
 // CHECK:STDOUT:   %t.var: ref [i32; 1] = var t
 // CHECK:STDOUT:   %t: ref [i32; 1] = bind_name t, %t.var
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%F, const = file.%F
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%F [template = file.%F]
 // CHECK:STDOUT:   %.loc10_22.1: init (i32,) = call %F.ref()
 // CHECK:STDOUT:   %.loc10_22.2: ref (i32,) = temporary_storage
 // CHECK:STDOUT:   %.loc10_22.3: ref (i32,) = temporary %.loc10_22.2, %.loc10_22.1

+ 15 - 15
toolchain/check/testdata/array/assign_var.carbon

@@ -10,26 +10,26 @@ var b: [i32; 3] = a;
 // CHECK:STDOUT: --- assign_var.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_22.1: type = tuple_type (type, type, type), const
-// CHECK:STDOUT:   %.loc7_22.2: type = tuple_type (i32, i32, i32), const
-// CHECK:STDOUT:   %.loc7_22.3: type = ptr_type (i32, i32, i32), const
-// CHECK:STDOUT:   %.loc7_27: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc7_30: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc7_33: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc8_15.1: type = array_type %.loc8_14, i32, const
-// CHECK:STDOUT:   %.loc8_15.2: type = ptr_type [i32; 3], const
+// CHECK:STDOUT:   %.loc7_22.1: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.loc7_22.2: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.loc7_22.3: type = ptr_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.loc7_27: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc7_30: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc7_33: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc8_15.1: type = array_type %.loc8_14, i32 [template]
+// CHECK:STDOUT:   %.loc8_15.2: type = ptr_type [i32; 3] [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.a = %a, .b = %b}
 // CHECK:STDOUT:   %.loc7_22.1: (type, type, type) = tuple_literal (i32, i32, i32)
-// CHECK:STDOUT:   %.loc7_22.2: type = converted %.loc7_22.1, constants.%.loc7_22.2, const = constants.%.loc7_22.2
+// CHECK:STDOUT:   %.loc7_22.2: type = converted %.loc7_22.1, constants.%.loc7_22.2 [template = constants.%.loc7_22.2]
 // CHECK:STDOUT:   %a.var: ref (i32, i32, i32) = var a
 // CHECK:STDOUT:   %a: ref (i32, i32, i32) = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc7_27: i32 = int_literal 1, const = constants.%.loc7_27
-// CHECK:STDOUT:   %.loc7_30: i32 = int_literal 2, const = constants.%.loc7_30
-// CHECK:STDOUT:   %.loc7_33: i32 = int_literal 3, const = constants.%.loc7_33
+// CHECK:STDOUT:   %.loc7_27: i32 = int_literal 1 [template = constants.%.loc7_27]
+// CHECK:STDOUT:   %.loc7_30: i32 = int_literal 2 [template = constants.%.loc7_30]
+// CHECK:STDOUT:   %.loc7_33: i32 = int_literal 3 [template = constants.%.loc7_33]
 // CHECK:STDOUT:   %.loc7_34.1: (i32, i32, i32) = tuple_literal (%.loc7_27, %.loc7_30, %.loc7_33)
 // CHECK:STDOUT:   %.loc7_34.2: ref i32 = tuple_access %a.var, element0
 // CHECK:STDOUT:   %.loc7_34.3: init i32 = initialize_from %.loc7_27 to %.loc7_34.2
@@ -40,8 +40,8 @@ var b: [i32; 3] = a;
 // CHECK:STDOUT:   %.loc7_34.8: init (i32, i32, i32) = tuple_init (%.loc7_34.3, %.loc7_34.5, %.loc7_34.7) to %a.var
 // CHECK:STDOUT:   %.loc7_34.9: init (i32, i32, i32) = converted %.loc7_34.1, %.loc7_34.8
 // CHECK:STDOUT:   assign %a.var, %.loc7_34.9
-// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 3, const = constants.%.loc8_14
-// CHECK:STDOUT:   %.loc8_15: type = array_type %.loc8_14, i32, const = constants.%.loc8_15.1
+// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 3 [template = constants.%.loc8_14]
+// CHECK:STDOUT:   %.loc8_15: type = array_type %.loc8_14, i32 [template = constants.%.loc8_15.1]
 // CHECK:STDOUT:   %b.var: ref [i32; 3] = var b
 // CHECK:STDOUT:   %b: ref [i32; 3] = bind_name b, %b.var
 // CHECK:STDOUT:   %a.ref: ref (i32, i32, i32) = name_ref a, %a

+ 26 - 26
toolchain/check/testdata/array/base.carbon

@@ -11,31 +11,31 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT: --- base.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc7_15.1: type = array_type %.loc7_14, i32, const
-// CHECK:STDOUT:   %.loc7_15.2: type = ptr_type [i32; 1], const
-// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc7_22: type = tuple_type (i32), const
-// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc8_15.1: type = array_type %.loc8_14, f64, const
-// CHECK:STDOUT:   %.loc8_15.2: type = ptr_type [f64; 2], const
-// CHECK:STDOUT:   %.loc8_20: f64 = real_literal 111e-1, const
-// CHECK:STDOUT:   %.loc8_26: f64 = real_literal 22e-1, const
-// CHECK:STDOUT:   %.loc8_30: type = tuple_type (f64, f64), const
-// CHECK:STDOUT:   %.loc9_10: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc9_13: i32 = int_literal 5, const
-// CHECK:STDOUT:   %.loc9_14.1: type = array_type %.loc9_13, (), const
-// CHECK:STDOUT:   %.loc9_14.2: type = ptr_type [(); 5], const
-// CHECK:STDOUT:   %.loc9_38: type = tuple_type ((), (), (), (), ()), const
+// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc7_15.1: type = array_type %.loc7_14, i32 [template]
+// CHECK:STDOUT:   %.loc7_15.2: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc7_22: type = tuple_type (i32) [template]
+// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc8_15.1: type = array_type %.loc8_14, f64 [template]
+// CHECK:STDOUT:   %.loc8_15.2: type = ptr_type [f64; 2] [template]
+// CHECK:STDOUT:   %.loc8_20: f64 = real_literal 111e-1 [template]
+// CHECK:STDOUT:   %.loc8_26: f64 = real_literal 22e-1 [template]
+// CHECK:STDOUT:   %.loc8_30: type = tuple_type (f64, f64) [template]
+// CHECK:STDOUT:   %.loc9_10: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc9_13: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.loc9_14.1: type = array_type %.loc9_13, () [template]
+// CHECK:STDOUT:   %.loc9_14.2: type = ptr_type [(); 5] [template]
+// CHECK:STDOUT:   %.loc9_38: type = tuple_type ((), (), (), (), ()) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.a = %a, .b = %b, .c = %c}
-// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 1, const = constants.%.loc7_14
-// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32, const = constants.%.loc7_15.1
+// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 1 [template = constants.%.loc7_14]
+// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32 [template = constants.%.loc7_15.1]
 // CHECK:STDOUT:   %a.var: ref [i32; 1] = var a
 // CHECK:STDOUT:   %a: ref [i32; 1] = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1, const = constants.%.loc7_20
+// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.loc7_20]
 // CHECK:STDOUT:   %.loc7_22.1: (i32,) = tuple_literal (%.loc7_20)
 // CHECK:STDOUT:   %.loc7_22.2: i32 = int_literal 0
 // CHECK:STDOUT:   %.loc7_22.3: ref i32 = array_index %a.var, %.loc7_22.2
@@ -43,12 +43,12 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT:   %.loc7_22.5: init [i32; 1] = array_init (%.loc7_22.4) to %a.var
 // CHECK:STDOUT:   %.loc7_22.6: init [i32; 1] = converted %.loc7_22.1, %.loc7_22.5
 // CHECK:STDOUT:   assign %a.var, %.loc7_22.6
-// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 2, const = constants.%.loc8_14
-// CHECK:STDOUT:   %.loc8_15: type = array_type %.loc8_14, f64, const = constants.%.loc8_15.1
+// CHECK:STDOUT:   %.loc8_14: i32 = int_literal 2 [template = constants.%.loc8_14]
+// CHECK:STDOUT:   %.loc8_15: type = array_type %.loc8_14, f64 [template = constants.%.loc8_15.1]
 // CHECK:STDOUT:   %b.var: ref [f64; 2] = var b
 // CHECK:STDOUT:   %b: ref [f64; 2] = bind_name b, %b.var
-// CHECK:STDOUT:   %.loc8_20: f64 = real_literal 111e-1, const = constants.%.loc8_20
-// CHECK:STDOUT:   %.loc8_26: f64 = real_literal 22e-1, const = constants.%.loc8_26
+// CHECK:STDOUT:   %.loc8_20: f64 = real_literal 111e-1 [template = constants.%.loc8_20]
+// CHECK:STDOUT:   %.loc8_26: f64 = real_literal 22e-1 [template = constants.%.loc8_26]
 // CHECK:STDOUT:   %.loc8_30.1: (f64, f64) = tuple_literal (%.loc8_20, %.loc8_26)
 // CHECK:STDOUT:   %.loc8_30.2: i32 = int_literal 0
 // CHECK:STDOUT:   %.loc8_30.3: ref f64 = array_index %b.var, %.loc8_30.2
@@ -60,9 +60,9 @@ var c: [(); 5] = ((), (), (), (), (),);
 // CHECK:STDOUT:   %.loc8_30.9: init [f64; 2] = converted %.loc8_30.1, %.loc8_30.8
 // CHECK:STDOUT:   assign %b.var, %.loc8_30.9
 // CHECK:STDOUT:   %.loc9_10.1: () = tuple_literal ()
-// CHECK:STDOUT:   %.loc9_13: i32 = int_literal 5, const = constants.%.loc9_13
-// CHECK:STDOUT:   %.loc9_10.2: type = converted %.loc9_10.1, constants.%.loc9_10, const = constants.%.loc9_10
-// CHECK:STDOUT:   %.loc9_14: type = array_type %.loc9_13, (), const = constants.%.loc9_14.1
+// CHECK:STDOUT:   %.loc9_13: i32 = int_literal 5 [template = constants.%.loc9_13]
+// CHECK:STDOUT:   %.loc9_10.2: type = converted %.loc9_10.1, constants.%.loc9_10 [template = constants.%.loc9_10]
+// CHECK:STDOUT:   %.loc9_14: type = array_type %.loc9_13, () [template = constants.%.loc9_14.1]
 // CHECK:STDOUT:   %c.var: ref [(); 5] = var c
 // CHECK:STDOUT:   %c: ref [(); 5] = bind_name c, %c.var
 // CHECK:STDOUT:   %.loc9_20.1: () = tuple_literal ()

+ 4 - 4
toolchain/check/testdata/array/fail_bound_overflow.carbon

@@ -12,14 +12,14 @@ var a: [1; 39999999999999999993];
 // CHECK:STDOUT: --- fail_bound_overflow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_9: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 39999999999999999993, const
+// CHECK:STDOUT:   %.loc10_9: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 39999999999999999993 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.a = %a}
-// CHECK:STDOUT:   %.loc10_9: i32 = int_literal 1, const = constants.%.loc10_9
-// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 39999999999999999993, const = constants.%.loc10_12
+// CHECK:STDOUT:   %.loc10_9: i32 = int_literal 1 [template = constants.%.loc10_9]
+// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 39999999999999999993 [template = constants.%.loc10_12]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
 // CHECK:STDOUT: }

+ 11 - 11
toolchain/check/testdata/array/fail_incomplete_element.carbon

@@ -22,27 +22,27 @@ var p: Incomplete* = &a[0];
 // CHECK:STDOUT: --- fail_incomplete_element.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc15_21: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc15_22: type = array_type %.loc15_21, Incomplete, const
-// CHECK:STDOUT:   %.loc20_25: i32 = int_literal 0, const
-// CHECK:STDOUT:   %.loc20_22: type = ptr_type <error>, const
+// CHECK:STDOUT:   %.loc15_21: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc15_22: type = array_type %.loc15_21, Incomplete [template]
+// CHECK:STDOUT:   %.loc20_25: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.loc20_22: type = ptr_type <error> [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Incomplete = %Incomplete.decl, .a = %a, .p = %p}
 // CHECK:STDOUT:   %Incomplete.decl = class_decl @Incomplete, ()
-// CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete, const
-// CHECK:STDOUT:   %Incomplete.ref.loc15: type = name_ref Incomplete, %Incomplete, const = %Incomplete
-// CHECK:STDOUT:   %.loc15_21: i32 = int_literal 1, const = constants.%.loc15_21
-// CHECK:STDOUT:   %.loc15_22: type = array_type %.loc15_21, Incomplete, const = constants.%.loc15_22
+// CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete [template]
+// CHECK:STDOUT:   %Incomplete.ref.loc15: type = name_ref Incomplete, %Incomplete [template = %Incomplete]
+// CHECK:STDOUT:   %.loc15_21: i32 = int_literal 1 [template = constants.%.loc15_21]
+// CHECK:STDOUT:   %.loc15_22: type = array_type %.loc15_21, Incomplete [template = constants.%.loc15_22]
 // CHECK:STDOUT:   %a.var: ref <error> = var a
 // CHECK:STDOUT:   %a: ref <error> = bind_name a, %a.var
-// CHECK:STDOUT:   %Incomplete.ref.loc20: type = name_ref Incomplete, %Incomplete, const = %Incomplete
-// CHECK:STDOUT:   %.loc20_18: type = ptr_type Incomplete, const
+// CHECK:STDOUT:   %Incomplete.ref.loc20: type = name_ref Incomplete, %Incomplete [template = %Incomplete]
+// CHECK:STDOUT:   %.loc20_18: type = ptr_type Incomplete [template]
 // CHECK:STDOUT:   %p.var: ref Incomplete* = var p
 // CHECK:STDOUT:   %p: ref Incomplete* = bind_name p, %p.var
 // CHECK:STDOUT:   %a.ref: ref <error> = name_ref a, %a
-// CHECK:STDOUT:   %.loc20_25: i32 = int_literal 0, const = constants.%.loc20_25
+// CHECK:STDOUT:   %.loc20_25: i32 = int_literal 0 [template = constants.%.loc20_25]
 // CHECK:STDOUT:   %.loc20_22: <error>* = addr_of <error>
 // CHECK:STDOUT:   assign %p.var, <error>
 // CHECK:STDOUT: }

+ 7 - 7
toolchain/check/testdata/array/fail_invalid_type.carbon

@@ -12,17 +12,17 @@ var a: [1; 1];
 // CHECK:STDOUT: --- fail_invalid_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_9: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc10_13.1: type = array_type %.loc10_12, <error>, const
-// CHECK:STDOUT:   %.loc10_13.2: type = ptr_type [<error>; 1], const
+// CHECK:STDOUT:   %.loc10_9: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc10_13.1: type = array_type %.loc10_12, <error> [template]
+// CHECK:STDOUT:   %.loc10_13.2: type = ptr_type [<error>; 1] [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.a = %a}
-// CHECK:STDOUT:   %.loc10_9: i32 = int_literal 1, const = constants.%.loc10_9
-// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 1, const = constants.%.loc10_12
-// CHECK:STDOUT:   %.loc10_13: type = array_type %.loc10_12, <error>, const = constants.%.loc10_13.1
+// CHECK:STDOUT:   %.loc10_9: i32 = int_literal 1 [template = constants.%.loc10_9]
+// CHECK:STDOUT:   %.loc10_12: i32 = int_literal 1 [template = constants.%.loc10_12]
+// CHECK:STDOUT:   %.loc10_13: type = array_type %.loc10_12, <error> [template = constants.%.loc10_13.1]
 // CHECK:STDOUT:   %a.var: ref [<error>; 1] = var a
 // CHECK:STDOUT:   %a: ref [<error>; 1] = bind_name a, %a.var
 // CHECK:STDOUT: }

+ 12 - 12
toolchain/check/testdata/array/fail_out_of_bound.carbon

@@ -12,24 +12,24 @@ var a: [i32; 1] = (1, 2, 3);
 // CHECK:STDOUT: --- fail_out_of_bound.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc10_15.1: type = array_type %.loc10_14, i32, const
-// CHECK:STDOUT:   %.loc10_15.2: type = ptr_type [i32; 1], const
-// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc10_23: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc10_27: type = tuple_type (i32, i32, i32), const
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc10_15.1: type = array_type %.loc10_14, i32 [template]
+// CHECK:STDOUT:   %.loc10_15.2: type = ptr_type [i32; 1] [template]
+// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc10_23: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc10_27: type = tuple_type (i32, i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.a = %a}
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1, const = constants.%.loc10_14
-// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, i32, const = constants.%.loc10_15.1
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1 [template = constants.%.loc10_14]
+// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, i32 [template = constants.%.loc10_15.1]
 // CHECK:STDOUT:   %a.var: ref [i32; 1] = var a
 // CHECK:STDOUT:   %a: ref [i32; 1] = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1, const = constants.%.loc10_20
-// CHECK:STDOUT:   %.loc10_23: i32 = int_literal 2, const = constants.%.loc10_23
-// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 3, const = constants.%.loc10_26
+// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1 [template = constants.%.loc10_20]
+// CHECK:STDOUT:   %.loc10_23: i32 = int_literal 2 [template = constants.%.loc10_23]
+// CHECK:STDOUT:   %.loc10_26: i32 = int_literal 3 [template = constants.%.loc10_26]
 // CHECK:STDOUT:   %.loc10_27: (i32, i32, i32) = tuple_literal (%.loc10_20, %.loc10_23, %.loc10_26)
 // CHECK:STDOUT:   assign %a.var, <error>
 // CHECK:STDOUT: }

+ 37 - 37
toolchain/check/testdata/array/fail_type_mismatch.carbon

@@ -29,50 +29,50 @@ var d: [i32; 3] = t2;
 // CHECK:STDOUT: --- fail_type_mismatch.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc10_15.1: type = array_type %.loc10_14, i32, const
-// CHECK:STDOUT:   %.loc10_15.2: type = ptr_type [i32; 3], const
-// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.1: type = ptr_type String, const
-// CHECK:STDOUT:   %.loc10_23: String = string_literal "Hello", const
-// CHECK:STDOUT:   %.loc10_32: String = string_literal "World", const
-// CHECK:STDOUT:   %.loc10_39.1: type = tuple_type (i32, String, String), const
-// CHECK:STDOUT:   %.loc12: type = tuple_type (type, type, type), const
-// CHECK:STDOUT:   %.loc10_39.2: type = tuple_type (i32, String*, String*), const
-// CHECK:STDOUT:   %.loc10_39.3: type = ptr_type (i32, String*, String*), const
-// CHECK:STDOUT:   %.loc16_14: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc16_15: type = array_type %.loc16_14, i32, const
-// CHECK:STDOUT:   %.loc21_14: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc21_15: type = array_type %.loc21_14, i32, const
-// CHECK:STDOUT:   %.loc21_20: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc21_23: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc21_24.1: type = tuple_type (i32, i32), const
-// CHECK:STDOUT:   %.loc23: type = tuple_type (type, type), const
-// CHECK:STDOUT:   %.loc21_24.2: type = ptr_type (i32, i32), const
-// CHECK:STDOUT:   %.loc27_14: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc27_15: type = array_type %.loc27_14, i32, const
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc10_15.1: type = array_type %.loc10_14, i32 [template]
+// CHECK:STDOUT:   %.loc10_15.2: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.1: type = ptr_type String [template]
+// CHECK:STDOUT:   %.loc10_23: String = string_literal "Hello" [template]
+// CHECK:STDOUT:   %.loc10_32: String = string_literal "World" [template]
+// CHECK:STDOUT:   %.loc10_39.1: type = tuple_type (i32, String, String) [template]
+// CHECK:STDOUT:   %.loc12: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.loc10_39.2: type = tuple_type (i32, String*, String*) [template]
+// CHECK:STDOUT:   %.loc10_39.3: type = ptr_type (i32, String*, String*) [template]
+// CHECK:STDOUT:   %.loc16_14: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc16_15: type = array_type %.loc16_14, i32 [template]
+// CHECK:STDOUT:   %.loc21_14: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc21_15: type = array_type %.loc21_14, i32 [template]
+// CHECK:STDOUT:   %.loc21_20: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc21_23: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc21_24.1: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc23: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.loc21_24.2: type = ptr_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc27_14: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc27_15: type = array_type %.loc27_14, i32 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.a = %a, .t1 = %t1, .b = %b, .c = %c, .t2 = %t2, .d = %d}
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 3, const = constants.%.loc10_14
-// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, i32, const = constants.%.loc10_15.1
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 3 [template = constants.%.loc10_14]
+// CHECK:STDOUT:   %.loc10_15: type = array_type %.loc10_14, i32 [template = constants.%.loc10_15.1]
 // CHECK:STDOUT:   %a.var: ref [i32; 3] = var a
 // CHECK:STDOUT:   %a: ref [i32; 3] = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1, const = constants.%.loc10_20
-// CHECK:STDOUT:   %.loc10_23: String = string_literal "Hello", const = constants.%.loc10_23
-// CHECK:STDOUT:   %.loc10_32: String = string_literal "World", const = constants.%.loc10_32
+// CHECK:STDOUT:   %.loc10_20: i32 = int_literal 1 [template = constants.%.loc10_20]
+// CHECK:STDOUT:   %.loc10_23: String = string_literal "Hello" [template = constants.%.loc10_23]
+// CHECK:STDOUT:   %.loc10_32: String = string_literal "World" [template = constants.%.loc10_32]
 // CHECK:STDOUT:   %.loc10_39.1: (i32, String, String) = tuple_literal (%.loc10_20, %.loc10_23, %.loc10_32)
 // CHECK:STDOUT:   %.loc10_39.2: i32 = int_literal 0
 // CHECK:STDOUT:   %.loc10_39.3: ref i32 = array_index %a.var, %.loc10_39.2
 // CHECK:STDOUT:   %.loc10_39.4: init i32 = initialize_from %.loc10_20 to %.loc10_39.3
 // CHECK:STDOUT:   assign %a.var, <error>
 // CHECK:STDOUT:   %.loc12: (type, type, type) = tuple_literal (i32, String, String)
-// CHECK:STDOUT:   %.loc10_39.5: type = converted %.loc12, constants.%.loc10_39.1, const = constants.%.loc10_39.1
+// CHECK:STDOUT:   %.loc10_39.5: type = converted %.loc12, constants.%.loc10_39.1 [template = constants.%.loc10_39.1]
 // CHECK:STDOUT:   %t1.var: ref (i32, String, String) = var t1
 // CHECK:STDOUT:   %t1: ref (i32, String, String) = bind_name t1, %t1.var
-// CHECK:STDOUT:   %.loc16_14: i32 = int_literal 3, const = constants.%.loc16_14
-// CHECK:STDOUT:   %.loc16_15: type = array_type %.loc16_14, i32, const = constants.%.loc16_15
+// CHECK:STDOUT:   %.loc16_14: i32 = int_literal 3 [template = constants.%.loc16_14]
+// CHECK:STDOUT:   %.loc16_15: type = array_type %.loc16_14, i32 [template = constants.%.loc16_15]
 // CHECK:STDOUT:   %b.var: ref [i32; 3] = var b
 // CHECK:STDOUT:   %b: ref [i32; 3] = bind_name b, %b.var
 // CHECK:STDOUT:   %t1.ref: ref (i32, String, String) = name_ref t1, %t1
@@ -83,20 +83,20 @@ var d: [i32; 3] = t2;
 // CHECK:STDOUT:   %.loc16_19.5: init i32 = initialize_from %.loc16_19.2 to %.loc16_19.4
 // CHECK:STDOUT:   %.loc16_19.6: ref String = tuple_access %t1.ref, element1
 // CHECK:STDOUT:   assign %b.var, <error>
-// CHECK:STDOUT:   %.loc21_14: i32 = int_literal 3, const = constants.%.loc21_14
-// CHECK:STDOUT:   %.loc21_15: type = array_type %.loc21_14, i32, const = constants.%.loc21_15
+// CHECK:STDOUT:   %.loc21_14: i32 = int_literal 3 [template = constants.%.loc21_14]
+// CHECK:STDOUT:   %.loc21_15: type = array_type %.loc21_14, i32 [template = constants.%.loc21_15]
 // CHECK:STDOUT:   %c.var: ref [i32; 3] = var c
 // CHECK:STDOUT:   %c: ref [i32; 3] = bind_name c, %c.var
-// CHECK:STDOUT:   %.loc21_20: i32 = int_literal 1, const = constants.%.loc21_20
-// CHECK:STDOUT:   %.loc21_23: i32 = int_literal 2, const = constants.%.loc21_23
+// CHECK:STDOUT:   %.loc21_20: i32 = int_literal 1 [template = constants.%.loc21_20]
+// CHECK:STDOUT:   %.loc21_23: i32 = int_literal 2 [template = constants.%.loc21_23]
 // CHECK:STDOUT:   %.loc21_24.1: (i32, i32) = tuple_literal (%.loc21_20, %.loc21_23)
 // CHECK:STDOUT:   assign %c.var, <error>
 // CHECK:STDOUT:   %.loc23: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc21_24.2: type = converted %.loc23, constants.%.loc21_24.1, const = constants.%.loc21_24.1
+// CHECK:STDOUT:   %.loc21_24.2: type = converted %.loc23, constants.%.loc21_24.1 [template = constants.%.loc21_24.1]
 // CHECK:STDOUT:   %t2.var: ref (i32, i32) = var t2
 // CHECK:STDOUT:   %t2: ref (i32, i32) = bind_name t2, %t2.var
-// CHECK:STDOUT:   %.loc27_14: i32 = int_literal 3, const = constants.%.loc27_14
-// CHECK:STDOUT:   %.loc27_15: type = array_type %.loc27_14, i32, const = constants.%.loc27_15
+// CHECK:STDOUT:   %.loc27_14: i32 = int_literal 3 [template = constants.%.loc27_14]
+// CHECK:STDOUT:   %.loc27_15: type = array_type %.loc27_14, i32 [template = constants.%.loc27_15]
 // CHECK:STDOUT:   %d.var: ref [i32; 3] = var d
 // CHECK:STDOUT:   %d: ref [i32; 3] = bind_name d, %d.var
 // CHECK:STDOUT:   %t2.ref: ref (i32, i32) = name_ref t2, %t2

+ 15 - 15
toolchain/check/testdata/array/function_param.carbon

@@ -15,20 +15,20 @@ fn G() -> i32 {
 // CHECK:STDOUT: --- function_param.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_17: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc7_18.1: type = array_type %.loc7_17, i32, const
-// CHECK:STDOUT:   %.loc7_18.2: type = ptr_type [i32; 3], const
-// CHECK:STDOUT:   %.loc12_13: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc12_16: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc12_19: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc12_20: type = tuple_type (i32, i32, i32), const
-// CHECK:STDOUT:   %.loc12_23: i32 = int_literal 1, const
+// CHECK:STDOUT:   %.loc7_17: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc7_18.1: type = array_type %.loc7_17, i32 [template]
+// CHECK:STDOUT:   %.loc7_18.2: type = ptr_type [i32; 3] [template]
+// CHECK:STDOUT:   %.loc12_13: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc12_16: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc12_19: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc12_20: type = tuple_type (i32, i32, i32) [template]
+// CHECK:STDOUT:   %.loc12_23: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.F = %F, .G = %G}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(%arr: [i32; 3], %i: i32) -> i32 {
@@ -43,12 +43,12 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%F, const = file.%F
-// CHECK:STDOUT:   %.loc12_13: i32 = int_literal 1, const = constants.%.loc12_13
-// CHECK:STDOUT:   %.loc12_16: i32 = int_literal 2, const = constants.%.loc12_16
-// CHECK:STDOUT:   %.loc12_19: i32 = int_literal 3, const = constants.%.loc12_19
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, file.%F [template = file.%F]
+// CHECK:STDOUT:   %.loc12_13: i32 = int_literal 1 [template = constants.%.loc12_13]
+// CHECK:STDOUT:   %.loc12_16: i32 = int_literal 2 [template = constants.%.loc12_16]
+// CHECK:STDOUT:   %.loc12_19: i32 = int_literal 3 [template = constants.%.loc12_19]
 // CHECK:STDOUT:   %.loc12_20.1: (i32, i32, i32) = tuple_literal (%.loc12_13, %.loc12_16, %.loc12_19)
-// CHECK:STDOUT:   %.loc12_23: i32 = int_literal 1, const = constants.%.loc12_23
+// CHECK:STDOUT:   %.loc12_23: i32 = int_literal 1 [template = constants.%.loc12_23]
 // CHECK:STDOUT:   %.loc12_20.2: ref [i32; 3] = temporary_storage
 // CHECK:STDOUT:   %.loc12_20.3: i32 = int_literal 0
 // CHECK:STDOUT:   %.loc12_20.4: ref i32 = array_index %.loc12_20.2, %.loc12_20.3

+ 24 - 24
toolchain/check/testdata/array/nine_elements.carbon

@@ -9,36 +9,36 @@ var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9);
 // CHECK:STDOUT: --- nine_elements.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 9, const
-// CHECK:STDOUT:   %.loc7_15.1: type = array_type %.loc7_14, i32, const
-// CHECK:STDOUT:   %.loc7_15.2: type = ptr_type [i32; 9], const
-// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc7_29: i32 = int_literal 4, const
-// CHECK:STDOUT:   %.loc7_32: i32 = int_literal 5, const
-// CHECK:STDOUT:   %.loc7_35: i32 = int_literal 6, const
-// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 7, const
-// CHECK:STDOUT:   %.loc7_41: i32 = int_literal 8, const
-// CHECK:STDOUT:   %.loc7_44: i32 = int_literal 9, const
-// CHECK:STDOUT:   %.loc7_45: type = tuple_type (i32, i32, i32, i32, i32, i32, i32, i32, i32), const
+// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 9 [template]
+// CHECK:STDOUT:   %.loc7_15.1: type = array_type %.loc7_14, i32 [template]
+// CHECK:STDOUT:   %.loc7_15.2: type = ptr_type [i32; 9] [template]
+// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc7_29: i32 = int_literal 4 [template]
+// CHECK:STDOUT:   %.loc7_32: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.loc7_35: i32 = int_literal 6 [template]
+// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 7 [template]
+// CHECK:STDOUT:   %.loc7_41: i32 = int_literal 8 [template]
+// CHECK:STDOUT:   %.loc7_44: i32 = int_literal 9 [template]
+// CHECK:STDOUT:   %.loc7_45: type = tuple_type (i32, i32, i32, i32, i32, i32, i32, i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.a = %a}
-// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 9, const = constants.%.loc7_14
-// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32, const = constants.%.loc7_15.1
+// CHECK:STDOUT:   %.loc7_14: i32 = int_literal 9 [template = constants.%.loc7_14]
+// CHECK:STDOUT:   %.loc7_15: type = array_type %.loc7_14, i32 [template = constants.%.loc7_15.1]
 // CHECK:STDOUT:   %a.var: ref [i32; 9] = var a
 // CHECK:STDOUT:   %a: ref [i32; 9] = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1, const = constants.%.loc7_20
-// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2, const = constants.%.loc7_23
-// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3, const = constants.%.loc7_26
-// CHECK:STDOUT:   %.loc7_29: i32 = int_literal 4, const = constants.%.loc7_29
-// CHECK:STDOUT:   %.loc7_32: i32 = int_literal 5, const = constants.%.loc7_32
-// CHECK:STDOUT:   %.loc7_35: i32 = int_literal 6, const = constants.%.loc7_35
-// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 7, const = constants.%.loc7_38
-// CHECK:STDOUT:   %.loc7_41: i32 = int_literal 8, const = constants.%.loc7_41
-// CHECK:STDOUT:   %.loc7_44: i32 = int_literal 9, const = constants.%.loc7_44
+// CHECK:STDOUT:   %.loc7_20: i32 = int_literal 1 [template = constants.%.loc7_20]
+// CHECK:STDOUT:   %.loc7_23: i32 = int_literal 2 [template = constants.%.loc7_23]
+// CHECK:STDOUT:   %.loc7_26: i32 = int_literal 3 [template = constants.%.loc7_26]
+// CHECK:STDOUT:   %.loc7_29: i32 = int_literal 4 [template = constants.%.loc7_29]
+// CHECK:STDOUT:   %.loc7_32: i32 = int_literal 5 [template = constants.%.loc7_32]
+// CHECK:STDOUT:   %.loc7_35: i32 = int_literal 6 [template = constants.%.loc7_35]
+// CHECK:STDOUT:   %.loc7_38: i32 = int_literal 7 [template = constants.%.loc7_38]
+// CHECK:STDOUT:   %.loc7_41: i32 = int_literal 8 [template = constants.%.loc7_41]
+// CHECK:STDOUT:   %.loc7_44: i32 = int_literal 9 [template = constants.%.loc7_44]
 // CHECK:STDOUT:   %.loc7_45.1: (i32, i32, i32, i32, i32, i32, i32, i32, i32) = tuple_literal (%.loc7_20, %.loc7_23, %.loc7_26, %.loc7_29, %.loc7_32, %.loc7_35, %.loc7_38, %.loc7_41, %.loc7_44)
 // CHECK:STDOUT:   %.loc7_45.2: i32 = int_literal 0
 // CHECK:STDOUT:   %.loc7_45.3: ref i32 = array_index %a.var, %.loc7_45.2

+ 3 - 3
toolchain/check/testdata/as/as_type.carbon

@@ -9,14 +9,14 @@ let t: type = (i32, i32) as type;
 // CHECK:STDOUT: --- as_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_24: type = tuple_type (type, type), const
-// CHECK:STDOUT:   %.loc7_26: type = tuple_type (i32, i32), const
+// CHECK:STDOUT:   %.loc7_24: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.loc7_26: type = tuple_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {}
 // CHECK:STDOUT:   %.loc7_24: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc7_26: type = converted %.loc7_24, constants.%.loc7_26, const = constants.%.loc7_26
+// CHECK:STDOUT:   %.loc7_26: type = converted %.loc7_24, constants.%.loc7_26 [template = constants.%.loc7_26]
 // CHECK:STDOUT:   %t: type = bind_name t, %.loc7_26
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 3 - 3
toolchain/check/testdata/as/basic.carbon

@@ -11,17 +11,17 @@ fn Main() -> i32 {
 // CHECK:STDOUT: --- basic.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 1, const
+// CHECK:STDOUT:   %.loc8: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Main = %Main}
-// CHECK:STDOUT:   %Main: <function> = fn_decl @Main, const
+// CHECK:STDOUT:   %Main: <function> = fn_decl @Main [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 1, const = constants.%.loc8
+// CHECK:STDOUT:   %.loc8: i32 = int_literal 1 [template = constants.%.loc8]
 // CHECK:STDOUT:   return %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 7 - 7
toolchain/check/testdata/as/fail_no_conversion.carbon

@@ -12,19 +12,19 @@ let n: (i32, i32) = 1 as (i32, i32);
 // CHECK:STDOUT: --- fail_no_conversion.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_17.1: type = tuple_type (type, type), const
-// CHECK:STDOUT:   %.loc10_17.2: type = tuple_type (i32, i32), const
-// CHECK:STDOUT:   %.loc10_17.3: type = ptr_type (i32, i32), const
-// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 1, const
+// CHECK:STDOUT:   %.loc10_17.1: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.loc10_17.2: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc10_17.3: type = ptr_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {}
 // CHECK:STDOUT:   %.loc10_17.1: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc10_17.2: type = converted %.loc10_17.1, constants.%.loc10_17.2, const = constants.%.loc10_17.2
-// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 1, const = constants.%.loc10_21
+// CHECK:STDOUT:   %.loc10_17.2: type = converted %.loc10_17.1, constants.%.loc10_17.2 [template = constants.%.loc10_17.2]
+// CHECK:STDOUT:   %.loc10_21: i32 = int_literal 1 [template = constants.%.loc10_21]
 // CHECK:STDOUT:   %.loc10_35: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc10_17.3: type = converted %.loc10_35, constants.%.loc10_17.2, const = constants.%.loc10_17.2
+// CHECK:STDOUT:   %.loc10_17.3: type = converted %.loc10_35, constants.%.loc10_17.2 [template = constants.%.loc10_17.2]
 // CHECK:STDOUT:   %n: (i32, i32) = bind_name n, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 4 - 4
toolchain/check/testdata/as/fail_not_type.carbon

@@ -12,14 +12,14 @@ let n: i32 = 1 as 2;
 // CHECK:STDOUT: --- fail_not_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 2, const
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {}
-// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1, const = constants.%.loc10_14
-// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 2, const = constants.%.loc10_19
+// CHECK:STDOUT:   %.loc10_14: i32 = int_literal 1 [template = constants.%.loc10_14]
+// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 2 [template = constants.%.loc10_19]
 // CHECK:STDOUT:   %n: i32 = bind_name n, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 16 - 16
toolchain/check/testdata/as/identity.carbon

@@ -27,19 +27,19 @@ fn Initializing() {
 // CHECK:STDOUT: --- identity.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc11_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc9: type = ptr_type {}, const
+// CHECK:STDOUT:   %.loc11_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc11_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc9: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.X = %X.decl, .Value = %Value, .Reference = %Reference, .Make = %Make, .Initializing = %Initializing}
 // CHECK:STDOUT:   %X.decl = class_decl @X, ()
-// CHECK:STDOUT:   %X: type = class_type @X, const
-// CHECK:STDOUT:   %Value: <function> = fn_decl @Value, const
-// CHECK:STDOUT:   %Reference: <function> = fn_decl @Reference, const
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make, const
-// CHECK:STDOUT:   %Initializing: <function> = fn_decl @Initializing, const
+// CHECK:STDOUT:   %X: type = class_type @X [template]
+// CHECK:STDOUT:   %Value: <function> = fn_decl @Value [template]
+// CHECK:STDOUT:   %Reference: <function> = fn_decl @Reference [template]
+// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template]
+// CHECK:STDOUT:   %Initializing: <function> = fn_decl @Initializing [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @X {
@@ -49,20 +49,20 @@ fn Initializing() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Value(%n: X) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %X.ref.loc14_10: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc14_10: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   %n.ref: X = name_ref n, %n
-// CHECK:STDOUT:   %X.ref.loc14_19: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc14_19: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   %m: X = bind_name m, %n.ref
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Reference(%p: X*) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %X.ref.loc18_10: type = name_ref X, file.%X, const = file.%X
-// CHECK:STDOUT:   %.loc18_11: type = ptr_type X, const
+// CHECK:STDOUT:   %X.ref.loc18_10: type = name_ref X, file.%X [template = file.%X]
+// CHECK:STDOUT:   %.loc18_11: type = ptr_type X [template]
 // CHECK:STDOUT:   %p.ref: X* = name_ref p, %p
 // CHECK:STDOUT:   %.loc18_17: ref X = deref %p.ref
-// CHECK:STDOUT:   %X.ref.loc18_23: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc18_23: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   %.loc18_15: X* = addr_of %.loc18_17
 // CHECK:STDOUT:   %q: X* = bind_name q, %.loc18_15
 // CHECK:STDOUT:   return
@@ -72,13 +72,13 @@ fn Initializing() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Initializing() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %X.ref.loc24_10: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc24_10: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   %x.var: ref X = var x
 // CHECK:STDOUT:   %x: ref X = bind_name x, %x.var
-// CHECK:STDOUT:   %Make.ref: <function> = name_ref Make, file.%Make, const = file.%Make
+// CHECK:STDOUT:   %Make.ref: <function> = name_ref Make, file.%Make [template = file.%Make]
 // CHECK:STDOUT:   %.loc24_7: ref X = splice_block %x.var {}
 // CHECK:STDOUT:   %.loc24_19: init X = call %Make.ref() to %.loc24_7
-// CHECK:STDOUT:   %X.ref.loc24_25: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc24_25: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   assign %x.var, %.loc24_19
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 27 - 27
toolchain/check/testdata/as/tuple.carbon

@@ -23,22 +23,22 @@ fn Var() {
 // CHECK:STDOUT: --- tuple.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc15_15.1: type = tuple_type (type, type), const
-// CHECK:STDOUT:   %.loc15_15.2: type = tuple_type (X, X), const
-// CHECK:STDOUT:   %.loc15_15.3: type = tuple_type ({}*, {}*), const
-// CHECK:STDOUT:   %.loc15_15.4: type = ptr_type ({}*, {}*), const
+// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc15_15.1: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.loc15_15.2: type = tuple_type (X, X) [template]
+// CHECK:STDOUT:   %.loc15_15.3: type = tuple_type ({}*, {}*) [template]
+// CHECK:STDOUT:   %.loc15_15.4: type = ptr_type ({}*, {}*) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.X = %X.decl, .Make = %Make, .Let = %Let, .Var = %Var}
 // CHECK:STDOUT:   %X.decl = class_decl @X, ()
-// CHECK:STDOUT:   %X: type = class_type @X, const
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make, const
-// CHECK:STDOUT:   %Let: <function> = fn_decl @Let, const
-// CHECK:STDOUT:   %Var: <function> = fn_decl @Var, const
+// CHECK:STDOUT:   %X: type = class_type @X [template]
+// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template]
+// CHECK:STDOUT:   %Let: <function> = fn_decl @Let [template]
+// CHECK:STDOUT:   %Var: <function> = fn_decl @Var [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @X {
@@ -50,21 +50,21 @@ fn Var() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Let() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %X.ref.loc15_11: type = name_ref X, file.%X, const = file.%X
-// CHECK:STDOUT:   %X.ref.loc15_14: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc15_11: type = name_ref X, file.%X [template = file.%X]
+// CHECK:STDOUT:   %X.ref.loc15_14: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   %.loc15_15.1: (type, type) = tuple_literal (%X.ref.loc15_11, %X.ref.loc15_14)
-// CHECK:STDOUT:   %.loc15_15.2: type = converted %.loc15_15.1, constants.%.loc15_15.2, const = constants.%.loc15_15.2
-// CHECK:STDOUT:   %Make.ref.loc15_20: <function> = name_ref Make, file.%Make, const = file.%Make
+// CHECK:STDOUT:   %.loc15_15.2: type = converted %.loc15_15.1, constants.%.loc15_15.2 [template = constants.%.loc15_15.2]
+// CHECK:STDOUT:   %Make.ref.loc15_20: <function> = name_ref Make, file.%Make [template = file.%Make]
 // CHECK:STDOUT:   %.loc15_24.1: ref X = temporary_storage
 // CHECK:STDOUT:   %.loc15_24.2: init X = call %Make.ref.loc15_20() to %.loc15_24.1
-// CHECK:STDOUT:   %Make.ref.loc15_28: <function> = name_ref Make, file.%Make, const = file.%Make
+// CHECK:STDOUT:   %Make.ref.loc15_28: <function> = name_ref Make, file.%Make [template = file.%Make]
 // CHECK:STDOUT:   %.loc15_32.1: ref X = temporary_storage
 // CHECK:STDOUT:   %.loc15_32.2: init X = call %Make.ref.loc15_28() to %.loc15_32.1
 // CHECK:STDOUT:   %.loc15_34.1: (X, X) = tuple_literal (%.loc15_24.2, %.loc15_32.2)
-// CHECK:STDOUT:   %X.ref.loc15_40: type = name_ref X, file.%X, const = file.%X
-// CHECK:STDOUT:   %X.ref.loc15_43: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc15_40: type = name_ref X, file.%X [template = file.%X]
+// CHECK:STDOUT:   %X.ref.loc15_43: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   %.loc15_44: (type, type) = tuple_literal (%X.ref.loc15_40, %X.ref.loc15_43)
-// CHECK:STDOUT:   %.loc15_15.3: type = converted %.loc15_44, constants.%.loc15_15.2, const = constants.%.loc15_15.2
+// CHECK:STDOUT:   %.loc15_15.3: type = converted %.loc15_44, constants.%.loc15_15.2 [template = constants.%.loc15_15.2]
 // CHECK:STDOUT:   %.loc15_24.3: ref X = temporary %.loc15_24.1, %.loc15_24.2
 // CHECK:STDOUT:   %.loc15_24.4: X = bind_value %.loc15_24.3
 // CHECK:STDOUT:   %.loc15_32.3: ref X = temporary %.loc15_32.1, %.loc15_32.2
@@ -77,23 +77,23 @@ fn Var() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Var() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %X.ref.loc20_11: type = name_ref X, file.%X, const = file.%X
-// CHECK:STDOUT:   %X.ref.loc20_14: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc20_11: type = name_ref X, file.%X [template = file.%X]
+// CHECK:STDOUT:   %X.ref.loc20_14: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   %.loc20_15: (type, type) = tuple_literal (%X.ref.loc20_11, %X.ref.loc20_14)
-// CHECK:STDOUT:   %.loc15_15.1: type = converted %.loc20_15, constants.%.loc15_15.2, const = constants.%.loc15_15.2
+// CHECK:STDOUT:   %.loc15_15.1: type = converted %.loc20_15, constants.%.loc15_15.2 [template = constants.%.loc15_15.2]
 // CHECK:STDOUT:   %b.var: ref (X, X) = var b
 // CHECK:STDOUT:   %b: ref (X, X) = bind_name b, %b.var
-// CHECK:STDOUT:   %Make.ref.loc20_20: <function> = name_ref Make, file.%Make, const = file.%Make
+// CHECK:STDOUT:   %Make.ref.loc20_20: <function> = name_ref Make, file.%Make [template = file.%Make]
 // CHECK:STDOUT:   %.loc20_34.1: ref X = tuple_access %b.var, element0
 // CHECK:STDOUT:   %.loc20_24: init X = call %Make.ref.loc20_20() to %.loc20_34.1
-// CHECK:STDOUT:   %Make.ref.loc20_28: <function> = name_ref Make, file.%Make, const = file.%Make
+// CHECK:STDOUT:   %Make.ref.loc20_28: <function> = name_ref Make, file.%Make [template = file.%Make]
 // CHECK:STDOUT:   %.loc20_34.2: ref X = tuple_access %b.var, element1
 // CHECK:STDOUT:   %.loc20_32: init X = call %Make.ref.loc20_28() to %.loc20_34.2
 // CHECK:STDOUT:   %.loc20_34.3: (X, X) = tuple_literal (%.loc20_24, %.loc20_32)
-// CHECK:STDOUT:   %X.ref.loc20_40: type = name_ref X, file.%X, const = file.%X
-// CHECK:STDOUT:   %X.ref.loc20_43: type = name_ref X, file.%X, const = file.%X
+// CHECK:STDOUT:   %X.ref.loc20_40: type = name_ref X, file.%X [template = file.%X]
+// CHECK:STDOUT:   %X.ref.loc20_43: type = name_ref X, file.%X [template = file.%X]
 // CHECK:STDOUT:   %.loc20_44: (type, type) = tuple_literal (%X.ref.loc20_40, %X.ref.loc20_43)
-// CHECK:STDOUT:   %.loc15_15.2: type = converted %.loc20_44, constants.%.loc15_15.2, const = constants.%.loc15_15.2
+// CHECK:STDOUT:   %.loc15_15.2: type = converted %.loc20_44, constants.%.loc15_15.2 [template = constants.%.loc15_15.2]
 // CHECK:STDOUT:   %.loc20_34.4: init (X, X) = tuple_init (%.loc20_24, %.loc20_32) to %b.var
 // CHECK:STDOUT:   %.loc20_34.5: init (X, X) = converted %.loc20_34.3, %.loc20_34.4
 // CHECK:STDOUT:   assign %b.var, %.loc20_34.5

+ 7 - 7
toolchain/check/testdata/basics/builtin_types.carbon

@@ -12,23 +12,23 @@ var test_type: type = i32;
 // CHECK:STDOUT: --- builtin_types.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7: i32 = int_literal 0, const
-// CHECK:STDOUT:   %.loc8: f64 = real_literal 1e-1, const
-// CHECK:STDOUT:   %.1: type = ptr_type String, const
-// CHECK:STDOUT:   %.loc9: String = string_literal "Test", const
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.loc8: f64 = real_literal 1e-1 [template]
+// CHECK:STDOUT:   %.1: type = ptr_type String [template]
+// CHECK:STDOUT:   %.loc9: String = string_literal "Test" [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.test_i32 = %test_i32, .test_f64 = %test_f64, .test_type = %test_type}
 // CHECK:STDOUT:   %test_i32.var: ref i32 = var test_i32
 // CHECK:STDOUT:   %test_i32: ref i32 = bind_name test_i32, %test_i32.var
-// CHECK:STDOUT:   %.loc7: i32 = int_literal 0, const = constants.%.loc7
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 0 [template = constants.%.loc7]
 // CHECK:STDOUT:   assign %test_i32.var, %.loc7
 // CHECK:STDOUT:   %test_f64.var: ref f64 = var test_f64
 // CHECK:STDOUT:   %test_f64: ref f64 = bind_name test_f64, %test_f64.var
-// CHECK:STDOUT:   %.loc8: f64 = real_literal 1e-1, const = constants.%.loc8
+// CHECK:STDOUT:   %.loc8: f64 = real_literal 1e-1 [template = constants.%.loc8]
 // CHECK:STDOUT:   assign %test_f64.var, %.loc8
-// CHECK:STDOUT:   %.loc9: String = string_literal "Test", const = constants.%.loc9
+// CHECK:STDOUT:   %.loc9: String = string_literal "Test" [template = constants.%.loc9]
 // CHECK:STDOUT:   %test_str: String = bind_name test_str, %.loc9
 // CHECK:STDOUT:   %test_type.var: ref type = var test_type
 // CHECK:STDOUT:   %test_type: ref type = bind_name test_type, %test_type.var

+ 3 - 3
toolchain/check/testdata/basics/fail_bad_run.carbon

@@ -15,13 +15,13 @@ fn Run() -> String {}
 // CHECK:STDOUT: --- fail_bad_run.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.1: type = ptr_type String, const
-// CHECK:STDOUT:   %.loc13: type = tuple_type (), const
+// CHECK:STDOUT:   %.1: type = ptr_type String [template]
+// CHECK:STDOUT:   %.loc13: type = tuple_type () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Run = %Run}
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() -> %return: String {

+ 1 - 1
toolchain/check/testdata/basics/fail_bad_run_2.carbon

@@ -13,7 +13,7 @@ fn Run(n: i32) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Run = %Run}
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run(%n: i32) {

+ 1 - 1
toolchain/check/testdata/basics/fail_name_lookup.carbon

@@ -15,7 +15,7 @@ fn Main() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Main = %Main}
-// CHECK:STDOUT:   %Main: <function> = fn_decl @Main, const
+// CHECK:STDOUT:   %Main: <function> = fn_decl @Main [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() {

+ 2 - 2
toolchain/check/testdata/basics/fail_non_type_as_type.carbon

@@ -12,14 +12,14 @@ var x: type = 42;
 // CHECK:STDOUT: --- fail_non_type_as_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10: i32 = int_literal 42, const
+// CHECK:STDOUT:   %.loc10: i32 = int_literal 42 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.x = %x}
 // CHECK:STDOUT:   %x.var: ref type = var x
 // CHECK:STDOUT:   %x: ref type = bind_name x, %x.var
-// CHECK:STDOUT:   %.loc10: i32 = int_literal 42, const = constants.%.loc10
+// CHECK:STDOUT:   %.loc10: i32 = int_literal 42 [template = constants.%.loc10]
 // CHECK:STDOUT:   assign %x.var, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 2 - 2
toolchain/check/testdata/basics/multifile.carbon

@@ -18,7 +18,7 @@ fn B() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A}
-// CHECK:STDOUT:   %A: <function> = fn_decl @A, const
+// CHECK:STDOUT:   %A: <function> = fn_decl @A [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @A() {
@@ -30,7 +30,7 @@ fn B() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.B = %B}
-// CHECK:STDOUT:   %B: <function> = fn_decl @B, const
+// CHECK:STDOUT:   %B: <function> = fn_decl @B [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @B() {

+ 4 - 4
toolchain/check/testdata/basics/multifile_raw_and_textual_ir.carbon

@@ -37,7 +37,7 @@ fn B() {}
 // CHECK:STDOUT:     inst+1:          {kind: FunctionDecl, arg0: function0, type: type1}
 // CHECK:STDOUT:     inst+2:          {kind: Return}
 // CHECK:STDOUT:   constant_values:
-// CHECK:STDOUT:     inst+1:          inst+1
+// CHECK:STDOUT:     inst+1:          template inst+1
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
@@ -53,7 +53,7 @@ fn B() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A}
-// CHECK:STDOUT:   %A: <function> = fn_decl @A, const
+// CHECK:STDOUT:   %A: <function> = fn_decl @A [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @A() {
@@ -80,7 +80,7 @@ fn B() {}
 // CHECK:STDOUT:     inst+1:          {kind: FunctionDecl, arg0: function0, type: type1}
 // CHECK:STDOUT:     inst+2:          {kind: Return}
 // CHECK:STDOUT:   constant_values:
-// CHECK:STDOUT:     inst+1:          inst+1
+// CHECK:STDOUT:     inst+1:          template inst+1
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
@@ -96,7 +96,7 @@ fn B() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.B = %B}
-// CHECK:STDOUT:   %B: <function> = fn_decl @B, const
+// CHECK:STDOUT:   %B: <function> = fn_decl @B [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @B() {

+ 2 - 2
toolchain/check/testdata/basics/multifile_raw_ir.carbon

@@ -37,7 +37,7 @@ fn B() {}
 // CHECK:STDOUT:     inst+1:          {kind: FunctionDecl, arg0: function0, type: type1}
 // CHECK:STDOUT:     inst+2:          {kind: Return}
 // CHECK:STDOUT:   constant_values:
-// CHECK:STDOUT:     inst+1:          inst+1
+// CHECK:STDOUT:     inst+1:          template inst+1
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
@@ -67,7 +67,7 @@ fn B() {}
 // CHECK:STDOUT:     inst+1:          {kind: FunctionDecl, arg0: function0, type: type1}
 // CHECK:STDOUT:     inst+2:          {kind: Return}
 // CHECK:STDOUT:   constant_values:
-// CHECK:STDOUT:     inst+1:          inst+1
+// CHECK:STDOUT:     inst+1:          template inst+1
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:

+ 37 - 37
toolchain/check/testdata/basics/numeric_literals.carbon

@@ -28,44 +28,44 @@ fn F() {
 // CHECK:STDOUT: --- numeric_literals.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 5, const
-// CHECK:STDOUT:   %.loc10_20.1: type = array_type %.loc10_19, i32, const
-// CHECK:STDOUT:   %.loc10_20.2: type = ptr_type [i32; 5], const
-// CHECK:STDOUT:   %.loc11: i32 = int_literal 8, const
-// CHECK:STDOUT:   %.loc12: i32 = int_literal 9, const
-// CHECK:STDOUT:   %.loc13: i32 = int_literal 8, const
-// CHECK:STDOUT:   %.loc14: i32 = int_literal 8, const
-// CHECK:STDOUT:   %.loc15: i32 = int_literal 39999999999999999993, const
-// CHECK:STDOUT:   %.loc16: type = tuple_type (i32, i32, i32, i32, i32), const
-// CHECK:STDOUT:   %.loc17_21: i32 = int_literal 7, const
-// CHECK:STDOUT:   %.loc17_22.1: type = array_type %.loc17_21, f64, const
-// CHECK:STDOUT:   %.loc17_22.2: type = ptr_type [f64; 7], const
-// CHECK:STDOUT:   %.loc18: f64 = real_literal 9e-1, const
-// CHECK:STDOUT:   %.loc19: f64 = real_literal 80e-1, const
-// CHECK:STDOUT:   %.loc20: f64 = real_literal 800e-1, const
-// CHECK:STDOUT:   %.loc21: f64 = real_literal 10e6, const
-// CHECK:STDOUT:   %.loc22: f64 = real_literal 10e7, const
-// CHECK:STDOUT:   %.loc23: f64 = real_literal 10e-9, const
-// CHECK:STDOUT:   %.loc24: f64 = real_literal 399999999999999999930e39999999999999999992, const
-// CHECK:STDOUT:   %.loc25: type = tuple_type (f64, f64, f64, f64, f64, f64, f64), const
+// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 5 [template]
+// CHECK:STDOUT:   %.loc10_20.1: type = array_type %.loc10_19, i32 [template]
+// CHECK:STDOUT:   %.loc10_20.2: type = ptr_type [i32; 5] [template]
+// CHECK:STDOUT:   %.loc11: i32 = int_literal 8 [template]
+// CHECK:STDOUT:   %.loc12: i32 = int_literal 9 [template]
+// CHECK:STDOUT:   %.loc13: i32 = int_literal 8 [template]
+// CHECK:STDOUT:   %.loc14: i32 = int_literal 8 [template]
+// CHECK:STDOUT:   %.loc15: i32 = int_literal 39999999999999999993 [template]
+// CHECK:STDOUT:   %.loc16: type = tuple_type (i32, i32, i32, i32, i32) [template]
+// CHECK:STDOUT:   %.loc17_21: i32 = int_literal 7 [template]
+// CHECK:STDOUT:   %.loc17_22.1: type = array_type %.loc17_21, f64 [template]
+// CHECK:STDOUT:   %.loc17_22.2: type = ptr_type [f64; 7] [template]
+// CHECK:STDOUT:   %.loc18: f64 = real_literal 9e-1 [template]
+// CHECK:STDOUT:   %.loc19: f64 = real_literal 80e-1 [template]
+// CHECK:STDOUT:   %.loc20: f64 = real_literal 800e-1 [template]
+// CHECK:STDOUT:   %.loc21: f64 = real_literal 10e6 [template]
+// CHECK:STDOUT:   %.loc22: f64 = real_literal 10e7 [template]
+// CHECK:STDOUT:   %.loc23: f64 = real_literal 10e-9 [template]
+// CHECK:STDOUT:   %.loc24: f64 = real_literal 399999999999999999930e39999999999999999992 [template]
+// CHECK:STDOUT:   %.loc25: type = tuple_type (f64, f64, f64, f64, f64, f64, f64) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.F = %F}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 5, const = constants.%.loc10_19
-// CHECK:STDOUT:   %.loc10_20: type = array_type %.loc10_19, i32, const = constants.%.loc10_20.1
+// CHECK:STDOUT:   %.loc10_19: i32 = int_literal 5 [template = constants.%.loc10_19]
+// CHECK:STDOUT:   %.loc10_20: type = array_type %.loc10_19, i32 [template = constants.%.loc10_20.1]
 // CHECK:STDOUT:   %ints.var: ref [i32; 5] = var ints
 // CHECK:STDOUT:   %ints: ref [i32; 5] = bind_name ints, %ints.var
-// CHECK:STDOUT:   %.loc11: i32 = int_literal 8, const = constants.%.loc11
-// CHECK:STDOUT:   %.loc12: i32 = int_literal 9, const = constants.%.loc12
-// CHECK:STDOUT:   %.loc13: i32 = int_literal 8, const = constants.%.loc13
-// CHECK:STDOUT:   %.loc14: i32 = int_literal 8, const = constants.%.loc14
-// CHECK:STDOUT:   %.loc15: i32 = int_literal 39999999999999999993, const = constants.%.loc15
+// CHECK:STDOUT:   %.loc11: i32 = int_literal 8 [template = constants.%.loc11]
+// CHECK:STDOUT:   %.loc12: i32 = int_literal 9 [template = constants.%.loc12]
+// CHECK:STDOUT:   %.loc13: i32 = int_literal 8 [template = constants.%.loc13]
+// CHECK:STDOUT:   %.loc14: i32 = int_literal 8 [template = constants.%.loc14]
+// CHECK:STDOUT:   %.loc15: i32 = int_literal 39999999999999999993 [template = constants.%.loc15]
 // CHECK:STDOUT:   %.loc16_3.1: (i32, i32, i32, i32, i32) = tuple_literal (%.loc11, %.loc12, %.loc13, %.loc14, %.loc15)
 // CHECK:STDOUT:   %.loc16_3.2: i32 = int_literal 0
 // CHECK:STDOUT:   %.loc16_3.3: ref i32 = array_index %ints.var, %.loc16_3.2
@@ -85,17 +85,17 @@ fn F() {
 // CHECK:STDOUT:   %.loc16_3.17: init [i32; 5] = array_init (%.loc16_3.4, %.loc16_3.7, %.loc16_3.10, %.loc16_3.13, %.loc16_3.16) to %ints.var
 // CHECK:STDOUT:   %.loc16_3.18: init [i32; 5] = converted %.loc16_3.1, %.loc16_3.17
 // CHECK:STDOUT:   assign %ints.var, %.loc16_3.18
-// CHECK:STDOUT:   %.loc17_21: i32 = int_literal 7, const = constants.%.loc17_21
-// CHECK:STDOUT:   %.loc17_22: type = array_type %.loc17_21, f64, const = constants.%.loc17_22.1
+// CHECK:STDOUT:   %.loc17_21: i32 = int_literal 7 [template = constants.%.loc17_21]
+// CHECK:STDOUT:   %.loc17_22: type = array_type %.loc17_21, f64 [template = constants.%.loc17_22.1]
 // CHECK:STDOUT:   %floats.var: ref [f64; 7] = var floats
 // CHECK:STDOUT:   %floats: ref [f64; 7] = bind_name floats, %floats.var
-// CHECK:STDOUT:   %.loc18: f64 = real_literal 9e-1, const = constants.%.loc18
-// CHECK:STDOUT:   %.loc19: f64 = real_literal 80e-1, const = constants.%.loc19
-// CHECK:STDOUT:   %.loc20: f64 = real_literal 800e-1, const = constants.%.loc20
-// CHECK:STDOUT:   %.loc21: f64 = real_literal 10e6, const = constants.%.loc21
-// CHECK:STDOUT:   %.loc22: f64 = real_literal 10e7, const = constants.%.loc22
-// CHECK:STDOUT:   %.loc23: f64 = real_literal 10e-9, const = constants.%.loc23
-// CHECK:STDOUT:   %.loc24: f64 = real_literal 399999999999999999930e39999999999999999992, const = constants.%.loc24
+// CHECK:STDOUT:   %.loc18: f64 = real_literal 9e-1 [template = constants.%.loc18]
+// CHECK:STDOUT:   %.loc19: f64 = real_literal 80e-1 [template = constants.%.loc19]
+// CHECK:STDOUT:   %.loc20: f64 = real_literal 800e-1 [template = constants.%.loc20]
+// CHECK:STDOUT:   %.loc21: f64 = real_literal 10e6 [template = constants.%.loc21]
+// CHECK:STDOUT:   %.loc22: f64 = real_literal 10e7 [template = constants.%.loc22]
+// CHECK:STDOUT:   %.loc23: f64 = real_literal 10e-9 [template = constants.%.loc23]
+// CHECK:STDOUT:   %.loc24: f64 = real_literal 399999999999999999930e39999999999999999992 [template = constants.%.loc24]
 // CHECK:STDOUT:   %.loc25_3.1: (f64, f64, f64, f64, f64, f64, f64) = tuple_literal (%.loc18, %.loc19, %.loc20, %.loc21, %.loc22, %.loc23, %.loc24)
 // CHECK:STDOUT:   %.loc25_3.2: i32 = int_literal 0
 // CHECK:STDOUT:   %.loc25_3.3: ref f64 = array_index %floats.var, %.loc25_3.2

+ 4 - 4
toolchain/check/testdata/basics/parens.carbon

@@ -10,19 +10,19 @@ var b: i32 = ((2));
 // CHECK:STDOUT: --- parens.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 2, const
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc8: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.a = %a, .b = %b}
 // CHECK:STDOUT:   %a.var: ref i32 = var a
 // CHECK:STDOUT:   %a: ref i32 = bind_name a, %a.var
-// CHECK:STDOUT:   %.loc7: i32 = int_literal 1, const = constants.%.loc7
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 1 [template = constants.%.loc7]
 // CHECK:STDOUT:   assign %a.var, %.loc7
 // CHECK:STDOUT:   %b.var: ref i32 = var b
 // CHECK:STDOUT:   %b: ref i32 = bind_name b, %b.var
-// CHECK:STDOUT:   %.loc8: i32 = int_literal 2, const = constants.%.loc8
+// CHECK:STDOUT:   %.loc8: i32 = int_literal 2 [template = constants.%.loc8]
 // CHECK:STDOUT:   assign %b.var, %.loc8
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 17 - 17
toolchain/check/testdata/basics/raw_and_textual_ir.carbon

@@ -67,15 +67,15 @@ fn Foo(n: i32) -> (i32, i32, f64) {
 // CHECK:STDOUT:     inst+23:         {kind: Converted, arg0: inst+15, arg1: inst+22, type: type4}
 // CHECK:STDOUT:     inst+24:         {kind: ReturnExpr, arg0: inst+23}
 // CHECK:STDOUT:   constant_values:
-// CHECK:STDOUT:     inst+3:          inst+3
-// CHECK:STDOUT:     inst+5:          inst+5
-// CHECK:STDOUT:     inst+6:          inst+5
-// CHECK:STDOUT:     inst+8:          inst+8
-// CHECK:STDOUT:     inst+9:          inst+9
-// CHECK:STDOUT:     inst+11:         inst+12
-// CHECK:STDOUT:     inst+12:         inst+12
-// CHECK:STDOUT:     inst+13:         inst+14
-// CHECK:STDOUT:     inst+14:         inst+14
+// CHECK:STDOUT:     inst+3:          template inst+3
+// CHECK:STDOUT:     inst+5:          template inst+5
+// CHECK:STDOUT:     inst+6:          template inst+5
+// CHECK:STDOUT:     inst+8:          template inst+8
+// CHECK:STDOUT:     inst+9:          template inst+9
+// CHECK:STDOUT:     inst+11:         template inst+12
+// CHECK:STDOUT:     inst+12:         template inst+12
+// CHECK:STDOUT:     inst+13:         template inst+14
+// CHECK:STDOUT:     inst+14:         template inst+14
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:
@@ -122,23 +122,23 @@ fn Foo(n: i32) -> (i32, i32, f64) {
 // CHECK:STDOUT: --- raw_and_textual_ir.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11_33.1: type = tuple_type (type, type, type), const
-// CHECK:STDOUT:   %.loc11_33.2: type = tuple_type (i32, i32, f64), const
-// CHECK:STDOUT:   %.loc11_33.3: type = ptr_type (i32, i32, f64), const
-// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1, const
+// CHECK:STDOUT:   %.loc11_33.1: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.loc11_33.2: type = tuple_type (i32, i32, f64) [template]
+// CHECK:STDOUT:   %.loc11_33.3: type = ptr_type (i32, i32, f64) [template]
+// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Foo = %Foo}
-// CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo, const
+// CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Foo(%n: i32) -> %return: (i32, i32, f64) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %n.ref: i32 = name_ref n, %n
-// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2, const = constants.%.loc12_14
-// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1, const = constants.%.loc12_17
+// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2 [template = constants.%.loc12_14]
+// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1 [template = constants.%.loc12_17]
 // CHECK:STDOUT:   %.loc12_20.1: (i32, i32, f64) = tuple_literal (%n.ref, %.loc12_14, %.loc12_17)
 // CHECK:STDOUT:   %.loc12_20.2: ref i32 = tuple_access %return, element0
 // CHECK:STDOUT:   %.loc12_20.3: init i32 = initialize_from %n.ref to %.loc12_20.2

+ 3 - 3
toolchain/check/testdata/basics/raw_identifier.carbon

@@ -24,9 +24,9 @@ fn C(r#if: i32) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A, .B = %B, .C = %C}
-// CHECK:STDOUT:   %A: <function> = fn_decl @A, const
-// CHECK:STDOUT:   %B: <function> = fn_decl @B, const
-// CHECK:STDOUT:   %C: <function> = fn_decl @C, const
+// CHECK:STDOUT:   %A: <function> = fn_decl @A [template]
+// CHECK:STDOUT:   %B: <function> = fn_decl @B [template]
+// CHECK:STDOUT:   %C: <function> = fn_decl @C [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @A(%n: i32) -> i32 {

+ 9 - 9
toolchain/check/testdata/basics/raw_ir.carbon

@@ -67,15 +67,15 @@ fn Foo(n: i32) -> (i32, i32, f64) {
 // CHECK:STDOUT:     inst+23:         {kind: Converted, arg0: inst+15, arg1: inst+22, type: type4}
 // CHECK:STDOUT:     inst+24:         {kind: ReturnExpr, arg0: inst+23}
 // CHECK:STDOUT:   constant_values:
-// CHECK:STDOUT:     inst+3:          inst+3
-// CHECK:STDOUT:     inst+5:          inst+5
-// CHECK:STDOUT:     inst+6:          inst+5
-// CHECK:STDOUT:     inst+8:          inst+8
-// CHECK:STDOUT:     inst+9:          inst+9
-// CHECK:STDOUT:     inst+11:         inst+12
-// CHECK:STDOUT:     inst+12:         inst+12
-// CHECK:STDOUT:     inst+13:         inst+14
-// CHECK:STDOUT:     inst+14:         inst+14
+// CHECK:STDOUT:     inst+3:          template inst+3
+// CHECK:STDOUT:     inst+5:          template inst+5
+// CHECK:STDOUT:     inst+6:          template inst+5
+// CHECK:STDOUT:     inst+8:          template inst+8
+// CHECK:STDOUT:     inst+9:          template inst+9
+// CHECK:STDOUT:     inst+11:         template inst+12
+// CHECK:STDOUT:     inst+12:         template inst+12
+// CHECK:STDOUT:     inst+13:         template inst+14
+// CHECK:STDOUT:     inst+14:         template inst+14
 // CHECK:STDOUT:   inst_blocks:
 // CHECK:STDOUT:     empty:           {}
 // CHECK:STDOUT:     exports:

+ 1 - 1
toolchain/check/testdata/basics/run.carbon

@@ -10,7 +10,7 @@ fn Run() {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Run = %Run}
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {

+ 3 - 3
toolchain/check/testdata/basics/run_i32.carbon

@@ -9,17 +9,17 @@ fn Run() -> i32 { return 0; }
 // CHECK:STDOUT: --- run_i32.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7: i32 = int_literal 0, const
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Run = %Run}
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc7: i32 = int_literal 0, const = constants.%.loc7
+// CHECK:STDOUT:   %.loc7: i32 = int_literal 0 [template = constants.%.loc7]
 // CHECK:STDOUT:   return %.loc7
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 8 - 8
toolchain/check/testdata/basics/textual_ir.carbon

@@ -15,23 +15,23 @@ fn Foo(n: i32) -> (i32, i32, f64) {
 // CHECK:STDOUT: --- textual_ir.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11_33.1: type = tuple_type (type, type, type), const
-// CHECK:STDOUT:   %.loc11_33.2: type = tuple_type (i32, i32, f64), const
-// CHECK:STDOUT:   %.loc11_33.3: type = ptr_type (i32, i32, f64), const
-// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1, const
+// CHECK:STDOUT:   %.loc11_33.1: type = tuple_type (type, type, type) [template]
+// CHECK:STDOUT:   %.loc11_33.2: type = tuple_type (i32, i32, f64) [template]
+// CHECK:STDOUT:   %.loc11_33.3: type = ptr_type (i32, i32, f64) [template]
+// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Foo = %Foo}
-// CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo, const
+// CHECK:STDOUT:   %Foo: <function> = fn_decl @Foo [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Foo(%n: i32) -> %return: (i32, i32, f64) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %n.ref: i32 = name_ref n, %n
-// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2, const = constants.%.loc12_14
-// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1, const = constants.%.loc12_17
+// CHECK:STDOUT:   %.loc12_14: i32 = int_literal 2 [template = constants.%.loc12_14]
+// CHECK:STDOUT:   %.loc12_17: f64 = real_literal 34e-1 [template = constants.%.loc12_17]
 // CHECK:STDOUT:   %.loc12_20.1: (i32, i32, f64) = tuple_literal (%n.ref, %.loc12_14, %.loc12_17)
 // CHECK:STDOUT:   %.loc12_20.2: ref i32 = tuple_access %return, element0
 // CHECK:STDOUT:   %.loc12_20.3: init i32 = initialize_from %n.ref to %.loc12_20.2

+ 27 - 27
toolchain/check/testdata/class/base.carbon

@@ -25,46 +25,46 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT: --- base.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: type = struct_type {.b: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.b: i32}, const
-// CHECK:STDOUT:   %.loc15_1.1: type = struct_type {.base: Base, .d: i32}, const
-// CHECK:STDOUT:   %.loc15_1.2: type = struct_type {.base: {.b: i32}*, .d: i32}, const
-// CHECK:STDOUT:   %.loc15_1.3: type = ptr_type {.base: {.b: i32}*, .d: i32}, const
-// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: Base, .d: i32}, const
-// CHECK:STDOUT:   %.loc18_25: i32 = int_literal 4, const
-// CHECK:STDOUT:   %.loc18_34: i32 = int_literal 7, const
-// CHECK:STDOUT:   %.loc18_35: type = struct_type {.base: {.b: i32}, .d: i32}, const
-// CHECK:STDOUT:   %.loc21_35.1: type = tuple_type (type, type), const
-// CHECK:STDOUT:   %.loc21_35.2: type = tuple_type (i32, i32), const
-// CHECK:STDOUT:   %.loc21_35.3: type = ptr_type (i32, i32), const
+// CHECK:STDOUT:   %.loc9: type = struct_type {.b: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.b: i32} [template]
+// CHECK:STDOUT:   %.loc15_1.1: type = struct_type {.base: Base, .d: i32} [template]
+// CHECK:STDOUT:   %.loc15_1.2: type = struct_type {.base: {.b: i32}*, .d: i32} [template]
+// CHECK:STDOUT:   %.loc15_1.3: type = ptr_type {.base: {.b: i32}*, .d: i32} [template]
+// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: Base, .d: i32} [template]
+// CHECK:STDOUT:   %.loc18_25: i32 = int_literal 4 [template]
+// CHECK:STDOUT:   %.loc18_34: i32 = int_literal 7 [template]
+// CHECK:STDOUT:   %.loc18_35: type = struct_type {.base: {.b: i32}, .d: i32} [template]
+// CHECK:STDOUT:   %.loc21_35.1: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.loc21_35.2: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc21_35.3: type = ptr_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Base = %Base.decl, .Derived = %Derived.decl, .Make = %Make, .Access = %Access}
 // CHECK:STDOUT:   %Base.decl = class_decl @Base, ()
-// CHECK:STDOUT:   %Base: type = class_type @Base, const
+// CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %Derived.decl = class_decl @Derived, ()
-// CHECK:STDOUT:   %Derived: type = class_type @Derived, const
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make, const
-// CHECK:STDOUT:   %Access: <function> = fn_decl @Access, const
+// CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
+// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template]
+// CHECK:STDOUT:   %Access: <function> = fn_decl @Access [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Base, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Base> = field_decl b, element0, const
-// CHECK:STDOUT:   %b: <unbound element of class Base> = bind_name b, %.loc8_8.2, const = %.loc8_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Base> = field_decl b, element0 [template]
+// CHECK:STDOUT:   %b: <unbound element of class Base> = bind_name b, %.loc8_8.2 [template = %.loc8_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .b = %b
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
-// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base, const = file.%Base
-// CHECK:STDOUT:   %.loc12_20.1: type = unbound_element_type Derived, Base, const
-// CHECK:STDOUT:   %.loc12_20.2: <unbound element of class Derived> = base_decl Base, element0, const
-// CHECK:STDOUT:   %.loc14_8.1: type = unbound_element_type Derived, i32, const
-// CHECK:STDOUT:   %.loc14_8.2: <unbound element of class Derived> = field_decl d, element1, const
-// CHECK:STDOUT:   %d: <unbound element of class Derived> = bind_name d, %.loc14_8.2, const = %.loc14_8.2
+// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base [template = file.%Base]
+// CHECK:STDOUT:   %.loc12_20.1: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.loc12_20.2: <unbound element of class Derived> = base_decl Base, element0 [template]
+// CHECK:STDOUT:   %.loc14_8.1: type = unbound_element_type Derived, i32 [template]
+// CHECK:STDOUT:   %.loc14_8.2: <unbound element of class Derived> = field_decl d, element1 [template]
+// CHECK:STDOUT:   %d: <unbound element of class Derived> = bind_name d, %.loc14_8.2 [template = %.loc14_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc12_20.2
@@ -74,9 +74,9 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: Derived {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc18_25: i32 = int_literal 4, const = constants.%.loc18_25
+// CHECK:STDOUT:   %.loc18_25: i32 = int_literal 4 [template = constants.%.loc18_25]
 // CHECK:STDOUT:   %.loc18_26.1: {.b: i32} = struct_literal (%.loc18_25)
-// CHECK:STDOUT:   %.loc18_34: i32 = int_literal 7, const = constants.%.loc18_34
+// CHECK:STDOUT:   %.loc18_34: i32 = int_literal 7 [template = constants.%.loc18_34]
 // CHECK:STDOUT:   %.loc18_35.1: {.base: {.b: i32}, .d: i32} = struct_literal (%.loc18_26.1, %.loc18_34)
 // CHECK:STDOUT:   %.loc18_35.2: ref Base = class_element_access %return, element0
 // CHECK:STDOUT:   %.loc18_26.2: ref i32 = class_element_access %.loc18_35.2, element0

+ 27 - 27
toolchain/check/testdata/class/base_field.carbon

@@ -24,33 +24,33 @@ fn Access(p: Derived*) -> i32* {
 // CHECK:STDOUT: --- base_field.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11_1.1: type = struct_type {.a: i32, .b: i32, .c: i32}, const
-// CHECK:STDOUT:   %.loc11_1.2: type = ptr_type {.a: i32, .b: i32, .c: i32}, const
-// CHECK:STDOUT:   %.loc18_1.1: type = struct_type {.base: Base, .d: i32, .e: i32}, const
-// CHECK:STDOUT:   %.loc18_1.2: type = struct_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32}, const
-// CHECK:STDOUT:   %.loc18_1.3: type = ptr_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32}, const
-// CHECK:STDOUT:   %.loc13: type = ptr_type {.base: Base, .d: i32, .e: i32}, const
+// CHECK:STDOUT:   %.loc11_1.1: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT:   %.loc11_1.2: type = ptr_type {.a: i32, .b: i32, .c: i32} [template]
+// CHECK:STDOUT:   %.loc18_1.1: type = struct_type {.base: Base, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %.loc18_1.2: type = struct_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %.loc18_1.3: type = ptr_type {.base: {.a: i32, .b: i32, .c: i32}*, .d: i32, .e: i32} [template]
+// CHECK:STDOUT:   %.loc13: type = ptr_type {.base: Base, .d: i32, .e: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Base = %Base.decl, .Derived = %Derived.decl, .Access = %Access}
 // CHECK:STDOUT:   %Base.decl = class_decl @Base, ()
-// CHECK:STDOUT:   %Base: type = class_type @Base, const
+// CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %Derived.decl = class_decl @Derived, ()
-// CHECK:STDOUT:   %Derived: type = class_type @Derived, const
-// CHECK:STDOUT:   %Access: <function> = fn_decl @Access, const
+// CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
+// CHECK:STDOUT:   %Access: <function> = fn_decl @Access [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Base, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Base> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Base> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Base, i32, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Base> = field_decl b, element1, const
-// CHECK:STDOUT:   %b: <unbound element of class Base> = bind_name b, %.loc9_8.2, const = %.loc9_8.2
-// CHECK:STDOUT:   %.loc10_8.1: type = unbound_element_type Base, i32, const
-// CHECK:STDOUT:   %.loc10_8.2: <unbound element of class Base> = field_decl c, element2, const
-// CHECK:STDOUT:   %c: <unbound element of class Base> = bind_name c, %.loc10_8.2, const = %.loc10_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Base> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Base> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Base> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %b: <unbound element of class Base> = bind_name b, %.loc9_8.2 [template = %.loc9_8.2]
+// CHECK:STDOUT:   %.loc10_8.1: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.loc10_8.2: <unbound element of class Base> = field_decl c, element2 [template]
+// CHECK:STDOUT:   %c: <unbound element of class Base> = bind_name c, %.loc10_8.2 [template = %.loc10_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
@@ -59,15 +59,15 @@ fn Access(p: Derived*) -> i32* {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
-// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base, const = file.%Base
-// CHECK:STDOUT:   %.loc14_20.1: type = unbound_element_type Derived, Base, const
-// CHECK:STDOUT:   %.loc14_20.2: <unbound element of class Derived> = base_decl Base, element0, const
-// CHECK:STDOUT:   %.loc16_8.1: type = unbound_element_type Derived, i32, const
-// CHECK:STDOUT:   %.loc16_8.2: <unbound element of class Derived> = field_decl d, element1, const
-// CHECK:STDOUT:   %d: <unbound element of class Derived> = bind_name d, %.loc16_8.2, const = %.loc16_8.2
-// CHECK:STDOUT:   %.loc17_8.1: type = unbound_element_type Derived, i32, const
-// CHECK:STDOUT:   %.loc17_8.2: <unbound element of class Derived> = field_decl e, element2, const
-// CHECK:STDOUT:   %e: <unbound element of class Derived> = bind_name e, %.loc17_8.2, const = %.loc17_8.2
+// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base [template = file.%Base]
+// CHECK:STDOUT:   %.loc14_20.1: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.loc14_20.2: <unbound element of class Derived> = base_decl Base, element0 [template]
+// CHECK:STDOUT:   %.loc16_8.1: type = unbound_element_type Derived, i32 [template]
+// CHECK:STDOUT:   %.loc16_8.2: <unbound element of class Derived> = field_decl d, element1 [template]
+// CHECK:STDOUT:   %d: <unbound element of class Derived> = bind_name d, %.loc16_8.2 [template = %.loc16_8.2]
+// CHECK:STDOUT:   %.loc17_8.1: type = unbound_element_type Derived, i32 [template]
+// CHECK:STDOUT:   %.loc17_8.2: <unbound element of class Derived> = field_decl e, element2 [template]
+// CHECK:STDOUT:   %e: <unbound element of class Derived> = bind_name e, %.loc17_8.2 [template = %.loc17_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc14_20.2

+ 15 - 15
toolchain/check/testdata/class/base_function_unqualified.carbon

@@ -22,34 +22,34 @@ fn Derived.H() {
 // CHECK:STDOUT: --- base_function_unqualified.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc16: type = struct_type {.base: Base}, const
+// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc16: type = struct_type {.base: Base} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Base = %Base.decl, .Derived = %Derived.decl}
 // CHECK:STDOUT:   %Base.decl = class_decl @Base, ()
-// CHECK:STDOUT:   %Base: type = class_type @Base, const
+// CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %Derived.decl = class_decl @Derived, ()
-// CHECK:STDOUT:   %Derived: type = class_type @Derived, const
-// CHECK:STDOUT:   %H: <function> = fn_decl @H, const
+// CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
+// CHECK:STDOUT:   %H: <function> = fn_decl @H [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
-// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base, const = file.%Base
-// CHECK:STDOUT:   %.loc12_20.1: type = unbound_element_type Derived, Base, const
-// CHECK:STDOUT:   %.loc12_20.2: <unbound element of class Derived> = base_decl Base, element0, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %H: <function> = fn_decl @H, const
+// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base [template = file.%Base]
+// CHECK:STDOUT:   %.loc12_20.1: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.loc12_20.2: <unbound element of class Derived> = base_decl Base, element0 [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %H: <function> = fn_decl @H [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc12_20.2
@@ -62,14 +62,14 @@ fn Derived.H() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F, const = @Base.%F
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F [template = @Base.%F]
 // CHECK:STDOUT:   %.loc14: init () = call %F.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @H() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F, const = @Base.%F
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Base.%F [template = @Base.%F]
 // CHECK:STDOUT:   %.loc19: init () = call %F.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 19 - 19
toolchain/check/testdata/class/base_method.carbon

@@ -25,30 +25,30 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT: --- base_method.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11: type = struct_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc14: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc19_1.1: type = struct_type {.base: Base}, const
-// CHECK:STDOUT:   %.loc19_1.2: type = struct_type {.base: {.a: i32}*}, const
-// CHECK:STDOUT:   %.loc17: type = ptr_type {.base: Base}, const
-// CHECK:STDOUT:   %.loc22: type = tuple_type (), const
+// CHECK:STDOUT:   %.loc11: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc14: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc19_1.1: type = struct_type {.base: Base} [template]
+// CHECK:STDOUT:   %.loc19_1.2: type = struct_type {.base: {.a: i32}*} [template]
+// CHECK:STDOUT:   %.loc17: type = ptr_type {.base: Base} [template]
+// CHECK:STDOUT:   %.loc22: type = tuple_type () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Base = %Base.decl, .Derived = %Derived.decl, .Call = %Call}
 // CHECK:STDOUT:   %Base.decl = class_decl @Base, ()
-// CHECK:STDOUT:   %Base: type = class_type @Base, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Base: type = class_type @Base [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:   %Derived.decl = class_decl @Derived, ()
-// CHECK:STDOUT:   %Derived: type = class_type @Derived, const
-// CHECK:STDOUT:   %Call: <function> = fn_decl @Call, const
+// CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
+// CHECK:STDOUT:   %Call: <function> = fn_decl @Call [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Base, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Base> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Base> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Base> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Base> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
@@ -56,9 +56,9 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
-// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base, const = file.%Base
-// CHECK:STDOUT:   %.loc18_20.1: type = unbound_element_type Derived, Base, const
-// CHECK:STDOUT:   %.loc18_20.2: <unbound element of class Derived> = base_decl Base, element0, const
+// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base [template = file.%Base]
+// CHECK:STDOUT:   %.loc18_20.1: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.loc18_20.2: <unbound element of class Derived> = base_decl Base, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc18_20.2
@@ -70,7 +70,7 @@ fn Call(p: Derived*) {
 // CHECK:STDOUT:   %self.ref: Base* = name_ref self, %self
 // CHECK:STDOUT:   %.loc14_4: ref Base = deref %self.ref
 // CHECK:STDOUT:   %.loc14_10: ref i32 = class_element_access %.loc14_4, element0
-// CHECK:STDOUT:   %.loc14_15: i32 = int_literal 1, const = constants.%.loc14
+// CHECK:STDOUT:   %.loc14_15: i32 = int_literal 1 [template = constants.%.loc14]
 // CHECK:STDOUT:   assign %.loc14_10, %.loc14_15
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 26 - 26
toolchain/check/testdata/class/base_method_shadow.carbon

@@ -32,42 +32,42 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT: --- base_method_shadow.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc14_1.1: type = struct_type {.base: A}, const
-// CHECK:STDOUT:   %.loc14_1.2: type = struct_type {.base: {}*}, const
-// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: A}, const
-// CHECK:STDOUT:   %.loc19_1.1: type = struct_type {.base: B}, const
-// CHECK:STDOUT:   %.loc19_1.2: type = struct_type {.base: {.base: A}*}, const
-// CHECK:STDOUT:   %.loc16: type = ptr_type {.base: B}, const
+// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc14_1.1: type = struct_type {.base: A} [template]
+// CHECK:STDOUT:   %.loc14_1.2: type = struct_type {.base: {}*} [template]
+// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: A} [template]
+// CHECK:STDOUT:   %.loc19_1.1: type = struct_type {.base: B} [template]
+// CHECK:STDOUT:   %.loc19_1.2: type = struct_type {.base: {.base: A}*} [template]
+// CHECK:STDOUT:   %.loc16: type = ptr_type {.base: B} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A.decl, .B = %B.decl, .C = %C.decl, .D = %D.decl, .Call = %Call}
 // CHECK:STDOUT:   %A.decl = class_decl @A, ()
-// CHECK:STDOUT:   %A: type = class_type @A, const
+// CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %B.decl = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %C.decl = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
+// CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %D.decl = class_decl @D, ()
-// CHECK:STDOUT:   %D: type = class_type @D, const
-// CHECK:STDOUT:   %Call: <function> = fn_decl @Call, const
+// CHECK:STDOUT:   %D: type = class_type @D [template]
+// CHECK:STDOUT:   %Call: <function> = fn_decl @Call [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
-// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A, const = file.%A
-// CHECK:STDOUT:   %.loc12_17.1: type = unbound_element_type B, A, const
-// CHECK:STDOUT:   %.loc12_17.2: <unbound element of class B> = base_decl A, element0, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2, const
+// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A [template = file.%A]
+// CHECK:STDOUT:   %.loc12_17.1: type = unbound_element_type B, A [template]
+// CHECK:STDOUT:   %.loc12_17.2: <unbound element of class B> = base_decl A, element0 [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc12_17.2
@@ -76,10 +76,10 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc17_17.1: type = unbound_element_type C, B, const
-// CHECK:STDOUT:   %.loc17_17.2: <unbound element of class C> = base_decl B, element0, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.3, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc17_17.1: type = unbound_element_type C, B [template]
+// CHECK:STDOUT:   %.loc17_17.2: <unbound element of class C> = base_decl B, element0 [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.3 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc17_17.2
@@ -88,9 +88,9 @@ fn Call(a: A*, b: B*, c: C*, d: D*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @D {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc22_17.1: type = unbound_element_type D, B, const
-// CHECK:STDOUT:   %.loc22_17.2: <unbound element of class D> = base_decl B, element0, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc22_17.1: type = unbound_element_type D, B [template]
+// CHECK:STDOUT:   %.loc22_17.2: <unbound element of class D> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc22_17.2

+ 13 - 13
toolchain/check/testdata/class/basic.carbon

@@ -25,24 +25,24 @@ fn Run() -> i32 {
 // CHECK:STDOUT: --- basic.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc15: type = struct_type {.k: i32}, const
-// CHECK:STDOUT:   %.loc22: i32 = int_literal 4, const
+// CHECK:STDOUT:   %.loc15: type = struct_type {.k: i32} [template]
+// CHECK:STDOUT:   %.loc22: i32 = int_literal 4 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .Run = %Run}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %.loc14_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc14_8.2: <unbound element of class Class> = field_decl k, element0, const
-// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc14_8.2, const = %.loc14_8.2
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %.loc14_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc14_8.2: <unbound element of class Class> = field_decl k, element0 [template]
+// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc14_8.2 [template = %.loc14_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -64,9 +64,9 @@ fn Run() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Class.%F, const = @Class.%F
-// CHECK:STDOUT:   %.loc22_18: i32 = int_literal 4, const = constants.%.loc22
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Class.%F [template = @Class.%F]
+// CHECK:STDOUT:   %.loc22_18: i32 = int_literal 4 [template = constants.%.loc22]
 // CHECK:STDOUT:   %.loc22_17: init i32 = call %F.ref(%.loc22_18)
 // CHECK:STDOUT:   %.loc22_20.1: i32 = value_of_initializer %.loc22_17
 // CHECK:STDOUT:   %.loc22_20.2: i32 = converted %.loc22_17, %.loc22_20.1

+ 46 - 46
toolchain/check/testdata/class/derived_to_base.carbon

@@ -37,55 +37,55 @@ fn ConvertInit() {
 // CHECK:STDOUT: --- derived_to_base.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: type = struct_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc14_1.1: type = struct_type {.base: A, .b: i32}, const
-// CHECK:STDOUT:   %.loc14_1.2: type = struct_type {.base: {.a: i32}*, .b: i32}, const
-// CHECK:STDOUT:   %.loc14_1.3: type = ptr_type {.base: {.a: i32}*, .b: i32}, const
-// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: A, .b: i32}, const
-// CHECK:STDOUT:   %.loc19_1.1: type = struct_type {.base: B, .c: i32}, const
-// CHECK:STDOUT:   %.loc19_1.2: type = struct_type {.base: {.base: A, .b: i32}*, .c: i32}, const
-// CHECK:STDOUT:   %.loc19_1.3: type = ptr_type {.base: {.base: A, .b: i32}*, .c: i32}, const
-// CHECK:STDOUT:   %.loc16: type = ptr_type {.base: B, .c: i32}, const
-// CHECK:STDOUT:   %.loc34_38: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc34_47: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc34_48: type = struct_type {.base: {.a: i32}, .b: i32}, const
-// CHECK:STDOUT:   %.loc34_56: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc34_57: type = struct_type {.base: {.base: {.a: i32}, .b: i32}, .c: i32}, const
+// CHECK:STDOUT:   %.loc9: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc14_1.1: type = struct_type {.base: A, .b: i32} [template]
+// CHECK:STDOUT:   %.loc14_1.2: type = struct_type {.base: {.a: i32}*, .b: i32} [template]
+// CHECK:STDOUT:   %.loc14_1.3: type = ptr_type {.base: {.a: i32}*, .b: i32} [template]
+// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: A, .b: i32} [template]
+// CHECK:STDOUT:   %.loc19_1.1: type = struct_type {.base: B, .c: i32} [template]
+// CHECK:STDOUT:   %.loc19_1.2: type = struct_type {.base: {.base: A, .b: i32}*, .c: i32} [template]
+// CHECK:STDOUT:   %.loc19_1.3: type = ptr_type {.base: {.base: A, .b: i32}*, .c: i32} [template]
+// CHECK:STDOUT:   %.loc16: type = ptr_type {.base: B, .c: i32} [template]
+// CHECK:STDOUT:   %.loc34_38: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc34_47: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc34_48: type = struct_type {.base: {.a: i32}, .b: i32} [template]
+// CHECK:STDOUT:   %.loc34_56: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc34_57: type = struct_type {.base: {.base: {.a: i32}, .b: i32}, .c: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A.decl, .B = %B.decl, .C = %C.decl, .ConvertCToB = %ConvertCToB, .ConvertBToA = %ConvertBToA, .ConvertCToA = %ConvertCToA, .ConvertValue = %ConvertValue, .ConvertRef = %ConvertRef, .ConvertInit = %ConvertInit}
 // CHECK:STDOUT:   %A.decl = class_decl @A, ()
-// CHECK:STDOUT:   %A: type = class_type @A, const
+// CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %B.decl = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %C.decl = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
-// CHECK:STDOUT:   %ConvertCToB: <function> = fn_decl @ConvertCToB, const
-// CHECK:STDOUT:   %ConvertBToA: <function> = fn_decl @ConvertBToA, const
-// CHECK:STDOUT:   %ConvertCToA: <function> = fn_decl @ConvertCToA, const
-// CHECK:STDOUT:   %ConvertValue: <function> = fn_decl @ConvertValue, const
-// CHECK:STDOUT:   %ConvertRef: <function> = fn_decl @ConvertRef, const
-// CHECK:STDOUT:   %ConvertInit: <function> = fn_decl @ConvertInit, const
+// CHECK:STDOUT:   %C: type = class_type @C [template]
+// CHECK:STDOUT:   %ConvertCToB: <function> = fn_decl @ConvertCToB [template]
+// CHECK:STDOUT:   %ConvertBToA: <function> = fn_decl @ConvertBToA [template]
+// CHECK:STDOUT:   %ConvertCToA: <function> = fn_decl @ConvertCToA [template]
+// CHECK:STDOUT:   %ConvertValue: <function> = fn_decl @ConvertValue [template]
+// CHECK:STDOUT:   %ConvertRef: <function> = fn_decl @ConvertRef [template]
+// CHECK:STDOUT:   %ConvertInit: <function> = fn_decl @ConvertInit [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type A, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class A> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class A> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type A, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class A> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class A> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
-// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A, const = file.%A
-// CHECK:STDOUT:   %.loc12_17.1: type = unbound_element_type B, A, const
-// CHECK:STDOUT:   %.loc12_17.2: <unbound element of class B> = base_decl A, element0, const
-// CHECK:STDOUT:   %.loc13_8.1: type = unbound_element_type B, i32, const
-// CHECK:STDOUT:   %.loc13_8.2: <unbound element of class B> = field_decl b, element1, const
-// CHECK:STDOUT:   %b: <unbound element of class B> = bind_name b, %.loc13_8.2, const = %.loc13_8.2
+// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A [template = file.%A]
+// CHECK:STDOUT:   %.loc12_17.1: type = unbound_element_type B, A [template]
+// CHECK:STDOUT:   %.loc12_17.2: <unbound element of class B> = base_decl A, element0 [template]
+// CHECK:STDOUT:   %.loc13_8.1: type = unbound_element_type B, i32 [template]
+// CHECK:STDOUT:   %.loc13_8.2: <unbound element of class B> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %b: <unbound element of class B> = bind_name b, %.loc13_8.2 [template = %.loc13_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc12_17.2
@@ -94,12 +94,12 @@ fn ConvertInit() {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc17_17.1: type = unbound_element_type C, B, const
-// CHECK:STDOUT:   %.loc17_17.2: <unbound element of class C> = base_decl B, element0, const
-// CHECK:STDOUT:   %.loc18_8.1: type = unbound_element_type C, i32, const
-// CHECK:STDOUT:   %.loc18_8.2: <unbound element of class C> = field_decl c, element1, const
-// CHECK:STDOUT:   %c: <unbound element of class C> = bind_name c, %.loc18_8.2, const = %.loc18_8.2
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc17_17.1: type = unbound_element_type C, B [template]
+// CHECK:STDOUT:   %.loc17_17.2: <unbound element of class C> = base_decl B, element0 [template]
+// CHECK:STDOUT:   %.loc18_8.1: type = unbound_element_type C, i32 [template]
+// CHECK:STDOUT:   %.loc18_8.2: <unbound element of class C> = field_decl c, element1 [template]
+// CHECK:STDOUT:   %c: <unbound element of class C> = bind_name c, %.loc18_8.2 [template = %.loc18_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc17_17.2
@@ -140,7 +140,7 @@ fn ConvertInit() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @ConvertValue(%c: C) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A, const = file.%A
+// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A [template = file.%A]
 // CHECK:STDOUT:   %c.ref: C = name_ref c, %c
 // CHECK:STDOUT:   %.loc26_15.1: ref B = class_element_access %c.ref, element0
 // CHECK:STDOUT:   %.loc26_15.2: ref A = class_element_access %.loc26_15.1, element0
@@ -154,7 +154,7 @@ fn ConvertInit() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %c.ref: C* = name_ref c, %c
 // CHECK:STDOUT:   %.loc30_12: ref C = deref %c.ref
-// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A, const = file.%A
+// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A [template = file.%A]
 // CHECK:STDOUT:   %.loc30_15.1: ref B = class_element_access %.loc30_12, element0
 // CHECK:STDOUT:   %.loc30_15.2: ref A = class_element_access %.loc30_15.1, element0
 // CHECK:STDOUT:   %.loc30_15.3: ref A = converted %.loc30_12, %.loc30_15.2
@@ -164,14 +164,14 @@ fn ConvertInit() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @ConvertInit() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A, const = file.%A
-// CHECK:STDOUT:   %.loc34_38: i32 = int_literal 1, const = constants.%.loc34_38
+// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A [template = file.%A]
+// CHECK:STDOUT:   %.loc34_38: i32 = int_literal 1 [template = constants.%.loc34_38]
 // CHECK:STDOUT:   %.loc34_39.1: {.a: i32} = struct_literal (%.loc34_38)
-// CHECK:STDOUT:   %.loc34_47: i32 = int_literal 2, const = constants.%.loc34_47
+// CHECK:STDOUT:   %.loc34_47: i32 = int_literal 2 [template = constants.%.loc34_47]
 // CHECK:STDOUT:   %.loc34_48.1: {.base: {.a: i32}, .b: i32} = struct_literal (%.loc34_39.1, %.loc34_47)
-// CHECK:STDOUT:   %.loc34_56: i32 = int_literal 3, const = constants.%.loc34_56
+// CHECK:STDOUT:   %.loc34_56: i32 = int_literal 3 [template = constants.%.loc34_56]
 // CHECK:STDOUT:   %.loc34_57.1: {.base: {.base: {.a: i32}, .b: i32}, .c: i32} = struct_literal (%.loc34_48.1, %.loc34_56)
-// CHECK:STDOUT:   %C.ref: type = name_ref C, file.%C, const = file.%C
+// CHECK:STDOUT:   %C.ref: type = name_ref C, file.%C [template = file.%C]
 // CHECK:STDOUT:   %.loc34_57.2: ref C = temporary_storage
 // CHECK:STDOUT:   %.loc34_57.3: ref B = class_element_access %.loc34_57.2, element0
 // CHECK:STDOUT:   %.loc34_48.2: ref A = class_element_access %.loc34_57.3, element0

+ 27 - 27
toolchain/check/testdata/class/fail_abstract.carbon

@@ -29,46 +29,46 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT: --- fail_abstract.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: type = struct_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc15_1.1: type = struct_type {.base: Abstract, .d: i32}, const
-// CHECK:STDOUT:   %.loc15_1.2: type = struct_type {.base: {.a: i32}*, .d: i32}, const
-// CHECK:STDOUT:   %.loc15_1.3: type = ptr_type {.base: {.a: i32}*, .d: i32}, const
-// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: Abstract, .d: i32}, const
-// CHECK:STDOUT:   %.loc22_25: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc22_34: i32 = int_literal 7, const
-// CHECK:STDOUT:   %.loc22_35: type = struct_type {.base: {.a: i32}, .d: i32}, const
-// CHECK:STDOUT:   %.loc25_35.1: type = tuple_type (type, type), const
-// CHECK:STDOUT:   %.loc25_35.2: type = tuple_type (i32, i32), const
-// CHECK:STDOUT:   %.loc25_35.3: type = ptr_type (i32, i32), const
+// CHECK:STDOUT:   %.loc9: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc15_1.1: type = struct_type {.base: Abstract, .d: i32} [template]
+// CHECK:STDOUT:   %.loc15_1.2: type = struct_type {.base: {.a: i32}*, .d: i32} [template]
+// CHECK:STDOUT:   %.loc15_1.3: type = ptr_type {.base: {.a: i32}*, .d: i32} [template]
+// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: Abstract, .d: i32} [template]
+// CHECK:STDOUT:   %.loc22_25: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc22_34: i32 = int_literal 7 [template]
+// CHECK:STDOUT:   %.loc22_35: type = struct_type {.base: {.a: i32}, .d: i32} [template]
+// CHECK:STDOUT:   %.loc25_35.1: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.loc25_35.2: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc25_35.3: type = ptr_type (i32, i32) [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Abstract = %Abstract.decl, .Derived = %Derived.decl, .Make = %Make, .Access = %Access}
 // CHECK:STDOUT:   %Abstract.decl = class_decl @Abstract, ()
-// CHECK:STDOUT:   %Abstract: type = class_type @Abstract, const
+// CHECK:STDOUT:   %Abstract: type = class_type @Abstract [template]
 // CHECK:STDOUT:   %Derived.decl = class_decl @Derived, ()
-// CHECK:STDOUT:   %Derived: type = class_type @Derived, const
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make, const
-// CHECK:STDOUT:   %Access: <function> = fn_decl @Access, const
+// CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
+// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template]
+// CHECK:STDOUT:   %Access: <function> = fn_decl @Access [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Abstract {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Abstract, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Abstract> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Abstract> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Abstract, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Abstract> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Abstract> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
-// CHECK:STDOUT:   %Abstract.ref: type = name_ref Abstract, file.%Abstract, const = file.%Abstract
-// CHECK:STDOUT:   %.loc12_24.1: type = unbound_element_type Derived, Abstract, const
-// CHECK:STDOUT:   %.loc12_24.2: <unbound element of class Derived> = base_decl Abstract, element0, const
-// CHECK:STDOUT:   %.loc14_8.1: type = unbound_element_type Derived, i32, const
-// CHECK:STDOUT:   %.loc14_8.2: <unbound element of class Derived> = field_decl d, element1, const
-// CHECK:STDOUT:   %d: <unbound element of class Derived> = bind_name d, %.loc14_8.2, const = %.loc14_8.2
+// CHECK:STDOUT:   %Abstract.ref: type = name_ref Abstract, file.%Abstract [template = file.%Abstract]
+// CHECK:STDOUT:   %.loc12_24.1: type = unbound_element_type Derived, Abstract [template]
+// CHECK:STDOUT:   %.loc12_24.2: <unbound element of class Derived> = base_decl Abstract, element0 [template]
+// CHECK:STDOUT:   %.loc14_8.1: type = unbound_element_type Derived, i32 [template]
+// CHECK:STDOUT:   %.loc14_8.2: <unbound element of class Derived> = field_decl d, element1 [template]
+// CHECK:STDOUT:   %d: <unbound element of class Derived> = bind_name d, %.loc14_8.2 [template = %.loc14_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc12_24.2
@@ -78,9 +78,9 @@ fn Access(d: Derived) -> (i32, i32) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Make() -> %return: Derived {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc22_25: i32 = int_literal 1, const = constants.%.loc22_25
+// CHECK:STDOUT:   %.loc22_25: i32 = int_literal 1 [template = constants.%.loc22_25]
 // CHECK:STDOUT:   %.loc22_26: {.a: i32} = struct_literal (%.loc22_25)
-// CHECK:STDOUT:   %.loc22_34: i32 = int_literal 7, const = constants.%.loc22_34
+// CHECK:STDOUT:   %.loc22_34: i32 = int_literal 7 [template = constants.%.loc22_34]
 // CHECK:STDOUT:   %.loc22_35: {.base: {.a: i32}, .d: i32} = struct_literal (%.loc22_26, %.loc22_34)
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }

+ 4 - 4
toolchain/check/testdata/class/fail_addr_not_self.carbon

@@ -19,18 +19,18 @@ class Class {
 // CHECK:STDOUT: --- fail_addr_not_self.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc17: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc17: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F

+ 7 - 7
toolchain/check/testdata/class/fail_addr_self.carbon

@@ -41,21 +41,21 @@ fn F(c: Class, p: Class*) {
 // CHECK:STDOUT: --- fail_addr_self.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc10_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .F = %F}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F

+ 61 - 61
toolchain/check/testdata/class/fail_base_bad_type.carbon

@@ -120,58 +120,58 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: --- fail_base_bad_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_18.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc10: type = struct_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc17: type = struct_type {.base: <error>}, const
-// CHECK:STDOUT:   %.loc12: type = ptr_type {.base: <error>}, const
-// CHECK:STDOUT:   %.loc26: i32 = int_literal 32, const
-// CHECK:STDOUT:   %.loc51_22: type = tuple_type (type), const
-// CHECK:STDOUT:   %.loc51_23.1: type = tuple_type (Base), const
-// CHECK:STDOUT:   %.loc7_18.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7_17: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc51_23.2: type = tuple_type ({}*), const
-// CHECK:STDOUT:   %.loc67: type = ptr_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc8: type = ptr_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc102_1.1: type = struct_type {.base: Final}, const
-// CHECK:STDOUT:   %.loc102_1.2: type = struct_type {.base: {.a: i32}*}, const
-// CHECK:STDOUT:   %.loc97: type = ptr_type {.base: Final}, const
+// CHECK:STDOUT:   %.loc7_18.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc10: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc17: type = struct_type {.base: <error>} [template]
+// CHECK:STDOUT:   %.loc12: type = ptr_type {.base: <error>} [template]
+// CHECK:STDOUT:   %.loc26: i32 = int_literal 32 [template]
+// CHECK:STDOUT:   %.loc51_22: type = tuple_type (type) [template]
+// CHECK:STDOUT:   %.loc51_23.1: type = tuple_type (Base) [template]
+// CHECK:STDOUT:   %.loc7_18.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7_17: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc51_23.2: type = tuple_type ({}*) [template]
+// CHECK:STDOUT:   %.loc67: type = ptr_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc8: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc102_1.1: type = struct_type {.base: Final} [template]
+// CHECK:STDOUT:   %.loc102_1.2: type = struct_type {.base: {.a: i32}*} [template]
+// CHECK:STDOUT:   %.loc97: type = ptr_type {.base: Final} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Base = %Base.decl, .Final = %Final.decl, .DeriveFromError = %DeriveFromError.decl, .AccessMemberWithInvalidBaseError = %AccessMemberWithInvalidBaseError, .DeriveFromNonType = %DeriveFromNonType.decl, .AccessMemberWithInvalidBasNonType = %AccessMemberWithInvalidBasNonType, .DeriveFromi32 = %DeriveFromi32.decl, .ConvertToBadBasei32 = %ConvertToBadBasei32, .AccessMemberWithInvalidBasei32 = %AccessMemberWithInvalidBasei32, .DeriveFromTuple = %DeriveFromTuple.decl, .ConvertToBadBaseTuple = %ConvertToBadBaseTuple, .AccessMemberWithInvalidBaseTuple = %AccessMemberWithInvalidBaseTuple, .DeriveFromStruct = %DeriveFromStruct.decl, .ConvertToBadBaseStruct = %ConvertToBadBaseStruct, .AccessMemberWithInvalidBaseStruct = %AccessMemberWithInvalidBaseStruct, .Incomplete = %Incomplete.decl, .DeriveFromIncomplete = %DeriveFromIncomplete.decl, .ConvertToBadBaseIncomplete = %ConvertToBadBaseIncomplete, .AccessMemberWithInvalidBaseIncomplete = %AccessMemberWithInvalidBaseIncomplete, .DeriveFromFinal = %DeriveFromFinal.decl, .ConvertToBadBaseFinal = %ConvertToBadBaseFinal, .AccessMemberWithInvalidBaseFinal_WithMember = %AccessMemberWithInvalidBaseFinal_WithMember, .AccessMemberWithInvalidBaseFinal_NoMember = %AccessMemberWithInvalidBaseFinal_NoMember}
 // CHECK:STDOUT:   %Base.decl = class_decl @Base, ()
-// CHECK:STDOUT:   %Base: type = class_type @Base, const
+// CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %Final.decl = class_decl @Final, ()
-// CHECK:STDOUT:   %Final: type = class_type @Final, const
+// CHECK:STDOUT:   %Final: type = class_type @Final [template]
 // CHECK:STDOUT:   %DeriveFromError.decl = class_decl @DeriveFromError, ()
-// CHECK:STDOUT:   %DeriveFromError: type = class_type @DeriveFromError, const
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseError: <function> = fn_decl @AccessMemberWithInvalidBaseError, const
+// CHECK:STDOUT:   %DeriveFromError: type = class_type @DeriveFromError [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseError: <function> = fn_decl @AccessMemberWithInvalidBaseError [template]
 // CHECK:STDOUT:   %DeriveFromNonType.decl = class_decl @DeriveFromNonType, ()
-// CHECK:STDOUT:   %DeriveFromNonType: type = class_type @DeriveFromNonType, const
-// CHECK:STDOUT:   %AccessMemberWithInvalidBasNonType: <function> = fn_decl @AccessMemberWithInvalidBasNonType, const
+// CHECK:STDOUT:   %DeriveFromNonType: type = class_type @DeriveFromNonType [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBasNonType: <function> = fn_decl @AccessMemberWithInvalidBasNonType [template]
 // CHECK:STDOUT:   %DeriveFromi32.decl = class_decl @DeriveFromi32, ()
-// CHECK:STDOUT:   %DeriveFromi32: type = class_type @DeriveFromi32, const
-// CHECK:STDOUT:   %ConvertToBadBasei32: <function> = fn_decl @ConvertToBadBasei32, const
-// CHECK:STDOUT:   %AccessMemberWithInvalidBasei32: <function> = fn_decl @AccessMemberWithInvalidBasei32, const
+// CHECK:STDOUT:   %DeriveFromi32: type = class_type @DeriveFromi32 [template]
+// CHECK:STDOUT:   %ConvertToBadBasei32: <function> = fn_decl @ConvertToBadBasei32 [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBasei32: <function> = fn_decl @AccessMemberWithInvalidBasei32 [template]
 // CHECK:STDOUT:   %DeriveFromTuple.decl = class_decl @DeriveFromTuple, ()
-// CHECK:STDOUT:   %DeriveFromTuple: type = class_type @DeriveFromTuple, const
-// CHECK:STDOUT:   %ConvertToBadBaseTuple: <function> = fn_decl @ConvertToBadBaseTuple, const
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseTuple: <function> = fn_decl @AccessMemberWithInvalidBaseTuple, const
+// CHECK:STDOUT:   %DeriveFromTuple: type = class_type @DeriveFromTuple [template]
+// CHECK:STDOUT:   %ConvertToBadBaseTuple: <function> = fn_decl @ConvertToBadBaseTuple [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseTuple: <function> = fn_decl @AccessMemberWithInvalidBaseTuple [template]
 // CHECK:STDOUT:   %DeriveFromStruct.decl = class_decl @DeriveFromStruct, ()
-// CHECK:STDOUT:   %DeriveFromStruct: type = class_type @DeriveFromStruct, const
-// CHECK:STDOUT:   %ConvertToBadBaseStruct: <function> = fn_decl @ConvertToBadBaseStruct, const
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseStruct: <function> = fn_decl @AccessMemberWithInvalidBaseStruct, const
+// CHECK:STDOUT:   %DeriveFromStruct: type = class_type @DeriveFromStruct [template]
+// CHECK:STDOUT:   %ConvertToBadBaseStruct: <function> = fn_decl @ConvertToBadBaseStruct [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseStruct: <function> = fn_decl @AccessMemberWithInvalidBaseStruct [template]
 // CHECK:STDOUT:   %Incomplete.decl = class_decl @Incomplete, ()
-// CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete, const
+// CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete [template]
 // CHECK:STDOUT:   %DeriveFromIncomplete.decl = class_decl @DeriveFromIncomplete, ()
-// CHECK:STDOUT:   %DeriveFromIncomplete: type = class_type @DeriveFromIncomplete, const
-// CHECK:STDOUT:   %ConvertToBadBaseIncomplete: <function> = fn_decl @ConvertToBadBaseIncomplete, const
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseIncomplete: <function> = fn_decl @AccessMemberWithInvalidBaseIncomplete, const
+// CHECK:STDOUT:   %DeriveFromIncomplete: type = class_type @DeriveFromIncomplete [template]
+// CHECK:STDOUT:   %ConvertToBadBaseIncomplete: <function> = fn_decl @ConvertToBadBaseIncomplete [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseIncomplete: <function> = fn_decl @AccessMemberWithInvalidBaseIncomplete [template]
 // CHECK:STDOUT:   %DeriveFromFinal.decl = class_decl @DeriveFromFinal, ()
-// CHECK:STDOUT:   %DeriveFromFinal: type = class_type @DeriveFromFinal, const
-// CHECK:STDOUT:   %ConvertToBadBaseFinal: <function> = fn_decl @ConvertToBadBaseFinal, const
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_WithMember: <function> = fn_decl @AccessMemberWithInvalidBaseFinal_WithMember, const
-// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_NoMember: <function> = fn_decl @AccessMemberWithInvalidBaseFinal_NoMember, const
+// CHECK:STDOUT:   %DeriveFromFinal: type = class_type @DeriveFromFinal [template]
+// CHECK:STDOUT:   %ConvertToBadBaseFinal: <function> = fn_decl @ConvertToBadBaseFinal [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_WithMember: <function> = fn_decl @AccessMemberWithInvalidBaseFinal_WithMember [template]
+// CHECK:STDOUT:   %AccessMemberWithInvalidBaseFinal_NoMember: <function> = fn_decl @AccessMemberWithInvalidBaseFinal_NoMember [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
@@ -180,9 +180,9 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Final {
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Final, i32, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Final> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Final> = bind_name a, %.loc9_8.2, const = %.loc9_8.2
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Final, i32 [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Final> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Final> = bind_name a, %.loc9_8.2 [template = %.loc9_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
@@ -190,8 +190,8 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromError {
 // CHECK:STDOUT:   %error.ref: <error> = name_ref error, <error>
-// CHECK:STDOUT:   %.loc16_21.1: type = unbound_element_type DeriveFromError, <error>, const
-// CHECK:STDOUT:   %.loc16_21.2: <unbound element of class DeriveFromError> = base_decl <error>, element0, const
+// CHECK:STDOUT:   %.loc16_21.1: type = unbound_element_type DeriveFromError, <error> [template]
+// CHECK:STDOUT:   %.loc16_21.2: <unbound element of class DeriveFromError> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc16_21.2
@@ -199,9 +199,9 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromNonType {
-// CHECK:STDOUT:   %.loc26_16: i32 = int_literal 32, const = constants.%.loc26
-// CHECK:STDOUT:   %.loc26_18.1: type = unbound_element_type DeriveFromNonType, <error>, const
-// CHECK:STDOUT:   %.loc26_18.2: <unbound element of class DeriveFromNonType> = base_decl <error>, element0, const
+// CHECK:STDOUT:   %.loc26_16: i32 = int_literal 32 [template = constants.%.loc26]
+// CHECK:STDOUT:   %.loc26_18.1: type = unbound_element_type DeriveFromNonType, <error> [template]
+// CHECK:STDOUT:   %.loc26_18.2: <unbound element of class DeriveFromNonType> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc26_18.2
@@ -209,8 +209,8 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromi32 {
-// CHECK:STDOUT:   %.loc35_19.1: type = unbound_element_type DeriveFromi32, <error>, const
-// CHECK:STDOUT:   %.loc35_19.2: <unbound element of class DeriveFromi32> = base_decl <error>, element0, const
+// CHECK:STDOUT:   %.loc35_19.1: type = unbound_element_type DeriveFromi32, <error> [template]
+// CHECK:STDOUT:   %.loc35_19.2: <unbound element of class DeriveFromi32> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc35_19.2
@@ -218,11 +218,11 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromTuple {
-// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base, const = file.%Base
+// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base [template = file.%Base]
 // CHECK:STDOUT:   %.loc51_22: (type,) = tuple_literal (%Base.ref)
-// CHECK:STDOUT:   %.loc51_23.1: type = converted %.loc51_22, constants.%.loc51_23.1, const = constants.%.loc51_23.1
-// CHECK:STDOUT:   %.loc51_23.2: type = unbound_element_type DeriveFromTuple, <error>, const
-// CHECK:STDOUT:   %.loc51_23.3: <unbound element of class DeriveFromTuple> = base_decl <error>, element0, const
+// CHECK:STDOUT:   %.loc51_23.1: type = converted %.loc51_22, constants.%.loc51_23.1 [template = constants.%.loc51_23.1]
+// CHECK:STDOUT:   %.loc51_23.2: type = unbound_element_type DeriveFromTuple, <error> [template]
+// CHECK:STDOUT:   %.loc51_23.3: <unbound element of class DeriveFromTuple> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc51_23.3
@@ -230,9 +230,9 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromStruct {
-// CHECK:STDOUT:   %.loc67_33: type = struct_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc67_34.1: type = unbound_element_type DeriveFromStruct, <error>, const
-// CHECK:STDOUT:   %.loc67_34.2: <unbound element of class DeriveFromStruct> = base_decl <error>, element0, const
+// CHECK:STDOUT:   %.loc67_33: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc67_34.1: type = unbound_element_type DeriveFromStruct, <error> [template]
+// CHECK:STDOUT:   %.loc67_34.2: <unbound element of class DeriveFromStruct> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc67_34.2
@@ -242,9 +242,9 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: class @Incomplete;
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromIncomplete {
-// CHECK:STDOUT:   %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete, const = file.%Incomplete
-// CHECK:STDOUT:   %.loc87_26.1: type = unbound_element_type DeriveFromIncomplete, <error>, const
-// CHECK:STDOUT:   %.loc87_26.2: <unbound element of class DeriveFromIncomplete> = base_decl <error>, element0, const
+// CHECK:STDOUT:   %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete [template = file.%Incomplete]
+// CHECK:STDOUT:   %.loc87_26.1: type = unbound_element_type DeriveFromIncomplete, <error> [template]
+// CHECK:STDOUT:   %.loc87_26.2: <unbound element of class DeriveFromIncomplete> = base_decl <error>, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc87_26.2
@@ -252,9 +252,9 @@ fn AccessMemberWithInvalidBaseFinal_NoMember(p: DeriveFromFinal*) -> i32 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DeriveFromFinal {
-// CHECK:STDOUT:   %Final.ref: type = name_ref Final, file.%Final, const = file.%Final
-// CHECK:STDOUT:   %.loc101_21.1: type = unbound_element_type DeriveFromFinal, Final, const
-// CHECK:STDOUT:   %.loc101_21.2: <unbound element of class DeriveFromFinal> = base_decl Final, element0, const
+// CHECK:STDOUT:   %Final.ref: type = name_ref Final, file.%Final [template = file.%Final]
+// CHECK:STDOUT:   %.loc101_21.1: type = unbound_element_type DeriveFromFinal, Final [template]
+// CHECK:STDOUT:   %.loc101_21.2: <unbound element of class DeriveFromFinal> = base_decl Final, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc101_21.2

+ 14 - 14
toolchain/check/testdata/class/fail_base_method_define.carbon

@@ -29,26 +29,26 @@ fn D.C.F() {}
 // CHECK:STDOUT: --- fail_base_method_define.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc12_3.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc12_3.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc17: type = struct_type {.base: B}, const
+// CHECK:STDOUT:   %.loc12_3.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc12_3.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc17: type = struct_type {.base: B} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.B = %B.decl, .D = %D.decl}
 // CHECK:STDOUT:   %B.decl = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %D.decl = class_decl @D, ()
-// CHECK:STDOUT:   %D: type = class_type @D, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.3, const
-// CHECK:STDOUT:   %.loc27: <function> = fn_decl @.1, const
+// CHECK:STDOUT:   %D: type = class_type @D [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.3 [template]
+// CHECK:STDOUT:   %.loc27: <function> = fn_decl @.1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template]
 // CHECK:STDOUT:   %C.decl = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
+// CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -56,16 +56,16 @@ fn D.C.F() {}
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @D {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc16_17.1: type = unbound_element_type D, B, const
-// CHECK:STDOUT:   %.loc16_17.2: <unbound element of class D> = base_decl B, element0, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc16_17.1: type = unbound_element_type D, B [template]
+// CHECK:STDOUT:   %.loc16_17.2: <unbound element of class D> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc16_17.2

+ 1 - 1
toolchain/check/testdata/class/fail_base_misplaced.carbon

@@ -24,7 +24,7 @@ fn F() {
 // CHECK:STDOUT: --- fail_base_misplaced.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc7: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {

+ 21 - 21
toolchain/check/testdata/class/fail_base_modifiers.carbon

@@ -46,24 +46,24 @@ class C4 {
 // CHECK:STDOUT: --- fail_base_modifiers.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_15.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc7_15.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7_14: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc14: type = struct_type {.base: B}, const
+// CHECK:STDOUT:   %.loc7_15.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc7_15.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7_14: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc14: type = struct_type {.base: B} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.B = %B.decl, .C1 = %C1.decl, .C2 = %C2.decl, .C3 = %C3.decl, .C4 = %C4.decl}
 // CHECK:STDOUT:   %B.decl = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %C1.decl = class_decl @C1, ()
-// CHECK:STDOUT:   %C1: type = class_type @C1, const
+// CHECK:STDOUT:   %C1: type = class_type @C1 [template]
 // CHECK:STDOUT:   %C2.decl = class_decl @C2, ()
-// CHECK:STDOUT:   %C2: type = class_type @C2, const
+// CHECK:STDOUT:   %C2: type = class_type @C2 [template]
 // CHECK:STDOUT:   %C3.decl = class_decl @C3, ()
-// CHECK:STDOUT:   %C3: type = class_type @C3, const
+// CHECK:STDOUT:   %C3: type = class_type @C3 [template]
 // CHECK:STDOUT:   %C4.decl = class_decl @C4, ()
-// CHECK:STDOUT:   %C4: type = class_type @C4, const
+// CHECK:STDOUT:   %C4: type = class_type @C4 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
@@ -72,9 +72,9 @@ class C4 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C1 {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc13_25.1: type = unbound_element_type C1, B, const
-// CHECK:STDOUT:   %.loc13_25.2: <unbound element of class C1> = base_decl B, element0, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc13_25.1: type = unbound_element_type C1, B [template]
+// CHECK:STDOUT:   %.loc13_25.2: <unbound element of class C1> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc13_25.2
@@ -82,18 +82,18 @@ class C4 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C2 {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc23_19.1: type = unbound_element_type C2, B, const
-// CHECK:STDOUT:   %.loc23_19.2: <unbound element of class C2> = base_decl B, element0, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc23_19.1: type = unbound_element_type C2, B [template]
+// CHECK:STDOUT:   %.loc23_19.2: <unbound element of class C2> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc23_19.2
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C3 {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc33_25.1: type = unbound_element_type C3, B, const
-// CHECK:STDOUT:   %.loc33_25.2: <unbound element of class C3> = base_decl B, element0, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc33_25.1: type = unbound_element_type C3, B [template]
+// CHECK:STDOUT:   %.loc33_25.2: <unbound element of class C3> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc33_25.2
@@ -101,9 +101,9 @@ class C4 {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C4 {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc43_24.1: type = unbound_element_type C4, B, const
-// CHECK:STDOUT:   %.loc43_24.2: <unbound element of class C4> = base_decl B, element0, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc43_24.1: type = unbound_element_type C4, B [template]
+// CHECK:STDOUT:   %.loc43_24.2: <unbound element of class C4> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc43_24.2

+ 9 - 9
toolchain/check/testdata/class/fail_base_no_extend.carbon

@@ -16,18 +16,18 @@ class C {
 // CHECK:STDOUT: --- fail_base_no_extend.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_15.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc7_15.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7_14: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc14: type = struct_type {.base: B}, const
+// CHECK:STDOUT:   %.loc7_15.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc7_15.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7_14: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc14: type = struct_type {.base: B} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.B = %B.decl, .C = %C.decl}
 // CHECK:STDOUT:   %B.decl = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %C.decl = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
+// CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
@@ -36,9 +36,9 @@ class C {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc13_10.1: type = unbound_element_type C, B, const
-// CHECK:STDOUT:   %.loc13_10.2: <unbound element of class C> = base_decl B, element0, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc13_10.1: type = unbound_element_type C, B [template]
+// CHECK:STDOUT:   %.loc13_10.2: <unbound element of class C> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc13_10.2

+ 16 - 16
toolchain/check/testdata/class/fail_base_repeated.carbon

@@ -33,22 +33,22 @@ class D {
 // CHECK:STDOUT: --- fail_base_repeated.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_16.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc7_16.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7_15: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc19: type = struct_type {.base: B1}, const
+// CHECK:STDOUT:   %.loc7_16.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc7_16.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7_15: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc19: type = struct_type {.base: B1} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.B1 = %B1.decl, .B2 = %B2.decl, .C = %C.decl, .D = %D.decl}
 // CHECK:STDOUT:   %B1.decl = class_decl @B1, ()
-// CHECK:STDOUT:   %B1: type = class_type @B1, const
+// CHECK:STDOUT:   %B1: type = class_type @B1 [template]
 // CHECK:STDOUT:   %B2.decl = class_decl @B2, ()
-// CHECK:STDOUT:   %B2: type = class_type @B2, const
+// CHECK:STDOUT:   %B2: type = class_type @B2 [template]
 // CHECK:STDOUT:   %C.decl = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
+// CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %D.decl = class_decl @D, ()
-// CHECK:STDOUT:   %D: type = class_type @D, const
+// CHECK:STDOUT:   %D: type = class_type @D [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B1 {
@@ -62,10 +62,10 @@ class D {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %B1.ref: type = name_ref B1, file.%B1, const = file.%B1
-// CHECK:STDOUT:   %.loc11_18.1: type = unbound_element_type C, B1, const
-// CHECK:STDOUT:   %.loc11_18.2: <unbound element of class C> = base_decl B1, element0, const
-// CHECK:STDOUT:   %B2.ref: type = name_ref B2, file.%B2, const = file.%B2
+// CHECK:STDOUT:   %B1.ref: type = name_ref B1, file.%B1 [template = file.%B1]
+// CHECK:STDOUT:   %.loc11_18.1: type = unbound_element_type C, B1 [template]
+// CHECK:STDOUT:   %.loc11_18.2: <unbound element of class C> = base_decl B1, element0 [template]
+// CHECK:STDOUT:   %B2.ref: type = name_ref B2, file.%B2 [template = file.%B2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc11_18.2
@@ -73,10 +73,10 @@ class D {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @D {
-// CHECK:STDOUT:   %B1.ref.loc23: type = name_ref B1, file.%B1, const = file.%B1
-// CHECK:STDOUT:   %.loc23_18.1: type = unbound_element_type D, B1, const
-// CHECK:STDOUT:   %.loc23_18.2: <unbound element of class D> = base_decl B1, element0, const
-// CHECK:STDOUT:   %B1.ref.loc30: type = name_ref B1, file.%B1, const = file.%B1
+// CHECK:STDOUT:   %B1.ref.loc23: type = name_ref B1, file.%B1 [template = file.%B1]
+// CHECK:STDOUT:   %.loc23_18.1: type = unbound_element_type D, B1 [template]
+// CHECK:STDOUT:   %.loc23_18.2: <unbound element of class D> = base_decl B1, element0 [template]
+// CHECK:STDOUT:   %B1.ref.loc30: type = name_ref B1, file.%B1 [template = file.%B1]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc23_18.2

+ 12 - 12
toolchain/check/testdata/class/fail_base_unbound.carbon

@@ -18,21 +18,21 @@ let b: B = C.base;
 // CHECK:STDOUT: --- fail_base_unbound.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_15.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc7_15.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7_14: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc11: type = struct_type {.base: B}, const
+// CHECK:STDOUT:   %.loc7_15.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc7_15.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7_14: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc11: type = struct_type {.base: B} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.B = %B.decl, .C = %C.decl}
 // CHECK:STDOUT:   %B.decl = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %C.decl = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
-// CHECK:STDOUT:   %B.ref: type = name_ref B, %B, const = %B
-// CHECK:STDOUT:   %C.ref: type = name_ref C, %C, const = %C
-// CHECK:STDOUT:   %base.ref: <unbound element of class C> = name_ref base, @C.%.loc10_17.2, const = @C.%.loc10_17.2
+// CHECK:STDOUT:   %C: type = class_type @C [template]
+// CHECK:STDOUT:   %B.ref: type = name_ref B, %B [template = %B]
+// CHECK:STDOUT:   %C.ref: type = name_ref C, %C [template = %C]
+// CHECK:STDOUT:   %base.ref: <unbound element of class C> = name_ref base, @C.%.loc10_17.2 [template = @C.%.loc10_17.2]
 // CHECK:STDOUT:   %b: B = bind_name b, <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -42,9 +42,9 @@ let b: B = C.base;
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {
-// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B, const = file.%B
-// CHECK:STDOUT:   %.loc10_17.1: type = unbound_element_type C, B, const
-// CHECK:STDOUT:   %.loc10_17.2: <unbound element of class C> = base_decl B, element0, const
+// CHECK:STDOUT:   %B.ref: type = name_ref B, file.%B [template = file.%B]
+// CHECK:STDOUT:   %.loc10_17.1: type = unbound_element_type C, B [template]
+// CHECK:STDOUT:   %.loc10_17.2: <unbound element of class C> = base_decl B, element0 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc10_17.2

+ 24 - 24
toolchain/check/testdata/class/fail_derived_to_base.carbon

@@ -32,53 +32,53 @@ fn ConvertIncomplete(p: Incomplete*) -> A2* { return p; }
 // CHECK:STDOUT: --- fail_derived_to_base.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: type = struct_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc11: type = ptr_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc18_1.1: type = struct_type {.base: A2, .b: i32}, const
-// CHECK:STDOUT:   %.loc18_1.2: type = struct_type {.base: {.a: i32}*, .b: i32}, const
-// CHECK:STDOUT:   %.loc18_1.3: type = ptr_type {.base: {.a: i32}*, .b: i32}, const
-// CHECK:STDOUT:   %.loc15: type = ptr_type {.base: A2, .b: i32}, const
+// CHECK:STDOUT:   %.loc9: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc11: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc18_1.1: type = struct_type {.base: A2, .b: i32} [template]
+// CHECK:STDOUT:   %.loc18_1.2: type = struct_type {.base: {.a: i32}*, .b: i32} [template]
+// CHECK:STDOUT:   %.loc18_1.3: type = ptr_type {.base: {.a: i32}*, .b: i32} [template]
+// CHECK:STDOUT:   %.loc15: type = ptr_type {.base: A2, .b: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A1 = %A1.decl, .A2 = %A2.decl, .B2 = %B2.decl, .ConvertUnrelated = %ConvertUnrelated, .Incomplete = %Incomplete.decl, .ConvertIncomplete = %ConvertIncomplete}
 // CHECK:STDOUT:   %A1.decl = class_decl @A1, ()
-// CHECK:STDOUT:   %A1: type = class_type @A1, const
+// CHECK:STDOUT:   %A1: type = class_type @A1 [template]
 // CHECK:STDOUT:   %A2.decl = class_decl @A2, ()
-// CHECK:STDOUT:   %A2: type = class_type @A2, const
+// CHECK:STDOUT:   %A2: type = class_type @A2 [template]
 // CHECK:STDOUT:   %B2.decl = class_decl @B2, ()
-// CHECK:STDOUT:   %B2: type = class_type @B2, const
-// CHECK:STDOUT:   %ConvertUnrelated: <function> = fn_decl @ConvertUnrelated, const
+// CHECK:STDOUT:   %B2: type = class_type @B2 [template]
+// CHECK:STDOUT:   %ConvertUnrelated: <function> = fn_decl @ConvertUnrelated [template]
 // CHECK:STDOUT:   %Incomplete.decl = class_decl @Incomplete, ()
-// CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete, const
-// CHECK:STDOUT:   %ConvertIncomplete: <function> = fn_decl @ConvertIncomplete, const
+// CHECK:STDOUT:   %Incomplete: type = class_type @Incomplete [template]
+// CHECK:STDOUT:   %ConvertIncomplete: <function> = fn_decl @ConvertIncomplete [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A1 {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type A1, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class A1> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class A1> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type A1, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class A1> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class A1> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A2 {
-// CHECK:STDOUT:   %.loc12_8.1: type = unbound_element_type A2, i32, const
-// CHECK:STDOUT:   %.loc12_8.2: <unbound element of class A2> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class A2> = bind_name a, %.loc12_8.2, const = %.loc12_8.2
+// CHECK:STDOUT:   %.loc12_8.1: type = unbound_element_type A2, i32 [template]
+// CHECK:STDOUT:   %.loc12_8.2: <unbound element of class A2> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class A2> = bind_name a, %.loc12_8.2 [template = %.loc12_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B2 {
-// CHECK:STDOUT:   %A2.ref: type = name_ref A2, file.%A2, const = file.%A2
-// CHECK:STDOUT:   %.loc16_18.1: type = unbound_element_type B2, A2, const
-// CHECK:STDOUT:   %.loc16_18.2: <unbound element of class B2> = base_decl A2, element0, const
-// CHECK:STDOUT:   %.loc17_8.1: type = unbound_element_type B2, i32, const
-// CHECK:STDOUT:   %.loc17_8.2: <unbound element of class B2> = field_decl b, element1, const
-// CHECK:STDOUT:   %b: <unbound element of class B2> = bind_name b, %.loc17_8.2, const = %.loc17_8.2
+// CHECK:STDOUT:   %A2.ref: type = name_ref A2, file.%A2 [template = file.%A2]
+// CHECK:STDOUT:   %.loc16_18.1: type = unbound_element_type B2, A2 [template]
+// CHECK:STDOUT:   %.loc16_18.2: <unbound element of class B2> = base_decl A2, element0 [template]
+// CHECK:STDOUT:   %.loc17_8.1: type = unbound_element_type B2, i32 [template]
+// CHECK:STDOUT:   %.loc17_8.2: <unbound element of class B2> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %b: <unbound element of class B2> = bind_name b, %.loc17_8.2 [template = %.loc17_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc16_18.2

+ 12 - 12
toolchain/check/testdata/class/fail_field_modifiers.carbon

@@ -30,27 +30,27 @@ class Class {
 // CHECK:STDOUT: --- fail_field_modifiers.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc22: i32 = int_literal 0, const
-// CHECK:STDOUT:   %.loc27: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc28: type = struct_type {.j: i32, .k: i32}, const
+// CHECK:STDOUT:   %.loc22: i32 = int_literal 0 [template]
+// CHECK:STDOUT:   %.loc27: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc28: type = struct_type {.j: i32, .k: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc12_16.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc12_16.2: <unbound element of class Class> = field_decl j, element0, const
-// CHECK:STDOUT:   %j: <unbound element of class Class> = bind_name j, %.loc12_16.2, const = %.loc12_16.2
-// CHECK:STDOUT:   %.loc17_14.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc17_14.2: <unbound element of class Class> = field_decl k, element1, const
-// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc17_14.2, const = %.loc17_14.2
-// CHECK:STDOUT:   %.loc22: i32 = int_literal 0, const = constants.%.loc22
+// CHECK:STDOUT:   %.loc12_16.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc12_16.2: <unbound element of class Class> = field_decl j, element0 [template]
+// CHECK:STDOUT:   %j: <unbound element of class Class> = bind_name j, %.loc12_16.2 [template = %.loc12_16.2]
+// CHECK:STDOUT:   %.loc17_14.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc17_14.2: <unbound element of class Class> = field_decl k, element1 [template]
+// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc17_14.2 [template = %.loc17_14.2]
+// CHECK:STDOUT:   %.loc22: i32 = int_literal 0 [template = constants.%.loc22]
 // CHECK:STDOUT:   %l: i32 = bind_name l, %.loc22
-// CHECK:STDOUT:   %.loc27: i32 = int_literal 1, const = constants.%.loc27
+// CHECK:STDOUT:   %.loc27: i32 = int_literal 1 [template = constants.%.loc27]
 // CHECK:STDOUT:   %m: i32 = bind_name m, %.loc27
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:

+ 19 - 19
toolchain/check/testdata/class/fail_incomplete.carbon

@@ -118,27 +118,27 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT: --- fail_incomplete.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc41: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc100: type = tuple_type (), const
+// CHECK:STDOUT:   %.loc41: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc100: type = tuple_type () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .CallClassFunction = %CallClassFunction, .global_var = %global_var, .ConvertFromStruct = %ConvertFromStruct, .MemberAccess = %MemberAccess, .Copy = %Copy, .Let = %Let, .TakeIncomplete = %TakeIncomplete, .ReturnIncomplete = %ReturnIncomplete, .CallTakeIncomplete = %CallTakeIncomplete, .CallReturnIncomplete = %CallReturnIncomplete}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %.loc15: <function> = fn_decl @.1, const
-// CHECK:STDOUT:   %CallClassFunction: <function> = fn_decl @CallClassFunction, const
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, %Class, const = %Class
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %.loc15: <function> = fn_decl @.1 [template]
+// CHECK:STDOUT:   %CallClassFunction: <function> = fn_decl @CallClassFunction [template]
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, %Class [template = %Class]
 // CHECK:STDOUT:   %global_var.var: ref <error> = var global_var
 // CHECK:STDOUT:   %global_var: ref <error> = bind_name global_var, %global_var.var
-// CHECK:STDOUT:   %ConvertFromStruct: <function> = fn_decl @ConvertFromStruct, const
-// CHECK:STDOUT:   %MemberAccess: <function> = fn_decl @MemberAccess, const
-// CHECK:STDOUT:   %Copy: <function> = fn_decl @Copy, const
-// CHECK:STDOUT:   %Let: <function> = fn_decl @Let, const
-// CHECK:STDOUT:   %TakeIncomplete: <function> = fn_decl @TakeIncomplete, const
-// CHECK:STDOUT:   %ReturnIncomplete: <function> = fn_decl @ReturnIncomplete, const
-// CHECK:STDOUT:   %CallTakeIncomplete: <function> = fn_decl @CallTakeIncomplete, const
-// CHECK:STDOUT:   %CallReturnIncomplete: <function> = fn_decl @CallReturnIncomplete, const
+// CHECK:STDOUT:   %ConvertFromStruct: <function> = fn_decl @ConvertFromStruct [template]
+// CHECK:STDOUT:   %MemberAccess: <function> = fn_decl @MemberAccess [template]
+// CHECK:STDOUT:   %Copy: <function> = fn_decl @Copy [template]
+// CHECK:STDOUT:   %Let: <function> = fn_decl @Let [template]
+// CHECK:STDOUT:   %TakeIncomplete: <function> = fn_decl @TakeIncomplete [template]
+// CHECK:STDOUT:   %ReturnIncomplete: <function> = fn_decl @ReturnIncomplete [template]
+// CHECK:STDOUT:   %CallTakeIncomplete: <function> = fn_decl @CallTakeIncomplete [template]
+// CHECK:STDOUT:   %CallReturnIncomplete: <function> = fn_decl @CallReturnIncomplete [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class;
@@ -150,7 +150,7 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallClassFunction() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %Function.ref: <error> = name_ref Function, <error>
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -177,7 +177,7 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Let(%p: Class*) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %p.ref: Class* = name_ref p, %p
 // CHECK:STDOUT:   %.loc75: ref Class = deref %p.ref
 // CHECK:STDOUT:   %c: <error> = bind_name c, <error>
@@ -190,11 +190,11 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallTakeIncomplete(%p: Class*) {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %TakeIncomplete.ref.loc100: <function> = name_ref TakeIncomplete, file.%TakeIncomplete, const = file.%TakeIncomplete
+// CHECK:STDOUT:   %TakeIncomplete.ref.loc100: <function> = name_ref TakeIncomplete, file.%TakeIncomplete [template = file.%TakeIncomplete]
 // CHECK:STDOUT:   %p.ref: Class* = name_ref p, %p
 // CHECK:STDOUT:   %.loc100_18: ref Class = deref %p.ref
 // CHECK:STDOUT:   %.loc100_17: init () = call %TakeIncomplete.ref.loc100(<invalid>)
-// CHECK:STDOUT:   %TakeIncomplete.ref.loc111: <function> = name_ref TakeIncomplete, file.%TakeIncomplete, const = file.%TakeIncomplete
+// CHECK:STDOUT:   %TakeIncomplete.ref.loc111: <function> = name_ref TakeIncomplete, file.%TakeIncomplete [template = file.%TakeIncomplete]
 // CHECK:STDOUT:   %.loc111_19: {} = struct_literal ()
 // CHECK:STDOUT:   %.loc111_17: init () = call %TakeIncomplete.ref.loc111(<invalid>)
 // CHECK:STDOUT:   return
@@ -202,7 +202,7 @@ fn CallReturnIncomplete() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallReturnIncomplete() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %ReturnIncomplete.ref: <function> = name_ref ReturnIncomplete, file.%ReturnIncomplete, const = file.%ReturnIncomplete
+// CHECK:STDOUT:   %ReturnIncomplete.ref: <function> = name_ref ReturnIncomplete, file.%ReturnIncomplete [template = file.%ReturnIncomplete]
 // CHECK:STDOUT:   %.loc115: init <error> = call %ReturnIncomplete.ref()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 28 - 28
toolchain/check/testdata/class/fail_init.carbon

@@ -27,33 +27,33 @@ fn F() {
 // CHECK:STDOUT: --- fail_init.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc16_9: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc16_10: type = struct_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc20_9: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc20_17: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc20_18: type = struct_type {.a: i32, .c: i32}, const
-// CHECK:STDOUT:   %.loc24_9: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc24_17: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc24_25: i32 = int_literal 3, const
-// CHECK:STDOUT:   %.loc24_26: type = struct_type {.a: i32, .b: i32, .c: i32}, const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc16_9: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc16_10: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc20_9: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc20_17: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc20_18: type = struct_type {.a: i32, .c: i32} [template]
+// CHECK:STDOUT:   %.loc24_9: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc24_17: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc24_25: i32 = int_literal 3 [template]
+// CHECK:STDOUT:   %.loc24_26: type = struct_type {.a: i32, .b: i32, .c: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .F = %F}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Class> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl b, element1, const
-// CHECK:STDOUT:   %b: <unbound element of class Class> = bind_name b, %.loc9_8.2, const = %.loc9_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Class> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %b: <unbound element of class Class> = bind_name b, %.loc9_8.2 [template = %.loc9_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
@@ -62,26 +62,26 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc16_9: i32 = int_literal 1, const = constants.%.loc16_9
+// CHECK:STDOUT:   %.loc16_9: i32 = int_literal 1 [template = constants.%.loc16_9]
 // CHECK:STDOUT:   %.loc16_10.1: {.a: i32} = struct_literal (%.loc16_9)
-// CHECK:STDOUT:   %Class.ref.loc16: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref.loc16: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %.loc16_10.2: ref Class = temporary_storage
 // CHECK:STDOUT:   %.loc16_10.3: ref Class = temporary %.loc16_10.2, <error>
 // CHECK:STDOUT:   %.loc16_10.4: ref Class = converted %.loc16_10.1, %.loc16_10.3
-// CHECK:STDOUT:   %.loc20_9: i32 = int_literal 1, const = constants.%.loc20_9
-// CHECK:STDOUT:   %.loc20_17: i32 = int_literal 2, const = constants.%.loc20_17
+// CHECK:STDOUT:   %.loc20_9: i32 = int_literal 1 [template = constants.%.loc20_9]
+// CHECK:STDOUT:   %.loc20_17: i32 = int_literal 2 [template = constants.%.loc20_17]
 // CHECK:STDOUT:   %.loc20_18.1: {.a: i32, .c: i32} = struct_literal (%.loc20_9, %.loc20_17)
-// CHECK:STDOUT:   %Class.ref.loc20: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref.loc20: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %.loc20_18.2: ref Class = temporary_storage
 // CHECK:STDOUT:   %.loc20_18.3: ref i32 = class_element_access %.loc20_18.2, element0
 // CHECK:STDOUT:   %.loc20_18.4: init i32 = initialize_from %.loc20_9 to %.loc20_18.3
 // CHECK:STDOUT:   %.loc20_18.5: ref Class = temporary %.loc20_18.2, <error>
 // CHECK:STDOUT:   %.loc20_18.6: ref Class = converted %.loc20_18.1, %.loc20_18.5
-// CHECK:STDOUT:   %.loc24_9: i32 = int_literal 1, const = constants.%.loc24_9
-// CHECK:STDOUT:   %.loc24_17: i32 = int_literal 2, const = constants.%.loc24_17
-// CHECK:STDOUT:   %.loc24_25: i32 = int_literal 3, const = constants.%.loc24_25
+// CHECK:STDOUT:   %.loc24_9: i32 = int_literal 1 [template = constants.%.loc24_9]
+// CHECK:STDOUT:   %.loc24_17: i32 = int_literal 2 [template = constants.%.loc24_17]
+// CHECK:STDOUT:   %.loc24_25: i32 = int_literal 3 [template = constants.%.loc24_25]
 // CHECK:STDOUT:   %.loc24_26.1: {.a: i32, .b: i32, .c: i32} = struct_literal (%.loc24_9, %.loc24_17, %.loc24_25)
-// CHECK:STDOUT:   %Class.ref.loc24: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref.loc24: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %.loc24_26.2: ref Class = temporary_storage
 // CHECK:STDOUT:   %.loc24_26.3: ref Class = temporary %.loc24_26.2, <error>
 // CHECK:STDOUT:   %.loc24_26.4: ref Class = converted %.loc24_26.1, %.loc24_26.3

+ 19 - 19
toolchain/check/testdata/class/fail_init_as_inplace.carbon

@@ -25,28 +25,28 @@ fn F() {
 // CHECK:STDOUT: --- fail_init_as_inplace.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc21_24: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc21_32: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc22: type = tuple_type (), const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc21_24: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc21_32: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc22: type = tuple_type () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .G = %G, .F = %F}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Class> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl b, element1, const
-// CHECK:STDOUT:   %b: <unbound element of class Class> = bind_name b, %.loc9_8.2, const = %.loc9_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Class> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %b: <unbound element of class Class> = bind_name b, %.loc9_8.2 [template = %.loc9_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
@@ -57,13 +57,13 @@ fn F() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref.loc21_10: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref.loc21_10: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %c.var: ref Class = var c
 // CHECK:STDOUT:   %c: ref Class = bind_name c, %c.var
-// CHECK:STDOUT:   %.loc21_24: i32 = int_literal 1, const = constants.%.loc21_24
-// CHECK:STDOUT:   %.loc21_32: i32 = int_literal 2, const = constants.%.loc21_32
+// CHECK:STDOUT:   %.loc21_24: i32 = int_literal 1 [template = constants.%.loc21_24]
+// CHECK:STDOUT:   %.loc21_32: i32 = int_literal 2 [template = constants.%.loc21_32]
 // CHECK:STDOUT:   %.loc21_33.1: {.a: i32, .b: i32} = struct_literal (%.loc21_24, %.loc21_32)
-// CHECK:STDOUT:   %Class.ref.loc21_38: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref.loc21_38: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %.loc21_33.2: ref Class = temporary_storage
 // CHECK:STDOUT:   %.loc21_33.3: ref i32 = class_element_access %.loc21_33.2, element0
 // CHECK:STDOUT:   %.loc21_33.4: init i32 = initialize_from %.loc21_24 to %.loc21_33.3
@@ -74,7 +74,7 @@ fn F() {
 // CHECK:STDOUT:   %.loc21_33.9: ref Class = converted %.loc21_33.1, %.loc21_33.8
 // CHECK:STDOUT:   %.loc21_33.10: Class = bind_value %.loc21_33.9
 // CHECK:STDOUT:   assign %c.var, <error>
-// CHECK:STDOUT:   %G.ref: <function> = name_ref G, file.%G, const = file.%G
+// CHECK:STDOUT:   %G.ref: <function> = name_ref G, file.%G [template = file.%G]
 // CHECK:STDOUT:   %c.ref: ref Class = name_ref c, %c
 // CHECK:STDOUT:   %.loc22_5: Class* = addr_of %c.ref
 // CHECK:STDOUT:   %.loc22_4: init () = call %G.ref(%.loc22_5)

+ 14 - 14
toolchain/check/testdata/class/fail_memaccess_category.carbon

@@ -36,35 +36,35 @@ fn F(s: {.a: A}, b: B) {
 // CHECK:STDOUT: --- fail_memaccess_category.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
-// CHECK:STDOUT:   %.loc13_1.1: type = struct_type {.a: A}, const
-// CHECK:STDOUT:   %.loc13_1.2: type = struct_type {.a: {}*}, const
-// CHECK:STDOUT:   %.loc11: type = ptr_type {.a: A}, const
+// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
+// CHECK:STDOUT:   %.loc13_1.1: type = struct_type {.a: A} [template]
+// CHECK:STDOUT:   %.loc13_1.2: type = struct_type {.a: {}*} [template]
+// CHECK:STDOUT:   %.loc11: type = ptr_type {.a: A} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A.decl, .B = %B.decl, .F = %F}
 // CHECK:STDOUT:   %A.decl = class_decl @A, ()
-// CHECK:STDOUT:   %A: type = class_type @A, const
+// CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %B.decl = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @B {
-// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A, const = file.%A
-// CHECK:STDOUT:   %.loc12_8.1: type = unbound_element_type B, A, const
-// CHECK:STDOUT:   %.loc12_8.2: <unbound element of class B> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class B> = bind_name a, %.loc12_8.2, const = %.loc12_8.2
+// CHECK:STDOUT:   %A.ref: type = name_ref A, file.%A [template = file.%A]
+// CHECK:STDOUT:   %.loc12_8.1: type = unbound_element_type B, A [template]
+// CHECK:STDOUT:   %.loc12_8.2: <unbound element of class B> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class B> = bind_name a, %.loc12_8.2 [template = %.loc12_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a

+ 5 - 5
toolchain/check/testdata/class/fail_member_of_let.carbon

@@ -21,20 +21,20 @@ fn T.F() {}
 // CHECK:STDOUT: --- fail_member_of_let.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc9: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, %Class, const = %Class
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, %Class [template = %Class]
 // CHECK:STDOUT:   %T: type = bind_name T, %Class.ref
-// CHECK:STDOUT:   %.loc19: <function> = fn_decl @.1, const
+// CHECK:STDOUT:   %.loc19: <function> = fn_decl @.1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F

+ 14 - 14
toolchain/check/testdata/class/fail_method.carbon

@@ -33,21 +33,21 @@ fn F(c: Class) {
 // CHECK:STDOUT: --- fail_method.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc10_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .F = %F}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %NoSelf: <function> = fn_decl @NoSelf, const
-// CHECK:STDOUT:   %WithSelf: <function> = fn_decl @WithSelf, const
+// CHECK:STDOUT:   %NoSelf: <function> = fn_decl @NoSelf [template]
+// CHECK:STDOUT:   %WithSelf: <function> = fn_decl @WithSelf [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .NoSelf = %NoSelf
@@ -61,19 +61,19 @@ fn F(c: Class) {
 // CHECK:STDOUT: fn @F(%c: Class) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %c.ref.loc13: Class = name_ref c, %c
-// CHECK:STDOUT:   %NoSelf.ref.loc13: <function> = name_ref NoSelf, @Class.%NoSelf, const = @Class.%NoSelf
+// CHECK:STDOUT:   %NoSelf.ref.loc13: <function> = name_ref NoSelf, @Class.%NoSelf [template = @Class.%NoSelf]
 // CHECK:STDOUT:   %.loc13: init () = call %NoSelf.ref.loc13()
 // CHECK:STDOUT:   %c.ref.loc14: Class = name_ref c, %c
 // CHECK:STDOUT:   %.loc14_4: <bound method> = bound_method %c.ref.loc14, @Class.%WithSelf
 // CHECK:STDOUT:   %.loc14_13: init () = call %.loc14_4(%c.ref.loc14)
-// CHECK:STDOUT:   %Class.ref.loc16: type = name_ref Class, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %NoSelf.ref.loc16: <function> = name_ref NoSelf, @Class.%NoSelf, const = @Class.%NoSelf
+// CHECK:STDOUT:   %Class.ref.loc16: type = name_ref Class, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %NoSelf.ref.loc16: <function> = name_ref NoSelf, @Class.%NoSelf [template = @Class.%NoSelf]
 // CHECK:STDOUT:   %.loc16: init () = call %NoSelf.ref.loc16()
-// CHECK:STDOUT:   %Class.ref.loc23: type = name_ref Class, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %WithSelf.ref.loc23: <function> = name_ref WithSelf, @Class.%WithSelf, const = @Class.%WithSelf
+// CHECK:STDOUT:   %Class.ref.loc23: type = name_ref Class, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %WithSelf.ref.loc23: <function> = name_ref WithSelf, @Class.%WithSelf [template = @Class.%WithSelf]
 // CHECK:STDOUT:   %.loc23: init () = call %WithSelf.ref.loc23(<invalid>)
-// CHECK:STDOUT:   %Class.ref.loc30: type = name_ref Class, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %WithSelf.ref.loc30: <function> = name_ref WithSelf, @Class.%WithSelf, const = @Class.%WithSelf
+// CHECK:STDOUT:   %Class.ref.loc30: type = name_ref Class, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %WithSelf.ref.loc30: <function> = name_ref WithSelf, @Class.%WithSelf [template = @Class.%WithSelf]
 // CHECK:STDOUT:   %c.ref.loc30: Class = name_ref c, %c
 // CHECK:STDOUT:   %.loc30: init () = call %WithSelf.ref.loc30(<invalid>)
 // CHECK:STDOUT:   return

+ 9 - 9
toolchain/check/testdata/class/fail_method_modifiers.carbon

@@ -50,22 +50,22 @@ base class BaseClass {
 // CHECK:STDOUT: --- fail_method_modifiers.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc24: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc24: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.FinalClass = %FinalClass.decl, .AbstractClass = %AbstractClass.decl, .BaseClass = %BaseClass.decl}
 // CHECK:STDOUT:   %FinalClass.decl = class_decl @FinalClass, ()
-// CHECK:STDOUT:   %FinalClass: type = class_type @FinalClass, const
+// CHECK:STDOUT:   %FinalClass: type = class_type @FinalClass [template]
 // CHECK:STDOUT:   %AbstractClass.decl = class_decl @AbstractClass, ()
-// CHECK:STDOUT:   %AbstractClass: type = class_type @AbstractClass, const
+// CHECK:STDOUT:   %AbstractClass: type = class_type @AbstractClass [template]
 // CHECK:STDOUT:   %BaseClass.decl = class_decl @BaseClass, ()
-// CHECK:STDOUT:   %BaseClass: type = class_type @BaseClass, const
+// CHECK:STDOUT:   %BaseClass: type = class_type @BaseClass [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @FinalClass {
-// CHECK:STDOUT:   %Abstract: <function> = fn_decl @Abstract.1, const
-// CHECK:STDOUT:   %Virtual: <function> = fn_decl @Virtual, const
+// CHECK:STDOUT:   %Abstract: <function> = fn_decl @Abstract.1 [template]
+// CHECK:STDOUT:   %Virtual: <function> = fn_decl @Virtual [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Abstract = %Abstract
@@ -73,8 +73,8 @@ base class BaseClass {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @AbstractClass {
-// CHECK:STDOUT:   %Default: <function> = fn_decl @Default, const
-// CHECK:STDOUT:   %Final: <function> = fn_decl @Final, const
+// CHECK:STDOUT:   %Default: <function> = fn_decl @Default [template]
+// CHECK:STDOUT:   %Final: <function> = fn_decl @Final [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Default = %Default
@@ -82,7 +82,7 @@ base class BaseClass {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @BaseClass {
-// CHECK:STDOUT:   %Abstract: <function> = fn_decl @Abstract.2, const
+// CHECK:STDOUT:   %Abstract: <function> = fn_decl @Abstract.2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Abstract = %Abstract

+ 7 - 7
toolchain/check/testdata/class/fail_modifiers.carbon

@@ -67,23 +67,23 @@ abstract base class AbstractAndBase {}
 // CHECK:STDOUT: --- fail_modifiers.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc27: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc27: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.DuplicatePrivate = %DuplicatePrivate.decl, .TwoAccess = %TwoAccess.decl, .TwoAbstract = %TwoAbstract.decl, .Virtual = %Virtual.decl, .WrongOrder = %WrongOrder.decl, .AbstractAndBase = %AbstractAndBase.decl}
 // CHECK:STDOUT:   %DuplicatePrivate.decl = class_decl @DuplicatePrivate, ()
-// CHECK:STDOUT:   %DuplicatePrivate: type = class_type @DuplicatePrivate, const
+// CHECK:STDOUT:   %DuplicatePrivate: type = class_type @DuplicatePrivate [template]
 // CHECK:STDOUT:   %TwoAccess.decl = class_decl @TwoAccess, ()
-// CHECK:STDOUT:   %TwoAccess: type = class_type @TwoAccess, const
+// CHECK:STDOUT:   %TwoAccess: type = class_type @TwoAccess [template]
 // CHECK:STDOUT:   %TwoAbstract.decl = class_decl @TwoAbstract, ()
-// CHECK:STDOUT:   %TwoAbstract: type = class_type @TwoAbstract, const
+// CHECK:STDOUT:   %TwoAbstract: type = class_type @TwoAbstract [template]
 // CHECK:STDOUT:   %Virtual.decl = class_decl @Virtual, ()
-// CHECK:STDOUT:   %Virtual: type = class_type @Virtual, const
+// CHECK:STDOUT:   %Virtual: type = class_type @Virtual [template]
 // CHECK:STDOUT:   %WrongOrder.decl = class_decl @WrongOrder, ()
-// CHECK:STDOUT:   %WrongOrder: type = class_type @WrongOrder, const
+// CHECK:STDOUT:   %WrongOrder: type = class_type @WrongOrder [template]
 // CHECK:STDOUT:   %AbstractAndBase.decl = class_decl @AbstractAndBase, ()
-// CHECK:STDOUT:   %AbstractAndBase: type = class_type @AbstractAndBase, const
+// CHECK:STDOUT:   %AbstractAndBase: type = class_type @AbstractAndBase [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @DuplicatePrivate;

+ 3 - 3
toolchain/check/testdata/class/fail_out_of_line_decl.carbon

@@ -14,14 +14,14 @@ fn C.F() {}
 // CHECK:STDOUT: --- fail_out_of_line_decl.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc7: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.C = %C.decl}
 // CHECK:STDOUT:   %C.decl = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %C: type = class_type @C [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @C {

+ 8 - 8
toolchain/check/testdata/class/fail_redeclaration_introducer.carbon

@@ -77,31 +77,31 @@ base class G;
 // CHECK:STDOUT: --- fail_redeclaration_introducer.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc14: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc14: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A.decl.loc7, .B = %B.decl.loc16, .C = %C.decl.loc25, .D = %D.decl.loc34, .E = %E.decl.loc43, .F = %F.decl.loc52, .G = %G.decl.loc61}
 // CHECK:STDOUT:   %A.decl.loc7 = class_decl @A, ()
-// CHECK:STDOUT:   %A: type = class_type @A, const
+// CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %A.decl.loc14 = class_decl @A, ()
 // CHECK:STDOUT:   %B.decl.loc16 = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %B.decl.loc23 = class_decl @B, ()
 // CHECK:STDOUT:   %C.decl.loc25 = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
+// CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %C.decl.loc32 = class_decl @C, ()
 // CHECK:STDOUT:   %D.decl.loc34 = class_decl @D, ()
-// CHECK:STDOUT:   %D: type = class_type @D, const
+// CHECK:STDOUT:   %D: type = class_type @D [template]
 // CHECK:STDOUT:   %D.decl.loc41 = class_decl @D, ()
 // CHECK:STDOUT:   %E.decl.loc43 = class_decl @E, ()
-// CHECK:STDOUT:   %E: type = class_type @E, const
+// CHECK:STDOUT:   %E: type = class_type @E [template]
 // CHECK:STDOUT:   %E.decl.loc50 = class_decl @E, ()
 // CHECK:STDOUT:   %F.decl.loc52 = class_decl @F, ()
-// CHECK:STDOUT:   %F: type = class_type @F, const
+// CHECK:STDOUT:   %F: type = class_type @F [template]
 // CHECK:STDOUT:   %F.decl.loc59 = class_decl @F, ()
 // CHECK:STDOUT:   %G.decl.loc61 = class_decl @G, ()
-// CHECK:STDOUT:   %G: type = class_type @G, const
+// CHECK:STDOUT:   %G: type = class_type @G [template]
 // CHECK:STDOUT:   %G.decl.loc68 = class_decl @G, ()
 // CHECK:STDOUT:   %G.decl.loc75 = class_decl @G, ()
 // CHECK:STDOUT: }

+ 8 - 8
toolchain/check/testdata/class/fail_redeclaration_scope.carbon

@@ -24,23 +24,23 @@ class Y {
 // CHECK:STDOUT: --- fail_redeclaration_scope.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc11: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A.decl.loc7, .X = %X.decl, .Y = %Y.decl}
 // CHECK:STDOUT:   %A.decl.loc7 = class_decl @A.1, ()
-// CHECK:STDOUT:   %A: type = class_type @A.1, const
+// CHECK:STDOUT:   %A: type = class_type @A.1 [template]
 // CHECK:STDOUT:   %X.decl = class_decl @X, ()
-// CHECK:STDOUT:   %X: type = class_type @X, const
+// CHECK:STDOUT:   %X: type = class_type @X [template]
 // CHECK:STDOUT:   %A.decl.loc15 = class_decl @A.1, ()
 // CHECK:STDOUT:   %Y.decl = class_decl @Y, ()
-// CHECK:STDOUT:   %Y: type = class_type @Y, const
+// CHECK:STDOUT:   %Y: type = class_type @Y [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A.1 {
 // CHECK:STDOUT:   %B.decl = class_decl @B.2, ()
-// CHECK:STDOUT:   %B: type = class_type @B.2, const
+// CHECK:STDOUT:   %B: type = class_type @B.2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .B = %B.decl
@@ -48,7 +48,7 @@ class Y {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @X {
 // CHECK:STDOUT:   %A.decl = class_decl @A.2, ()
-// CHECK:STDOUT:   %A: type = class_type @A.2, const
+// CHECK:STDOUT:   %A: type = class_type @A.2 [template]
 // CHECK:STDOUT:   %B.decl = class_decl @B.1, ()
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
@@ -57,7 +57,7 @@ class Y {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @A.2 {
 // CHECK:STDOUT:   %B.decl = class_decl @B.1, ()
-// CHECK:STDOUT:   %B: type = class_type @B.1, const
+// CHECK:STDOUT:   %B: type = class_type @B.1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .B = %B.decl
@@ -72,7 +72,7 @@ class Y {
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Y {
 // CHECK:STDOUT:   %.decl = class_decl @.1, ()
-// CHECK:STDOUT:   %.loc21: type = class_type @.1, const
+// CHECK:STDOUT:   %.loc21: type = class_type @.1 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT: }

+ 7 - 7
toolchain/check/testdata/class/fail_redefinition.carbon

@@ -27,22 +27,22 @@ fn Class.H() {}
 // CHECK:STDOUT: --- fail_redefinition.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc10: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl.loc7}
 // CHECK:STDOUT:   %Class.decl.loc7 = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT:   %Class.decl.loc18 = class_decl @Class, ()
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %H: <function> = fn_decl @H, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %H: <function> = fn_decl @H [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %H: <function> = fn_decl @H, const
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %H: <function> = fn_decl @H [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = <unexpected instref inst+3>

+ 7 - 7
toolchain/check/testdata/class/fail_reorder.carbon

@@ -28,19 +28,19 @@ class Class {
 // CHECK:STDOUT: --- fail_reorder.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc24: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc26: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc24: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc26: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .G = %G
@@ -49,14 +49,14 @@ class Class {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %F.ref: <error> = name_ref F, <error>
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc24: i32 = int_literal 1, const = constants.%.loc24
+// CHECK:STDOUT:   %.loc24: i32 = int_literal 1 [template = constants.%.loc24]
 // CHECK:STDOUT:   return %.loc24
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 6 - 6
toolchain/check/testdata/class/fail_scope.carbon

@@ -20,19 +20,19 @@ fn G() -> i32 {
 // CHECK:STDOUT: --- fail_scope.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc11: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc9: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc11: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .G = %G}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -40,7 +40,7 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc9: i32 = int_literal 1, const = constants.%.loc9
+// CHECK:STDOUT:   %.loc9: i32 = int_literal 1 [template = constants.%.loc9]
 // CHECK:STDOUT:   return %.loc9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 12 - 12
toolchain/check/testdata/class/fail_self.carbon

@@ -53,25 +53,25 @@ fn CallWrongSelf(ws: WrongSelf) {
 // CHECK:STDOUT: --- fail_self.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc20_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc20_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
+// CHECK:STDOUT:   %.loc20_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc20_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .WrongSelf = %WrongSelf.decl, .CallWrongSelf = %CallWrongSelf}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT:   %WrongSelf.decl = class_decl @WrongSelf, ()
-// CHECK:STDOUT:   %WrongSelf: type = class_type @WrongSelf, const
-// CHECK:STDOUT:   %CallWrongSelf: <function> = fn_decl @CallWrongSelf, const
+// CHECK:STDOUT:   %WrongSelf: type = class_type @WrongSelf [template]
+// CHECK:STDOUT:   %CallWrongSelf: <function> = fn_decl @CallWrongSelf [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -79,7 +79,7 @@ fn CallWrongSelf(ws: WrongSelf) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @WrongSelf {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -92,7 +92,7 @@ fn CallWrongSelf(ws: WrongSelf) {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> %return: Class {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %self.var: ref Class = var self
 // CHECK:STDOUT:   %self: ref Class = bind_name self, %self.var
 // CHECK:STDOUT:   %self.ref: ref Class = name_ref self, %self

+ 18 - 18
toolchain/check/testdata/class/fail_todo_modifiers.carbon

@@ -61,29 +61,29 @@ abstract class Abstract {
 // CHECK:STDOUT: --- fail_todo_modifiers.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc28: type = struct_type {.k: i32, .l: i32}, const
-// CHECK:STDOUT:   %.loc41: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc28: type = struct_type {.k: i32, .l: i32} [template]
+// CHECK:STDOUT:   %.loc41: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Access = %Access.decl, .Base = %Base.decl, .Abstract = %Abstract.decl}
 // CHECK:STDOUT:   %Access.decl = class_decl @Access, ()
-// CHECK:STDOUT:   %Access: type = class_type @Access, const
+// CHECK:STDOUT:   %Access: type = class_type @Access [template]
 // CHECK:STDOUT:   %Base.decl = class_decl @Base, ()
-// CHECK:STDOUT:   %Base: type = class_type @Base, const
+// CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %Abstract.decl = class_decl @Abstract, ()
-// CHECK:STDOUT:   %Abstract: type = class_type @Abstract, const
+// CHECK:STDOUT:   %Abstract: type = class_type @Abstract [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Access {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %.loc22_16.1: type = unbound_element_type Access, i32, const
-// CHECK:STDOUT:   %.loc22_16.2: <unbound element of class Access> = field_decl k, element0, const
-// CHECK:STDOUT:   %k: <unbound element of class Access> = bind_name k, %.loc22_16.2, const = %.loc22_16.2
-// CHECK:STDOUT:   %.loc27_18.1: type = unbound_element_type Access, i32, const
-// CHECK:STDOUT:   %.loc27_18.2: <unbound element of class Access> = field_decl l, element1, const
-// CHECK:STDOUT:   %l: <unbound element of class Access> = bind_name l, %.loc27_18.2, const = %.loc27_18.2
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %.loc22_16.1: type = unbound_element_type Access, i32 [template]
+// CHECK:STDOUT:   %.loc22_16.2: <unbound element of class Access> = field_decl k, element0 [template]
+// CHECK:STDOUT:   %k: <unbound element of class Access> = bind_name k, %.loc22_16.2 [template = %.loc22_16.2]
+// CHECK:STDOUT:   %.loc27_18.1: type = unbound_element_type Access, i32 [template]
+// CHECK:STDOUT:   %.loc27_18.2: <unbound element of class Access> = field_decl l, element1 [template]
+// CHECK:STDOUT:   %l: <unbound element of class Access> = bind_name l, %.loc27_18.2 [template = %.loc27_18.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -93,8 +93,8 @@ abstract class Abstract {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %H: <function> = fn_decl @H, const
-// CHECK:STDOUT:   %I: <function> = fn_decl @I, const
+// CHECK:STDOUT:   %H: <function> = fn_decl @H [template]
+// CHECK:STDOUT:   %I: <function> = fn_decl @I [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .H = %H
@@ -102,9 +102,9 @@ abstract class Abstract {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Abstract {
-// CHECK:STDOUT:   %J: <function> = fn_decl @J, const
-// CHECK:STDOUT:   %K: <function> = fn_decl @K, const
-// CHECK:STDOUT:   %L: <function> = fn_decl @L, const
+// CHECK:STDOUT:   %J: <function> = fn_decl @J [template]
+// CHECK:STDOUT:   %K: <function> = fn_decl @K [template]
+// CHECK:STDOUT:   %L: <function> = fn_decl @L [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .J = %J

+ 10 - 10
toolchain/check/testdata/class/fail_unbound_field.carbon

@@ -24,21 +24,21 @@ fn G() -> i32 {
 // CHECK:STDOUT: --- fail_unbound_field.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc15: type = struct_type {.field: i32}, const
+// CHECK:STDOUT:   %.loc15: type = struct_type {.field: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .G = %G}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8_12.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc8_12.2: <unbound element of class Class> = field_decl field, element0, const
-// CHECK:STDOUT:   %field: <unbound element of class Class> = bind_name field, %.loc8_12.2, const = %.loc8_12.2
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %.loc8_12.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc8_12.2: <unbound element of class Class> = field_decl field, element0 [template]
+// CHECK:STDOUT:   %field: <unbound element of class Class> = bind_name field, %.loc8_12.2 [template = %.loc8_12.2]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .field = %field
@@ -47,14 +47,14 @@ fn G() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %field.ref: <unbound element of class Class> = name_ref field, @Class.%field, const = @Class.%.loc8_12.2
+// CHECK:STDOUT:   %field.ref: <unbound element of class Class> = name_ref field, @Class.%field [template = @Class.%.loc8_12.2]
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %field.ref: <unbound element of class Class> = name_ref field, @Class.%field, const = @Class.%.loc8_12.2
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %field.ref: <unbound element of class Class> = name_ref field, @Class.%field [template = @Class.%.loc8_12.2]
 // CHECK:STDOUT:   return <error>
 // CHECK:STDOUT: }
 // CHECK:STDOUT:

+ 7 - 7
toolchain/check/testdata/class/fail_unknown_member.carbon

@@ -19,21 +19,21 @@ fn G(c: Class) -> i32 {
 // CHECK:STDOUT: --- fail_unknown_member.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: type = struct_type {.n: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.n: i32}, const
+// CHECK:STDOUT:   %.loc9: type = struct_type {.n: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.n: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .G = %G}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl n, element0, const
-// CHECK:STDOUT:   %n: <unbound element of class Class> = bind_name n, %.loc8_8.2, const = %.loc8_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl n, element0 [template]
+// CHECK:STDOUT:   %n: <unbound element of class Class> = bind_name n, %.loc8_8.2 [template = %.loc8_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .n = %n

+ 15 - 15
toolchain/check/testdata/class/field_access.carbon

@@ -20,26 +20,26 @@ fn Run() {
 // CHECK:STDOUT: --- field_access.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.j: i32, .k: i32}, const
-// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.j: i32, .k: i32}, const
-// CHECK:STDOUT:   %.loc14: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc15: i32 = int_literal 2, const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.j: i32, .k: i32} [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.j: i32, .k: i32} [template]
+// CHECK:STDOUT:   %.loc14: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc15: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .Run = %Run}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl j, element0, const
-// CHECK:STDOUT:   %j: <unbound element of class Class> = bind_name j, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl k, element1, const
-// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc9_8.2, const = %.loc9_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl j, element0 [template]
+// CHECK:STDOUT:   %j: <unbound element of class Class> = bind_name j, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl k, element1 [template]
+// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc9_8.2 [template = %.loc9_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .j = %j
@@ -48,16 +48,16 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %c.var: ref Class = var c
 // CHECK:STDOUT:   %c: ref Class = bind_name c, %c.var
 // CHECK:STDOUT:   %c.ref.loc14: ref Class = name_ref c, %c
 // CHECK:STDOUT:   %.loc14_4: ref i32 = class_element_access %c.ref.loc14, element0
-// CHECK:STDOUT:   %.loc14_9: i32 = int_literal 1, const = constants.%.loc14
+// CHECK:STDOUT:   %.loc14_9: i32 = int_literal 1 [template = constants.%.loc14]
 // CHECK:STDOUT:   assign %.loc14_4, %.loc14_9
 // CHECK:STDOUT:   %c.ref.loc15: ref Class = name_ref c, %c
 // CHECK:STDOUT:   %.loc15_4: ref i32 = class_element_access %c.ref.loc15, element1
-// CHECK:STDOUT:   %.loc15_9: i32 = int_literal 2, const = constants.%.loc15
+// CHECK:STDOUT:   %.loc15_9: i32 = int_literal 2 [template = constants.%.loc15]
 // CHECK:STDOUT:   assign %.loc15_4, %.loc15_9
 // CHECK:STDOUT:   %cj.var: ref i32 = var cj
 // CHECK:STDOUT:   %cj: ref i32 = bind_name cj, %cj.var

+ 16 - 16
toolchain/check/testdata/class/field_access_in_value.carbon

@@ -21,26 +21,26 @@ fn Test() {
 // CHECK:STDOUT: --- field_access_in_value.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.j: i32, .k: i32}, const
-// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.j: i32, .k: i32}, const
-// CHECK:STDOUT:   %.loc14: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc15: i32 = int_literal 2, const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.j: i32, .k: i32} [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.j: i32, .k: i32} [template]
+// CHECK:STDOUT:   %.loc14: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc15: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .Test = %Test}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %Test: <function> = fn_decl @Test, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %Test: <function> = fn_decl @Test [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl j, element0, const
-// CHECK:STDOUT:   %j: <unbound element of class Class> = bind_name j, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl k, element1, const
-// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc9_8.2, const = %.loc9_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl j, element0 [template]
+// CHECK:STDOUT:   %j: <unbound element of class Class> = bind_name j, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl k, element1 [template]
+// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc9_8.2 [template = %.loc9_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .j = %j
@@ -49,18 +49,18 @@ fn Test() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Test() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref.loc13: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref.loc13: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %cv.var: ref Class = var cv
 // CHECK:STDOUT:   %cv: ref Class = bind_name cv, %cv.var
 // CHECK:STDOUT:   %cv.ref.loc14: ref Class = name_ref cv, %cv
 // CHECK:STDOUT:   %.loc14_5: ref i32 = class_element_access %cv.ref.loc14, element0
-// CHECK:STDOUT:   %.loc14_10: i32 = int_literal 1, const = constants.%.loc14
+// CHECK:STDOUT:   %.loc14_10: i32 = int_literal 1 [template = constants.%.loc14]
 // CHECK:STDOUT:   assign %.loc14_5, %.loc14_10
 // CHECK:STDOUT:   %cv.ref.loc15: ref Class = name_ref cv, %cv
 // CHECK:STDOUT:   %.loc15_5: ref i32 = class_element_access %cv.ref.loc15, element1
-// CHECK:STDOUT:   %.loc15_10: i32 = int_literal 2, const = constants.%.loc15
+// CHECK:STDOUT:   %.loc15_10: i32 = int_literal 2 [template = constants.%.loc15]
 // CHECK:STDOUT:   assign %.loc15_5, %.loc15_10
-// CHECK:STDOUT:   %Class.ref.loc16: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref.loc16: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %cv.ref.loc16: ref Class = name_ref cv, %cv
 // CHECK:STDOUT:   %.loc16: Class = bind_value %cv.ref.loc16
 // CHECK:STDOUT:   %c: Class = bind_name c, %.loc16

+ 2 - 2
toolchain/check/testdata/class/forward_declared.carbon

@@ -13,8 +13,8 @@ fn F(p: Class*) -> Class* { return p; }
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .F = %F}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class;

+ 14 - 14
toolchain/check/testdata/class/init.carbon

@@ -20,28 +20,28 @@ fn MakeReorder(n: i32, next: Class*) -> Class {
 // CHECK:STDOUT: --- init.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.n: i32, .next: Class*}, const
-// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.n: i32, .next: Class*}, const
-// CHECK:STDOUT:   %.loc17: type = struct_type {.next: Class*, .n: i32}, const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.n: i32, .next: Class*} [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.n: i32, .next: Class*} [template]
+// CHECK:STDOUT:   %.loc17: type = struct_type {.next: Class*, .n: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .Make = %Make, .MakeReorder = %MakeReorder}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make, const
-// CHECK:STDOUT:   %MakeReorder: <function> = fn_decl @MakeReorder, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template]
+// CHECK:STDOUT:   %MakeReorder: <function> = fn_decl @MakeReorder [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl n, element0, const
-// CHECK:STDOUT:   %n: <unbound element of class Class> = bind_name n, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %.loc9_18: type = ptr_type Class, const
-// CHECK:STDOUT:   %.loc9_11.1: type = unbound_element_type Class, Class*, const
-// CHECK:STDOUT:   %.loc9_11.2: <unbound element of class Class> = field_decl next, element1, const
-// CHECK:STDOUT:   %next: <unbound element of class Class> = bind_name next, %.loc9_11.2, const = %.loc9_11.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl n, element0 [template]
+// CHECK:STDOUT:   %n: <unbound element of class Class> = bind_name n, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %.loc9_18: type = ptr_type Class [template]
+// CHECK:STDOUT:   %.loc9_11.1: type = unbound_element_type Class, Class* [template]
+// CHECK:STDOUT:   %.loc9_11.2: <unbound element of class Class> = field_decl next, element1 [template]
+// CHECK:STDOUT:   %next: <unbound element of class Class> = bind_name next, %.loc9_11.2 [template = %.loc9_11.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .n = %n

+ 15 - 15
toolchain/check/testdata/class/init_as.carbon

@@ -16,26 +16,26 @@ fn F() -> i32 {
 // CHECK:STDOUT: --- init_as.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc13_17: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc13_25: i32 = int_literal 2, const
-// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.a: i32, .b: i32}, const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc13_17: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc13_25: i32 = int_literal 2 [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.a: i32, .b: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .F = %F}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Class> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl b, element1, const
-// CHECK:STDOUT:   %b: <unbound element of class Class> = bind_name b, %.loc9_8.2, const = %.loc9_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Class> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Class> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %b: <unbound element of class Class> = bind_name b, %.loc9_8.2 [template = %.loc9_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
@@ -44,10 +44,10 @@ fn F() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc13_17: i32 = int_literal 1, const = constants.%.loc13_17
-// CHECK:STDOUT:   %.loc13_25: i32 = int_literal 2, const = constants.%.loc13_25
+// CHECK:STDOUT:   %.loc13_17: i32 = int_literal 1 [template = constants.%.loc13_17]
+// CHECK:STDOUT:   %.loc13_25: i32 = int_literal 2 [template = constants.%.loc13_25]
 // CHECK:STDOUT:   %.loc13_26.1: {.a: i32, .b: i32} = struct_literal (%.loc13_17, %.loc13_25)
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %.loc13_26.2: ref Class = temporary_storage
 // CHECK:STDOUT:   %.loc13_26.3: ref i32 = class_element_access %.loc13_26.2, element0
 // CHECK:STDOUT:   %.loc13_26.4: init i32 = initialize_from %.loc13_17 to %.loc13_26.3

+ 26 - 26
toolchain/check/testdata/class/init_nested.carbon

@@ -23,31 +23,31 @@ fn MakeOuter() -> Outer {
 // CHECK:STDOUT: --- init_nested.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.a: i32, .b: i32}, const
-// CHECK:STDOUT:   %.loc17_1.1: type = struct_type {.c: Inner, .d: Inner}, const
-// CHECK:STDOUT:   %.loc17_1.2: type = struct_type {.c: {.a: i32, .b: i32}*, .d: {.a: i32, .b: i32}*}, const
-// CHECK:STDOUT:   %.loc17_1.3: type = ptr_type {.c: {.a: i32, .b: i32}*, .d: {.a: i32, .b: i32}*}, const
-// CHECK:STDOUT:   %.loc14: type = ptr_type {.c: Inner, .d: Inner}, const
+// CHECK:STDOUT:   %.loc10_1.1: type = struct_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc10_1.2: type = ptr_type {.a: i32, .b: i32} [template]
+// CHECK:STDOUT:   %.loc17_1.1: type = struct_type {.c: Inner, .d: Inner} [template]
+// CHECK:STDOUT:   %.loc17_1.2: type = struct_type {.c: {.a: i32, .b: i32}*, .d: {.a: i32, .b: i32}*} [template]
+// CHECK:STDOUT:   %.loc17_1.3: type = ptr_type {.c: {.a: i32, .b: i32}*, .d: {.a: i32, .b: i32}*} [template]
+// CHECK:STDOUT:   %.loc14: type = ptr_type {.c: Inner, .d: Inner} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Inner = %Inner.decl, .MakeInner = %MakeInner, .Outer = %Outer.decl, .MakeOuter = %MakeOuter}
 // CHECK:STDOUT:   %Inner.decl = class_decl @Inner, ()
-// CHECK:STDOUT:   %Inner: type = class_type @Inner, const
-// CHECK:STDOUT:   %MakeInner: <function> = fn_decl @MakeInner, const
+// CHECK:STDOUT:   %Inner: type = class_type @Inner [template]
+// CHECK:STDOUT:   %MakeInner: <function> = fn_decl @MakeInner [template]
 // CHECK:STDOUT:   %Outer.decl = class_decl @Outer, ()
-// CHECK:STDOUT:   %Outer: type = class_type @Outer, const
-// CHECK:STDOUT:   %MakeOuter: <function> = fn_decl @MakeOuter, const
+// CHECK:STDOUT:   %Outer: type = class_type @Outer [template]
+// CHECK:STDOUT:   %MakeOuter: <function> = fn_decl @MakeOuter [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Inner {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Inner, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Inner> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Inner> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Inner, i32, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Inner> = field_decl b, element1, const
-// CHECK:STDOUT:   %b: <unbound element of class Inner> = bind_name b, %.loc9_8.2, const = %.loc9_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Inner, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Inner> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Inner> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Inner, i32 [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Inner> = field_decl b, element1 [template]
+// CHECK:STDOUT:   %b: <unbound element of class Inner> = bind_name b, %.loc9_8.2 [template = %.loc9_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
@@ -55,14 +55,14 @@ fn MakeOuter() -> Outer {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Outer {
-// CHECK:STDOUT:   %Inner.ref.loc15: type = name_ref Inner, file.%Inner, const = file.%Inner
-// CHECK:STDOUT:   %.loc15_8.1: type = unbound_element_type Outer, Inner, const
-// CHECK:STDOUT:   %.loc15_8.2: <unbound element of class Outer> = field_decl c, element0, const
-// CHECK:STDOUT:   %c: <unbound element of class Outer> = bind_name c, %.loc15_8.2, const = %.loc15_8.2
-// CHECK:STDOUT:   %Inner.ref.loc16: type = name_ref Inner, file.%Inner, const = file.%Inner
-// CHECK:STDOUT:   %.loc16_8.1: type = unbound_element_type Outer, Inner, const
-// CHECK:STDOUT:   %.loc16_8.2: <unbound element of class Outer> = field_decl d, element1, const
-// CHECK:STDOUT:   %d: <unbound element of class Outer> = bind_name d, %.loc16_8.2, const = %.loc16_8.2
+// CHECK:STDOUT:   %Inner.ref.loc15: type = name_ref Inner, file.%Inner [template = file.%Inner]
+// CHECK:STDOUT:   %.loc15_8.1: type = unbound_element_type Outer, Inner [template]
+// CHECK:STDOUT:   %.loc15_8.2: <unbound element of class Outer> = field_decl c, element0 [template]
+// CHECK:STDOUT:   %c: <unbound element of class Outer> = bind_name c, %.loc15_8.2 [template = %.loc15_8.2]
+// CHECK:STDOUT:   %Inner.ref.loc16: type = name_ref Inner, file.%Inner [template = file.%Inner]
+// CHECK:STDOUT:   %.loc16_8.1: type = unbound_element_type Outer, Inner [template]
+// CHECK:STDOUT:   %.loc16_8.2: <unbound element of class Outer> = field_decl d, element1 [template]
+// CHECK:STDOUT:   %d: <unbound element of class Outer> = bind_name d, %.loc16_8.2 [template = %.loc16_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .c = %c
@@ -73,10 +73,10 @@ fn MakeOuter() -> Outer {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @MakeOuter() -> %return: Outer {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %MakeInner.ref.loc20_16: <function> = name_ref MakeInner, file.%MakeInner, const = file.%MakeInner
+// CHECK:STDOUT:   %MakeInner.ref.loc20_16: <function> = name_ref MakeInner, file.%MakeInner [template = file.%MakeInner]
 // CHECK:STDOUT:   %.loc20_45.1: ref Inner = class_element_access %return, element0
 // CHECK:STDOUT:   %.loc20_25: init Inner = call %MakeInner.ref.loc20_16() to %.loc20_45.1
-// CHECK:STDOUT:   %MakeInner.ref.loc20_34: <function> = name_ref MakeInner, file.%MakeInner, const = file.%MakeInner
+// CHECK:STDOUT:   %MakeInner.ref.loc20_34: <function> = name_ref MakeInner, file.%MakeInner [template = file.%MakeInner]
 // CHECK:STDOUT:   %.loc20_45.2: ref Inner = class_element_access %return, element1
 // CHECK:STDOUT:   %.loc20_43: init Inner = call %MakeInner.ref.loc20_34() to %.loc20_45.2
 // CHECK:STDOUT:   %.loc20_45.3: {.c: Inner, .d: Inner} = struct_literal (%.loc20_25, %.loc20_43)

+ 23 - 23
toolchain/check/testdata/class/method.carbon

@@ -51,32 +51,32 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT: --- method.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc12: type = struct_type {.k: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.k: i32}, const
-// CHECK:STDOUT:   %.loc25: i32 = int_literal 1, const
+// CHECK:STDOUT:   %.loc12: type = struct_type {.k: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.k: i32} [template]
+// CHECK:STDOUT:   %.loc25: i32 = int_literal 1 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .Call = %Call, .CallOnConstBoundMethod = %CallOnConstBoundMethod, .CallWithAddr = %CallWithAddr, .CallFThroughPointer = %CallFThroughPointer, .CallGThroughPointer = %CallGThroughPointer, .Make = %Make, .CallFOnInitializingExpr = %CallFOnInitializingExpr, .CallGOnInitializingExpr = %CallGOnInitializingExpr}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %Call: <function> = fn_decl @Call, const
-// CHECK:STDOUT:   %CallOnConstBoundMethod: <function> = fn_decl @CallOnConstBoundMethod, const
-// CHECK:STDOUT:   %CallWithAddr: <function> = fn_decl @CallWithAddr, const
-// CHECK:STDOUT:   %CallFThroughPointer: <function> = fn_decl @CallFThroughPointer, const
-// CHECK:STDOUT:   %CallGThroughPointer: <function> = fn_decl @CallGThroughPointer, const
-// CHECK:STDOUT:   %Make: <function> = fn_decl @Make, const
-// CHECK:STDOUT:   %CallFOnInitializingExpr: <function> = fn_decl @CallFOnInitializingExpr, const
-// CHECK:STDOUT:   %CallGOnInitializingExpr: <function> = fn_decl @CallGOnInitializingExpr, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %Call: <function> = fn_decl @Call [template]
+// CHECK:STDOUT:   %CallOnConstBoundMethod: <function> = fn_decl @CallOnConstBoundMethod [template]
+// CHECK:STDOUT:   %CallWithAddr: <function> = fn_decl @CallWithAddr [template]
+// CHECK:STDOUT:   %CallFThroughPointer: <function> = fn_decl @CallFThroughPointer [template]
+// CHECK:STDOUT:   %CallGThroughPointer: <function> = fn_decl @CallGThroughPointer [template]
+// CHECK:STDOUT:   %Make: <function> = fn_decl @Make [template]
+// CHECK:STDOUT:   %CallFOnInitializingExpr: <function> = fn_decl @CallFOnInitializingExpr [template]
+// CHECK:STDOUT:   %CallGOnInitializingExpr: <function> = fn_decl @CallGOnInitializingExpr [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %.loc11_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc11_8.2: <unbound element of class Class> = field_decl k, element0, const
-// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc11_8.2, const = %.loc11_8.2
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %.loc11_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc11_8.2: <unbound element of class Class> = field_decl k, element0 [template]
+// CHECK:STDOUT:   %k: <unbound element of class Class> = bind_name k, %.loc11_8.2 [template = %.loc11_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -106,9 +106,9 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallOnConstBoundMethod() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc25_17: i32 = int_literal 1, const = constants.%.loc25
+// CHECK:STDOUT:   %.loc25_17: i32 = int_literal 1 [template = constants.%.loc25]
 // CHECK:STDOUT:   %.loc25_18.1: {.k: i32} = struct_literal (%.loc25_17)
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %.loc25_18.2: ref Class = temporary_storage
 // CHECK:STDOUT:   %.loc25_18.3: ref i32 = class_element_access %.loc25_18.2, element0
 // CHECK:STDOUT:   %.loc25_18.4: init i32 = initialize_from %.loc25_17 to %.loc25_18.3
@@ -125,7 +125,7 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallWithAddr() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %c.var: ref Class = var c
 // CHECK:STDOUT:   %c: ref Class = bind_name c, %c.var
 // CHECK:STDOUT:   %c.ref: ref Class = name_ref c, %c
@@ -165,7 +165,7 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallFOnInitializingExpr() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Make.ref: <function> = name_ref Make, file.%Make, const = file.%Make
+// CHECK:STDOUT:   %Make.ref: <function> = name_ref Make, file.%Make [template = file.%Make]
 // CHECK:STDOUT:   %.loc44_14.1: ref Class = temporary_storage
 // CHECK:STDOUT:   %.loc44_14.2: init Class = call %Make.ref() to %.loc44_14.1
 // CHECK:STDOUT:   %.loc44_14.3: ref Class = temporary %.loc44_14.1, %.loc44_14.2
@@ -179,7 +179,7 @@ fn CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @CallGOnInitializingExpr() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Make.ref: <function> = name_ref Make, file.%Make, const = file.%Make
+// CHECK:STDOUT:   %Make.ref: <function> = name_ref Make, file.%Make [template = file.%Make]
 // CHECK:STDOUT:   %.loc48_14.1: ref Class = temporary_storage
 // CHECK:STDOUT:   %.loc48_14.2: init Class = call %Make.ref() to %.loc48_14.1
 // CHECK:STDOUT:   %.loc48_14.3: ref Class = temporary %.loc48_14.1, %.loc48_14.2

+ 37 - 37
toolchain/check/testdata/class/nested.carbon

@@ -31,37 +31,37 @@ fn F(a: Outer*) {
 // CHECK:STDOUT: --- nested.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc12_3.1: type = struct_type {.pi: Inner*, .po: Outer*, .qi: Inner*}, const
-// CHECK:STDOUT:   %.loc17_1.1: type = struct_type {.po: Outer*, .qo: Outer*, .pi: Inner*}, const
-// CHECK:STDOUT:   %.loc17_1.2: type = ptr_type {.po: Outer*, .qo: Outer*, .pi: Inner*}, const
-// CHECK:STDOUT:   %.loc12_3.2: type = ptr_type {.pi: Inner*, .po: Outer*, .qi: Inner*}, const
+// CHECK:STDOUT:   %.loc12_3.1: type = struct_type {.pi: Inner*, .po: Outer*, .qi: Inner*} [template]
+// CHECK:STDOUT:   %.loc17_1.1: type = struct_type {.po: Outer*, .qo: Outer*, .pi: Inner*} [template]
+// CHECK:STDOUT:   %.loc17_1.2: type = ptr_type {.po: Outer*, .qo: Outer*, .pi: Inner*} [template]
+// CHECK:STDOUT:   %.loc12_3.2: type = ptr_type {.pi: Inner*, .po: Outer*, .qi: Inner*} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Outer = %Outer.decl, .F = %F}
 // CHECK:STDOUT:   %Outer.decl = class_decl @Outer, ()
-// CHECK:STDOUT:   %Outer: type = class_type @Outer, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Outer: type = class_type @Outer [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Outer {
 // CHECK:STDOUT:   %Inner.decl = class_decl @Inner, ()
-// CHECK:STDOUT:   %Inner: type = class_type @Inner, const
-// CHECK:STDOUT:   %Self.ref: type = name_ref Self, file.%Outer, const = file.%Outer
-// CHECK:STDOUT:   %.loc14_15: type = ptr_type Outer, const
-// CHECK:STDOUT:   %.loc14_9.1: type = unbound_element_type Outer, Outer*, const
-// CHECK:STDOUT:   %.loc14_9.2: <unbound element of class Outer> = field_decl po, element0, const
-// CHECK:STDOUT:   %po: <unbound element of class Outer> = bind_name po, %.loc14_9.2, const = %.loc14_9.2
-// CHECK:STDOUT:   %Outer.ref: type = name_ref Outer, file.%Outer, const = file.%Outer
-// CHECK:STDOUT:   %.loc15_16: type = ptr_type Outer, const
-// CHECK:STDOUT:   %.loc15_9.1: type = unbound_element_type Outer, Outer*, const
-// CHECK:STDOUT:   %.loc15_9.2: <unbound element of class Outer> = field_decl qo, element1, const
-// CHECK:STDOUT:   %qo: <unbound element of class Outer> = bind_name qo, %.loc15_9.2, const = %.loc15_9.2
-// CHECK:STDOUT:   %Inner.ref: type = name_ref Inner, %Inner, const = %Inner
-// CHECK:STDOUT:   %.loc16_16: type = ptr_type Inner, const
-// CHECK:STDOUT:   %.loc16_9.1: type = unbound_element_type Outer, Inner*, const
-// CHECK:STDOUT:   %.loc16_9.2: <unbound element of class Outer> = field_decl pi, element2, const
-// CHECK:STDOUT:   %pi: <unbound element of class Outer> = bind_name pi, %.loc16_9.2, const = %.loc16_9.2
+// CHECK:STDOUT:   %Inner: type = class_type @Inner [template]
+// CHECK:STDOUT:   %Self.ref: type = name_ref Self, file.%Outer [template = file.%Outer]
+// CHECK:STDOUT:   %.loc14_15: type = ptr_type Outer [template]
+// CHECK:STDOUT:   %.loc14_9.1: type = unbound_element_type Outer, Outer* [template]
+// CHECK:STDOUT:   %.loc14_9.2: <unbound element of class Outer> = field_decl po, element0 [template]
+// CHECK:STDOUT:   %po: <unbound element of class Outer> = bind_name po, %.loc14_9.2 [template = %.loc14_9.2]
+// CHECK:STDOUT:   %Outer.ref: type = name_ref Outer, file.%Outer [template = file.%Outer]
+// CHECK:STDOUT:   %.loc15_16: type = ptr_type Outer [template]
+// CHECK:STDOUT:   %.loc15_9.1: type = unbound_element_type Outer, Outer* [template]
+// CHECK:STDOUT:   %.loc15_9.2: <unbound element of class Outer> = field_decl qo, element1 [template]
+// CHECK:STDOUT:   %qo: <unbound element of class Outer> = bind_name qo, %.loc15_9.2 [template = %.loc15_9.2]
+// CHECK:STDOUT:   %Inner.ref: type = name_ref Inner, %Inner [template = %Inner]
+// CHECK:STDOUT:   %.loc16_16: type = ptr_type Inner [template]
+// CHECK:STDOUT:   %.loc16_9.1: type = unbound_element_type Outer, Inner* [template]
+// CHECK:STDOUT:   %.loc16_9.2: <unbound element of class Outer> = field_decl pi, element2 [template]
+// CHECK:STDOUT:   %pi: <unbound element of class Outer> = bind_name pi, %.loc16_9.2 [template = %.loc16_9.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Inner = %Inner.decl
@@ -71,21 +71,21 @@ fn F(a: Outer*) {
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Inner {
-// CHECK:STDOUT:   %Self.ref: type = name_ref Self, @Outer.%Inner, const = @Outer.%Inner
-// CHECK:STDOUT:   %.loc9_17: type = ptr_type Inner, const
-// CHECK:STDOUT:   %.loc9_11.1: type = unbound_element_type Inner, Inner*, const
-// CHECK:STDOUT:   %.loc9_11.2: <unbound element of class Inner> = field_decl pi, element0, const
-// CHECK:STDOUT:   %pi: <unbound element of class Inner> = bind_name pi, %.loc9_11.2, const = %.loc9_11.2
-// CHECK:STDOUT:   %Outer.ref: type = name_ref Outer, file.%Outer, const = file.%Outer
-// CHECK:STDOUT:   %.loc10_18: type = ptr_type Outer, const
-// CHECK:STDOUT:   %.loc10_11.1: type = unbound_element_type Inner, Outer*, const
-// CHECK:STDOUT:   %.loc10_11.2: <unbound element of class Inner> = field_decl po, element1, const
-// CHECK:STDOUT:   %po: <unbound element of class Inner> = bind_name po, %.loc10_11.2, const = %.loc10_11.2
-// CHECK:STDOUT:   %Inner.ref: type = name_ref Inner, @Outer.%Inner, const = @Outer.%Inner
-// CHECK:STDOUT:   %.loc11_18: type = ptr_type Inner, const
-// CHECK:STDOUT:   %.loc11_11.1: type = unbound_element_type Inner, Inner*, const
-// CHECK:STDOUT:   %.loc11_11.2: <unbound element of class Inner> = field_decl qi, element2, const
-// CHECK:STDOUT:   %qi: <unbound element of class Inner> = bind_name qi, %.loc11_11.2, const = %.loc11_11.2
+// CHECK:STDOUT:   %Self.ref: type = name_ref Self, @Outer.%Inner [template = @Outer.%Inner]
+// CHECK:STDOUT:   %.loc9_17: type = ptr_type Inner [template]
+// CHECK:STDOUT:   %.loc9_11.1: type = unbound_element_type Inner, Inner* [template]
+// CHECK:STDOUT:   %.loc9_11.2: <unbound element of class Inner> = field_decl pi, element0 [template]
+// CHECK:STDOUT:   %pi: <unbound element of class Inner> = bind_name pi, %.loc9_11.2 [template = %.loc9_11.2]
+// CHECK:STDOUT:   %Outer.ref: type = name_ref Outer, file.%Outer [template = file.%Outer]
+// CHECK:STDOUT:   %.loc10_18: type = ptr_type Outer [template]
+// CHECK:STDOUT:   %.loc10_11.1: type = unbound_element_type Inner, Outer* [template]
+// CHECK:STDOUT:   %.loc10_11.2: <unbound element of class Inner> = field_decl po, element1 [template]
+// CHECK:STDOUT:   %po: <unbound element of class Inner> = bind_name po, %.loc10_11.2 [template = %.loc10_11.2]
+// CHECK:STDOUT:   %Inner.ref: type = name_ref Inner, @Outer.%Inner [template = @Outer.%Inner]
+// CHECK:STDOUT:   %.loc11_18: type = ptr_type Inner [template]
+// CHECK:STDOUT:   %.loc11_11.1: type = unbound_element_type Inner, Inner* [template]
+// CHECK:STDOUT:   %.loc11_11.2: <unbound element of class Inner> = field_decl qi, element2 [template]
+// CHECK:STDOUT:   %qi: <unbound element of class Inner> = bind_name qi, %.loc11_11.2 [template = %.loc11_11.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .pi = %pi

+ 13 - 13
toolchain/check/testdata/class/nested_name.carbon

@@ -21,33 +21,33 @@ fn G(o: Outer) {
 // CHECK:STDOUT: --- nested_name.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10: type = struct_type {.n: i32}, const
-// CHECK:STDOUT:   %.loc11_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc8: type = ptr_type {.n: i32}, const
-// CHECK:STDOUT:   %.loc11_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
+// CHECK:STDOUT:   %.loc10: type = struct_type {.n: i32} [template]
+// CHECK:STDOUT:   %.loc11_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc8: type = ptr_type {.n: i32} [template]
+// CHECK:STDOUT:   %.loc11_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Outer = %Outer.decl, .F = %F, .G = %G}
 // CHECK:STDOUT:   %Outer.decl = class_decl @Outer, ()
-// CHECK:STDOUT:   %Outer: type = class_type @Outer, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %Outer: type = class_type @Outer [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Outer {
 // CHECK:STDOUT:   %Inner.decl = class_decl @Inner, ()
-// CHECK:STDOUT:   %Inner: type = class_type @Inner, const
+// CHECK:STDOUT:   %Inner: type = class_type @Inner [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Inner = %Inner.decl
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Inner {
-// CHECK:STDOUT:   %.loc9_10.1: type = unbound_element_type Inner, i32, const
-// CHECK:STDOUT:   %.loc9_10.2: <unbound element of class Inner> = field_decl n, element0, const
-// CHECK:STDOUT:   %n: <unbound element of class Inner> = bind_name n, %.loc9_10.2, const = %.loc9_10.2
+// CHECK:STDOUT:   %.loc9_10.1: type = unbound_element_type Inner, i32 [template]
+// CHECK:STDOUT:   %.loc9_10.2: <unbound element of class Inner> = field_decl n, element0 [template]
+// CHECK:STDOUT:   %n: <unbound element of class Inner> = bind_name n, %.loc9_10.2 [template = %.loc9_10.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .n = %n
@@ -64,7 +64,7 @@ fn G(o: Outer) {
 // CHECK:STDOUT: fn @G(%o: Outer) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %o.ref: Outer = name_ref o, %o
-// CHECK:STDOUT:   %Inner.ref: type = name_ref Inner, @Outer.%Inner, const = @Outer.%Inner
+// CHECK:STDOUT:   %Inner.ref: type = name_ref Inner, @Outer.%Inner [template = @Outer.%Inner]
 // CHECK:STDOUT:   %i.var: ref Inner = var i
 // CHECK:STDOUT:   %i: ref Inner = bind_name i, %i.var
 // CHECK:STDOUT:   return

+ 13 - 13
toolchain/check/testdata/class/raw_self.carbon

@@ -21,27 +21,27 @@ fn Class.G[self: Class](r#self: i32) -> (i32, i32) {
 // CHECK:STDOUT: --- raw_self.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9_46.1: type = tuple_type (type, type), const
-// CHECK:STDOUT:   %.loc9_46.2: type = tuple_type (i32, i32), const
-// CHECK:STDOUT:   %.loc9_46.3: type = ptr_type (i32, i32), const
-// CHECK:STDOUT:   %.loc11: type = struct_type {.n: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.n: i32}, const
+// CHECK:STDOUT:   %.loc9_46.1: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.loc9_46.2: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc9_46.3: type = ptr_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc11: type = struct_type {.n: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.n: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %.loc10_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc10_8.2: <unbound element of class Class> = field_decl n, element0, const
-// CHECK:STDOUT:   %n: <unbound element of class Class> = bind_name n, %.loc10_8.2, const = %.loc10_8.2
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %.loc10_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc10_8.2: <unbound element of class Class> = field_decl n, element0 [template]
+// CHECK:STDOUT:   %n: <unbound element of class Class> = bind_name n, %.loc10_8.2 [template = %.loc10_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F

+ 7 - 7
toolchain/check/testdata/class/raw_self_type.carbon

@@ -14,17 +14,17 @@ class Class {
 // CHECK:STDOUT: --- raw_self_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc12: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc12: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -32,12 +32,12 @@ class Class {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Self.ref.loc9: type = name_ref Self, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %.loc9: type = ptr_type Class, const
+// CHECK:STDOUT:   %Self.ref.loc9: type = name_ref Self, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %.loc9: type = ptr_type Class [template]
 // CHECK:STDOUT:   %Self.var: ref Class* = var r#Self
 // CHECK:STDOUT:   %Self: ref Class* = bind_name r#Self, %Self.var
-// CHECK:STDOUT:   %Self.ref.loc10_12: type = name_ref Self, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %.loc10_16: type = ptr_type Class, const
+// CHECK:STDOUT:   %Self.ref.loc10_12: type = name_ref Self, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %.loc10_16: type = ptr_type Class [template]
 // CHECK:STDOUT:   %p.var: ref Class* = var p
 // CHECK:STDOUT:   %p: ref Class* = bind_name p, %p.var
 // CHECK:STDOUT:   %Self.ref.loc10_20: ref Class* = name_ref r#Self, %Self

+ 4 - 4
toolchain/check/testdata/class/redeclaration.carbon

@@ -15,19 +15,19 @@ fn Class.F() {}
 // CHECK:STDOUT: --- redeclaration.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc11: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl.loc7}
 // CHECK:STDOUT:   %Class.decl.loc7 = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
 // CHECK:STDOUT:   %Class.decl.loc9 = class_decl @Class, ()
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F

+ 4 - 4
toolchain/check/testdata/class/redeclaration_introducer.carbon

@@ -15,17 +15,17 @@ abstract class C {}
 // CHECK:STDOUT: --- redeclaration_introducer.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc11: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc11: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.A = %A.decl.loc7, .B = %B.decl.loc8, .C = %C.decl.loc9}
 // CHECK:STDOUT:   %A.decl.loc7 = class_decl @A, ()
-// CHECK:STDOUT:   %A: type = class_type @A, const
+// CHECK:STDOUT:   %A: type = class_type @A [template]
 // CHECK:STDOUT:   %B.decl.loc8 = class_decl @B, ()
-// CHECK:STDOUT:   %B: type = class_type @B, const
+// CHECK:STDOUT:   %B: type = class_type @B [template]
 // CHECK:STDOUT:   %C.decl.loc9 = class_decl @C, ()
-// CHECK:STDOUT:   %C: type = class_type @C, const
+// CHECK:STDOUT:   %C: type = class_type @C [template]
 // CHECK:STDOUT:   %A.decl.loc11 = class_decl @A, ()
 // CHECK:STDOUT:   %B.decl.loc12 = class_decl @B, ()
 // CHECK:STDOUT:   %C.decl.loc13 = class_decl @C, ()

+ 6 - 6
toolchain/check/testdata/class/reenter_scope.carbon

@@ -16,19 +16,19 @@ fn Class.F() -> i32 {
 // CHECK:STDOUT: --- reenter_scope.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10: type = struct_type {}, const
+// CHECK:STDOUT:   %.loc10: type = struct_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -37,7 +37,7 @@ fn Class.F() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %G.ref: <function> = name_ref G, @Class.%G, const = @Class.%G
+// CHECK:STDOUT:   %G.ref: <function> = name_ref G, @Class.%G [template = @Class.%G]
 // CHECK:STDOUT:   %.loc13_11: init i32 = call %G.ref()
 // CHECK:STDOUT:   %.loc13_13.1: i32 = value_of_initializer %.loc13_11
 // CHECK:STDOUT:   %.loc13_13.2: i32 = converted %.loc13_11, %.loc13_13.1

+ 14 - 14
toolchain/check/testdata/class/scope.carbon

@@ -26,22 +26,22 @@ fn Run() {
 // CHECK:STDOUT: --- scope.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc15: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc18: i32 = int_literal 2, const
+// CHECK:STDOUT:   %.loc9: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc15: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc18: i32 = int_literal 2 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .F = %F, .Run = %Run}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.2, const
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.2 [template]
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F.1, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F.1 [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -50,13 +50,13 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.1() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc9: i32 = int_literal 1, const = constants.%.loc9
+// CHECK:STDOUT:   %.loc9: i32 = int_literal 1 [template = constants.%.loc9]
 // CHECK:STDOUT:   return %.loc9
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Class.%F, const = @Class.%F
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Class.%F [template = @Class.%F]
 // CHECK:STDOUT:   %.loc13_13: init i32 = call %F.ref()
 // CHECK:STDOUT:   %.loc13_15.1: i32 = value_of_initializer %.loc13_13
 // CHECK:STDOUT:   %.loc13_15.2: i32 = converted %.loc13_13, %.loc13_15.1
@@ -65,7 +65,7 @@ fn Run() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F.2() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc18: i32 = int_literal 2, const = constants.%.loc18
+// CHECK:STDOUT:   %.loc18: i32 = int_literal 2 [template = constants.%.loc18]
 // CHECK:STDOUT:   return %.loc18
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
@@ -73,13 +73,13 @@ fn Run() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %a.var: ref i32 = var a
 // CHECK:STDOUT:   %a: ref i32 = bind_name a, %a.var
-// CHECK:STDOUT:   %F.ref.loc22: <function> = name_ref F, file.%F, const = file.%F
+// CHECK:STDOUT:   %F.ref.loc22: <function> = name_ref F, file.%F [template = file.%F]
 // CHECK:STDOUT:   %.loc22: init i32 = call %F.ref.loc22()
 // CHECK:STDOUT:   assign %a.var, %.loc22
 // CHECK:STDOUT:   %b.var: ref i32 = var b
 // CHECK:STDOUT:   %b: ref i32 = bind_name b, %b.var
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %F.ref.loc23: <function> = name_ref F, @Class.%F, const = @Class.%F
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %F.ref.loc23: <function> = name_ref F, @Class.%F [template = @Class.%F]
 // CHECK:STDOUT:   %.loc23: init i32 = call %F.ref.loc23()
 // CHECK:STDOUT:   assign %b.var, %.loc23
 // CHECK:STDOUT:   return

+ 10 - 10
toolchain/check/testdata/class/self.carbon

@@ -22,24 +22,24 @@ fn Class.G[addr self: Class*]() -> i32 {
 // CHECK:STDOUT: --- self.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc12: type = struct_type {.n: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.n: i32}, const
+// CHECK:STDOUT:   %.loc12: type = struct_type {.n: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.n: i32} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %.loc11_8.1: type = unbound_element_type Class, i32, const
-// CHECK:STDOUT:   %.loc11_8.2: <unbound element of class Class> = field_decl n, element0, const
-// CHECK:STDOUT:   %n: <unbound element of class Class> = bind_name n, %.loc11_8.2, const = %.loc11_8.2
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %.loc11_8.1: type = unbound_element_type Class, i32 [template]
+// CHECK:STDOUT:   %.loc11_8.2: <unbound element of class Class> = field_decl n, element0 [template]
+// CHECK:STDOUT:   %n: <unbound element of class Class> = bind_name n, %.loc11_8.2 [template = %.loc11_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F

+ 21 - 21
toolchain/check/testdata/class/self_conversion.carbon

@@ -31,41 +31,41 @@ fn Call(p: Derived*) -> i32 {
 // CHECK:STDOUT: --- self_conversion.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9: type = struct_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.a: i32}, const
-// CHECK:STDOUT:   %.loc16_1.1: type = struct_type {.base: Base}, const
-// CHECK:STDOUT:   %.loc23: i32 = int_literal 1, const
-// CHECK:STDOUT:   %.loc16_1.2: type = struct_type {.base: {.a: i32}*}, const
-// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: Base}, const
-// CHECK:STDOUT:   %.loc27: type = tuple_type (), const
+// CHECK:STDOUT:   %.loc9: type = struct_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.a: i32} [template]
+// CHECK:STDOUT:   %.loc16_1.1: type = struct_type {.base: Base} [template]
+// CHECK:STDOUT:   %.loc23: i32 = int_literal 1 [template]
+// CHECK:STDOUT:   %.loc16_1.2: type = struct_type {.base: {.a: i32}*} [template]
+// CHECK:STDOUT:   %.loc11: type = ptr_type {.base: Base} [template]
+// CHECK:STDOUT:   %.loc27: type = tuple_type () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Base = %Base.decl, .Derived = %Derived.decl, .Call = %Call}
 // CHECK:STDOUT:   %Base.decl = class_decl @Base, ()
-// CHECK:STDOUT:   %Base: type = class_type @Base, const
+// CHECK:STDOUT:   %Base: type = class_type @Base [template]
 // CHECK:STDOUT:   %Derived.decl = class_decl @Derived, ()
-// CHECK:STDOUT:   %Derived: type = class_type @Derived, const
-// CHECK:STDOUT:   %SelfBase: <function> = fn_decl @SelfBase, const
-// CHECK:STDOUT:   %AddrSelfBase: <function> = fn_decl @AddrSelfBase, const
-// CHECK:STDOUT:   %Call: <function> = fn_decl @Call, const
+// CHECK:STDOUT:   %Derived: type = class_type @Derived [template]
+// CHECK:STDOUT:   %SelfBase: <function> = fn_decl @SelfBase [template]
+// CHECK:STDOUT:   %AddrSelfBase: <function> = fn_decl @AddrSelfBase [template]
+// CHECK:STDOUT:   %Call: <function> = fn_decl @Call [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Base {
-// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Base, i32, const
-// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Base> = field_decl a, element0, const
-// CHECK:STDOUT:   %a: <unbound element of class Base> = bind_name a, %.loc8_8.2, const = %.loc8_8.2
+// CHECK:STDOUT:   %.loc8_8.1: type = unbound_element_type Base, i32 [template]
+// CHECK:STDOUT:   %.loc8_8.2: <unbound element of class Base> = field_decl a, element0 [template]
+// CHECK:STDOUT:   %a: <unbound element of class Base> = bind_name a, %.loc8_8.2 [template = %.loc8_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .a = %a
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Derived {
-// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base, const = file.%Base
-// CHECK:STDOUT:   %.loc12_20.1: type = unbound_element_type Derived, Base, const
-// CHECK:STDOUT:   %.loc12_20.2: <unbound element of class Derived> = base_decl Base, element0, const
-// CHECK:STDOUT:   %SelfBase: <function> = fn_decl @SelfBase, const
-// CHECK:STDOUT:   %AddrSelfBase: <function> = fn_decl @AddrSelfBase, const
+// CHECK:STDOUT:   %Base.ref: type = name_ref Base, file.%Base [template = file.%Base]
+// CHECK:STDOUT:   %.loc12_20.1: type = unbound_element_type Derived, Base [template]
+// CHECK:STDOUT:   %.loc12_20.2: <unbound element of class Derived> = base_decl Base, element0 [template]
+// CHECK:STDOUT:   %SelfBase: <function> = fn_decl @SelfBase [template]
+// CHECK:STDOUT:   %AddrSelfBase: <function> = fn_decl @AddrSelfBase [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .base = %.loc12_20.2
@@ -87,7 +87,7 @@ fn Call(p: Derived*) -> i32 {
 // CHECK:STDOUT:   %self.ref: Base* = name_ref self, %self
 // CHECK:STDOUT:   %.loc23_4: ref Base = deref %self.ref
 // CHECK:STDOUT:   %.loc23_10: ref i32 = class_element_access %.loc23_4, element0
-// CHECK:STDOUT:   %.loc23_15: i32 = int_literal 1, const = constants.%.loc23
+// CHECK:STDOUT:   %.loc23_15: i32 = int_literal 1 [template = constants.%.loc23]
 // CHECK:STDOUT:   assign %.loc23_10, %.loc23_15
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 10 - 10
toolchain/check/testdata/class/self_type.carbon

@@ -19,24 +19,24 @@ fn Class.F[self: Class]() -> i32 {
 // CHECK:STDOUT: --- self_type.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc10: type = struct_type {.p: Class*}, const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {.p: Class*}, const
+// CHECK:STDOUT:   %.loc10: type = struct_type {.p: Class*} [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {.p: Class*} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %Self.ref: type = name_ref Self, file.%Class, const = file.%Class
-// CHECK:STDOUT:   %.loc9_14: type = ptr_type Class, const
-// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, Class*, const
-// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl p, element0, const
-// CHECK:STDOUT:   %p: <unbound element of class Class> = bind_name p, %.loc9_8.2, const = %.loc9_8.2
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %Self.ref: type = name_ref Self, file.%Class [template = file.%Class]
+// CHECK:STDOUT:   %.loc9_14: type = ptr_type Class [template]
+// CHECK:STDOUT:   %.loc9_8.1: type = unbound_element_type Class, Class* [template]
+// CHECK:STDOUT:   %.loc9_8.2: <unbound element of class Class> = field_decl p, element0 [template]
+// CHECK:STDOUT:   %p: <unbound element of class Class> = bind_name p, %.loc9_8.2 [template = %.loc9_8.2]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F

+ 8 - 8
toolchain/check/testdata/class/static_method.carbon

@@ -16,20 +16,20 @@ fn Run() -> i32 {
 // CHECK:STDOUT: --- static_method.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc7: type = ptr_type {}, const
+// CHECK:STDOUT:   %.loc9_1.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc9_1.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc7: type = ptr_type {} [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Class = %Class.decl, .Run = %Run}
 // CHECK:STDOUT:   %Class.decl = class_decl @Class, ()
-// CHECK:STDOUT:   %Class: type = class_type @Class, const
-// CHECK:STDOUT:   %Run: <function> = fn_decl @Run, const
+// CHECK:STDOUT:   %Class: type = class_type @Class [template]
+// CHECK:STDOUT:   %Run: <function> = fn_decl @Run [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: class @Class {
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .F = %F
@@ -39,11 +39,11 @@ fn Run() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class, const = file.%Class
+// CHECK:STDOUT:   %Class.ref: type = name_ref Class, file.%Class [template = file.%Class]
 // CHECK:STDOUT:   %c.var: ref Class = var c
 // CHECK:STDOUT:   %c: ref Class = bind_name c, %c.var
 // CHECK:STDOUT:   %c.ref: ref Class = name_ref c, %c
-// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Class.%F, const = @Class.%F
+// CHECK:STDOUT:   %F.ref: <function> = name_ref F, @Class.%F [template = @Class.%F]
 // CHECK:STDOUT:   %.loc13_13: init i32 = call %F.ref()
 // CHECK:STDOUT:   %.loc13_15.1: i32 = value_of_initializer %.loc13_13
 // CHECK:STDOUT:   %.loc13_15.2: i32 = converted %.loc13_13, %.loc13_15.1

+ 1 - 1
toolchain/check/testdata/const/collapse.carbon

@@ -16,7 +16,7 @@ fn F(p: const i32**) -> const (const i32)** {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.F = %F}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F(%p: const i32**) -> const i32** {

+ 1 - 1
toolchain/check/testdata/const/fail_collapse.carbon

@@ -18,7 +18,7 @@ fn G(p: const (const i32)**) -> i32** {
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.G = %G}
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @G(%p: const i32**) -> i32** {

+ 13 - 13
toolchain/check/testdata/expr_category/in_place_tuple_init.carbon

@@ -19,17 +19,17 @@ fn H() -> i32 {
 // CHECK:STDOUT: --- in_place_tuple_init.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_20.1: type = tuple_type (type, type), const
-// CHECK:STDOUT:   %.loc7_20.2: type = tuple_type (i32, i32), const
-// CHECK:STDOUT:   %.loc7_20.3: type = ptr_type (i32, i32), const
-// CHECK:STDOUT:   %.loc16: i32 = int_literal 0, const
+// CHECK:STDOUT:   %.loc7_20.1: type = tuple_type (type, type) [template]
+// CHECK:STDOUT:   %.loc7_20.2: type = tuple_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc7_20.3: type = ptr_type (i32, i32) [template]
+// CHECK:STDOUT:   %.loc16: i32 = int_literal 0 [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.F = %F, .G = %G, .H = %H}
-// CHECK:STDOUT:   %F: <function> = fn_decl @F, const
-// CHECK:STDOUT:   %G: <function> = fn_decl @G, const
-// CHECK:STDOUT:   %H: <function> = fn_decl @H, const
+// CHECK:STDOUT:   %F: <function> = fn_decl @F [template]
+// CHECK:STDOUT:   %G: <function> = fn_decl @G [template]
+// CHECK:STDOUT:   %H: <function> = fn_decl @H [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @F() -> %return: (i32, i32);
@@ -37,19 +37,19 @@ fn H() -> i32 {
 // CHECK:STDOUT: fn @G() -> %return: (i32, i32) {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %.loc10_19: (type, type) = tuple_literal (i32, i32)
-// CHECK:STDOUT:   %.loc7: type = converted %.loc10_19, constants.%.loc7_20.2, const = constants.%.loc7_20.2
+// CHECK:STDOUT:   %.loc7: type = converted %.loc10_19, constants.%.loc7_20.2 [template = constants.%.loc7_20.2]
 // CHECK:STDOUT:   %v.var: ref (i32, i32) = var v
 // CHECK:STDOUT:   %v: ref (i32, i32) = bind_name v, %v.var
-// CHECK:STDOUT:   %F.ref.loc10: <function> = name_ref F, file.%F, const = file.%F
+// CHECK:STDOUT:   %F.ref.loc10: <function> = name_ref F, file.%F [template = file.%F]
 // CHECK:STDOUT:   %.loc10_7: ref (i32, i32) = splice_block %v.var {}
 // CHECK:STDOUT:   %.loc10_24: init (i32, i32) = call %F.ref.loc10() to %.loc10_7
 // CHECK:STDOUT:   assign %v.var, %.loc10_24
 // CHECK:STDOUT:   %v.ref: ref (i32, i32) = name_ref v, %v
-// CHECK:STDOUT:   %F.ref.loc11: <function> = name_ref F, file.%F, const = file.%F
+// CHECK:STDOUT:   %F.ref.loc11: <function> = name_ref F, file.%F [template = file.%F]
 // CHECK:STDOUT:   %.loc11_3: ref (i32, i32) = splice_block %v.ref {}
 // CHECK:STDOUT:   %.loc11_8: init (i32, i32) = call %F.ref.loc11() to %.loc11_3
 // CHECK:STDOUT:   assign %v.ref, %.loc11_8
-// CHECK:STDOUT:   %F.ref.loc12: <function> = name_ref F, file.%F, const = file.%F
+// CHECK:STDOUT:   %F.ref.loc12: <function> = name_ref F, file.%F [template = file.%F]
 // CHECK:STDOUT:   %.loc9: ref (i32, i32) = splice_block %return {}
 // CHECK:STDOUT:   %.loc12: init (i32, i32) = call %F.ref.loc12() to %.loc9
 // CHECK:STDOUT:   return %.loc12
@@ -57,10 +57,10 @@ fn H() -> i32 {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @H() -> i32 {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %G.ref: <function> = name_ref G, file.%G, const = file.%G
+// CHECK:STDOUT:   %G.ref: <function> = name_ref G, file.%G [template = file.%G]
 // CHECK:STDOUT:   %.loc16_11.1: ref (i32, i32) = temporary_storage
 // CHECK:STDOUT:   %.loc16_11.2: init (i32, i32) = call %G.ref() to %.loc16_11.1
-// CHECK:STDOUT:   %.loc16_14: i32 = int_literal 0, const = constants.%.loc16
+// CHECK:STDOUT:   %.loc16_14: i32 = int_literal 0 [template = constants.%.loc16]
 // CHECK:STDOUT:   %.loc16_11.3: ref (i32, i32) = temporary %.loc16_11.1, %.loc16_11.2
 // CHECK:STDOUT:   %.loc16_15.1: ref i32 = tuple_index %.loc16_11.3, %.loc16_14
 // CHECK:STDOUT:   %.loc16_15.2: i32 = bind_value %.loc16_15.1

+ 8 - 8
toolchain/check/testdata/function/call/empty_struct.carbon

@@ -15,15 +15,15 @@ fn Main() {
 // CHECK:STDOUT: --- empty_struct.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7_13.1: type = struct_type {}, const
-// CHECK:STDOUT:   %.loc7_13.2: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc12: {} = struct_value (), const
+// CHECK:STDOUT:   %.loc7_13.1: type = struct_type {} [template]
+// CHECK:STDOUT:   %.loc7_13.2: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc12: {} = struct_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Echo = %Echo, .Main = %Main}
-// CHECK:STDOUT:   %Echo: <function> = fn_decl @Echo, const
-// CHECK:STDOUT:   %Main: <function> = fn_decl @Main, const
+// CHECK:STDOUT:   %Echo: <function> = fn_decl @Echo [template]
+// CHECK:STDOUT:   %Main: <function> = fn_decl @Main [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Echo(%a: {}) -> {} {
@@ -34,10 +34,10 @@ fn Main() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Echo.ref: <function> = name_ref Echo, file.%Echo, const = file.%Echo
+// CHECK:STDOUT:   %Echo.ref: <function> = name_ref Echo, file.%Echo [template = file.%Echo]
 // CHECK:STDOUT:   %.loc12_9.1: {} = struct_literal ()
-// CHECK:STDOUT:   %.loc12_9.2: {} = struct_value (), const = constants.%.loc12
-// CHECK:STDOUT:   %.loc12_9.3: {} = converted %.loc12_9.1, %.loc12_9.2, const = constants.%.loc12
+// CHECK:STDOUT:   %.loc12_9.2: {} = struct_value () [template = constants.%.loc12]
+// CHECK:STDOUT:   %.loc12_9.3: {} = converted %.loc12_9.1, %.loc12_9.2 [template = constants.%.loc12]
 // CHECK:STDOUT:   %.loc12_7: init {} = call %Echo.ref(%.loc12_9.3)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 7 - 7
toolchain/check/testdata/function/call/empty_tuple.carbon

@@ -15,14 +15,14 @@ fn Main() {
 // CHECK:STDOUT: --- empty_tuple.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
-// CHECK:STDOUT:   %.loc7: type = tuple_type (), const
-// CHECK:STDOUT:   %.loc12: () = tuple_value (), const
+// CHECK:STDOUT:   %.loc7: type = tuple_type () [template]
+// CHECK:STDOUT:   %.loc12: () = tuple_value () [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace package, {.Echo = %Echo, .Main = %Main}
-// CHECK:STDOUT:   %Echo: <function> = fn_decl @Echo, const
-// CHECK:STDOUT:   %Main: <function> = fn_decl @Main, const
+// CHECK:STDOUT:   %Echo: <function> = fn_decl @Echo [template]
+// CHECK:STDOUT:   %Main: <function> = fn_decl @Main [template]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Echo(%a: ()) -> () {
@@ -33,10 +33,10 @@ fn Main() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @Main() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %Echo.ref: <function> = name_ref Echo, file.%Echo, const = file.%Echo
+// CHECK:STDOUT:   %Echo.ref: <function> = name_ref Echo, file.%Echo [template = file.%Echo]
 // CHECK:STDOUT:   %.loc12_9.1: () = tuple_literal ()
-// CHECK:STDOUT:   %.loc12_9.2: () = tuple_value (), const = constants.%.loc12
-// CHECK:STDOUT:   %.loc12_9.3: () = converted %.loc12_9.1, %.loc12_9.2, const = constants.%.loc12
+// CHECK:STDOUT:   %.loc12_9.2: () = tuple_value () [template = constants.%.loc12]
+// CHECK:STDOUT:   %.loc12_9.3: () = converted %.loc12_9.1, %.loc12_9.2 [template = constants.%.loc12]
 // CHECK:STDOUT:   %.loc12_7: init () = call %Echo.ref(%.loc12_9.3)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä