소스 검색

Rename DiagnosticLocationTranslator -> DiagnosticConverter (#3804)

Since the addition of TranslateArg, I don't think this type is going to
go away (cutting a TODO). Refactoring names slightly to fit the current
role, and adding const to ConvertLocation.
Jon Ross-Perkins 2 년 전
부모
커밋
0bd45f0d6b

+ 2 - 2
toolchain/check/BUILD

@@ -82,7 +82,7 @@ cc_library(
         "//toolchain/lex:tokenized_buffer",
         "//toolchain/parse:node_kind",
         "//toolchain/parse:tree",
-        "//toolchain/parse:tree_node_location_translator",
+        "//toolchain/parse:tree_node_diagnostic_converter",
         "//toolchain/sem_ir:builtin_kind",
         "//toolchain/sem_ir:file",
         "//toolchain/sem_ir:ids",
@@ -119,7 +119,7 @@ cc_library(
         "//toolchain/lex:tokenized_buffer",
         "//toolchain/parse:node_kind",
         "//toolchain/parse:tree",
-        "//toolchain/parse:tree_node_location_translator",
+        "//toolchain/parse:tree_node_diagnostic_converter",
         "//toolchain/sem_ir:entry_point",
         "//toolchain/sem_ir:file",
         "//toolchain/sem_ir:ids",

+ 35 - 38
toolchain/check/check.cpp

@@ -12,7 +12,7 @@
 #include "toolchain/lex/token_kind.h"
 #include "toolchain/parse/node_ids.h"
 #include "toolchain/parse/tree.h"
-#include "toolchain/parse/tree_node_location_translator.h"
+#include "toolchain/parse/tree_node_diagnostic_converter.h"
 #include "toolchain/sem_ir/file.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/typed_insts.h"
@@ -25,19 +25,18 @@ namespace Carbon::Check {
 #include "toolchain/parse/node_kind.def"
 
 // Handles the transformation of a SemIRLocation to a DiagnosticLocation.
-class SemIRLocationTranslator
-    : public DiagnosticLocationTranslator<SemIRLocation> {
+class SemIRDiagnosticConverter : public DiagnosticConverter<SemIRLocation> {
  public:
-  explicit SemIRLocationTranslator(
-      const llvm::DenseMap<const SemIR::File*, Parse::NodeLocationTranslator*>*
-          node_translators,
+  explicit SemIRDiagnosticConverter(
+      const llvm::DenseMap<const SemIR::File*, Parse::NodeLocationConverter*>*
+          node_converters,
       const SemIR::File* sem_ir)
-      : node_translators_(node_translators), sem_ir_(sem_ir) {}
+      : node_converters_(node_converters), sem_ir_(sem_ir) {}
 
-  auto GetLocation(SemIRLocation loc) -> DiagnosticLocation override {
+  auto ConvertLocation(SemIRLocation loc) const -> DiagnosticLocation override {
     // Parse nodes always refer to the current IR.
     if (!loc.is_inst_id) {
-      return GetLocationInFile(sem_ir_, loc.node_location);
+      return ConvertLocationInFile(sem_ir_, loc.node_location);
     }
 
     const auto* cursor_ir = sem_ir_;
@@ -46,7 +45,7 @@ class SemIRLocationTranslator
       // If the parse node is valid, use it for the location.
       if (auto node_id = cursor_ir->insts().GetNodeId(cursor_inst_id);
           node_id.is_valid()) {
-        return GetLocationInFile(cursor_ir, node_id);
+        return ConvertLocationInFile(cursor_ir, node_id);
       }
 
       // If the parse node was invalid, recurse through import references when
@@ -69,38 +68,37 @@ class SemIRLocationTranslator
       }
 
       // Invalid parse node but not an import; just nothing to point at.
-      return GetLocationInFile(cursor_ir, Parse::NodeId::Invalid);
+      return ConvertLocationInFile(cursor_ir, Parse::NodeId::Invalid);
     }
   }
 
-  auto TranslateArg(DiagnosticTypeTranslation translation, llvm::Any arg) const
+  auto ConvertArg(DiagnosticTypeConversion conversion, llvm::Any arg) const
       -> llvm::Any override {
-    switch (translation) {
-      case DiagnosticTypeTranslation::NameId: {
+    switch (conversion) {
+      case DiagnosticTypeConversion::NameId: {
         auto name_id = llvm::any_cast<SemIR::NameId>(arg);
         return sem_ir_->names().GetFormatted(name_id).str();
       }
-      case DiagnosticTypeTranslation::TypeId: {
+      case DiagnosticTypeConversion::TypeId: {
         auto type_id = llvm::any_cast<SemIR::TypeId>(arg);
         return sem_ir_->StringifyType(type_id);
       }
       default:
-        return DiagnosticLocationTranslator<SemIRLocation>::TranslateArg(
-            translation, arg);
+        return DiagnosticConverter<SemIRLocation>::ConvertArg(conversion, arg);
     }
   }
 
  private:
-  auto GetLocationInFile(const SemIR::File* sem_ir,
-                         Parse::NodeLocation node_location) const
+  auto ConvertLocationInFile(const SemIR::File* sem_ir,
+                             Parse::NodeLocation node_location) const
       -> DiagnosticLocation {
-    auto it = node_translators_->find(sem_ir);
-    CARBON_CHECK(it != node_translators_->end());
-    return it->second->GetLocation(node_location);
+    auto it = node_converters_->find(sem_ir);
+    CARBON_CHECK(it != node_converters_->end());
+    return it->second->ConvertLocation(node_location);
   }
 
-  const llvm::DenseMap<const SemIR::File*, Parse::NodeLocationTranslator*>*
-      node_translators_;
+  const llvm::DenseMap<const SemIR::File*, Parse::NodeLocationConverter*>*
+      node_converters_;
   const SemIR::File* sem_ir_;
 };
 
@@ -129,15 +127,15 @@ struct UnitInfo {
 
   explicit UnitInfo(Unit& unit)
       : unit(&unit),
-        translator(unit.tokens, unit.tokens->source().filename(),
-                   unit.parse_tree),
+        converter(unit.tokens, unit.tokens->source().filename(),
+                  unit.parse_tree),
         err_tracker(*unit.consumer),
-        emitter(translator, err_tracker) {}
+        emitter(converter, err_tracker) {}
 
   Unit* unit;
 
   // Emitter information.
-  Parse::NodeLocationTranslator translator;
+  Parse::NodeLocationConverter converter;
   ErrorTrackingDiagnosticConsumer err_tracker;
   DiagnosticEmitter<Parse::NodeLocation> emitter;
 
@@ -255,8 +253,8 @@ static auto ProcessNodeIds(Context& context,
 
 // Produces and checks the IR for the provided Parse::Tree.
 static auto CheckParseTree(
-    llvm::DenseMap<const SemIR::File*, Parse::NodeLocationTranslator*>*
-        node_translators,
+    llvm::DenseMap<const SemIR::File*, Parse::NodeLocationConverter*>*
+        node_converters,
     const SemIR::File& builtin_ir, UnitInfo& unit_info,
     llvm::raw_ostream* vlog_stream) -> void {
   unit_info.unit->sem_ir->emplace(
@@ -265,11 +263,10 @@ static auto CheckParseTree(
 
   // For ease-of-access.
   SemIR::File& sem_ir = **unit_info.unit->sem_ir;
-  CARBON_CHECK(
-      node_translators->insert({&sem_ir, &unit_info.translator}).second);
+  CARBON_CHECK(node_converters->insert({&sem_ir, &unit_info.converter}).second);
 
-  SemIRLocationTranslator translator(node_translators, &sem_ir);
-  Context::DiagnosticEmitter emitter(translator, unit_info.err_tracker);
+  SemIRDiagnosticConverter converter(node_converters, &sem_ir);
+  Context::DiagnosticEmitter emitter(converter, unit_info.err_tracker);
   Context context(*unit_info.unit->tokens, emitter, *unit_info.unit->parse_tree,
                   sem_ir, vlog_stream);
   PrettyStackTraceFunction context_dumper(
@@ -582,15 +579,15 @@ auto CheckParseTrees(const SemIR::File& builtin_ir,
     }
   }
 
-  llvm::DenseMap<const SemIR::File*, Parse::NodeLocationTranslator*>
-      node_translators;
+  llvm::DenseMap<const SemIR::File*, Parse::NodeLocationConverter*>
+      node_converters;
 
   // Check everything with no dependencies. Earlier entries with dependencies
   // will be checked as soon as all their dependencies have been checked.
   for (int check_index = 0;
        check_index < static_cast<int>(ready_to_check.size()); ++check_index) {
     auto* unit_info = ready_to_check[check_index];
-    CheckParseTree(&node_translators, builtin_ir, *unit_info, vlog_stream);
+    CheckParseTree(&node_converters, builtin_ir, *unit_info, vlog_stream);
     for (auto* incoming_import : unit_info->incoming_imports) {
       --incoming_import->imports_remaining;
       if (incoming_import->imports_remaining == 0) {
@@ -635,7 +632,7 @@ auto CheckParseTrees(const SemIR::File& builtin_ir,
     // incomplete imports.
     for (auto& unit_info : unit_infos) {
       if (unit_info.imports_remaining > 0) {
-        CheckParseTree(&node_translators, builtin_ir, unit_info, vlog_stream);
+        CheckParseTree(&node_converters, builtin_ir, unit_info, vlog_stream);
       }
     }
   }

+ 1 - 1
toolchain/check/context.h

@@ -16,7 +16,7 @@
 #include "toolchain/check/scope_stack.h"
 #include "toolchain/parse/node_ids.h"
 #include "toolchain/parse/tree.h"
-#include "toolchain/parse/tree_node_location_translator.h"
+#include "toolchain/parse/tree_node_diagnostic_converter.h"
 #include "toolchain/sem_ir/file.h"
 #include "toolchain/sem_ir/ids.h"
 #include "toolchain/sem_ir/inst.h"

+ 1 - 1
toolchain/check/handle_function.cpp

@@ -9,7 +9,7 @@
 #include "toolchain/check/function.h"
 #include "toolchain/check/interface.h"
 #include "toolchain/check/modifiers.h"
-#include "toolchain/parse/tree_node_location_translator.h"
+#include "toolchain/parse/tree_node_diagnostic_converter.h"
 #include "toolchain/sem_ir/entry_point.h"
 #include "toolchain/sem_ir/function.h"
 #include "toolchain/sem_ir/ids.h"

+ 1 - 1
toolchain/diagnostics/BUILD

@@ -17,8 +17,8 @@ cc_library(
     hdrs = [
         "diagnostic.h",
         "diagnostic_consumer.h",
+        "diagnostic_converter.h",
         "diagnostic_emitter.h",
-        "diagnostic_translator.h",
     ],
     deps = [
         ":diagnostic_kind",

+ 79 - 0
toolchain/diagnostics/diagnostic_converter.h

@@ -0,0 +1,79 @@
+// 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
+
+#ifndef CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_CONVERTER_H_
+#define CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_CONVERTER_H_
+
+#include <cstdint>
+
+#include "common/check.h"
+#include "llvm/ADT/Any.h"
+#include "toolchain/diagnostics/diagnostic.h"
+
+namespace Carbon {
+
+// Known diagnostic type conversions. These are enumerated because `llvm::Any`
+// doesn't expose the contained type; instead, we infer it from a given
+// diagnostic.
+enum class DiagnosticTypeConversion : int8_t {
+  None,
+  NameId,
+  TypeId,
+};
+
+// An interface that can convert some representation of a location into a
+// diagnostic location.
+template <typename LocationT>
+class DiagnosticConverter {
+ public:
+  virtual ~DiagnosticConverter() = default;
+
+  virtual auto ConvertLocation(LocationT loc) const -> DiagnosticLocation = 0;
+
+  // Converts arg types as needed. Not all uses support conversion, so the
+  // default simply errors.
+  virtual auto ConvertArg(DiagnosticTypeConversion conversion,
+                          llvm::Any /*arg*/) const -> llvm::Any {
+    CARBON_FATAL() << "Unexpected call to ConvertArg: "
+                   << static_cast<int8_t>(conversion);
+  }
+};
+
+// Used by types to indicate a DiagnosticTypeConversion that results in the
+// provided StorageType. For example, to convert NameId to a std::string, we
+// write:
+//
+// struct NameId {
+//   using DiagnosticType =
+//       DiagnosticTypeInfo<std::string, DiagnosticTypeConversion::NameId>;
+// };
+template <typename StorageTypeT, DiagnosticTypeConversion ConversionV>
+struct DiagnosticTypeInfo {
+  using StorageType = StorageTypeT;
+  static constexpr DiagnosticTypeConversion Conversion = ConversionV;
+};
+
+namespace Internal {
+
+// Determines whether there's a DiagnosticType member on Arg.
+// Used by DiagnosticEmitter.
+template <typename Arg>
+concept HasDiagnosticType =
+    requires { std::type_identity<typename Arg::DiagnosticType>(); };
+
+// The default implementation with no conversion.
+template <typename Arg, typename /*Unused*/ = void>
+struct DiagnosticTypeForArg
+    : public DiagnosticTypeInfo<Arg, DiagnosticTypeConversion::None> {};
+
+// Exposes a custom conversion for an argument type.
+template <typename Arg>
+  requires HasDiagnosticType<Arg>
+struct DiagnosticTypeForArg<Arg> : public Arg::DiagnosticType {};
+
+}  // namespace Internal
+
+}  // namespace Carbon
+
+#endif  // CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_CONVERTER_H_

+ 12 - 13
toolchain/diagnostics/diagnostic_emitter.h

@@ -16,8 +16,8 @@
 #include "llvm/Support/FormatVariadic.h"
 #include "toolchain/diagnostics/diagnostic.h"
 #include "toolchain/diagnostics/diagnostic_consumer.h"
+#include "toolchain/diagnostics/diagnostic_converter.h"
 #include "toolchain/diagnostics/diagnostic_kind.h"
-#include "toolchain/diagnostics/diagnostic_translator.h"
 
 namespace Carbon {
 
@@ -103,7 +103,7 @@ class DiagnosticEmitter {
         const Internal::DiagnosticBase<Args...>& diagnostic_base,
         llvm::SmallVector<llvm::Any> args) -> DiagnosticMessage {
       return DiagnosticMessage(
-          diagnostic_base.Kind, emitter->translator_->GetLocation(location),
+          diagnostic_base.Kind, emitter->converter_->ConvertLocation(location),
           diagnostic_base.Format, std::move(args),
           [](const DiagnosticMessage& message) -> std::string {
             return FormatFn<Args...>(
@@ -131,12 +131,11 @@ class DiagnosticEmitter {
     Diagnostic diagnostic_;
   };
 
-  // The `translator` and `consumer` are required to outlive the diagnostic
+  // The `converter` and `consumer` are required to outlive the diagnostic
   // emitter.
-  explicit DiagnosticEmitter(
-      DiagnosticLocationTranslator<LocationT>& translator,
-      DiagnosticConsumer& consumer)
-      : translator_(&translator), consumer_(&consumer) {}
+  explicit DiagnosticEmitter(DiagnosticConverter<LocationT>& converter,
+                             DiagnosticConsumer& consumer)
+      : converter_(&converter), consumer_(&consumer) {}
   ~DiagnosticEmitter() = default;
 
   // Emits an error.
@@ -167,22 +166,22 @@ class DiagnosticEmitter {
 
  private:
   // Converts an argument to llvm::Any for storage, handling input to storage
-  // type translation when needed.
+  // type conversion when needed.
   template <typename Arg>
   auto MakeAny(Arg arg) -> llvm::Any {
-    if constexpr (Internal::DiagnosticTypeForArg<Arg>::Translation ==
-                  DiagnosticTypeTranslation::None) {
+    if constexpr (Internal::DiagnosticTypeForArg<Arg>::Conversion ==
+                  DiagnosticTypeConversion::None) {
       return arg;
     } else {
-      return translator_->TranslateArg(
-          Internal::DiagnosticTypeForArg<Arg>::Translation, arg);
+      return converter_->ConvertArg(
+          Internal::DiagnosticTypeForArg<Arg>::Conversion, arg);
     }
   }
 
   template <typename LocT, typename AnnotateFn>
   friend class DiagnosticAnnotationScope;
 
-  DiagnosticLocationTranslator<LocationT>* translator_;
+  DiagnosticConverter<LocationT>* converter_;
   DiagnosticConsumer* consumer_;
   llvm::SmallVector<llvm::function_ref<auto(DiagnosticBuilder& builder)->void>>
       annotate_fns_;

+ 4 - 4
toolchain/diagnostics/diagnostic_emitter_test.cpp

@@ -15,17 +15,17 @@ namespace {
 
 using ::Carbon::Testing::IsDiagnostic;
 
-struct FakeDiagnosticLocationTranslator : DiagnosticLocationTranslator<int> {
-  auto GetLocation(int n) -> DiagnosticLocation override {
+struct FakeDiagnosticConverter : DiagnosticConverter<int> {
+  auto ConvertLocation(int n) const -> DiagnosticLocation override {
     return {.line_number = 1, .column_number = n};
   }
 };
 
 class DiagnosticEmitterTest : public ::testing::Test {
  protected:
-  DiagnosticEmitterTest() : emitter_(translator_, consumer_) {}
+  DiagnosticEmitterTest() : emitter_(converter_, consumer_) {}
 
-  FakeDiagnosticLocationTranslator translator_;
+  FakeDiagnosticConverter converter_;
   Testing::MockDiagnosticConsumer consumer_;
   DiagnosticEmitter<int> emitter_;
 };

+ 0 - 82
toolchain/diagnostics/diagnostic_translator.h

@@ -1,82 +0,0 @@
-// 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
-
-#ifndef CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_TRANSLATOR_H_
-#define CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_TRANSLATOR_H_
-
-#include <cstdint>
-
-#include "common/check.h"
-#include "llvm/ADT/Any.h"
-#include "toolchain/diagnostics/diagnostic.h"
-
-namespace Carbon {
-
-// Known diagnostic type translations. These are enumerated because `llvm::Any`
-// doesn't expose the contained type; instead, we infer it from a given
-// diagnostic.
-enum class DiagnosticTypeTranslation : int8_t {
-  None,
-  NameId,
-  TypeId,
-};
-
-// An interface that can translate some representation of a location into a
-// diagnostic location.
-//
-// TODO: Revisit this once the diagnostics machinery is more complete and see
-// if we can turn it into a `std::function`.
-template <typename LocationT>
-class DiagnosticLocationTranslator {
- public:
-  virtual ~DiagnosticLocationTranslator() = default;
-
-  virtual auto GetLocation(LocationT loc) -> DiagnosticLocation = 0;
-
-  // Translates arg types as needed. Not all uses support translation, so the
-  // default simply errors.
-  virtual auto TranslateArg(DiagnosticTypeTranslation translation,
-                            llvm::Any /*arg*/) const -> llvm::Any {
-    CARBON_FATAL() << "Unexpected call to TranslateArg: "
-                   << static_cast<int8_t>(translation);
-  }
-};
-
-// Used by types to indicate a DiagnosticTypeTranslation that results in the
-// provided StorageType. For example, to translate NameId to a std::string, we
-// write:
-//
-// struct NameId {
-//   using DiagnosticType =
-//       DiagnosticTypeInfo<std::string, DiagnosticTypeTranslation::NameId>;
-// };
-template <typename StorageTypeT, DiagnosticTypeTranslation TranslationV>
-struct DiagnosticTypeInfo {
-  using StorageType = StorageTypeT;
-  static constexpr DiagnosticTypeTranslation Translation = TranslationV;
-};
-
-namespace Internal {
-
-// Determines whether there's a DiagnosticType member on Arg.
-// Used by DiagnosticEmitter.
-template <typename Arg>
-concept HasDiagnosticType =
-    requires { std::type_identity<typename Arg::DiagnosticType>(); };
-
-// The default implementation with no translation.
-template <typename Arg, typename /*Unused*/ = void>
-struct DiagnosticTypeForArg
-    : public DiagnosticTypeInfo<Arg, DiagnosticTypeTranslation::None> {};
-
-// Exposes a custom translation for an argument type.
-template <typename Arg>
-  requires HasDiagnosticType<Arg>
-struct DiagnosticTypeForArg<Arg> : public Arg::DiagnosticType {};
-
-}  // namespace Internal
-
-}  // namespace Carbon
-
-#endif  // CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_TRANSLATOR_H_

+ 7 - 7
toolchain/diagnostics/null_diagnostics.h

@@ -10,15 +10,15 @@
 namespace Carbon {
 
 template <typename LocationT>
-inline auto NullDiagnosticLocationTranslator()
-    -> DiagnosticLocationTranslator<LocationT>& {
-  struct Translator : DiagnosticLocationTranslator<LocationT> {
-    auto GetLocation(LocationT /*loc*/) -> DiagnosticLocation override {
+inline auto NullDiagnosticConverter() -> DiagnosticConverter<LocationT>& {
+  struct Converter : DiagnosticConverter<LocationT> {
+    auto ConvertLocation(LocationT /*loc*/) const
+        -> DiagnosticLocation override {
       return {};
     }
   };
-  static auto* translator = new Translator;
-  return *translator;
+  static auto* converter = new Converter;
+  return *converter;
 }
 
 inline auto NullDiagnosticConsumer() -> DiagnosticConsumer& {
@@ -32,7 +32,7 @@ inline auto NullDiagnosticConsumer() -> DiagnosticConsumer& {
 template <typename LocationT>
 inline auto NullDiagnosticEmitter() -> DiagnosticEmitter<LocationT>& {
   static auto* emitter = new DiagnosticEmitter<LocationT>(
-      NullDiagnosticLocationTranslator<LocationT>(), NullDiagnosticConsumer());
+      NullDiagnosticConverter<LocationT>(), NullDiagnosticConsumer());
   return *emitter;
 }
 

+ 5 - 5
toolchain/diagnostics/sorting_diagnostic_consumer_test.cpp

@@ -19,18 +19,18 @@ using ::testing::InSequence;
 
 CARBON_DIAGNOSTIC(TestDiagnostic, Error, "{0}", llvm::StringLiteral);
 
-struct FakeDiagnosticLocationTranslator
-    : DiagnosticLocationTranslator<DiagnosticLocation> {
-  auto GetLocation(DiagnosticLocation loc) -> DiagnosticLocation override {
+struct FakeDiagnosticConverter : DiagnosticConverter<DiagnosticLocation> {
+  auto ConvertLocation(DiagnosticLocation loc) const
+      -> DiagnosticLocation override {
     return loc;
   }
 };
 
 TEST(SortedDiagnosticEmitterTest, SortErrors) {
-  FakeDiagnosticLocationTranslator translator;
+  FakeDiagnosticConverter converter;
   Testing::MockDiagnosticConsumer consumer;
   SortingDiagnosticConsumer sorting_consumer(consumer);
-  DiagnosticEmitter<DiagnosticLocation> emitter(translator, sorting_consumer);
+  DiagnosticEmitter<DiagnosticLocation> emitter(converter, sorting_consumer);
 
   emitter.Emit({"f", "line", 2, 1}, TestDiagnostic, "M1");
   emitter.Emit({"f", "line", 1, 1}, TestDiagnostic, "M2");

+ 6 - 6
toolchain/lex/lex.cpp

@@ -77,10 +77,10 @@ class [[clang::internal_linkage]] Lexer {
         DiagnosticConsumer& consumer)
       : buffer_(value_stores, source),
         consumer_(consumer),
-        translator_(&buffer_),
-        emitter_(translator_, consumer_),
-        token_translator_(&buffer_),
-        token_emitter_(token_translator_, consumer_) {}
+        converter_(&buffer_),
+        emitter_(converter_, consumer_),
+        token_converter_(&buffer_),
+        token_emitter_(token_converter_, consumer_) {}
 
   // Find all line endings and create the line data structures.
   //
@@ -170,10 +170,10 @@ class [[clang::internal_linkage]] Lexer {
 
   ErrorTrackingDiagnosticConsumer consumer_;
 
-  TokenizedBuffer::SourceBufferLocationTranslator translator_;
+  TokenizedBuffer::SourceBufferDiagnosticConverter converter_;
   LexerDiagnosticEmitter emitter_;
 
-  TokenLocationTranslator token_translator_;
+  TokenDiagnosticConverter token_converter_;
   TokenDiagnosticEmitter token_emitter_;
 };
 

+ 2 - 2
toolchain/lex/numeric_literal_test.cpp

@@ -33,8 +33,8 @@ class NumericLiteralTest : public ::testing::Test {
   }
 
   auto Parse(llvm::StringRef text) -> NumericLiteral::Value {
-    Testing::SingleTokenDiagnosticTranslator translator(text);
-    DiagnosticEmitter<const char*> emitter(translator, error_tracker);
+    Testing::SingleTokenDiagnosticConverter converter(text);
+    DiagnosticEmitter<const char*> emitter(converter, error_tracker);
     return Lex(text).ComputeValue(emitter);
   }
 

+ 2 - 2
toolchain/lex/string_literal_test.cpp

@@ -27,8 +27,8 @@ class StringLiteralTest : public ::testing::Test {
 
   auto Parse(llvm::StringRef text) -> llvm::StringRef {
     StringLiteral token = Lex(text);
-    Testing::SingleTokenDiagnosticTranslator translator(text);
-    DiagnosticEmitter<const char*> emitter(translator, error_tracker);
+    Testing::SingleTokenDiagnosticConverter converter(text);
+    DiagnosticEmitter<const char*> emitter(converter, error_tracker);
     return token.ComputeValue(allocator, emitter);
   }
 

+ 5 - 6
toolchain/lex/test_helpers.h

@@ -15,17 +15,16 @@
 
 namespace Carbon::Testing {
 
-// A diagnostic translator for tests that lex a single token. Produces
+// A diagnostic converter for tests that lex a single token. Produces
 // locations such as "`12.5`:1:3" to refer to the third character in the token.
-class SingleTokenDiagnosticTranslator
-    : public DiagnosticLocationTranslator<const char*> {
+class SingleTokenDiagnosticConverter : public DiagnosticConverter<const char*> {
  public:
-  // Form a translator for a given token. The string provided here must refer
+  // Form a converter for a given token. The string provided here must refer
   // to the same character array that we are going to lex.
-  explicit SingleTokenDiagnosticTranslator(llvm::StringRef token)
+  explicit SingleTokenDiagnosticConverter(llvm::StringRef token)
       : token_(token) {}
 
-  auto GetLocation(const char* pos) -> DiagnosticLocation override {
+  auto ConvertLocation(const char* pos) const -> DiagnosticLocation override {
     CARBON_CHECK(StringRefContainsPointer(token_, pos))
         << "invalid diagnostic location";
     llvm::StringRef prefix = token_.take_front(pos - token_.begin());

+ 4 - 4
toolchain/lex/tokenized_buffer.cpp

@@ -345,8 +345,8 @@ auto TokenIterator::Print(llvm::raw_ostream& output) const -> void {
   output << token_.index;
 }
 
-auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation(
-    const char* loc) -> DiagnosticLocation {
+auto TokenizedBuffer::SourceBufferDiagnosticConverter::ConvertLocation(
+    const char* loc) const -> DiagnosticLocation {
   CARBON_CHECK(StringRefContainsPointer(buffer_->source_->text(), loc))
       << "location not within buffer";
   int64_t offset = loc - buffer_->source_->text().begin();
@@ -390,7 +390,7 @@ auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation(
           .column_number = column_number + 1};
 }
 
-auto TokenLocationTranslator::GetLocation(TokenIndex token)
+auto TokenDiagnosticConverter::ConvertLocation(TokenIndex token) const
     -> DiagnosticLocation {
   // Map the token location into a position within the source buffer.
   const auto& token_info = buffer_->GetTokenInfo(token);
@@ -402,7 +402,7 @@ auto TokenLocationTranslator::GetLocation(TokenIndex token)
   // TODO: Should we somehow indicate in the diagnostic location if this token
   // is a recovery token that doesn't correspond to the original source?
   DiagnosticLocation loc =
-      TokenizedBuffer::SourceBufferLocationTranslator(buffer_).GetLocation(
+      TokenizedBuffer::SourceBufferDiagnosticConverter(buffer_).ConvertLocation(
           token_start);
   loc.length = buffer_->GetTokenText(token).size();
   return loc;

+ 10 - 11
toolchain/lex/tokenized_buffer.h

@@ -111,16 +111,15 @@ class TokenIterator
   TokenIndex token_;
 };
 
-// A diagnostic location translator that maps token locations into source
+// A diagnostic location converter that maps token locations into source
 // buffer locations.
-class TokenLocationTranslator
-    : public DiagnosticLocationTranslator<TokenIndex> {
+class TokenDiagnosticConverter : public DiagnosticConverter<TokenIndex> {
  public:
-  explicit TokenLocationTranslator(const TokenizedBuffer* buffer)
+  explicit TokenDiagnosticConverter(const TokenizedBuffer* buffer)
       : buffer_(buffer) {}
 
   // Map the given token into a diagnostic location.
-  auto GetLocation(TokenIndex token) -> DiagnosticLocation override;
+  auto ConvertLocation(TokenIndex token) const -> DiagnosticLocation override;
 
  private:
   const TokenizedBuffer* buffer_;
@@ -244,19 +243,19 @@ class TokenizedBuffer : public Printable<TokenizedBuffer> {
 
  private:
   friend class Lexer;
-  friend class TokenLocationTranslator;
+  friend class TokenDiagnosticConverter;
 
-  // A diagnostic location translator that maps token locations into source
+  // A diagnostic location converter that maps token locations into source
   // buffer locations.
-  class SourceBufferLocationTranslator
-      : public DiagnosticLocationTranslator<const char*> {
+  class SourceBufferDiagnosticConverter
+      : public DiagnosticConverter<const char*> {
    public:
-    explicit SourceBufferLocationTranslator(const TokenizedBuffer* buffer)
+    explicit SourceBufferDiagnosticConverter(const TokenizedBuffer* buffer)
         : buffer_(buffer) {}
 
     // Map the given position within the source buffer into a diagnostic
     // location.
-    auto GetLocation(const char* loc) -> DiagnosticLocation override;
+    auto ConvertLocation(const char* loc) const -> DiagnosticLocation override;
 
    private:
     const TokenizedBuffer* buffer_;

+ 2 - 2
toolchain/parse/BUILD

@@ -154,8 +154,8 @@ cc_fuzz_test(
 )
 
 cc_library(
-    name = "tree_node_location_translator",
-    hdrs = ["tree_node_location_translator.h"],
+    name = "tree_node_diagnostic_converter",
+    hdrs = ["tree_node_diagnostic_converter.h"],
     deps = [
         ":tree",
         "//toolchain/diagnostics:diagnostic_emitter",

+ 2 - 2
toolchain/parse/parse.cpp

@@ -20,8 +20,8 @@ auto HandleInvalid(Context& context) -> void {
 
 auto Parse(Lex::TokenizedBuffer& tokens, DiagnosticConsumer& consumer,
            llvm::raw_ostream* vlog_stream) -> Tree {
-  Lex::TokenLocationTranslator translator(&tokens);
-  Lex::TokenDiagnosticEmitter emitter(translator, consumer);
+  Lex::TokenDiagnosticConverter converter(&tokens);
+  Lex::TokenDiagnosticEmitter emitter(converter, consumer);
 
   // Delegate to the parser.
   Tree tree(tokens);

+ 15 - 14
toolchain/parse/tree_node_location_translator.h → toolchain/parse/tree_node_diagnostic_converter.h

@@ -2,8 +2,8 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-#ifndef CARBON_TOOLCHAIN_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_
-#define CARBON_TOOLCHAIN_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_
+#ifndef CARBON_TOOLCHAIN_PARSE_TREE_NODE_DIAGNOSTIC_CONVERTER_H_
+#define CARBON_TOOLCHAIN_PARSE_TREE_NODE_DIAGNOSTIC_CONVERTER_H_
 
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/lex/tokenized_buffer.h"
@@ -34,18 +34,18 @@ inline auto TokenOnly(NodeId node_id) -> NodeLocation {
   return NodeLocation(node_id, true);
 }
 
-class NodeLocationTranslator
-    : public DiagnosticLocationTranslator<NodeLocation> {
+class NodeLocationConverter : public DiagnosticConverter<NodeLocation> {
  public:
-  explicit NodeLocationTranslator(const Lex::TokenizedBuffer* tokens,
-                                  llvm::StringRef filename,
-                                  const Tree* parse_tree)
-      : token_translator_(tokens),
+  explicit NodeLocationConverter(const Lex::TokenizedBuffer* tokens,
+                                 llvm::StringRef filename,
+                                 const Tree* parse_tree)
+      : token_converter_(tokens),
         filename_(filename),
         parse_tree_(parse_tree) {}
 
   // Map the given token into a diagnostic location.
-  auto GetLocation(NodeLocation node_location) -> DiagnosticLocation override {
+  auto ConvertLocation(NodeLocation node_location) const
+      -> DiagnosticLocation override {
     // Support the invalid token as a way to emit only the filename, when there
     // is no line association.
     if (!node_location.node_id().is_valid()) {
@@ -53,7 +53,7 @@ class NodeLocationTranslator
     }
 
     if (node_location.token_only()) {
-      return token_translator_.GetLocation(
+      return token_converter_.ConvertLocation(
           parse_tree_->node_token(node_location.node_id()));
     }
 
@@ -73,11 +73,12 @@ class NodeLocationTranslator
         end_token = desc_token;
       }
     }
-    DiagnosticLocation start_loc = token_translator_.GetLocation(start_token);
+    DiagnosticLocation start_loc =
+        token_converter_.ConvertLocation(start_token);
     if (start_token == end_token) {
       return start_loc;
     }
-    DiagnosticLocation end_loc = token_translator_.GetLocation(end_token);
+    DiagnosticLocation end_loc = token_converter_.ConvertLocation(end_token);
     // For multiline locations we simply return the rest of the line for now
     // since true multiline locations are not yet supported.
     if (start_loc.line_number != end_loc.line_number) {
@@ -92,11 +93,11 @@ class NodeLocationTranslator
   }
 
  private:
-  Lex::TokenLocationTranslator token_translator_;
+  Lex::TokenDiagnosticConverter token_converter_;
   llvm::StringRef filename_;
   const Tree* parse_tree_;
 };
 
 }  // namespace Carbon::Parse
 
-#endif  // CARBON_TOOLCHAIN_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_
+#endif  // CARBON_TOOLCHAIN_PARSE_TREE_NODE_DIAGNOSTIC_CONVERTER_H_

+ 2 - 2
toolchain/sem_ir/ids.h

@@ -285,7 +285,7 @@ constexpr BoolValue BoolValue::True = BoolValue(1);
 struct NameId : public IdBase, public Printable<NameId> {
   // names().GetFormatted() is used for diagnostics.
   using DiagnosticType =
-      DiagnosticTypeInfo<std::string, DiagnosticTypeTranslation::NameId>;
+      DiagnosticTypeInfo<std::string, DiagnosticTypeConversion::NameId>;
 
   // An explicitly invalid ID.
   static const NameId Invalid;
@@ -423,7 +423,7 @@ struct TypeId : public IdBase, public Printable<TypeId> {
   using ValueType = TypeInfo;
   // StringifyType() is used for diagnostics.
   using DiagnosticType =
-      DiagnosticTypeInfo<std::string, DiagnosticTypeTranslation::TypeId>;
+      DiagnosticTypeInfo<std::string, DiagnosticTypeConversion::TypeId>;
 
   // The builtin TypeType.
   static const TypeId TypeType;

+ 7 - 6
toolchain/source/source_buffer.cpp

@@ -11,8 +11,9 @@
 namespace Carbon {
 
 namespace {
-struct FilenameTranslator : DiagnosticLocationTranslator<llvm::StringRef> {
-  auto GetLocation(llvm::StringRef filename) -> DiagnosticLocation override {
+struct FilenameConverter : DiagnosticConverter<llvm::StringRef> {
+  auto ConvertLocation(llvm::StringRef filename) const
+      -> DiagnosticLocation override {
     return {.filename = filename};
   }
 };
@@ -28,8 +29,8 @@ auto SourceBuffer::MakeFromFile(llvm::vfs::FileSystem& fs,
                                 llvm::StringRef filename,
                                 DiagnosticConsumer& consumer)
     -> std::optional<SourceBuffer> {
-  FilenameTranslator translator;
-  DiagnosticEmitter<llvm::StringRef> emitter(translator, consumer);
+  FilenameConverter converter;
+  DiagnosticEmitter<llvm::StringRef> emitter(converter, consumer);
 
   llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>> file =
       fs.openFileForRead(filename);
@@ -63,8 +64,8 @@ auto SourceBuffer::MakeFromMemoryBuffer(
     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer,
     llvm::StringRef filename, bool is_regular_file,
     DiagnosticConsumer& consumer) -> std::optional<SourceBuffer> {
-  FilenameTranslator translator;
-  DiagnosticEmitter<llvm::StringRef> emitter(translator, consumer);
+  FilenameConverter converter;
+  DiagnosticEmitter<llvm::StringRef> emitter(converter, consumer);
 
   if (buffer.getError()) {
     CARBON_DIAGNOSTIC(ErrorReadingFile, Error, "Error reading file: {0}",