Просмотр исходного кода

Refactor File constructors to share logic. (#3675)

I was considering this again while working on #3674, it would be helpful
to share initialization for both regular and builtin File constructors.
Jon Ross-Perkins 2 лет назад
Родитель
Сommit
134766d50c
2 измененных файлов с 34 добавлено и 39 удалено
  1. 30 39
      toolchain/sem_ir/file.cpp
  2. 4 0
      toolchain/sem_ir/file.h

+ 30 - 39
toolchain/sem_ir/file.cpp

@@ -60,63 +60,54 @@ auto TypeInfo::Print(llvm::raw_ostream& out) const -> void {
   out << "{constant: " << constant_id << ", value_rep: " << value_repr << "}";
 }
 
-File::File(SharedValueStores& value_stores)
+File::File(SharedValueStores& value_stores, std::string filename,
+           const File* builtins, llvm::function_ref<void()> init_builtins)
     : value_stores_(&value_stores),
-      filename_("<builtins>"),
+      filename_(std::move(filename)),
       type_blocks_(allocator_),
       inst_blocks_(allocator_),
       constants_(*this, allocator_) {
-  auto builtins_id = import_irs_.Add(this);
+  CARBON_CHECK(builtins != nullptr);
+  auto builtins_id = import_irs_.Add(builtins);
   CARBON_CHECK(builtins_id == ImportIRId::Builtins)
-      << "Builtins must be the first IR, even if self-referential";
+      << "Builtins must be the first IR";
 
   insts_.Reserve(BuiltinKind::ValidCount);
+  init_builtins();
+  CARBON_CHECK(insts_.size() == BuiltinKind::ValidCount)
+      << "Builtins should produce " << BuiltinKind::ValidCount
+      << " insts, actual: " << insts_.size();
+  for (auto i : llvm::seq(BuiltinKind::ValidCount)) {
+    auto builtin_id = SemIR::InstId(i);
+    constant_values_.Set(builtin_id,
+                         SemIR::ConstantId::ForTemplateConstant(builtin_id));
+  }
+}
 
-  // Error uses a self-referential type so that it's not accidentally treated as
-  // a normal type. Every other builtin is a type, including the
-  // self-referential TypeType.
+File::File(SharedValueStores& value_stores)
+    : File(value_stores, "<builtins>", this, [&]() {
+// Error uses a self-referential type so that it's not accidentally treated as
+// a normal type. Every other builtin is a type, including the
+// self-referential TypeType.
 #define CARBON_SEM_IR_BUILTIN_KIND(Name, ...)                              \
   insts_.AddInNoBlock(                                                     \
       {Builtin{BuiltinKind::Name == BuiltinKind::Error ? TypeId::Error     \
                                                        : TypeId::TypeType, \
                BuiltinKind::Name}});
 #include "toolchain/sem_ir/builtin_kind.def"
-  for (auto [i, inst] : llvm::enumerate(insts_.array_ref())) {
-    auto builtin_id = SemIR::InstId(i);
-    constant_values_.Set(builtin_id,
-                         SemIR::ConstantId::ForTemplateConstant(builtin_id));
-  }
-
-  CARBON_CHECK(insts_.size() == BuiltinKind::ValidCount)
-      << "Builtins should produce " << BuiltinKind::ValidCount
-      << " insts, actual: " << insts_.size();
+      }) {
 }
 
 File::File(SharedValueStores& value_stores, std::string filename,
            const File* builtins)
-    : value_stores_(&value_stores),
-      filename_(std::move(filename)),
-      type_blocks_(allocator_),
-      inst_blocks_(allocator_),
-      constants_(*this, allocator_) {
-  CARBON_CHECK(builtins != nullptr);
-  auto builtins_id = import_irs_.Add(builtins);
-  CARBON_CHECK(builtins_id == ImportIRId::Builtins)
-      << "Builtins must be the first IR";
-
-  // Copy builtins over.
-  insts_.Reserve(BuiltinKind::ValidCount);
-  for (auto [i, inst] : llvm::enumerate(builtins->insts_.array_ref())) {
-    // We can reuse the type IDs from the builtins IR because they're
-    // special-cased values.
-    auto type_id = inst.type_id();
-    auto builtin_id = SemIR::InstId(i);
-    insts_.AddInNoBlock(
-        {ImportRefUsed{type_id, ImportIRId::Builtins, builtin_id}});
-    constant_values_.Set(builtin_id,
-                         SemIR::ConstantId::ForTemplateConstant(builtin_id));
-  }
-}
+    : File(value_stores, filename, builtins, [&]() {
+        for (auto [i, inst] : llvm::enumerate(builtins->insts_.array_ref())) {
+          // We can reuse the type_id from the builtin IR's inst because they're
+          // special-cased values.
+          insts_.AddInNoBlock({ImportRefUsed{
+              inst.type_id(), ImportIRId::Builtins, SemIR::InstId(i)}});
+        }
+      }) {}
 
 auto File::Verify() const -> ErrorOr<Success> {
   // Invariants don't necessarily hold for invalid IR.

+ 4 - 0
toolchain/sem_ir/file.h

@@ -314,6 +314,10 @@ class File : public Printable<File> {
   auto filename() const -> llvm::StringRef { return filename_; }
 
  private:
+  // Common File initialization.
+  explicit File(SharedValueStores& value_stores, std::string filename,
+                const File* builtins, llvm::function_ref<void()> init_builtins);
+
   bool has_errors_ = false;
 
   // Shared, compile-scoped values.