diff --git a/toolchain/parser/BUILD b/toolchain/parser/BUILD index 53bf7d02d06e..685315747b1a 100644 --- a/toolchain/parser/BUILD +++ b/toolchain/parser/BUILD @@ -109,6 +109,12 @@ cc_fuzz_test( ], ) +cc_library( + name = "parse_tree_node_location_translator", + hdrs = ["parse_tree_node_location_translator.h"], + deps = [":parse_tree"], +) + cc_library( name = "precedence", srcs = ["precedence.cpp"], diff --git a/toolchain/parser/parse_tree_node_location_translator.h b/toolchain/parser/parse_tree_node_location_translator.h new file mode 100644 index 000000000000..cd42c612a8e9 --- /dev/null +++ b/toolchain/parser/parse_tree_node_location_translator.h @@ -0,0 +1,31 @@ +// 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_PARSER_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_ +#define CARBON_TOOLCHAIN_PARSER_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_ + +#include "toolchain/parser/parse_tree.h" + +namespace Carbon { + +class ParseTreeNodeLocationTranslator + : public DiagnosticLocationTranslator { + public: + explicit ParseTreeNodeLocationTranslator(const TokenizedBuffer* tokens, + const ParseTree* parse_tree) + : token_translator_(tokens, nullptr), parse_tree_(parse_tree) {} + + // Map the given token into a diagnostic location. + auto GetLocation(ParseTree::Node node) -> DiagnosticLocation override { + return token_translator_.GetLocation(parse_tree_->node_token(node)); + } + + private: + TokenizedBuffer::TokenLocationTranslator token_translator_; + const ParseTree* parse_tree_; +}; + +} // namespace Carbon + +#endif // CARBON_TOOLCHAIN_PARSER_PARSE_TREE_NODE_LOCATION_TRANSLATOR_H_ diff --git a/toolchain/semantics/BUILD b/toolchain/semantics/BUILD index 28f1fcfd48e6..71dffd2494d9 100644 --- a/toolchain/semantics/BUILD +++ b/toolchain/semantics/BUILD @@ -49,6 +49,7 @@ cc_library( "//toolchain/lexer:tokenized_buffer", "//toolchain/parser:parse_node_kind", "//toolchain/parser:parse_tree", + "//toolchain/parser:parse_tree_node_location_translator", "@llvm-project//llvm:Support", ], ) diff --git a/toolchain/semantics/semantics_ir.cpp b/toolchain/semantics/semantics_ir.cpp index a25b31fa3335..81b91002592a 100644 --- a/toolchain/semantics/semantics_ir.cpp +++ b/toolchain/semantics/semantics_ir.cpp @@ -5,8 +5,7 @@ #include "toolchain/semantics/semantics_ir.h" #include "common/check.h" -#include "llvm/Support/FormatVariadic.h" -#include "toolchain/lexer/tokenized_buffer.h" +#include "toolchain/parser/parse_tree_node_location_translator.h" #include "toolchain/semantics/semantics_builtin_kind.h" #include "toolchain/semantics/semantics_node.h" #include "toolchain/semantics/semantics_parse_tree_handler.h" @@ -64,10 +63,9 @@ auto SemanticsIR::MakeFromParseTree(const SemanticsIR& builtin_ir, SemanticsNode::MakeCrossReference(type, BuiltinIR, SemanticsNodeId(i)); } - TokenizedBuffer::TokenLocationTranslator translator( - &tokens, /*last_line_lexed_to_column=*/nullptr); + ParseTreeNodeLocationTranslator translator(&tokens, &parse_tree); ErrorTrackingDiagnosticConsumer err_tracker(consumer); - TokenDiagnosticEmitter emitter(translator, err_tracker); + DiagnosticEmitter emitter(translator, err_tracker); SemanticsParseTreeHandler(tokens, emitter, parse_tree, semantics, vlog_stream) .Build(); semantics.has_errors_ = err_tracker.seen_error(); diff --git a/toolchain/semantics/semantics_parse_tree_handler.cpp b/toolchain/semantics/semantics_parse_tree_handler.cpp index 0be658750060..9d06caaa913a 100644 --- a/toolchain/semantics/semantics_parse_tree_handler.cpp +++ b/toolchain/semantics/semantics_parse_tree_handler.cpp @@ -108,7 +108,7 @@ auto SemanticsParseTreeHandler::BindName(ParseTree::Node name_node, } else { CARBON_DIAGNOSTIC(NameRedefined, Error, "Redefining {0} in the same scope.", llvm::StringRef); - emitter_->Emit(parse_tree_->node_token(name_node), NameRedefined, name_str); + emitter_->Emit(name_node, NameRedefined, name_str); // TODO: This should be a note and sorted with the above diagnostic. // But that depends on more diagnostic support we currently don't have. @@ -116,8 +116,7 @@ auto SemanticsParseTreeHandler::BindName(ParseTree::Node name_node, auto prev_def = semantics_->GetNode(prev_def_id); CARBON_DIAGNOSTIC(PreviousDefinition, Error, "Previous definition is here."); - emitter_->Emit(parse_tree_->node_token(prev_def.parse_node()), - PreviousDefinition); + emitter_->Emit(prev_def.parse_node(), PreviousDefinition); } } @@ -237,8 +236,7 @@ auto SemanticsParseTreeHandler::TryTypeConversion(ParseTree::Node parse_node, CARBON_DIAGNOSTIC(TypeMismatch, Error, "Type mismatch: lhs is {0}, rhs is {1}", SemanticsNodeId, SemanticsNodeId); - emitter_->Emit(parse_tree_->node_token(parse_node), TypeMismatch, - lhs_type, rhs_type); + emitter_->Emit(parse_node, TypeMismatch, lhs_type, rhs_type); } return invalid_type; } @@ -492,7 +490,7 @@ auto SemanticsParseTreeHandler::HandleNameReference(ParseTree::Node parse_node) auto name_not_found = [&] { CARBON_DIAGNOSTIC(NameNotFound, Error, "Name {0} not found", llvm::StringRef); - emitter_->Emit(parse_tree_->node_token(parse_node), NameNotFound, name_str); + emitter_->Emit(parse_node, NameNotFound, name_str); Push(parse_node, SemanticsNodeId::MakeBuiltinReference( SemanticsBuiltinKind::InvalidType())); }; diff --git a/toolchain/semantics/semantics_parse_tree_handler.h b/toolchain/semantics/semantics_parse_tree_handler.h index c238e64664b7..884c137633f3 100644 --- a/toolchain/semantics/semantics_parse_tree_handler.h +++ b/toolchain/semantics/semantics_parse_tree_handler.h @@ -18,11 +18,10 @@ namespace Carbon { class SemanticsParseTreeHandler { public: // Stores references for work. - explicit SemanticsParseTreeHandler(const TokenizedBuffer& tokens, - TokenDiagnosticEmitter& emitter, - const ParseTree& parse_tree, - SemanticsIR& semantics, - llvm::raw_ostream* vlog_stream) + explicit SemanticsParseTreeHandler( + const TokenizedBuffer& tokens, + DiagnosticEmitter& emitter, const ParseTree& parse_tree, + SemanticsIR& semantics, llvm::raw_ostream* vlog_stream) : tokens_(&tokens), emitter_(&emitter), parse_tree_(&parse_tree), @@ -136,7 +135,7 @@ class SemanticsParseTreeHandler { const TokenizedBuffer* tokens_; // Handles diagnostics. - TokenDiagnosticEmitter* emitter_; + DiagnosticEmitter* emitter_; // The file's parse tree. const ParseTree* parse_tree_;