Explorar o código

Adding ValueStore printing and --dump-shared-values (#3320)

This replaces the printing that was removed from SemIR's raw dump. It's
separate because (for example) lexing generates shared values, and so
reviewing them is not specific to any particular phase.
Jon Ross-Perkins %!s(int64=2) %!d(string=hai) anos
pai
achega
843dd40f22

+ 30 - 3
toolchain/base/value_store.h

@@ -10,6 +10,7 @@
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/YAMLParser.h"
 #include "toolchain/base/index_base.h"
 
 namespace Carbon {
@@ -80,7 +81,7 @@ constexpr StringId StringId::Invalid(StringId::InvalidIndex);
 // A simple wrapper for accumulating values, providing IDs to later retrieve the
 // value. This does not do deduplication.
 template <typename IdT>
-class ValueStore {
+class ValueStore : public Printable<ValueStore<IdT>> {
  public:
   // Stores the value and returns an ID to reference it.
   auto Add(typename IdT::IndexedType value) -> IdT {
@@ -96,6 +97,14 @@ class ValueStore {
     return values_[id.index];
   }
 
+  auto Print(llvm::raw_ostream& out) const -> void { Print(out, 0); }
+  auto Print(llvm::raw_ostream& out, int indent) const -> void {
+    for (const auto& value : values_) {
+      out.indent(indent);
+      out << "- " << value << "\n";
+    }
+  }
+
  private:
   llvm::SmallVector<typename IdT::IndexedType> values_;
 };
@@ -103,7 +112,7 @@ class ValueStore {
 // Storage for StringRefs. The caller is responsible for ensuring storage is
 // allocated.
 template <>
-class ValueStore<StringId> {
+class ValueStore<StringId> : public Printable<ValueStore<StringId>> {
  public:
   // Returns an ID to reference the value. May return an existing ID if the
   // string was previously added.
@@ -122,6 +131,14 @@ class ValueStore<StringId> {
     return values_[id.index];
   }
 
+  auto Print(llvm::raw_ostream& out) const -> void { Print(out, 0); }
+  auto Print(llvm::raw_ostream& out, int indent) const -> void {
+    for (auto value : values_) {
+      out.indent(indent);
+      out << "- \"" << llvm::yaml::escape(value) << "\"\n";
+    }
+  }
+
  private:
   llvm::DenseMap<llvm::StringRef, StringId> map_;
   llvm::SmallVector<llvm::StringRef> values_;
@@ -129,7 +146,7 @@ class ValueStore<StringId> {
 
 // Stores that will be used across compiler steps. This is provided mainly so
 // that they don't need to be passed separately.
-class SharedValueStores {
+class SharedValueStores : public Printable<SharedValueStores> {
  public:
   auto integers() -> ValueStore<IntegerId>& { return integers_; }
   auto integers() const -> const ValueStore<IntegerId>& { return integers_; }
@@ -138,6 +155,16 @@ class SharedValueStores {
   auto strings() -> ValueStore<StringId>& { return strings_; }
   auto strings() const -> const ValueStore<StringId>& { return strings_; }
 
+  auto Print(llvm::raw_ostream& out) const -> void {
+    out << "shared_values:\n"
+        << "  - integers:\n";
+    integers_.Print(out, 6);
+    out << "  - reals:\n";
+    reals_.Print(out, 6);
+    out << "  - strings:\n";
+    strings_.Print(out, 6);
+  }
+
  private:
   ValueStore<IntegerId> integers_;
   ValueStore<RealId> reals_;

+ 15 - 1
toolchain/driver/driver.cpp

@@ -180,6 +180,14 @@ and displaying them in source order.
         },
         [&](auto& arg_b) { arg_b.Set(&stream_errors); });
 
+    b.AddFlag(
+        {
+            .name = "dump-shared-values",
+            .help = R"""(
+Dumps shared values. These aren't owned by any particular file or phase.
+)""",
+        },
+        [&](auto& arg_b) { arg_b.Set(&dump_shared_values); });
     b.AddFlag(
         {
             .name = "dump-tokens",
@@ -257,6 +265,7 @@ Dump the generated assembly to stdout after codegen.
 
   bool asm_output = false;
   bool force_obj_output = false;
+  bool dump_shared_values = false;
   bool dump_tokens = false;
   bool dump_parse_tree = false;
   bool dump_raw_sem_ir = false;
@@ -599,7 +608,6 @@ auto Driver::Compile(const CompileOptions& options) -> bool {
     return false;
   }
 
-  SharedValueStores value_stores;
   llvm::SmallVector<std::unique_ptr<CompilationUnit>> units;
   auto flush = llvm::make_scope_exit([&]() {
     // The diagnostics consumer must be flushed before compilation artifacts are
@@ -609,6 +617,12 @@ auto Driver::Compile(const CompileOptions& options) -> bool {
       unit->Flush();
     }
   });
+  SharedValueStores value_stores;
+  auto dump_shared_values = llvm::make_scope_exit([&]() {
+    if (options.dump_shared_values) {
+      output_stream_ << value_stores;
+    }
+  });
   for (const auto& input_file_name : options.input_file_names) {
     units.push_back(std::make_unique<CompilationUnit>(
         this, &value_stores, options, input_file_name));

+ 20 - 0
toolchain/driver/testdata/dump_shared_values.carbon

@@ -0,0 +1,20 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+// ARGS: compile --phase=lex --dump-shared-values %s
+//
+// AUTOUPDATE
+
+var a: f64 = 1.0;
+var b: String = "ab\"c";
+
+// CHECK:STDOUT: shared_values:
+// CHECK:STDOUT:   - integers:
+// CHECK:STDOUT:       - 64
+// CHECK:STDOUT:   - reals:
+// CHECK:STDOUT:       - 10*10^-1
+// CHECK:STDOUT:   - strings:
+// CHECK:STDOUT:       - "a"
+// CHECK:STDOUT:       - "b"
+// CHECK:STDOUT:       - "ab\"c"