mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Refactor LocId to merge in SemIRLoc (#5284)
The main goal of this is to collapse the LocId and SemIRLoc types into a single type, eliminating the need for APIs to decide which to use. This originated from discussion about UnwrapSemIRLoc in #5169. Although that was removed in #5202, it's probably still a good direction for LocId. This changes the packing of LocId to allow adding InstId, making it tri-modal: ImportIRInstId, InstId, or NodeId. This has a side-effect of reducing the available space for ImportIRInstId, although not by much due to the pre-existing `ImplicitBit` behavior. If needed, we could also probably play with packing a bit more since `ImplicitBit` really only applies to `NodeId`, but I was trying to keep the logic a little simpler. Note `TokenOnlyBit` can still apply to `ImportIRInstId`. This leaves in place a typedef for SemIRLoc -- I intend to clean that up separately. Some Discord discussion is [here](https://discord.com/channels/655572317891461132/655578254970716160/1353755830058745959).
This commit is contained in:
@@ -21,24 +21,36 @@ static auto FollowImportRef(
|
||||
"thoroughly track ImportDecls.");
|
||||
|
||||
auto import_loc_id = cursor_ir->insts().GetLocId(import_ir.decl_id);
|
||||
if (import_loc_id.is_node_id()) {
|
||||
// For imports in the current file, the location is simple.
|
||||
absolute_node_ids.push_back({.check_ir_id = cursor_ir->check_ir_id(),
|
||||
.node_id = import_loc_id.node_id()});
|
||||
} else if (import_loc_id.is_import_ir_inst_id()) {
|
||||
// For implicit imports, we need to unravel the location a little
|
||||
// further.
|
||||
auto implicit_import_ir_inst =
|
||||
cursor_ir->import_ir_insts().Get(import_loc_id.import_ir_inst_id());
|
||||
const auto& implicit_ir =
|
||||
cursor_ir->import_irs().Get(implicit_import_ir_inst.ir_id);
|
||||
auto implicit_loc_id =
|
||||
implicit_ir.sem_ir->insts().GetLocId(implicit_import_ir_inst.inst_id);
|
||||
CARBON_CHECK(implicit_loc_id.is_node_id(),
|
||||
"Should only be one layer of implicit imports");
|
||||
absolute_node_ids.push_back(
|
||||
{.check_ir_id = implicit_ir.sem_ir->check_ir_id(),
|
||||
.node_id = implicit_loc_id.node_id()});
|
||||
switch (import_loc_id.kind()) {
|
||||
case SemIR::LocId::Kind::None:
|
||||
break;
|
||||
|
||||
case SemIR::LocId::Kind::ImportIRInstId: {
|
||||
// For implicit imports, we need to unravel the location a little
|
||||
// further.
|
||||
auto implicit_import_ir_inst =
|
||||
cursor_ir->import_ir_insts().Get(import_loc_id.import_ir_inst_id());
|
||||
const auto& implicit_ir =
|
||||
cursor_ir->import_irs().Get(implicit_import_ir_inst.ir_id);
|
||||
auto implicit_loc_id =
|
||||
implicit_ir.sem_ir->insts().GetLocId(implicit_import_ir_inst.inst_id);
|
||||
CARBON_CHECK(implicit_loc_id.kind() == SemIR::LocId::Kind::NodeId,
|
||||
"Should only be one layer of implicit imports");
|
||||
absolute_node_ids.push_back(
|
||||
{.check_ir_id = implicit_ir.sem_ir->check_ir_id(),
|
||||
.node_id = implicit_loc_id.node_id()});
|
||||
break;
|
||||
}
|
||||
|
||||
case SemIR::LocId::Kind::InstId:
|
||||
CARBON_FATAL("Unexpected LocId: {0}", import_loc_id);
|
||||
|
||||
case SemIR::LocId::Kind::NodeId: {
|
||||
// For imports in the current file, the location is simple.
|
||||
absolute_node_ids.push_back({.check_ir_id = cursor_ir->check_ir_id(),
|
||||
.node_id = import_loc_id.node_id()});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cursor_ir = import_ir.sem_ir;
|
||||
@@ -50,15 +62,23 @@ static auto FollowImportRef(
|
||||
static auto HandleLocId(llvm::SmallVector<AbsoluteNodeId>& absolute_node_ids,
|
||||
const File*& cursor_ir, InstId& cursor_inst_id,
|
||||
LocId loc_id) -> bool {
|
||||
if (loc_id.is_import_ir_inst_id()) {
|
||||
FollowImportRef(absolute_node_ids, cursor_ir, cursor_inst_id,
|
||||
loc_id.import_ir_inst_id());
|
||||
return false;
|
||||
} else {
|
||||
// Parse nodes always refer to the current IR.
|
||||
absolute_node_ids.push_back(
|
||||
{.check_ir_id = cursor_ir->check_ir_id(), .node_id = loc_id.node_id()});
|
||||
return true;
|
||||
switch (loc_id.kind()) {
|
||||
case SemIR::LocId::Kind::ImportIRInstId: {
|
||||
FollowImportRef(absolute_node_ids, cursor_ir, cursor_inst_id,
|
||||
loc_id.import_ir_inst_id());
|
||||
return false;
|
||||
}
|
||||
|
||||
case SemIR::LocId::Kind::NodeId: {
|
||||
// Parse nodes always refer to the current IR.
|
||||
absolute_node_ids.push_back({.check_ir_id = cursor_ir->check_ir_id(),
|
||||
.node_id = loc_id.node_id()});
|
||||
return true;
|
||||
}
|
||||
|
||||
case SemIR::LocId::Kind::None:
|
||||
case SemIR::LocId::Kind::InstId:
|
||||
CARBON_FATAL("Unexpected LocId: {0}", loc_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,18 +128,28 @@ auto GetAbsoluteNodeId(const File* sem_ir, InstId inst_id)
|
||||
auto GetAbsoluteNodeId(const File* sem_ir, LocId loc_id)
|
||||
-> llvm::SmallVector<AbsoluteNodeId> {
|
||||
llvm::SmallVector<AbsoluteNodeId> absolute_node_ids;
|
||||
if (!loc_id.has_value()) {
|
||||
absolute_node_ids.push_back(
|
||||
{.check_ir_id = sem_ir->check_ir_id(), .node_id = Parse::NodeId::None});
|
||||
return absolute_node_ids;
|
||||
switch (loc_id.kind()) {
|
||||
case SemIR::LocId::Kind::None:
|
||||
absolute_node_ids.push_back({.check_ir_id = sem_ir->check_ir_id(),
|
||||
.node_id = Parse::NodeId::None});
|
||||
break;
|
||||
|
||||
case SemIR::LocId::Kind::InstId:
|
||||
absolute_node_ids = GetAbsoluteNodeId(sem_ir, loc_id.inst_id());
|
||||
break;
|
||||
|
||||
case SemIR::LocId::Kind::ImportIRInstId:
|
||||
case SemIR::LocId::Kind::NodeId: {
|
||||
const File* cursor_ir = sem_ir;
|
||||
InstId cursor_inst_id = InstId::None;
|
||||
if (HandleLocId(absolute_node_ids, cursor_ir, cursor_inst_id, loc_id)) {
|
||||
break;
|
||||
}
|
||||
CARBON_CHECK(cursor_inst_id.has_value(), "Should be set by HandleLocId");
|
||||
GetAbsoluteNodeIdImpl(absolute_node_ids, cursor_ir, cursor_inst_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
const File* cursor_ir = sem_ir;
|
||||
InstId cursor_inst_id = InstId::None;
|
||||
if (HandleLocId(absolute_node_ids, cursor_ir, cursor_inst_id, loc_id)) {
|
||||
return absolute_node_ids;
|
||||
}
|
||||
CARBON_CHECK(cursor_inst_id.has_value(), "Should be set by HandleLocId");
|
||||
GetAbsoluteNodeIdImpl(absolute_node_ids, cursor_ir, cursor_inst_id);
|
||||
return absolute_node_ids;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user