Support for locations in transitively imported C++ code (#7093)

Instead of treating all C++ code as coming from a single synthetic
`CheckIRId`, track the `SemIR::File` associated with each C++ location.
This is necessary since each `SemIR::File` has a distinct `CppFile` and
therefore distinct `SourceLocation`s and `ClangSourceLocId`s.

Assisted-by: Gemini via Antigravity
This commit is contained in:
Richard Smith
2026-04-23 20:11:04 +00:00
committed by GitHub
parent ab12932e56
commit 709776ad1c
20 changed files with 190 additions and 186 deletions
+9 -9
View File
@@ -4,7 +4,7 @@
#include "toolchain/check/cpp/location.h"
#include "toolchain/sem_ir/absolute_node_id.h"
#include "toolchain/sem_ir/absolute_node_ref.h"
#include "toolchain/sem_ir/ids.h"
namespace Carbon::Check {
@@ -62,20 +62,20 @@ auto GetCppLocation(Context& context, SemIR::LocId loc_id)
// Break down the `LocId` into an import path. If that ends in a C++ location,
// we can just return that directly.
llvm::SmallVector<SemIR::AbsoluteNodeId> absolute_node_ids =
SemIR::GetAbsoluteNodeId(&context.sem_ir(), loc_id);
if (absolute_node_ids.back().check_ir_id() == SemIR::CheckIRId::Cpp) {
return context.sem_ir().clang_source_locs().Get(
absolute_node_ids.back().clang_source_loc_id());
llvm::SmallVector<SemIR::AbsoluteNodeRef> absolute_node_refs =
SemIR::GetAbsoluteNodeRef(&context.sem_ir(), loc_id);
const auto& final_node = absolute_node_refs.back();
if (final_node.is_cpp()) {
return final_node.file()->clang_source_locs().Get(
final_node.clang_source_loc_id());
}
// This is a location in Carbon code; get or create a corresponding file in
// Clang and build a corresponding location.
auto absolute_node_id = absolute_node_ids.back();
auto [ir, start_loc] = GetFileInfo(context, absolute_node_id.check_ir_id());
auto [ir, start_loc] = GetFileInfo(context, final_node.check_ir_id());
const auto& tree = ir->parse_tree();
auto offset =
tree.tokens().GetByteOffset(tree.node_token(absolute_node_id.node_id()));
tree.tokens().GetByteOffset(tree.node_token(final_node.node_id()));
return start_loc.getLocWithOffset(offset);
}