diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index 262d4277522e..99a4c8109654 100644 --- a/toolchain/check/BUILD +++ b/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", diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index 8383092e1c1d..0e06b2298c34 100644 --- a/toolchain/check/check.cpp +++ b/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 { +class SemIRDiagnosticConverter : public DiagnosticConverter { public: - explicit SemIRLocationTranslator( - const llvm::DenseMap* - node_translators, + explicit SemIRDiagnosticConverter( + const llvm::DenseMap* + 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(arg); return sem_ir_->names().GetFormatted(name_id).str(); } - case DiagnosticTypeTranslation::TypeId: { + case DiagnosticTypeConversion::TypeId: { auto type_id = llvm::any_cast(arg); return sem_ir_->StringifyType(type_id); } default: - return DiagnosticLocationTranslator::TranslateArg( - translation, arg); + return DiagnosticConverter::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* - node_translators_; + const llvm::DenseMap* + 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 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* - node_translators, + llvm::DenseMap* + 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 - node_translators; + llvm::DenseMap + 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(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); } } } diff --git a/toolchain/check/context.h b/toolchain/check/context.h index d41799ff4c1a..34e272f60f3c 100644 --- a/toolchain/check/context.h +++ b/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" diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index 843a5b9adb4c..e5465ad25886 100644 --- a/toolchain/check/handle_function.cpp +++ b/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" diff --git a/toolchain/diagnostics/BUILD b/toolchain/diagnostics/BUILD index 024a008a85d4..08e2e94d15a8 100644 --- a/toolchain/diagnostics/BUILD +++ b/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", diff --git a/toolchain/diagnostics/diagnostic_converter.h b/toolchain/diagnostics/diagnostic_converter.h new file mode 100644 index 000000000000..486653116bbb --- /dev/null +++ b/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 + +#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 +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(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; +// }; +template +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 +concept HasDiagnosticType = + requires { std::type_identity(); }; + +// The default implementation with no conversion. +template +struct DiagnosticTypeForArg + : public DiagnosticTypeInfo {}; + +// Exposes a custom conversion for an argument type. +template + requires HasDiagnosticType +struct DiagnosticTypeForArg : public Arg::DiagnosticType {}; + +} // namespace Internal + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_CONVERTER_H_ diff --git a/toolchain/diagnostics/diagnostic_emitter.h b/toolchain/diagnostics/diagnostic_emitter.h index 35a768b28d3b..04e01c0a4b60 100644 --- a/toolchain/diagnostics/diagnostic_emitter.h +++ b/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& diagnostic_base, llvm::SmallVector 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( @@ -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& translator, - DiagnosticConsumer& consumer) - : translator_(&translator), consumer_(&consumer) {} + explicit DiagnosticEmitter(DiagnosticConverter& 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 auto MakeAny(Arg arg) -> llvm::Any { - if constexpr (Internal::DiagnosticTypeForArg::Translation == - DiagnosticTypeTranslation::None) { + if constexpr (Internal::DiagnosticTypeForArg::Conversion == + DiagnosticTypeConversion::None) { return arg; } else { - return translator_->TranslateArg( - Internal::DiagnosticTypeForArg::Translation, arg); + return converter_->ConvertArg( + Internal::DiagnosticTypeForArg::Conversion, arg); } } template friend class DiagnosticAnnotationScope; - DiagnosticLocationTranslator* translator_; + DiagnosticConverter* converter_; DiagnosticConsumer* consumer_; llvm::SmallVectorvoid>> annotate_fns_; diff --git a/toolchain/diagnostics/diagnostic_emitter_test.cpp b/toolchain/diagnostics/diagnostic_emitter_test.cpp index e4222d858c58..15c47d0d208a 100644 --- a/toolchain/diagnostics/diagnostic_emitter_test.cpp +++ b/toolchain/diagnostics/diagnostic_emitter_test.cpp @@ -15,17 +15,17 @@ namespace { using ::Carbon::Testing::IsDiagnostic; -struct FakeDiagnosticLocationTranslator : DiagnosticLocationTranslator { - auto GetLocation(int n) -> DiagnosticLocation override { +struct FakeDiagnosticConverter : DiagnosticConverter { + 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 emitter_; }; diff --git a/toolchain/diagnostics/diagnostic_translator.h b/toolchain/diagnostics/diagnostic_translator.h deleted file mode 100644 index 378b732467f2..000000000000 --- a/toolchain/diagnostics/diagnostic_translator.h +++ /dev/null @@ -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 - -#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 -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(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; -// }; -template -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 -concept HasDiagnosticType = - requires { std::type_identity(); }; - -// The default implementation with no translation. -template -struct DiagnosticTypeForArg - : public DiagnosticTypeInfo {}; - -// Exposes a custom translation for an argument type. -template - requires HasDiagnosticType -struct DiagnosticTypeForArg : public Arg::DiagnosticType {}; - -} // namespace Internal - -} // namespace Carbon - -#endif // CARBON_TOOLCHAIN_DIAGNOSTICS_DIAGNOSTIC_TRANSLATOR_H_ diff --git a/toolchain/diagnostics/null_diagnostics.h b/toolchain/diagnostics/null_diagnostics.h index c536d1f61238..c36dcd7cf3bc 100644 --- a/toolchain/diagnostics/null_diagnostics.h +++ b/toolchain/diagnostics/null_diagnostics.h @@ -10,15 +10,15 @@ namespace Carbon { template -inline auto NullDiagnosticLocationTranslator() - -> DiagnosticLocationTranslator& { - struct Translator : DiagnosticLocationTranslator { - auto GetLocation(LocationT /*loc*/) -> DiagnosticLocation override { +inline auto NullDiagnosticConverter() -> DiagnosticConverter& { + struct Converter : DiagnosticConverter { + 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 inline auto NullDiagnosticEmitter() -> DiagnosticEmitter& { static auto* emitter = new DiagnosticEmitter( - NullDiagnosticLocationTranslator(), NullDiagnosticConsumer()); + NullDiagnosticConverter(), NullDiagnosticConsumer()); return *emitter; } diff --git a/toolchain/diagnostics/sorting_diagnostic_consumer_test.cpp b/toolchain/diagnostics/sorting_diagnostic_consumer_test.cpp index faf2bb49b34b..493241ec4458 100644 --- a/toolchain/diagnostics/sorting_diagnostic_consumer_test.cpp +++ b/toolchain/diagnostics/sorting_diagnostic_consumer_test.cpp @@ -19,18 +19,18 @@ using ::testing::InSequence; CARBON_DIAGNOSTIC(TestDiagnostic, Error, "{0}", llvm::StringLiteral); -struct FakeDiagnosticLocationTranslator - : DiagnosticLocationTranslator { - auto GetLocation(DiagnosticLocation loc) -> DiagnosticLocation override { +struct FakeDiagnosticConverter : DiagnosticConverter { + auto ConvertLocation(DiagnosticLocation loc) const + -> DiagnosticLocation override { return loc; } }; TEST(SortedDiagnosticEmitterTest, SortErrors) { - FakeDiagnosticLocationTranslator translator; + FakeDiagnosticConverter converter; Testing::MockDiagnosticConsumer consumer; SortingDiagnosticConsumer sorting_consumer(consumer); - DiagnosticEmitter emitter(translator, sorting_consumer); + DiagnosticEmitter emitter(converter, sorting_consumer); emitter.Emit({"f", "line", 2, 1}, TestDiagnostic, "M1"); emitter.Emit({"f", "line", 1, 1}, TestDiagnostic, "M2"); diff --git a/toolchain/lex/lex.cpp b/toolchain/lex/lex.cpp index 3ea6352df0e5..bdd23fbc79a8 100644 --- a/toolchain/lex/lex.cpp +++ b/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_; }; diff --git a/toolchain/lex/numeric_literal_test.cpp b/toolchain/lex/numeric_literal_test.cpp index e0529019a206..0efe4ea4419e 100644 --- a/toolchain/lex/numeric_literal_test.cpp +++ b/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 emitter(translator, error_tracker); + Testing::SingleTokenDiagnosticConverter converter(text); + DiagnosticEmitter emitter(converter, error_tracker); return Lex(text).ComputeValue(emitter); } diff --git a/toolchain/lex/string_literal_test.cpp b/toolchain/lex/string_literal_test.cpp index 1f43e1fbcc66..82db0679b7f4 100644 --- a/toolchain/lex/string_literal_test.cpp +++ b/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 emitter(translator, error_tracker); + Testing::SingleTokenDiagnosticConverter converter(text); + DiagnosticEmitter emitter(converter, error_tracker); return token.ComputeValue(allocator, emitter); } diff --git a/toolchain/lex/test_helpers.h b/toolchain/lex/test_helpers.h index 730c4ae3ca69..7d5d6418e3e2 100644 --- a/toolchain/lex/test_helpers.h +++ b/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 { +class SingleTokenDiagnosticConverter : public DiagnosticConverter { 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()); diff --git a/toolchain/lex/tokenized_buffer.cpp b/toolchain/lex/tokenized_buffer.cpp index 14398f348d5b..2af12fb3478d 100644 --- a/toolchain/lex/tokenized_buffer.cpp +++ b/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; diff --git a/toolchain/lex/tokenized_buffer.h b/toolchain/lex/tokenized_buffer.h index fff132febe37..b5bafde87cd0 100644 --- a/toolchain/lex/tokenized_buffer.h +++ b/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 { +class TokenDiagnosticConverter : public DiagnosticConverter { 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 { 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 { + class SourceBufferDiagnosticConverter + : public DiagnosticConverter { 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_; diff --git a/toolchain/parse/BUILD b/toolchain/parse/BUILD index bdf9a6d29ccd..bd8448d170df 100644 --- a/toolchain/parse/BUILD +++ b/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", diff --git a/toolchain/parse/parse.cpp b/toolchain/parse/parse.cpp index 3b8335bd9bcb..a9f437063f33 100644 --- a/toolchain/parse/parse.cpp +++ b/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); diff --git a/toolchain/parse/tree_node_location_translator.h b/toolchain/parse/tree_node_diagnostic_converter.h similarity index 76% rename from toolchain/parse/tree_node_location_translator.h rename to toolchain/parse/tree_node_diagnostic_converter.h index 3fc5c3577b04..a6b13019981e 100644 --- a/toolchain/parse/tree_node_location_translator.h +++ b/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 { +class NodeLocationConverter : public DiagnosticConverter { 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_ diff --git a/toolchain/sem_ir/ids.h b/toolchain/sem_ir/ids.h index a5d1ff97d00a..d861caeea428 100644 --- a/toolchain/sem_ir/ids.h +++ b/toolchain/sem_ir/ids.h @@ -285,7 +285,7 @@ constexpr BoolValue BoolValue::True = BoolValue(1); struct NameId : public IdBase, public Printable { // names().GetFormatted() is used for diagnostics. using DiagnosticType = - DiagnosticTypeInfo; + DiagnosticTypeInfo; // An explicitly invalid ID. static const NameId Invalid; @@ -423,7 +423,7 @@ struct TypeId : public IdBase, public Printable { using ValueType = TypeInfo; // StringifyType() is used for diagnostics. using DiagnosticType = - DiagnosticTypeInfo; + DiagnosticTypeInfo; // The builtin TypeType. static const TypeId TypeType; diff --git a/toolchain/source/source_buffer.cpp b/toolchain/source/source_buffer.cpp index 776f58f2aed4..c2887663c697 100644 --- a/toolchain/source/source_buffer.cpp +++ b/toolchain/source/source_buffer.cpp @@ -11,8 +11,9 @@ namespace Carbon { namespace { -struct FilenameTranslator : DiagnosticLocationTranslator { - auto GetLocation(llvm::StringRef filename) -> DiagnosticLocation override { +struct FilenameConverter : DiagnosticConverter { + 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 { - FilenameTranslator translator; - DiagnosticEmitter emitter(translator, consumer); + FilenameConverter converter; + DiagnosticEmitter emitter(converter, consumer); llvm::ErrorOr> file = fs.openFileForRead(filename); @@ -63,8 +64,8 @@ auto SourceBuffer::MakeFromMemoryBuffer( llvm::ErrorOr> buffer, llvm::StringRef filename, bool is_regular_file, DiagnosticConsumer& consumer) -> std::optional { - FilenameTranslator translator; - DiagnosticEmitter emitter(translator, consumer); + FilenameConverter converter; + DiagnosticEmitter emitter(converter, consumer); if (buffer.getError()) { CARBON_DIAGNOSTIC(ErrorReadingFile, Error, "Error reading file: {0}",