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

Add more empty stack verification (#5020)

Jon Ross-Perkins 1 год назад
Родитель
Сommit
5574ad361d

+ 7 - 0
toolchain/check/check_unit.cpp

@@ -65,6 +65,10 @@ auto CheckUnit::Run() -> void {
   // Add a block for the file.
   context_.inst_block_stack().Push();
 
+  // TODO: Remove this and the pop in `FinishRun` once we properly push and pop
+  // in the right places.
+  context_.generic_region_stack().Push();
+
   InitPackageScopeAndImports();
 
   // Eagerly import the impls declared in the api file to prepare to redeclare
@@ -491,6 +495,9 @@ auto CheckUnit::CheckRequiredDefinitions() -> void {
 }
 
 auto CheckUnit::FinishRun() -> void {
+  // TODO: Remove this once we properly push and pop in the right places.
+  context_.generic_region_stack().Pop();
+
   CheckRequiredDeclarations();
   CheckRequiredDefinitions();
 

+ 9 - 9
toolchain/check/context.cpp

@@ -31,10 +31,6 @@ Context::Context(DiagnosticEmitter<SemIRLoc>* emitter,
   import_irs().Reserve(imported_ir_count);
   import_ir_constant_values_.reserve(imported_ir_count);
   check_ir_map_.resize(total_ir_count, SemIR::ImportIRId::None);
-
-  // TODO: Remove this and add a `VerifyOnFinish` once we properly push and pop
-  // in the right places.
-  generic_region_stack().Push();
 }
 
 auto Context::TODO(SemIRLoc loc, std::string label) -> bool {
@@ -46,17 +42,21 @@ auto Context::TODO(SemIRLoc loc, std::string label) -> bool {
 auto Context::VerifyOnFinish() const -> void {
   // Information in all the various context objects should be cleaned up as
   // various pieces of context go out of scope. At this point, nothing should
-  // remain.
-  // node_stack_ will still contain top-level entities.
+  // remain, so we verify stacks are empty. `node_stack_` is an exception
+  // because it ends containing all top-level entities.
   inst_block_stack_.VerifyOnFinish();
   pattern_block_stack_.VerifyOnFinish();
   param_and_arg_refs_stack_.VerifyOnFinish();
   args_type_info_stack_.VerifyOnFinish();
   CARBON_CHECK(struct_type_fields_stack_.empty());
-  // TODO: Add verification for decl_name_stack_ and
-  // decl_introducer_state_stack_.
+  CARBON_CHECK(field_decls_stack_.empty());
+  decl_name_stack_.VerifyOnFinish();
+  decl_introducer_state_stack_.VerifyOnFinish();
   scope_stack_.VerifyOnFinish();
-  // TODO: Add verification for generic_region_stack_.
+  generic_region_stack_.VerifyOnFinish();
+  vtable_stack_.VerifyOnFinish();
+  region_stack_.VerifyOnFinish();
+  CARBON_CHECK(impl_lookup_stack_.empty());
 
 #ifndef NDEBUG
   if (auto verify = sem_ir_->Verify(); !verify.ok()) {

+ 7 - 0
toolchain/check/decl_introducer_state.h

@@ -78,6 +78,13 @@ class DeclIntroducerStateStack {
     return stack_.pop_back_val();
   }
 
+  // Runs verification that the processing cleanly finished.
+  auto VerifyOnFinish() const -> void {
+    CARBON_CHECK(stack_.empty(),
+                 "decl_introduce_state_stack still has {0} entries",
+                 stack_.size());
+  }
+
  private:
   llvm::SmallVector<DeclIntroducerState> stack_;
 };

+ 7 - 0
toolchain/check/decl_name_stack.h

@@ -252,6 +252,13 @@ class DeclNameStack {
                        SemIR::AccessKind access_kind)
       -> SemIR::ScopeLookupResult;
 
+  // Runs verification that the processing cleanly finished.
+  auto VerifyOnFinish() const -> void {
+    CARBON_CHECK(decl_name_stack_.empty(),
+                 "decl_name_stack still has {0} entries",
+                 decl_name_stack_.size());
+  }
+
  private:
   // Returns a name context corresponding to an empty name.
   auto MakeEmptyNameContext() -> NameContext;

+ 7 - 0
toolchain/check/generic_region_stack.h

@@ -58,6 +58,13 @@ class GenericRegionStack {
   // Returns the list of dependent instructions in the current generic region.
   auto PeekDependentInsts() -> llvm::ArrayRef<DependentInst>;
 
+  // Runs verification that the processing cleanly finished.
+  auto VerifyOnFinish() const -> void {
+    CARBON_CHECK(dependent_insts_stack_.empty(),
+                 "generic_region_stack still has {0} entries",
+                 dependent_insts_stack_.all_values_size());
+  }
+
  private:
   // A stack of symbolic constants for enclosing generic regions.
   ArrayStack<DependentInst> dependent_insts_stack_;

+ 6 - 0
toolchain/check/region_stack.h

@@ -68,6 +68,12 @@ class RegionStack {
     return stack_.PeekArray();
   }
 
+  // Runs verification that the processing cleanly finished.
+  auto VerifyOnFinish() const -> void {
+    CARBON_CHECK(stack_.empty(), "region_stack still has {0} entries",
+                 stack_.all_values_size());
+  }
+
   // Returns true if any regions have been added.
   auto empty() -> bool { return stack_.empty(); }