Rename parse_node -> node_id (#3760)

This was previously discussed at
https://discord.com/channels/655572317891461132/655578254970716160/1209975051588210729.
I'm initiating this mainly because we typically use "id" suffixes to
indicate an `IdBase` being passed around and the non-id suffix of
`parse_node` suggests at it carrying more data than it actually does.
There used to be more reason for avoiding `node_id` because
`SemIR::InstId` used to be named `NodeId`, but that's no longer
necessary. As a consequence, I'd like to rename `parse_node` to more
precisely reflect its type.

In full, this is doing:

```
parse_node_kind -> node_kind
parse_node -> node_id
ParseNodeCategory -> NodeCategory
ParseNodeKind -> NodeKind
ParseNode -> NodeId
```

This is primarily in check and sem_ir, but with some `parse_node_kind`
references in parse too.

Pluralization is consistent with name forms on both sides, so that
wasn't part of my replacements.
This commit is contained in:
Jon Ross-Perkins
2024-03-09 00:21:29 +00:00
committed by GitHub
parent a1317e61e0
commit 86a7c9ff45
57 changed files with 1050 additions and 1115 deletions
+10 -10
View File
@@ -21,7 +21,7 @@ namespace Carbon::Check {
// Parse node handlers. Returns false for unrecoverable errors.
#define CARBON_PARSE_NODE_KIND(Name) \
auto Handle##Name(Context& context, Parse::Name##Id parse_node) -> bool;
auto Handle##Name(Context& context, Parse::Name##Id node_id) -> bool;
#include "toolchain/parse/node_kind.def"
// Handles the transformation of a SemIRLocation to a DiagnosticLocation.
@@ -44,9 +44,9 @@ class SemIRLocationTranslator
auto cursor_inst_id = loc.inst_id;
while (true) {
// If the parse node is valid, use it for the location.
if (auto parse_node = cursor_ir->insts().GetParseNode(cursor_inst_id);
parse_node.is_valid()) {
return GetLocationInFile(cursor_ir, parse_node);
if (auto node_id = cursor_ir->insts().GetNodeId(cursor_inst_id);
node_id.is_valid()) {
return GetLocationInFile(cursor_ir, node_id);
}
// If the parse node was invalid, recurse through import references when
@@ -222,14 +222,14 @@ static auto InitPackageScopeAndImports(Context& context, UnitInfo& unit_info)
// Loops over all nodes in the tree. On some errors, this may return early,
// for example if an unrecoverable state is encountered.
// NOLINTNEXTLINE(readability-function-size)
static auto ProcessParseNodes(Context& context,
ErrorTrackingDiagnosticConsumer& err_tracker)
static auto ProcessNodeIds(Context& context,
ErrorTrackingDiagnosticConsumer& err_tracker)
-> bool {
for (auto parse_node : context.parse_tree().postorder()) {
switch (auto parse_kind = context.parse_tree().node_kind(parse_node)) {
for (auto node_id : context.parse_tree().postorder()) {
switch (auto parse_kind = context.parse_tree().node_kind(node_id)) {
#define CARBON_PARSE_NODE_KIND(Name) \
case Parse::NodeKind::Name: { \
if (!Check::Handle##Name(context, Parse::Name##Id(parse_node))) { \
if (!Check::Handle##Name(context, Parse::Name##Id(node_id))) { \
CARBON_CHECK(err_tracker.seen_error()) \
<< "Handle" #Name " returned false without printing a diagnostic"; \
return false; \
@@ -269,7 +269,7 @@ static auto CheckParseTree(
InitPackageScopeAndImports(context, unit_info);
if (!ProcessParseNodes(context, unit_info.err_tracker)) {
if (!ProcessNodeIds(context, unit_info.err_tracker)) {
context.sem_ir().set_has_errors(true);
return;
}
+53 -58
View File
@@ -50,10 +50,10 @@ Context::Context(const Lex::TokenizedBuffer& tokens, DiagnosticEmitter& emitter,
SemIR::TypeId::TypeType});
}
auto Context::TODO(Parse::NodeId parse_node, std::string label) -> bool {
auto Context::TODO(Parse::NodeId node_id, std::string label) -> bool {
CARBON_DIAGNOSTIC(SemanticsTodo, Error, "Semantics TODO: `{0}`.",
std::string);
emitter_->Emit(parse_node, SemanticsTodo, std::move(label));
emitter_->Emit(node_id, SemanticsTodo, std::move(label));
return false;
}
@@ -67,14 +67,14 @@ auto Context::VerifyOnFinish() -> void {
param_and_arg_refs_stack_.VerifyOnFinish();
}
auto Context::AddInstInNoBlock(SemIR::ParseNodeAndInst parse_node_and_inst)
auto Context::AddInstInNoBlock(SemIR::NodeIdAndInst node_id_and_inst)
-> SemIR::InstId {
auto inst_id = sem_ir().insts().AddInNoBlock(parse_node_and_inst);
CARBON_VLOG() << "AddInst: " << parse_node_and_inst.inst << "\n";
auto inst_id = sem_ir().insts().AddInNoBlock(node_id_and_inst);
CARBON_VLOG() << "AddInst: " << node_id_and_inst.inst << "\n";
auto const_id = TryEvalInst(*this, inst_id, parse_node_and_inst.inst);
auto const_id = TryEvalInst(*this, inst_id, node_id_and_inst.inst);
if (const_id.is_constant()) {
CARBON_VLOG() << "Constant: " << parse_node_and_inst.inst << " -> "
CARBON_VLOG() << "Constant: " << node_id_and_inst.inst << " -> "
<< const_id.inst_id() << "\n";
constant_values().Set(inst_id, const_id);
}
@@ -82,24 +82,23 @@ auto Context::AddInstInNoBlock(SemIR::ParseNodeAndInst parse_node_and_inst)
return inst_id;
}
auto Context::AddInst(SemIR::ParseNodeAndInst parse_node_and_inst)
-> SemIR::InstId {
auto inst_id = AddInstInNoBlock(parse_node_and_inst);
auto Context::AddInst(SemIR::NodeIdAndInst node_id_and_inst) -> SemIR::InstId {
auto inst_id = AddInstInNoBlock(node_id_and_inst);
inst_block_stack_.AddInstId(inst_id);
return inst_id;
}
auto Context::AddPlaceholderInstInNoBlock(
SemIR::ParseNodeAndInst parse_node_and_inst) -> SemIR::InstId {
auto inst_id = sem_ir().insts().AddInNoBlock(parse_node_and_inst);
CARBON_VLOG() << "AddPlaceholderInst: " << parse_node_and_inst.inst << "\n";
auto Context::AddPlaceholderInstInNoBlock(SemIR::NodeIdAndInst node_id_and_inst)
-> SemIR::InstId {
auto inst_id = sem_ir().insts().AddInNoBlock(node_id_and_inst);
CARBON_VLOG() << "AddPlaceholderInst: " << node_id_and_inst.inst << "\n";
constant_values().Set(inst_id, SemIR::ConstantId::Invalid);
return inst_id;
}
auto Context::AddPlaceholderInst(SemIR::ParseNodeAndInst parse_node_and_inst)
auto Context::AddPlaceholderInst(SemIR::NodeIdAndInst node_id_and_inst)
-> SemIR::InstId {
auto inst_id = AddPlaceholderInstInNoBlock(parse_node_and_inst);
auto inst_id = AddPlaceholderInstInNoBlock(node_id_and_inst);
inst_block_stack_.AddInstId(inst_id);
return inst_id;
}
@@ -111,26 +110,24 @@ auto Context::AddConstant(SemIR::Inst inst, bool is_symbolic)
return const_id;
}
auto Context::AddInstAndPush(SemIR::ParseNodeAndInst parse_node_and_inst)
-> void {
auto inst_id = AddInst(parse_node_and_inst);
node_stack_.Push(parse_node_and_inst.parse_node, inst_id);
auto Context::AddInstAndPush(SemIR::NodeIdAndInst node_id_and_inst) -> void {
auto inst_id = AddInst(node_id_and_inst);
node_stack_.Push(node_id_and_inst.node_id, inst_id);
}
auto Context::ReplaceInstBeforeConstantUse(
SemIR::InstId inst_id, SemIR::ParseNodeAndInst parse_node_and_inst)
-> void {
sem_ir().insts().Set(inst_id, parse_node_and_inst);
SemIR::InstId inst_id, SemIR::NodeIdAndInst node_id_and_inst) -> void {
sem_ir().insts().Set(inst_id, node_id_and_inst);
CARBON_VLOG() << "ReplaceInst: " << inst_id << " -> "
<< parse_node_and_inst.inst << "\n";
CARBON_VLOG() << "ReplaceInst: " << inst_id << " -> " << node_id_and_inst.inst
<< "\n";
// Redo evaluation. This is only safe to do if this instruction has not
// already been used as a constant, which is the caller's responsibility to
// ensure.
auto const_id = TryEvalInst(*this, inst_id, parse_node_and_inst.inst);
auto const_id = TryEvalInst(*this, inst_id, node_id_and_inst.inst);
if (const_id.is_constant()) {
CARBON_VLOG() << "Constant: " << parse_node_and_inst.inst << " -> "
CARBON_VLOG() << "Constant: " << node_id_and_inst.inst << " -> "
<< const_id.inst_id() << "\n";
}
constant_values().Set(inst_id, const_id);
@@ -147,11 +144,11 @@ auto Context::DiagnoseDuplicateName(SemIR::InstId dup_def_id,
.Emit();
}
auto Context::DiagnoseNameNotFound(Parse::NodeId parse_node,
SemIR::NameId name_id) -> void {
auto Context::DiagnoseNameNotFound(Parse::NodeId node_id, SemIR::NameId name_id)
-> void {
CARBON_DIAGNOSTIC(NameNotFound, Error, "Name `{0}` not found.",
SemIR::NameId);
emitter_->Emit(parse_node, NameNotFound, name_id);
emitter_->Emit(node_id, NameNotFound, name_id);
}
auto Context::NoteIncompleteClass(SemIR::ClassId class_id,
@@ -230,8 +227,7 @@ auto Context::AddNameToLookup(SemIR::NameId name_id, SemIR::InstId target_id)
}
}
auto Context::LookupNameInDecl(Parse::NodeId /*parse_node*/,
SemIR::NameId name_id,
auto Context::LookupNameInDecl(Parse::NodeId /*node_id*/, SemIR::NameId name_id,
SemIR::NameScopeId scope_id) -> SemIR::InstId {
if (!scope_id.is_valid()) {
// Look for a name in the current scope only. There are two cases where the
@@ -276,7 +272,7 @@ auto Context::LookupNameInDecl(Parse::NodeId /*parse_node*/,
}
}
auto Context::LookupUnqualifiedName(Parse::NodeId parse_node,
auto Context::LookupUnqualifiedName(Parse::NodeId node_id,
SemIR::NameId name_id) -> SemIR::InstId {
// TODO: Check for shadowed lookup results.
@@ -288,7 +284,7 @@ auto Context::LookupUnqualifiedName(Parse::NodeId parse_node,
// Walk the non-lexical scopes and perform lookups into each of them.
for (auto [index, name_scope_id] : llvm::reverse(non_lexical_scopes)) {
if (auto non_lexical_result =
LookupQualifiedName(parse_node, name_id, name_scope_id,
LookupQualifiedName(node_id, name_id, name_scope_id,
/*required=*/false);
non_lexical_result.is_valid()) {
return non_lexical_result;
@@ -301,7 +297,7 @@ auto Context::LookupUnqualifiedName(Parse::NodeId parse_node,
}
// We didn't find anything at all.
DiagnoseNameNotFound(parse_node, name_id);
DiagnoseNameNotFound(node_id, name_id);
return SemIR::InstId::BuiltinError;
}
@@ -315,8 +311,7 @@ auto Context::LookupNameInExactScope(SemIR::NameId name_id,
return SemIR::InstId::Invalid;
}
auto Context::LookupQualifiedName(Parse::NodeId parse_node,
SemIR::NameId name_id,
auto Context::LookupQualifiedName(Parse::NodeId node_id, SemIR::NameId name_id,
SemIR::NameScopeId scope_id, bool required)
-> SemIR::InstId {
llvm::SmallVector<SemIR::NameScopeId> scope_ids = {scope_id};
@@ -345,7 +340,7 @@ auto Context::LookupQualifiedName(Parse::NodeId parse_node,
NameAmbiguousDueToExtend, Error,
"Ambiguous use of name `{0}` found in multiple extended scopes.",
SemIR::NameId);
emitter_->Emit(parse_node, NameAmbiguousDueToExtend, name_id);
emitter_->Emit(node_id, NameAmbiguousDueToExtend, name_id);
// TODO: Add notes pointing to the scopes.
return SemIR::InstId::BuiltinError;
}
@@ -355,7 +350,7 @@ auto Context::LookupQualifiedName(Parse::NodeId parse_node,
if (required && !result_id.is_valid()) {
if (!has_error) {
DiagnoseNameNotFound(parse_node, name_id);
DiagnoseNameNotFound(node_id, name_id);
}
return SemIR::InstId::BuiltinError;
}
@@ -365,37 +360,37 @@ auto Context::LookupQualifiedName(Parse::NodeId parse_node,
template <typename BranchNode, typename... Args>
static auto AddDominatedBlockAndBranchImpl(Context& context,
Parse::NodeId parse_node,
Args... args) -> SemIR::InstBlockId {
Parse::NodeId node_id, Args... args)
-> SemIR::InstBlockId {
if (!context.inst_block_stack().is_current_block_reachable()) {
return SemIR::InstBlockId::Unreachable;
}
auto block_id = context.inst_blocks().AddDefaultValue();
context.AddInst({parse_node, BranchNode{block_id, args...}});
context.AddInst({node_id, BranchNode{block_id, args...}});
return block_id;
}
auto Context::AddDominatedBlockAndBranch(Parse::NodeId parse_node)
auto Context::AddDominatedBlockAndBranch(Parse::NodeId node_id)
-> SemIR::InstBlockId {
return AddDominatedBlockAndBranchImpl<SemIR::Branch>(*this, parse_node);
return AddDominatedBlockAndBranchImpl<SemIR::Branch>(*this, node_id);
}
auto Context::AddDominatedBlockAndBranchWithArg(Parse::NodeId parse_node,
auto Context::AddDominatedBlockAndBranchWithArg(Parse::NodeId node_id,
SemIR::InstId arg_id)
-> SemIR::InstBlockId {
return AddDominatedBlockAndBranchImpl<SemIR::BranchWithArg>(*this, parse_node,
return AddDominatedBlockAndBranchImpl<SemIR::BranchWithArg>(*this, node_id,
arg_id);
}
auto Context::AddDominatedBlockAndBranchIf(Parse::NodeId parse_node,
auto Context::AddDominatedBlockAndBranchIf(Parse::NodeId node_id,
SemIR::InstId cond_id)
-> SemIR::InstBlockId {
return AddDominatedBlockAndBranchImpl<SemIR::BranchIf>(*this, parse_node,
return AddDominatedBlockAndBranchImpl<SemIR::BranchIf>(*this, node_id,
cond_id);
}
auto Context::AddConvergenceBlockAndPush(Parse::NodeId parse_node,
int num_blocks) -> void {
auto Context::AddConvergenceBlockAndPush(Parse::NodeId node_id, int num_blocks)
-> void {
CARBON_CHECK(num_blocks >= 2) << "no convergence";
SemIR::InstBlockId new_block_id = SemIR::InstBlockId::Unreachable;
@@ -404,7 +399,7 @@ auto Context::AddConvergenceBlockAndPush(Parse::NodeId parse_node,
if (new_block_id == SemIR::InstBlockId::Unreachable) {
new_block_id = inst_blocks().AddDefaultValue();
}
AddInst({parse_node, SemIR::Branch{new_block_id}});
AddInst({node_id, SemIR::Branch{new_block_id}});
}
inst_block_stack().Pop();
}
@@ -412,7 +407,7 @@ auto Context::AddConvergenceBlockAndPush(Parse::NodeId parse_node,
}
auto Context::AddConvergenceBlockWithArgAndPush(
Parse::NodeId parse_node, std::initializer_list<SemIR::InstId> block_args)
Parse::NodeId node_id, std::initializer_list<SemIR::InstId> block_args)
-> SemIR::InstId {
CARBON_CHECK(block_args.size() >= 2) << "no convergence";
@@ -422,7 +417,7 @@ auto Context::AddConvergenceBlockWithArgAndPush(
if (new_block_id == SemIR::InstBlockId::Unreachable) {
new_block_id = inst_blocks().AddDefaultValue();
}
AddInst({parse_node, SemIR::BranchWithArg{new_block_id, arg_id}});
AddInst({node_id, SemIR::BranchWithArg{new_block_id, arg_id}});
}
inst_block_stack().Pop();
}
@@ -430,17 +425,17 @@ auto Context::AddConvergenceBlockWithArgAndPush(
// Acquire the result value.
SemIR::TypeId result_type_id = insts().Get(*block_args.begin()).type_id();
return AddInst({parse_node, SemIR::BlockArg{result_type_id, new_block_id}});
return AddInst({node_id, SemIR::BlockArg{result_type_id, new_block_id}});
}
// Add the current code block to the enclosing function.
auto Context::AddCurrentCodeBlockToFunction(Parse::NodeId parse_node) -> void {
auto Context::AddCurrentCodeBlockToFunction(Parse::NodeId node_id) -> void {
CARBON_CHECK(!inst_block_stack().empty()) << "no current code block";
if (return_scope_stack().empty()) {
CARBON_CHECK(parse_node.is_valid())
<< "No current function, but parse_node not provided";
TODO(parse_node,
CARBON_CHECK(node_id.is_valid())
<< "No current function, but node_id not provided";
TODO(node_id,
"Control flow expressions are currently only supported inside "
"functions.");
return;
+24 -26
View File
@@ -56,29 +56,28 @@ class Context {
SemIR::File& sem_ir, llvm::raw_ostream* vlog_stream);
// Marks an implementation TODO. Always returns false.
auto TODO(Parse::NodeId parse_node, std::string label) -> bool;
auto TODO(Parse::NodeId node_id, std::string label) -> bool;
// Runs verification that the processing cleanly finished.
auto VerifyOnFinish() -> void;
// Adds an instruction to the current block, returning the produced ID.
auto AddInst(SemIR::ParseNodeAndInst parse_node_and_inst) -> SemIR::InstId;
auto AddInst(SemIR::NodeIdAndInst node_id_and_inst) -> SemIR::InstId;
// Adds an instruction in no block, returning the produced ID. Should be used
// rarely.
auto AddInstInNoBlock(SemIR::ParseNodeAndInst parse_node_and_inst)
-> SemIR::InstId;
auto AddInstInNoBlock(SemIR::NodeIdAndInst node_id_and_inst) -> SemIR::InstId;
// Adds an instruction to the current block, returning the produced ID. The
// instruction is a placeholder that is expected to be replaced by
// `ReplaceInstBeforeConstantUse`.
auto AddPlaceholderInst(SemIR::ParseNodeAndInst parse_node_and_inst)
auto AddPlaceholderInst(SemIR::NodeIdAndInst node_id_and_inst)
-> SemIR::InstId;
// Adds an instruction in no block, returning the produced ID. Should be used
// rarely. The instruction is a placeholder that is expected to be replaced by
// `ReplaceInstBeforeConstantUse`.
auto AddPlaceholderInstInNoBlock(SemIR::ParseNodeAndInst parse_node_and_inst)
auto AddPlaceholderInstInNoBlock(SemIR::NodeIdAndInst node_id_and_inst)
-> SemIR::InstId;
// Adds an instruction to the constants block, returning the produced ID.
@@ -86,15 +85,15 @@ class Context {
// Pushes a parse tree node onto the stack, storing the SemIR::Inst as the
// result.
auto AddInstAndPush(SemIR::ParseNodeAndInst parse_node_and_inst) -> void;
auto AddInstAndPush(SemIR::NodeIdAndInst node_id_and_inst) -> void;
// Replaces the value of the instruction `inst_id` with `parse_node_and_inst`.
// Replaces the value of the instruction `inst_id` with `node_id_and_inst`.
// The instruction is required to not have been used in any constant
// evaluation, either because it's newly created and entirely unused, or
// because it's only used in a position that constant evaluation ignores, such
// as a return slot.
auto ReplaceInstBeforeConstantUse(SemIR::InstId inst_id,
SemIR::ParseNodeAndInst parse_node_and_inst)
SemIR::NodeIdAndInst node_id_and_inst)
-> void;
// Sets only the parse node of an instruction. This is only used when setting
@@ -102,9 +101,9 @@ class Context {
// ReplaceInstBeforeConstantUse, it is safe to use after the namespace is used
// in constant evaluation. It's exposed this way mainly so that `insts()` can
// remain const.
auto SetNamespaceParseNode(SemIR::InstId inst_id, Parse::NodeId parse_node)
auto SetNamespaceNodeId(SemIR::InstId inst_id, Parse::NodeId node_id)
-> void {
sem_ir().insts().SetParseNode(inst_id, parse_node);
sem_ir().insts().SetNodeId(inst_id, node_id);
}
// Adds a package's imports to name lookup, with all libraries together.
@@ -119,11 +118,11 @@ class Context {
// Performs name lookup in a specified scope for a name appearing in a
// declaration, returning the referenced instruction. If scope_id is invalid,
// uses the current contextual scope.
auto LookupNameInDecl(Parse::NodeId parse_node, SemIR::NameId name_id,
auto LookupNameInDecl(Parse::NodeId node_id, SemIR::NameId name_id,
SemIR::NameScopeId scope_id) -> SemIR::InstId;
// Performs an unqualified name lookup, returning the referenced instruction.
auto LookupUnqualifiedName(Parse::NodeId parse_node, SemIR::NameId name_id)
auto LookupUnqualifiedName(Parse::NodeId node_id, SemIR::NameId name_id)
-> SemIR::InstId;
// Performs a name lookup in a specified scope, returning the referenced
@@ -134,7 +133,7 @@ class Context {
// Performs a qualified name lookup in a specified scope and in scopes that
// it extends, returning the referenced instruction.
auto LookupQualifiedName(Parse::NodeId parse_node, SemIR::NameId name_id,
auto LookupQualifiedName(Parse::NodeId node_id, SemIR::NameId name_id,
SemIR::NameScopeId scope_id, bool required = true)
-> SemIR::InstId;
@@ -143,7 +142,7 @@ class Context {
SemIR::InstId prev_def_id) -> void;
// Prints a diagnostic for a missing name.
auto DiagnoseNameNotFound(Parse::NodeId parse_node, SemIR::NameId name_id)
auto DiagnoseNameNotFound(Parse::NodeId node_id, SemIR::NameId name_id)
-> void;
// Adds a note to a diagnostic explaining that a class is incomplete.
@@ -164,27 +163,26 @@ class Context {
// Adds a `Branch` instruction branching to a new instruction block, and
// returns the ID of the new block. All paths to the branch target must go
// through the current block, though not necessarily through this branch.
auto AddDominatedBlockAndBranch(Parse::NodeId parse_node)
-> SemIR::InstBlockId;
auto AddDominatedBlockAndBranch(Parse::NodeId node_id) -> SemIR::InstBlockId;
// Adds a `Branch` instruction branching to a new instruction block with a
// value, and returns the ID of the new block. All paths to the branch target
// must go through the current block.
auto AddDominatedBlockAndBranchWithArg(Parse::NodeId parse_node,
auto AddDominatedBlockAndBranchWithArg(Parse::NodeId node_id,
SemIR::InstId arg_id)
-> SemIR::InstBlockId;
// Adds a `BranchIf` instruction branching to a new instruction block, and
// returns the ID of the new block. All paths to the branch target must go
// through the current block.
auto AddDominatedBlockAndBranchIf(Parse::NodeId parse_node,
auto AddDominatedBlockAndBranchIf(Parse::NodeId node_id,
SemIR::InstId cond_id)
-> SemIR::InstBlockId;
// Handles recovergence of control flow. Adds branches from the top
// `num_blocks` on the instruction block stack to a new block, pops the
// existing blocks, and pushes the new block onto the instruction block stack.
auto AddConvergenceBlockAndPush(Parse::NodeId parse_node, int num_blocks)
auto AddConvergenceBlockAndPush(Parse::NodeId node_id, int num_blocks)
-> void;
// Handles recovergence of control flow with a result value. Adds branches
@@ -194,15 +192,15 @@ class Context {
// corresponding result values are the elements of `block_args`. Returns an
// instruction referring to the result value.
auto AddConvergenceBlockWithArgAndPush(
Parse::NodeId parse_node, std::initializer_list<SemIR::InstId> block_args)
Parse::NodeId node_id, std::initializer_list<SemIR::InstId> block_args)
-> SemIR::InstId;
// Add the current code block to the enclosing function.
// TODO: The parse_node is taken for expressions, which can occur in
// TODO: The node_id is taken for expressions, which can occur in
// non-function contexts. This should be refactored to support non-function
// contexts, and parse_node removed.
// contexts, and node_id removed.
auto AddCurrentCodeBlockToFunction(
Parse::NodeId parse_node = Parse::NodeId::Invalid) -> void;
Parse::NodeId node_id = Parse::NodeId::Invalid) -> void;
// Returns whether the current position in the current block is reachable.
auto is_current_position_reachable() -> bool;
@@ -279,8 +277,8 @@ class Context {
auto PrintForStackDump(llvm::raw_ostream& output) const -> void;
// Get the Lex::TokenKind of a node for diagnostics.
auto token_kind(Parse::NodeId parse_node) -> Lex::TokenKind {
return tokens().GetKind(parse_tree().node_token(parse_node));
auto token_kind(Parse::NodeId node_id) -> Lex::TokenKind {
return tokens().GetKind(parse_tree().node_token(node_id));
}
auto tokens() -> const Lex::TokenizedBuffer& { return *tokens_; }
+84 -85
View File
@@ -95,7 +95,7 @@ static auto FinalizeTemporary(Context& context, SemIR::InstId init_id,
<< sem_ir.insts().Get(return_slot_id);
auto init = sem_ir.insts().Get(init_id);
return context.AddInst(
{sem_ir.insts().GetParseNode(init_id),
{sem_ir.insts().GetNodeId(init_id),
SemIR::Temporary{init.type_id(), return_slot_id, init_id}});
}
@@ -110,11 +110,11 @@ static auto FinalizeTemporary(Context& context, SemIR::InstId init_id,
// materialize and initialize a temporary, rather than two separate
// instructions.
auto init = sem_ir.insts().Get(init_id);
auto parse_node = sem_ir.insts().GetParseNode(init_id);
auto node_id = sem_ir.insts().GetNodeId(init_id);
auto temporary_id =
context.AddInst({parse_node, SemIR::TemporaryStorage{init.type_id()}});
context.AddInst({node_id, SemIR::TemporaryStorage{init.type_id()}});
return context.AddInst(
{parse_node, SemIR::Temporary{init.type_id(), temporary_id, init_id}});
{node_id, SemIR::Temporary{init.type_id(), temporary_id, init_id}});
}
// Materialize a temporary to hold the result of the given expression if it is
@@ -130,7 +130,7 @@ static auto MaterializeIfInitializing(Context& context, SemIR::InstId expr_id)
// Creates and adds an instruction to perform element access into an aggregate.
template <typename AccessInstT, typename InstBlockT>
static auto MakeElementAccessInst(Context& context, Parse::NodeId parse_node,
static auto MakeElementAccessInst(Context& context, Parse::NodeId node_id,
SemIR::InstId aggregate_id,
SemIR::TypeId elem_type_id, InstBlockT& block,
std::size_t i) {
@@ -139,14 +139,14 @@ static auto MakeElementAccessInst(Context& context, Parse::NodeId parse_node,
// index so that we don't need an integer literal instruction here, and
// remove this special case.
auto index_id = block.AddInst(
{parse_node,
{node_id,
SemIR::IntLiteral{context.GetBuiltinType(SemIR::BuiltinKind::IntType),
context.ints().Add(llvm::APInt(32, i))}});
return block.AddInst(
{parse_node, AccessInstT{elem_type_id, aggregate_id, index_id}});
{node_id, AccessInstT{elem_type_id, aggregate_id, index_id}});
} else {
return block.AddInst({parse_node, AccessInstT{elem_type_id, aggregate_id,
SemIR::ElementIndex(i)}});
return block.AddInst({node_id, AccessInstT{elem_type_id, aggregate_id,
SemIR::ElementIndex(i)}});
}
}
@@ -165,7 +165,7 @@ static auto MakeElementAccessInst(Context& context, Parse::NodeId parse_node,
// instruction used to access the destination element.
template <typename SourceAccessInstT, typename TargetAccessInstT>
static auto ConvertAggregateElement(
Context& context, Parse::NodeId parse_node, SemIR::InstId src_id,
Context& context, Parse::NodeId node_id, SemIR::InstId src_id,
SemIR::TypeId src_elem_type,
llvm::ArrayRef<SemIR::InstId> src_literal_elems,
ConversionTarget::Kind kind, SemIR::InstId target_id,
@@ -176,22 +176,22 @@ static auto ConvertAggregateElement(
auto src_elem_id =
!src_literal_elems.empty()
? src_literal_elems[i]
: MakeElementAccessInst<SourceAccessInstT>(
context, parse_node, src_id, src_elem_type, context, i);
: MakeElementAccessInst<SourceAccessInstT>(context, node_id, src_id,
src_elem_type, context, i);
// If we're performing a conversion rather than an initialization, we won't
// have or need a target.
ConversionTarget target = {.kind = kind, .type_id = target_elem_type};
if (!target.is_initializer()) {
return Convert(context, parse_node, src_elem_id, target);
return Convert(context, node_id, src_elem_id, target);
}
// Compute the location of the target element and initialize it.
PendingBlock::DiscardUnusedInstsScope scope(target_block);
target.init_block = target_block;
target.init_id = MakeElementAccessInst<TargetAccessInstT>(
context, parse_node, target_id, target_elem_type, *target_block, i);
return Convert(context, parse_node, src_elem_id, target);
context, node_id, target_id, target_elem_type, *target_block, i);
return Convert(context, node_id, src_elem_id, target);
}
namespace {
@@ -246,7 +246,7 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
auto tuple_elem_types = sem_ir.type_blocks().Get(tuple_type.elements_id);
auto value = sem_ir.insts().Get(value_id);
auto value_parse_node = sem_ir.insts().GetParseNode(value_id);
auto value_node_id = sem_ir.insts().GetNodeId(value_id);
// If we're initializing from a tuple literal, we will use its elements
// directly. Otherwise, materialize a temporary if needed and index into the
@@ -269,7 +269,7 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
"Cannot initialize array of {0} element(s) from tuple "
"with {1} element(s).",
uint64_t, size_t);
context.emitter().Emit(value_parse_node,
context.emitter().Emit(value_node_id,
literal_elems.empty()
? ArrayInitFromExprArgCountMismatch
: ArrayInitFromLiteralArgCountMismatch,
@@ -286,7 +286,7 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
SemIR::InstId return_slot_id = target.init_id;
if (!target.init_id.is_valid()) {
return_slot_id = target_block->AddInst(
{value_parse_node, SemIR::TemporaryStorage{target.type_id}});
{value_node_id, SemIR::TemporaryStorage{target.type_id}});
}
// Initialize each element of the array from the corresponding element of the
@@ -300,7 +300,7 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
// approach.
auto init_id =
ConvertAggregateElement<SemIR::TupleAccess, SemIR::ArrayIndex>(
context, value_parse_node, value_id, src_type_id, literal_elems,
context, value_node_id, value_id, src_type_id, literal_elems,
ConversionTarget::FullInitializer, return_slot_id,
array_type.element_type_id, target_block, i);
if (init_id == SemIR::InstId::BuiltinError) {
@@ -313,7 +313,7 @@ static auto ConvertTupleToArray(Context& context, SemIR::TupleType tuple_type,
// reference to the return slot.
target_block->InsertHere();
return context.AddInst(
{value_parse_node,
{value_node_id,
SemIR::ArrayInit{target.type_id, sem_ir.inst_blocks().Add(inits),
return_slot_id}});
}
@@ -330,7 +330,7 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type,
auto dest_elem_types = sem_ir.type_blocks().Get(dest_type.elements_id);
auto value = sem_ir.insts().Get(value_id);
auto value_parse_node = sem_ir.insts().GetParseNode(value_id);
auto value_node_id = sem_ir.insts().GetNodeId(value_id);
// If we're initializing from a tuple literal, we will use its elements
// directly. Otherwise, materialize a temporary if needed and index into the
@@ -350,7 +350,7 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type,
"Cannot initialize tuple of {0} element(s) from tuple "
"with {1} element(s).",
size_t, size_t);
context.emitter().Emit(value_parse_node, TupleInitElementCountMismatch,
context.emitter().Emit(value_node_id, TupleInitElementCountMismatch,
dest_elem_types.size(), src_elem_types.size());
return SemIR::InstId::BuiltinError;
}
@@ -377,7 +377,7 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type,
// approach.
auto init_id =
ConvertAggregateElement<SemIR::TupleAccess, SemIR::TupleAccess>(
context, value_parse_node, value_id, src_type_id, literal_elems,
context, value_node_id, value_id, src_type_id, literal_elems,
inner_kind, target.init_id, dest_type_id, target.init_block, i);
if (init_id == SemIR::InstId::BuiltinError) {
return SemIR::InstId::BuiltinError;
@@ -388,11 +388,11 @@ static auto ConvertTupleToTuple(Context& context, SemIR::TupleType src_type,
if (is_init) {
target.init_block->InsertHere();
return context.AddInst(
{value_parse_node,
{value_node_id,
SemIR::TupleInit{target.type_id, new_block.id(), target.init_id}});
} else {
return context.AddInst(
{value_parse_node, SemIR::TupleValue{target.type_id, new_block.id()}});
{value_node_id, SemIR::TupleValue{target.type_id, new_block.id()}});
}
}
@@ -409,7 +409,7 @@ static auto ConvertStructToStructOrClass(Context& context,
auto dest_elem_fields = sem_ir.inst_blocks().Get(dest_type.fields_id);
auto value = sem_ir.insts().Get(value_id);
auto value_parse_node = sem_ir.insts().GetParseNode(value_id);
auto value_node_id = sem_ir.insts().GetNodeId(value_id);
// If we're initializing from a struct literal, we will use its elements
// directly. Otherwise, materialize a temporary if needed and index into the
@@ -432,7 +432,7 @@ static auto ConvertStructToStructOrClass(Context& context,
"with {2} field(s).",
llvm::StringLiteral, size_t, size_t);
context.emitter().Emit(
value_parse_node, StructInitElementCountMismatch,
value_node_id, StructInitElementCountMismatch,
is_class ? llvm::StringLiteral("class") : llvm::StringLiteral("struct"),
dest_elem_fields.size(), src_elem_fields.size());
return SemIR::InstId::BuiltinError;
@@ -478,8 +478,7 @@ static auto ConvertStructToStructOrClass(Context& context,
StructInitMissingFieldInLiteral, Error,
"Missing value for field `{0}` in struct initialization.",
SemIR::NameId);
context.emitter().Emit(value_parse_node,
StructInitMissingFieldInLiteral,
context.emitter().Emit(value_node_id, StructInitMissingFieldInLiteral,
dest_field.name_id);
} else {
CARBON_DIAGNOSTIC(StructInitMissingFieldInConversion, Error,
@@ -487,7 +486,7 @@ static auto ConvertStructToStructOrClass(Context& context,
"missing field `{2}` in source type.",
SemIR::TypeId, SemIR::TypeId, SemIR::NameId);
context.emitter().Emit(
value_parse_node, StructInitMissingFieldInConversion,
value_node_id, StructInitMissingFieldInConversion,
value.type_id(), target.type_id, dest_field.name_id);
}
return SemIR::InstId::BuiltinError;
@@ -501,7 +500,7 @@ static auto ConvertStructToStructOrClass(Context& context,
// approach.
auto init_id =
ConvertAggregateElement<SemIR::StructAccess, TargetAccessInstT>(
context, value_parse_node, value_id, src_field.field_type_id,
context, value_node_id, value_id, src_field.field_type_id,
literal_elems, inner_kind, target.init_id, dest_field.field_type_id,
target.init_block, src_field_index);
if (init_id == SemIR::InstId::BuiltinError) {
@@ -515,16 +514,16 @@ static auto ConvertStructToStructOrClass(Context& context,
CARBON_CHECK(is_init)
<< "Converting directly to a class value is not supported";
return context.AddInst(
{value_parse_node,
{value_node_id,
SemIR::ClassInit{target.type_id, new_block.id(), target.init_id}});
} else if (is_init) {
target.init_block->InsertHere();
return context.AddInst(
{value_parse_node,
{value_node_id,
SemIR::StructInit{target.type_id, new_block.id(), target.init_id}});
} else {
return context.AddInst(
{value_parse_node, SemIR::StructValue{target.type_id, new_block.id()}});
{value_node_id, SemIR::StructValue{target.type_id, new_block.id()}});
}
}
@@ -570,7 +569,7 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
target.kind = ConversionTarget::Initializer;
target.init_block = &target_block;
target.init_id =
target_block.AddInst({context.insts().GetParseNode(value_id),
target_block.AddInst({context.insts().GetNodeId(value_id),
SemIR::TemporaryStorage{target.type_id}});
}
@@ -580,7 +579,7 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
if (need_temporary) {
target_block.InsertHere();
result_id = context.AddInst(
{context.insts().GetParseNode(value_id),
{context.insts().GetNodeId(value_id),
SemIR::Temporary{target.type_id, target.init_id, result_id}});
}
return result_id;
@@ -627,7 +626,7 @@ static auto ComputeInheritancePath(Context& context, SemIR::TypeId derived_id,
// Performs a conversion from a derived class value or reference to a base class
// value or reference.
static auto ConvertDerivedToBase(Context& context, Parse::NodeId parse_node,
static auto ConvertDerivedToBase(Context& context, Parse::NodeId node_id,
SemIR::InstId value_id,
const InheritancePath& path) -> SemIR::InstId {
// Materialize a temporary if necessary.
@@ -637,27 +636,27 @@ static auto ConvertDerivedToBase(Context& context, Parse::NodeId parse_node,
for (auto base_id : path) {
auto base_decl = context.insts().GetAs<SemIR::BaseDecl>(base_id);
value_id = context.AddInst(
{parse_node, SemIR::ClassElementAccess{base_decl.base_type_id, value_id,
base_decl.index}});
{node_id, SemIR::ClassElementAccess{base_decl.base_type_id, value_id,
base_decl.index}});
}
return value_id;
}
// Performs a conversion from a derived class pointer to a base class pointer.
static auto ConvertDerivedPointerToBasePointer(
Context& context, Parse::NodeId parse_node, SemIR::PointerType src_ptr_type,
Context& context, Parse::NodeId node_id, SemIR::PointerType src_ptr_type,
SemIR::TypeId dest_ptr_type_id, SemIR::InstId ptr_id,
const InheritancePath& path) -> SemIR::InstId {
// Form `*p`.
ptr_id = ConvertToValueExpr(context, ptr_id);
auto ref_id = context.AddInst(
{parse_node, SemIR::Deref{src_ptr_type.pointee_id, ptr_id}});
auto ref_id =
context.AddInst({node_id, SemIR::Deref{src_ptr_type.pointee_id, ptr_id}});
// Convert as a reference expression.
ref_id = ConvertDerivedToBase(context, parse_node, ref_id, path);
ref_id = ConvertDerivedToBase(context, node_id, ref_id, path);
// Take the address.
return context.AddInst({parse_node, SemIR::AddrOf{dest_ptr_type_id, ref_id}});
return context.AddInst({node_id, SemIR::AddrOf{dest_ptr_type_id, ref_id}});
}
// Returns whether `category` is a valid expression category to produce as a
@@ -682,7 +681,7 @@ static auto IsValidExprCategoryForConversionTarget(
}
}
static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
static auto PerformBuiltinConversion(Context& context, Parse::NodeId node_id,
SemIR::InstId value_id,
ConversionTarget target) -> SemIR::InstId {
auto& sem_ir = context.sem_ir();
@@ -740,7 +739,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
// value representation is a copy of the object representation, so we
// already have a value of the right form.
return context.AddInst(
{parse_node, SemIR::ValueOfInitializer{value_type_id, value_id}});
{node_id, SemIR::ValueOfInitializer{value_type_id, value_id}});
}
}
}
@@ -791,7 +790,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
if (auto path =
ComputeInheritancePath(context, value_type_id, target.type_id);
path && !path->empty()) {
return ConvertDerivedToBase(context, parse_node, value_id, *path);
return ConvertDerivedToBase(context, node_id, value_id, *path);
}
}
@@ -804,7 +803,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
target_pointer_type->pointee_id);
path && !path->empty()) {
return ConvertDerivedPointerToBasePointer(
context, parse_node, *src_pointer_type, target.type_id, value_id,
context, node_id, *src_pointer_type, target.type_id, value_id,
*path);
}
}
@@ -819,7 +818,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
sem_ir.inst_blocks().Get(tuple_literal->elements_id)) {
// TODO: This call recurses back into conversion. Switch to an
// iterative approach.
type_ids.push_back(ExprAsType(context, parse_node, tuple_inst_id));
type_ids.push_back(ExprAsType(context, node_id, tuple_inst_id));
}
auto tuple_type_id = context.GetTupleType(type_ids);
return sem_ir.types().GetInstId(tuple_type_id);
@@ -843,7 +842,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
// combining the above conversions and this one in a single conversion.
if (sem_ir.types().Is<SemIR::InterfaceType>(value_type_id)) {
return context.AddInst(
{parse_node, SemIR::FacetTypeAccess{target.type_id, value_id}});
{node_id, SemIR::FacetTypeAccess{target.type_id, value_id}});
}
}
@@ -880,7 +879,7 @@ static auto PerformCopy(Context& context, SemIR::InstId expr_id)
return SemIR::InstId::BuiltinError;
}
auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
auto Convert(Context& context, Parse::NodeId node_id, SemIR::InstId expr_id,
ConversionTarget target) -> SemIR::InstId {
auto& sem_ir = context.sem_ir();
auto orig_expr_id = expr_id;
@@ -913,7 +912,7 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
CARBON_DIAGNOSTIC(IncompleteTypeInConversion, Error,
"Invalid use of incomplete type `{0}`.",
SemIR::TypeId);
return context.emitter().Build(parse_node,
return context.emitter().Build(node_id,
target.is_initializer()
? IncompleteTypeInInit
: target.kind == ConversionTarget::Value
@@ -925,7 +924,7 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
}
// Check whether any builtin conversion applies.
expr_id = PerformBuiltinConversion(context, parse_node, expr_id, target);
expr_id = PerformBuiltinConversion(context, node_id, expr_id, target);
if (expr_id == SemIR::InstId::BuiltinError) {
return expr_id;
}
@@ -942,7 +941,7 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
"Cannot convert from `{0}` to `{1}` with `as`.",
SemIR::TypeId, SemIR::TypeId);
context.emitter()
.Build(parse_node,
.Build(node_id,
target.kind == ConversionTarget::ExplicitAs
? ExplicitAsConversionFailure
: ImplicitAsConversionFailure,
@@ -954,7 +953,7 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
// Track that we performed a type conversion, if we did so.
if (orig_expr_id != expr_id) {
expr_id = context.AddInst(
{context.insts().GetParseNode(orig_expr_id),
{context.insts().GetNodeId(orig_expr_id),
SemIR::Converted{target.type_id, orig_expr_id, expr_id}});
}
@@ -1005,7 +1004,7 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
// If we have a reference and don't want one, form a value binding.
// TODO: Support types with custom value representations.
expr_id = context.AddInst({context.insts().GetParseNode(expr_id),
expr_id = context.AddInst({context.insts().GetNodeId(expr_id),
SemIR::BindValue{expr.type_id(), expr_id}});
// We now have a value expression.
[[fallthrough]];
@@ -1024,7 +1023,7 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
init_rep.kind == SemIR::InitRepr::ByCopy) {
target.init_block->InsertHere();
expr_id = context.AddInst(
{parse_node,
{node_id,
SemIR::InitializeFrom{target.type_id, expr_id, target.init_id}});
}
}
@@ -1032,11 +1031,11 @@ auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
return expr_id;
}
auto Initialize(Context& context, Parse::NodeId parse_node,
auto Initialize(Context& context, Parse::NodeId node_id,
SemIR::InstId target_id, SemIR::InstId value_id)
-> SemIR::InstId {
PendingBlock target_block(context);
return Convert(context, parse_node, value_id,
return Convert(context, node_id, value_id,
{.kind = ConversionTarget::Initializer,
.type_id = context.insts().Get(target_id).type_id(),
.init_id = target_id,
@@ -1045,36 +1044,36 @@ auto Initialize(Context& context, Parse::NodeId parse_node,
auto ConvertToValueExpr(Context& context, SemIR::InstId expr_id)
-> SemIR::InstId {
return Convert(context, context.insts().GetParseNode(expr_id), expr_id,
return Convert(context, context.insts().GetNodeId(expr_id), expr_id,
{.kind = ConversionTarget::Value,
.type_id = context.insts().Get(expr_id).type_id()});
}
auto ConvertToValueOrRefExpr(Context& context, SemIR::InstId expr_id)
-> SemIR::InstId {
return Convert(context, context.insts().GetParseNode(expr_id), expr_id,
return Convert(context, context.insts().GetNodeId(expr_id), expr_id,
{.kind = ConversionTarget::ValueOrRef,
.type_id = context.insts().Get(expr_id).type_id()});
}
auto ConvertToValueOfType(Context& context, Parse::NodeId parse_node,
auto ConvertToValueOfType(Context& context, Parse::NodeId node_id,
SemIR::InstId expr_id, SemIR::TypeId type_id)
-> SemIR::InstId {
return Convert(context, parse_node, expr_id,
return Convert(context, node_id, expr_id,
{.kind = ConversionTarget::Value, .type_id = type_id});
}
auto ConvertToValueOrRefOfType(Context& context, Parse::NodeId parse_node,
auto ConvertToValueOrRefOfType(Context& context, Parse::NodeId node_id,
SemIR::InstId expr_id, SemIR::TypeId type_id)
-> SemIR::InstId {
return Convert(context, parse_node, expr_id,
return Convert(context, node_id, expr_id,
{.kind = ConversionTarget::ValueOrRef, .type_id = type_id});
}
auto ConvertToBoolValue(Context& context, Parse::NodeId parse_node,
auto ConvertToBoolValue(Context& context, Parse::NodeId node_id,
SemIR::InstId value_id) -> SemIR::InstId {
return ConvertToValueOfType(
context, parse_node, value_id,
context, node_id, value_id,
context.GetBuiltinType(SemIR::BuiltinKind::BoolType));
}
@@ -1088,7 +1087,7 @@ auto ConvertForExplicitAs(Context& context, Parse::NodeId as_node,
CARBON_DIAGNOSTIC(InCallToFunction, Note, "Calling function declared here.");
// Convert the object argument in a method call to match the `self` parameter.
static auto ConvertSelf(Context& context, Parse::NodeId call_parse_node,
static auto ConvertSelf(Context& context, Parse::NodeId call_node_id,
SemIR::InstId callee_id,
std::optional<SemIR::AddrPattern> addr_pattern,
SemIR::InstId self_param_id, SemIR::Param self_param,
@@ -1097,7 +1096,7 @@ static auto ConvertSelf(Context& context, Parse::NodeId call_parse_node,
CARBON_DIAGNOSTIC(MissingObjectInMethodCall, Error,
"Missing object argument in method call.");
context.emitter()
.Build(call_parse_node, MissingObjectInMethodCall)
.Build(call_node_id, MissingObjectInMethodCall)
.Note(callee_id, InCallToFunction)
.Emit();
return SemIR::InstId::BuiltinError;
@@ -1127,20 +1126,20 @@ static auto ConvertSelf(Context& context, Parse::NodeId call_parse_node,
default:
CARBON_DIAGNOSTIC(AddrSelfIsNonRef, Error,
"`addr self` method cannot be invoked on a value.");
context.emitter().Emit(TokenOnly(call_parse_node), AddrSelfIsNonRef);
context.emitter().Emit(TokenOnly(call_node_id), AddrSelfIsNonRef);
return SemIR::InstId::BuiltinError;
}
auto parse_node = context.insts().GetParseNode(self_or_addr_id);
auto node_id = context.insts().GetNodeId(self_or_addr_id);
self_or_addr_id = context.AddInst(
{parse_node, SemIR::AddrOf{context.GetPointerType(self.type_id()),
self_or_addr_id}});
{node_id, SemIR::AddrOf{context.GetPointerType(self.type_id()),
self_or_addr_id}});
}
return ConvertToValueOfType(context, call_parse_node, self_or_addr_id,
return ConvertToValueOfType(context, call_node_id, self_or_addr_id,
self_param.type_id);
}
auto ConvertCallArgs(Context& context, Parse::NodeId call_parse_node,
auto ConvertCallArgs(Context& context, Parse::NodeId call_node_id,
SemIR::InstId self_id,
llvm::ArrayRef<SemIR::InstId> arg_refs,
SemIR::InstId return_storage_id, SemIR::InstId callee_id,
@@ -1156,7 +1155,7 @@ auto ConvertCallArgs(Context& context, Parse::NodeId call_parse_node,
"{1} argument(s).",
int, int);
context.emitter()
.Build(call_parse_node, CallArgCountMismatch, arg_refs.size(),
.Build(call_node_id, CallArgCountMismatch, arg_refs.size(),
param_refs.size())
.Note(callee_id, InCallToFunction)
.Emit();
@@ -1176,15 +1175,15 @@ auto ConvertCallArgs(Context& context, Parse::NodeId call_parse_node,
context.sem_ir(), implicit_param_id);
if (param.name_id == SemIR::NameId::SelfValue) {
auto converted_self_id =
ConvertSelf(context, call_parse_node, callee_id, addr_pattern,
param_id, param, self_id);
ConvertSelf(context, call_node_id, callee_id, addr_pattern, param_id,
param, self_id);
if (converted_self_id == SemIR::InstId::BuiltinError) {
return SemIR::InstBlockId::Invalid;
}
args.push_back(converted_self_id);
} else {
// TODO: Form argument values for implicit parameters.
context.TODO(call_parse_node, "Call with implicit parameters");
context.TODO(call_node_id, "Call with implicit parameters");
return SemIR::InstBlockId::Invalid;
}
}
@@ -1206,7 +1205,7 @@ auto ConvertCallArgs(Context& context, Parse::NodeId call_parse_node,
// TODO: Convert to the proper expression category. For now, we assume
// parameters are all `let` bindings.
auto converted_arg_id =
ConvertToValueOfType(context, call_parse_node, arg_id, param_type_id);
ConvertToValueOfType(context, call_node_id, arg_id, param_type_id);
if (converted_arg_id == SemIR::InstId::BuiltinError) {
return SemIR::InstBlockId::Invalid;
}
@@ -1222,10 +1221,10 @@ auto ConvertCallArgs(Context& context, Parse::NodeId call_parse_node,
return context.inst_blocks().Add(args);
}
auto ExprAsType(Context& context, Parse::NodeId parse_node,
SemIR::InstId value_id) -> SemIR::TypeId {
auto type_inst_id = ConvertToValueOfType(context, parse_node, value_id,
SemIR::TypeId::TypeType);
auto ExprAsType(Context& context, Parse::NodeId node_id, SemIR::InstId value_id)
-> SemIR::TypeId {
auto type_inst_id =
ConvertToValueOfType(context, node_id, value_id, SemIR::TypeId::TypeType);
if (type_inst_id == SemIR::InstId::BuiltinError) {
return SemIR::TypeId::Error;
}
@@ -1234,7 +1233,7 @@ auto ExprAsType(Context& context, Parse::NodeId parse_node,
if (!type_const_id.is_constant()) {
CARBON_DIAGNOSTIC(TypeExprEvaluationFailure, Error,
"Cannot evaluate type expression.");
context.emitter().Emit(parse_node, TypeExprEvaluationFailure);
context.emitter().Emit(node_id, TypeExprEvaluationFailure);
return SemIR::TypeId::Error;
}
+8 -8
View File
@@ -50,13 +50,13 @@ struct ConversionTarget {
};
// Convert a value to another type and expression category.
auto Convert(Context& context, Parse::NodeId parse_node, SemIR::InstId expr_id,
auto Convert(Context& context, Parse::NodeId node_id, SemIR::InstId expr_id,
ConversionTarget target) -> SemIR::InstId;
// Performs initialization of `target_id` from `value_id`. Returns the
// possibly-converted initializing expression, which should be assigned to the
// target using a suitable node for the kind of initialization.
auto Initialize(Context& context, Parse::NodeId parse_node,
auto Initialize(Context& context, Parse::NodeId node_id,
SemIR::InstId target_id, SemIR::InstId value_id)
-> SemIR::InstId;
@@ -70,18 +70,18 @@ auto ConvertToValueOrRefExpr(Context& context, SemIR::InstId expr_id)
-> SemIR::InstId;
// Converts `expr_id` to a value expression of type `type_id`.
auto ConvertToValueOfType(Context& context, Parse::NodeId parse_node,
auto ConvertToValueOfType(Context& context, Parse::NodeId node_id,
SemIR::InstId expr_id, SemIR::TypeId type_id)
-> SemIR::InstId;
// Convert the given expression to a value or reference expression of the given
// type.
auto ConvertToValueOrRefOfType(Context& context, Parse::NodeId parse_node,
auto ConvertToValueOrRefOfType(Context& context, Parse::NodeId node_id,
SemIR::InstId expr_id, SemIR::TypeId type_id)
-> SemIR::InstId;
// Converts `value_id` to a value expression of type `bool`.
auto ConvertToBoolValue(Context& context, Parse::NodeId parse_node,
auto ConvertToBoolValue(Context& context, Parse::NodeId node_id,
SemIR::InstId value_id) -> SemIR::InstId;
// Converts `value_id` to type `type_id` for an `as` expression.
@@ -92,7 +92,7 @@ auto ConvertForExplicitAs(Context& context, Parse::NodeId as_node,
// Implicitly converts a set of arguments to match the parameter types in a
// function call. Returns a block containing the converted implicit and explicit
// argument values.
auto ConvertCallArgs(Context& context, Parse::NodeId call_parse_node,
auto ConvertCallArgs(Context& context, Parse::NodeId call_node_id,
SemIR::InstId self_id,
llvm::ArrayRef<SemIR::InstId> arg_refs,
SemIR::InstId return_storage_id, SemIR::InstId callee_id,
@@ -100,8 +100,8 @@ auto ConvertCallArgs(Context& context, Parse::NodeId call_parse_node,
SemIR::InstBlockId param_refs_id) -> SemIR::InstBlockId;
// Converts an expression for use as a type.
auto ExprAsType(Context& context, Parse::NodeId parse_node,
SemIR::InstId value_id) -> SemIR::TypeId;
auto ExprAsType(Context& context, Parse::NodeId node_id, SemIR::InstId value_id)
-> SemIR::TypeId;
} // namespace Carbon::Check
+18 -18
View File
@@ -15,10 +15,10 @@ auto DeclNameStack::MakeEmptyNameContext() -> NameContext {
.target_scope_id = context_->scope_stack().PeekNameScopeId()};
}
auto DeclNameStack::MakeUnqualifiedName(Parse::NodeId parse_node,
auto DeclNameStack::MakeUnqualifiedName(Parse::NodeId node_id,
SemIR::NameId name_id) -> NameContext {
NameContext context = MakeEmptyNameContext();
ApplyNameQualifierTo(context, parse_node, name_id, /*is_unqualified=*/true);
ApplyNameQualifierTo(context, node_id, name_id, /*is_unqualified=*/true);
return context;
}
@@ -33,13 +33,13 @@ auto DeclNameStack::FinishName() -> NameContext {
CARBON_CHECK(decl_name_stack_.back().state != NameContext::State::Finished)
<< "Finished name twice";
if (context_->node_stack()
.PopAndDiscardSoloParseNodeIf<Parse::NodeKind::QualifiedName>()) {
.PopAndDiscardSoloNodeIdIf<Parse::NodeKind::QualifiedName>()) {
// Any parts from a QualifiedName will already have been processed
// into the name.
} else {
// The name had no qualifiers, so we need to process the node now.
auto [parse_node, name_id] = context_->node_stack().PopNameWithParseNode();
ApplyNameQualifier(parse_node, name_id);
auto [node_id, name_id] = context_->node_stack().PopNameWithNodeId();
ApplyNameQualifier(node_id, name_id);
}
NameContext result = decl_name_stack_.back();
@@ -92,7 +92,7 @@ auto DeclNameStack::LookupOrAddName(NameContext name_context,
QualifiedDeclOutsideScopeEntity, Error,
"Out-of-line declaration requires a declaration in "
"scoped entity.");
context_->emitter().Emit(name_context.parse_node,
context_->emitter().Emit(name_context.node_id,
QualifiedDeclOutsideScopeEntity);
}
}
@@ -125,20 +125,20 @@ auto DeclNameStack::AddNameToLookup(NameContext name_context,
}
}
auto DeclNameStack::ApplyNameQualifier(Parse::NodeId parse_node,
auto DeclNameStack::ApplyNameQualifier(Parse::NodeId node_id,
SemIR::NameId name_id) -> void {
ApplyNameQualifierTo(decl_name_stack_.back(), parse_node, name_id,
ApplyNameQualifierTo(decl_name_stack_.back(), node_id, name_id,
/*is_unqualified=*/false);
}
auto DeclNameStack::ApplyNameQualifierTo(NameContext& name_context,
Parse::NodeId parse_node,
Parse::NodeId node_id,
SemIR::NameId name_id,
bool is_unqualified) -> void {
if (TryResolveQualifier(name_context, parse_node)) {
if (TryResolveQualifier(name_context, node_id)) {
// For identifier nodes, we need to perform a lookup on the identifier.
auto resolved_inst_id = context_->LookupNameInDecl(
name_context.parse_node, name_id, name_context.target_scope_id);
name_context.node_id, name_id, name_context.target_scope_id);
if (!resolved_inst_id.is_valid()) {
// Invalid indicates an unresolved name. Store it and return.
name_context.state = NameContext::State::Unresolved;
@@ -228,7 +228,7 @@ auto DeclNameStack::UpdateScopeIfNeeded(NameContext& name_context,
}
auto DeclNameStack::TryResolveQualifier(NameContext& name_context,
Parse::NodeId parse_node) -> bool {
Parse::NodeId node_id) -> bool {
// Update has_qualifiers based on the state before any possible changes. If
// this is the first qualifier, it may just be the name.
name_context.has_qualifiers = name_context.state != NameContext::State::Empty;
@@ -242,7 +242,7 @@ auto DeclNameStack::TryResolveQualifier(NameContext& name_context,
// Because more qualifiers were found, we diagnose that the earlier
// qualifier failed to resolve.
name_context.state = NameContext::State::Error;
context_->DiagnoseNameNotFound(name_context.parse_node,
context_->DiagnoseNameNotFound(name_context.node_id,
name_context.unresolved_name_id);
return false;
@@ -255,7 +255,7 @@ auto DeclNameStack::TryResolveQualifier(NameContext& name_context,
"Cannot declare a member of incomplete class `{0}`.",
SemIR::TypeId);
auto builder = context_->emitter().Build(
name_context.parse_node, QualifiedDeclInIncompleteClassScope,
name_context.node_id, QualifiedDeclInIncompleteClassScope,
context_->classes().Get(class_decl->class_id).self_type_id);
context_->NoteIncompleteClass(class_decl->class_id, builder);
builder.Emit();
@@ -267,7 +267,7 @@ auto DeclNameStack::TryResolveQualifier(NameContext& name_context,
"Cannot declare a member of undefined interface `{0}`.",
std::string);
auto builder = context_->emitter().Build(
name_context.parse_node, QualifiedDeclInUndefinedInterfaceScope,
name_context.node_id, QualifiedDeclInUndefinedInterfaceScope,
context_->sem_ir().StringifyTypeExpr(
context_->sem_ir()
.constant_values()
@@ -282,8 +282,8 @@ auto DeclNameStack::TryResolveQualifier(NameContext& name_context,
CARBON_DIAGNOSTIC(QualifiedNameNonScopeEntity, Note,
"Non-scope entity referenced here.");
context_->emitter()
.Build(parse_node, QualifiedNameInNonScope)
.Note(name_context.parse_node, QualifiedNameNonScopeEntity)
.Build(node_id, QualifiedNameInNonScope)
.Note(name_context.node_id, QualifiedNameNonScopeEntity)
.Emit();
}
name_context.state = NameContext::State::Error;
@@ -292,7 +292,7 @@ auto DeclNameStack::TryResolveQualifier(NameContext& name_context,
case NameContext::State::Empty:
case NameContext::State::Resolved: {
name_context.parse_node = parse_node;
name_context.node_id = node_id;
return true;
}
+5 -6
View File
@@ -125,7 +125,7 @@ class DeclNameStack {
SemIR::NameScopeId target_scope_id;
// The last parse node used.
Parse::NodeId parse_node = Parse::NodeId::Invalid;
Parse::NodeId node_id = Parse::NodeId::Invalid;
union {
// The ID of a resolved qualifier, including both identifiers and
@@ -177,14 +177,13 @@ class DeclNameStack {
// unqualified name in the current context. This is suitable for adding to
// name lookup in situations where a qualified name is not permitted, such as
// a pattern binding.
auto MakeUnqualifiedName(Parse::NodeId parse_node, SemIR::NameId name_id)
auto MakeUnqualifiedName(Parse::NodeId node_id, SemIR::NameId name_id)
-> NameContext;
// Applies a Name from the name stack to the top of the declaration name
// stack. This will enter the scope corresponding to the name if the name
// describes an existing scope, such as a namespace or a defined class.
auto ApplyNameQualifier(Parse::NodeId parse_node, SemIR::NameId name_id)
-> void;
auto ApplyNameQualifier(Parse::NodeId node_id, SemIR::NameId name_id) -> void;
// Adds a name to name lookup. Prints a diagnostic for name conflicts.
auto AddNameToLookup(NameContext name_context, SemIR::InstId target_id)
@@ -200,12 +199,12 @@ class DeclNameStack {
auto MakeEmptyNameContext() -> NameContext;
// Applies a Name from the name stack to given name context.
auto ApplyNameQualifierTo(NameContext& name_context, Parse::NodeId parse_node,
auto ApplyNameQualifierTo(NameContext& name_context, Parse::NodeId node_id,
SemIR::NameId name_id, bool is_unqualified) -> void;
// Returns true if the context is in a state where it can resolve qualifiers.
// Updates name_context as needed.
auto TryResolveQualifier(NameContext& name_context, Parse::NodeId parse_node)
auto TryResolveQualifier(NameContext& name_context, Parse::NodeId node_id)
-> bool;
// Updates the scope on name_context as needed. This is called after
+1 -1
View File
@@ -302,7 +302,7 @@ auto TryEvalInst(Context& context, SemIR::InstId inst_id, SemIR::Inst inst)
if (!int_bound) {
// TODO: Permit symbolic array bounds. This will require fixing
// callers of `GetArrayBoundValue`.
context.TODO(context.insts().GetParseNode(bound_id),
context.TODO(context.insts().GetNodeId(bound_id),
"symbolic array bound");
return false;
}
+3 -3
View File
@@ -179,7 +179,7 @@ auto CheckFunctionRedecl(Context& context, SemIR::FunctionId new_function_id,
context.functions().Get(prev_function_id));
}
auto MergeFunctionRedecl(Context& context, Parse::NodeId parse_node,
auto MergeFunctionRedecl(Context& context, Parse::NodeId node_id,
SemIR::Function& new_function,
SemIR::FunctionId prev_function_id, bool is_definition)
-> bool {
@@ -196,7 +196,7 @@ auto MergeFunctionRedecl(Context& context, Parse::NodeId parse_node,
SemIR::NameId);
CARBON_DIAGNOSTIC(FunctionPreviousDecl, Note, "Previously declared here.");
context.emitter()
.Build(parse_node, FunctionRedecl, prev_function.name_id)
.Build(node_id, FunctionRedecl, prev_function.name_id)
.Note(prev_function.decl_id, FunctionPreviousDecl)
.Emit();
// The diagnostic doesn't prevent a merge.
@@ -207,7 +207,7 @@ auto MergeFunctionRedecl(Context& context, Parse::NodeId parse_node,
CARBON_DIAGNOSTIC(FunctionPreviousDefinition, Note,
"Previously defined here.");
context.emitter()
.Build(parse_node, FunctionRedefinition, prev_function.name_id)
.Build(node_id, FunctionRedefinition, prev_function.name_id)
.Note(prev_function.definition_id, FunctionPreviousDefinition)
.Emit();
// The second definition will be unused as a consequence of the error.
+1 -1
View File
@@ -21,7 +21,7 @@ auto CheckFunctionRedecl(Context& context, SemIR::FunctionId new_function_id,
//
// If merging is successful, updates the FunctionId on new_function and returns
// true. Otherwise, returns false. Prints a diagnostic when appropriate.
auto MergeFunctionRedecl(Context& context, Parse::NodeId parse_node,
auto MergeFunctionRedecl(Context& context, Parse::NodeId node_id,
SemIR::Function& new_function,
SemIR::FunctionId prev_function_id, bool is_definition)
-> bool;
+7 -7
View File
@@ -11,19 +11,19 @@
namespace Carbon::Check {
auto HandleAliasIntroducer(Context& context,
Parse::AliasIntroducerId /*parse_node*/) -> bool {
Parse::AliasIntroducerId /*node_id*/) -> bool {
context.decl_state_stack().Push(DeclState::Alias);
context.decl_name_stack().PushScopeAndStartName();
return true;
}
auto HandleAliasInitializer(Context& /*context*/,
Parse::AliasInitializerId /*parse_node*/) -> bool {
Parse::AliasInitializerId /*node_id*/) -> bool {
return true;
}
auto HandleAlias(Context& context, Parse::AliasId /*parse_node*/) -> bool {
auto [expr_node, expr_id] = context.node_stack().PopExprWithParseNode();
auto HandleAlias(Context& context, Parse::AliasId /*node_id*/) -> bool {
auto [expr_node, expr_id] = context.node_stack().PopExprWithNodeId();
auto name_context = context.decl_name_stack().FinishName();
@@ -48,20 +48,20 @@ auto HandleAlias(Context& context, Parse::AliasId /*parse_node*/) -> bool {
// TODO: Look into handling `false`, this doesn't do it right now because it
// sees a value instruction instead of a builtin.
alias_id = context.AddInst(
{name_context.parse_node,
{name_context.node_id,
SemIR::BindAlias{context.insts().Get(expr_id).type_id(), bind_name_id,
expr_id}});
} else if (auto inst = context.insts().TryGetAs<SemIR::NameRef>(expr_id)) {
// Pass through name references, albeit changing the name in use.
alias_id = context.AddInst(
{name_context.parse_node,
{name_context.node_id,
SemIR::BindAlias{inst->type_id, bind_name_id, inst->value_id}});
} else {
CARBON_DIAGNOSTIC(AliasRequiresNameRef, Error,
"Alias initializer must be a name reference.");
context.emitter().Emit(expr_node, AliasRequiresNameRef);
alias_id =
context.AddInst({name_context.parse_node,
context.AddInst({name_context.node_id,
SemIR::BindAlias{SemIR::TypeId::Error, bind_name_id,
SemIR::InstId::BuiltinError}});
}
+12 -12
View File
@@ -9,29 +9,29 @@
namespace Carbon::Check {
auto HandleArrayExprStart(Context& /*context*/,
Parse::ArrayExprStartId /*parse_node*/) -> bool {
Parse::ArrayExprStartId /*node_id*/) -> bool {
return true;
}
auto HandleArrayExprSemi(Context& context, Parse::ArrayExprSemiId parse_node)
auto HandleArrayExprSemi(Context& context, Parse::ArrayExprSemiId node_id)
-> bool {
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
return true;
}
auto HandleArrayExpr(Context& context, Parse::ArrayExprId parse_node) -> bool {
auto HandleArrayExpr(Context& context, Parse::ArrayExprId node_id) -> bool {
// TODO: Handle array type with undefined bound.
if (context.node_stack()
.PopAndDiscardSoloParseNodeIf<Parse::NodeKind::ArrayExprSemi>()) {
.PopAndDiscardSoloNodeIdIf<Parse::NodeKind::ArrayExprSemi>()) {
context.node_stack().PopAndIgnore();
return context.TODO(parse_node, "HandleArrayExprWithoutBounds");
return context.TODO(node_id, "HandleArrayExprWithoutBounds");
}
auto bound_inst_id = context.node_stack().PopExpr();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ArrayExprSemi>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::ArrayExprSemi>();
auto [element_type_node_id, element_type_inst_id] =
context.node_stack().PopExprWithParseNode();
context.node_stack().PopExprWithNodeId();
// The array bound must be a constant.
//
@@ -42,14 +42,14 @@ auto HandleArrayExpr(Context& context, Parse::ArrayExprId parse_node) -> bool {
CARBON_DIAGNOSTIC(InvalidArrayExpr, Error,
"Array bound is not a constant.");
context.emitter().Emit(bound_inst_id, InvalidArrayExpr);
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinError);
return true;
}
context.AddInstAndPush(
{parse_node, SemIR::ArrayType{SemIR::TypeId::TypeType, bound_inst_id,
ExprAsType(context, element_type_node_id,
element_type_inst_id)}});
{node_id, SemIR::ArrayType{SemIR::TypeId::TypeType, bound_inst_id,
ExprAsType(context, element_type_node_id,
element_type_inst_id)}});
return true;
}
+29 -31
View File
@@ -8,20 +8,19 @@
namespace Carbon::Check {
auto HandleAnyBindingPattern(Context& context, Parse::NodeId parse_node,
auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id,
bool is_generic) -> bool {
auto [type_node, parsed_type_id] =
context.node_stack().PopExprWithParseNode();
auto [type_node, parsed_type_id] = context.node_stack().PopExprWithNodeId();
auto cast_type_id = ExprAsType(context, type_node, parsed_type_id);
// TODO: Handle `_` bindings.
// Every other kind of pattern binding has a name.
auto [name_node, name_id] = context.node_stack().PopNameWithParseNode();
auto [name_node, name_id] = context.node_stack().PopNameWithNodeId();
// Create the appropriate kind of binding for this pattern.
auto make_bind_name = [&](SemIR::TypeId type_id,
SemIR::InstId value_id) -> SemIR::ParseNodeAndInst {
SemIR::InstId value_id) -> SemIR::NodeIdAndInst {
// TODO: Eventually the name will need to support associations with other
// scopes, but right now we don't support qualified names here.
auto bind_name_id = context.bind_names().Add(
@@ -42,15 +41,14 @@ auto HandleAnyBindingPattern(Context& context, Parse::NodeId parse_node,
CARBON_DIAGNOSTIC(
SelfOutsideImplicitParamList, Error,
"`self` can only be declared in an implicit parameter list.");
context.emitter().Emit(parse_node, SelfOutsideImplicitParamList);
context.emitter().Emit(node_id, SelfOutsideImplicitParamList);
}
// Allocate an instruction of the appropriate kind, linked to the name for
// error locations.
// TODO: The node stack is a fragile way of getting context information.
// Get this information from somewhere else.
switch (auto context_parse_node_kind =
context.node_stack().PeekParseNodeKind()) {
switch (auto context_node_kind = context.node_stack().PeekNodeKind()) {
case Parse::NodeKind::ReturnedModifier:
case Parse::NodeKind::VariableIntroducer: {
if (is_generic) {
@@ -62,7 +60,7 @@ auto HandleAnyBindingPattern(Context& context, Parse::NodeId parse_node,
auto binding_id =
is_generic
? Parse::NodeId::Invalid
: context.parse_tree().As<Parse::BindingPatternId>(parse_node);
: context.parse_tree().As<Parse::BindingPatternId>(node_id);
// A `var` declaration at class scope introduces a field.
auto enclosing_class_decl = context.GetCurrentScopeAs<SemIR::ClassDecl>();
@@ -77,8 +75,7 @@ auto HandleAnyBindingPattern(Context& context, Parse::NodeId parse_node,
cast_type_id);
});
if (enclosing_class_decl) {
CARBON_CHECK(context_parse_node_kind ==
Parse::NodeKind::VariableIntroducer)
CARBON_CHECK(context_node_kind == Parse::NodeKind::VariableIntroducer)
<< "`returned var` at class scope";
auto& class_info =
context.classes().Get(enclosing_class_decl->class_id);
@@ -94,25 +91,25 @@ auto HandleAnyBindingPattern(Context& context, Parse::NodeId parse_node,
// Add a corresponding field to the object representation of the class.
context.args_type_info_stack().AddInstId(context.AddInstInNoBlock(
{binding_id, SemIR::StructTypeField{name_id, cast_type_id}}));
context.node_stack().Push(parse_node, field_id);
context.node_stack().Push(node_id, field_id);
break;
}
SemIR::InstId value_id = SemIR::InstId::Invalid;
if (context_parse_node_kind == Parse::NodeKind::ReturnedModifier) {
if (context_node_kind == Parse::NodeKind::ReturnedModifier) {
// TODO: Should we check this for the `var` as a whole, rather than for
// the name binding?
value_id =
CheckReturnedVar(context, context.node_stack().PeekParseNode(),
CheckReturnedVar(context, context.node_stack().PeekNodeId(),
name_node, name_id, type_node, cast_type_id);
} else {
value_id = context.AddInst(
{name_node, SemIR::VarStorage{cast_type_id, name_id}});
}
auto bind_id = context.AddInst(make_bind_name(cast_type_id, value_id));
context.node_stack().Push(parse_node, bind_id);
context.node_stack().Push(node_id, bind_id);
if (context_parse_node_kind == Parse::NodeKind::ReturnedModifier) {
if (context_node_kind == Parse::NodeKind::ReturnedModifier) {
RegisterReturnedVar(context, bind_id);
}
break;
@@ -130,7 +127,7 @@ auto HandleAnyBindingPattern(Context& context, Parse::NodeId parse_node,
// TODO: Bindings should come into scope immediately in other contexts
// too.
context.AddNameToLookup(name_id, bind_id);
context.node_stack().Push(parse_node, bind_id);
context.node_stack().Push(node_id, bind_id);
break;
}
@@ -147,28 +144,29 @@ auto HandleAnyBindingPattern(Context& context, Parse::NodeId parse_node,
// TODO: For general pattern parsing, we'll need to create a block to hold
// the `let` pattern before we see the initializer.
context.node_stack().Push(
parse_node, context.AddPlaceholderInstInNoBlock(make_bind_name(
cast_type_id, SemIR::InstId::Invalid)));
node_id, context.AddPlaceholderInstInNoBlock(
make_bind_name(cast_type_id, SemIR::InstId::Invalid)));
break;
default:
CARBON_FATAL() << "Found a pattern binding in unexpected context "
<< context_parse_node_kind;
<< context_node_kind;
}
return true;
}
auto HandleBindingPattern(Context& context, Parse::BindingPatternId parse_node)
auto HandleBindingPattern(Context& context, Parse::BindingPatternId node_id)
-> bool {
return HandleAnyBindingPattern(context, parse_node, /*is_generic=*/false);
return HandleAnyBindingPattern(context, node_id, /*is_generic=*/false);
}
auto HandleCompileTimeBindingPattern(
Context& context, Parse::CompileTimeBindingPatternId parse_node) -> bool {
return HandleAnyBindingPattern(context, parse_node, /*is_generic=*/true);
auto HandleCompileTimeBindingPattern(Context& context,
Parse::CompileTimeBindingPatternId node_id)
-> bool {
return HandleAnyBindingPattern(context, node_id, /*is_generic=*/true);
}
auto HandleAddr(Context& context, Parse::AddrId parse_node) -> bool {
auto HandleAddr(Context& context, Parse::AddrId node_id) -> bool {
auto self_param_id = context.node_stack().PopPattern();
if (auto self_param =
context.insts().TryGetAs<SemIR::AnyBindName>(self_param_id);
@@ -178,18 +176,18 @@ auto HandleAddr(Context& context, Parse::AddrId parse_node) -> bool {
// TODO: The type of an `addr_pattern` should probably be the non-pointer
// type, because that's the type that the pattern matches.
context.AddInstAndPush(
{parse_node, SemIR::AddrPattern{self_param->type_id, self_param_id}});
{node_id, SemIR::AddrPattern{self_param->type_id, self_param_id}});
} else {
CARBON_DIAGNOSTIC(AddrOnNonSelfParam, Error,
"`addr` can only be applied to a `self` parameter.");
context.emitter().Emit(TokenOnly(parse_node), AddrOnNonSelfParam);
context.node_stack().Push(parse_node, self_param_id);
context.emitter().Emit(TokenOnly(node_id), AddrOnNonSelfParam);
context.node_stack().Push(node_id, self_param_id);
}
return true;
}
auto HandleTemplate(Context& context, Parse::TemplateId parse_node) -> bool {
return context.TODO(parse_node, "HandleTemplate");
auto HandleTemplate(Context& context, Parse::TemplateId node_id) -> bool {
return context.TODO(node_id, "HandleTemplate");
}
} // namespace Carbon::Check
+16 -18
View File
@@ -9,40 +9,40 @@
namespace Carbon::Check {
auto HandleCallExprStart(Context& context, Parse::CallExprStartId parse_node)
auto HandleCallExprStart(Context& context, Parse::CallExprStartId node_id)
-> bool {
auto name_id = context.node_stack().PopExpr();
context.node_stack().Push(parse_node, name_id);
context.node_stack().Push(node_id, name_id);
context.param_and_arg_refs_stack().Push();
return true;
}
auto HandleCallExprComma(Context& context,
Parse::CallExprCommaId /*parse_node*/) -> bool {
auto HandleCallExprComma(Context& context, Parse::CallExprCommaId /*node_id*/)
-> bool {
context.param_and_arg_refs_stack().ApplyComma();
return true;
}
auto HandleCallExpr(Context& context, Parse::CallExprId parse_node) -> bool {
auto HandleCallExpr(Context& context, Parse::CallExprId node_id) -> bool {
// Process the final explicit call argument now, but leave the arguments
// block on the stack until the end of this function.
context.param_and_arg_refs_stack().EndNoPop(Parse::NodeKind::CallExprStart);
auto discard_args_block = llvm::make_scope_exit(
[&] { context.param_and_arg_refs_stack().PopAndDiscard(); });
auto [call_expr_parse_node, callee_id] =
context.node_stack().PopWithParseNode<Parse::NodeKind::CallExprStart>();
auto [call_expr_node_id, callee_id] =
context.node_stack().PopWithNodeId<Parse::NodeKind::CallExprStart>();
auto diagnose_not_callable = [&, call_expr_parse_node = call_expr_parse_node,
auto diagnose_not_callable = [&, call_expr_node_id = call_expr_node_id,
callee_id = callee_id] {
auto callee_type_id = context.insts().Get(callee_id).type_id();
if (callee_type_id != SemIR::TypeId::Error) {
CARBON_DIAGNOSTIC(CallToNonCallable, Error,
"Value of type `{0}` is not callable.", SemIR::TypeId);
context.emitter().Emit(call_expr_parse_node, CallToNonCallable,
context.emitter().Emit(call_expr_node_id, CallToNonCallable,
callee_type_id);
}
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinError);
return true;
};
@@ -81,22 +81,20 @@ auto HandleCallExpr(Context& context, Parse::CallExprId parse_node) -> bool {
if (callable.return_slot_id.is_valid()) {
// Tentatively put storage for a temporary in the function's return slot.
// This will be replaced if necessary when we perform initialization.
return_storage_id =
context.AddInst({call_expr_parse_node,
SemIR::TemporaryStorage{callable.return_type_id}});
return_storage_id = context.AddInst(
{call_expr_node_id, SemIR::TemporaryStorage{callable.return_type_id}});
}
// Convert the arguments to match the parameters.
auto converted_args_id = ConvertCallArgs(
context, call_expr_parse_node, self_id,
context, call_expr_node_id, self_id,
context.param_and_arg_refs_stack().PeekCurrentBlockContents(),
return_storage_id, function_decl_id.inst_id(),
callable.implicit_param_refs_id, callable.param_refs_id);
auto call_inst_id =
context.AddInst({call_expr_parse_node,
SemIR::Call{type_id, callee_id, converted_args_id}});
auto call_inst_id = context.AddInst(
{call_expr_node_id, SemIR::Call{type_id, callee_id, converted_args_id}});
context.node_stack().Push(parse_node, call_inst_id);
context.node_stack().Push(node_id, call_inst_id);
return true;
}
+10 -10
View File
@@ -6,25 +6,25 @@
namespace Carbon::Check {
auto HandleChoiceDefinition(Context& context,
Parse::ChoiceDefinitionId parse_node) -> bool {
return context.TODO(parse_node, "HandleChoiceDefinition");
auto HandleChoiceDefinition(Context& context, Parse::ChoiceDefinitionId node_id)
-> bool {
return context.TODO(node_id, "HandleChoiceDefinition");
}
auto HandleChoiceIntroducer(Context& context,
Parse::ChoiceIntroducerId parse_node) -> bool {
return context.TODO(parse_node, "HandleChoiceIntroducer");
auto HandleChoiceIntroducer(Context& context, Parse::ChoiceIntroducerId node_id)
-> bool {
return context.TODO(node_id, "HandleChoiceIntroducer");
}
auto HandleChoiceDefinitionStart(Context& context,
Parse::ChoiceDefinitionStartId parse_node)
Parse::ChoiceDefinitionStartId node_id)
-> bool {
return context.TODO(parse_node, "HandleChoiceDefinitionStart");
return context.TODO(node_id, "HandleChoiceDefinitionStart");
}
auto HandleChoiceAlternativeListComma(
Context& context, Parse::ChoiceAlternativeListCommaId parse_node) -> bool {
return context.TODO(parse_node, "HandleChoiceAlternativeListComma");
Context& context, Parse::ChoiceAlternativeListCommaId node_id) -> bool {
return context.TODO(node_id, "HandleChoiceAlternativeListComma");
}
} // namespace Carbon::Check
+35 -36
View File
@@ -9,31 +9,31 @@
namespace Carbon::Check {
auto HandleClassIntroducer(Context& context,
Parse::ClassIntroducerId parse_node) -> bool {
auto HandleClassIntroducer(Context& context, Parse::ClassIntroducerId node_id)
-> bool {
// Create an instruction block to hold the instructions created as part of the
// class signature, such as generic parameters.
context.inst_block_stack().Push();
// Push the bracketing node.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
// Optional modifiers and the name follow.
context.decl_state_stack().Push(DeclState::Class);
context.decl_name_stack().PushScopeAndStartName();
return true;
}
static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId parse_node)
static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id)
-> std::tuple<SemIR::ClassId, SemIR::InstId> {
if (context.node_stack().PopIf<Parse::NodeKind::TuplePattern>()) {
context.TODO(parse_node, "generic class");
context.TODO(node_id, "generic class");
}
if (context.node_stack().PopIf<Parse::NodeKind::ImplicitParamList>()) {
context.TODO(parse_node, "generic class");
context.TODO(node_id, "generic class");
}
auto name_context = context.decl_name_stack().FinishName();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ClassIntroducer>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::ClassIntroducer>();
// Process modifiers.
CheckAccessModifiersOnDecl(context, Lex::TokenKind::Class,
@@ -59,7 +59,7 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId parse_node)
// Add the class declaration.
auto class_decl = SemIR::ClassDecl{SemIR::TypeId::TypeType,
SemIR::ClassId::Invalid, decl_block_id};
auto class_decl_id = context.AddPlaceholderInst({parse_node, class_decl});
auto class_decl_id = context.AddPlaceholderInst({node_id, class_decl});
// Check whether this is a redeclaration.
auto existing_id =
@@ -79,7 +79,7 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId parse_node)
CARBON_DIAGNOSTIC(ClassRedeclarationDifferentIntroducerPrevious, Note,
"Previously declared here.");
context.emitter()
.Build(parse_node, ClassRedeclarationDifferentIntroducer)
.Build(node_id, ClassRedeclarationDifferentIntroducer)
.Note(existing_id, ClassRedeclarationDifferentIntroducerPrevious)
.Emit();
}
@@ -108,7 +108,7 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId parse_node)
}
// Write the class ID into the ClassDecl.
context.ReplaceInstBeforeConstantUse(class_decl_id, {parse_node, class_decl});
context.ReplaceInstBeforeConstantUse(class_decl_id, {node_id, class_decl});
if (is_new_class) {
// Build the `Self` type using the resulting type constant.
@@ -119,16 +119,15 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId parse_node)
return {class_decl.class_id, class_decl_id};
}
auto HandleClassDecl(Context& context, Parse::ClassDeclId parse_node) -> bool {
BuildClassDecl(context, parse_node);
auto HandleClassDecl(Context& context, Parse::ClassDeclId node_id) -> bool {
BuildClassDecl(context, node_id);
context.decl_name_stack().PopScope();
return true;
}
auto HandleClassDefinitionStart(Context& context,
Parse::ClassDefinitionStartId parse_node)
-> bool {
auto [class_id, class_decl_id] = BuildClassDecl(context, parse_node);
Parse::ClassDefinitionStartId node_id) -> bool {
auto [class_id, class_decl_id] = BuildClassDecl(context, node_id);
auto& class_info = context.classes().Get(class_id);
// Track that this declaration is the definition.
@@ -138,7 +137,7 @@ auto HandleClassDefinitionStart(Context& context,
CARBON_DIAGNOSTIC(ClassPreviousDefinition, Note,
"Previous definition was here.");
context.emitter()
.Build(parse_node, ClassRedefinition, class_info.name_id)
.Build(node_id, ClassRedefinition, class_info.name_id)
.Note(class_info.definition_id, ClassPreviousDefinition)
.Emit();
} else {
@@ -157,7 +156,7 @@ auto HandleClassDefinitionStart(Context& context,
context.types().GetInstId(class_info.self_type_id)});
context.inst_block_stack().Push();
context.node_stack().Push(parse_node, class_id);
context.node_stack().Push(node_id, class_id);
context.args_type_info_stack().Push();
// TODO: Handle the case where there's control flow in the class body. For
@@ -173,13 +172,13 @@ auto HandleClassDefinitionStart(Context& context,
return true;
}
auto HandleBaseIntroducer(Context& context,
Parse::BaseIntroducerId /*parse_node*/) -> bool {
auto HandleBaseIntroducer(Context& context, Parse::BaseIntroducerId /*node_id*/)
-> bool {
context.decl_state_stack().Push(DeclState::Base);
return true;
}
auto HandleBaseColon(Context& /*context*/, Parse::BaseColonId /*parse_node*/)
auto HandleBaseColon(Context& /*context*/, Parse::BaseColonId /*node_id*/)
-> bool {
return true;
}
@@ -209,23 +208,23 @@ static auto TryGetAsClass(Context& context, SemIR::TypeId type_id)
}
// Diagnoses an attempt to derive from a final type.
static auto DiagnoseBaseIsFinal(Context& context, Parse::NodeId parse_node,
static auto DiagnoseBaseIsFinal(Context& context, Parse::NodeId node_id,
SemIR::TypeId base_type_id) -> void {
CARBON_DIAGNOSTIC(BaseIsFinal, Error,
"Deriving from final type `{0}`. Base type must be an "
"`abstract` or `base` class.",
SemIR::TypeId);
context.emitter().Emit(parse_node, BaseIsFinal, base_type_id);
context.emitter().Emit(node_id, BaseIsFinal, base_type_id);
}
// Checks that the specified base type is valid.
static auto CheckBaseType(Context& context, Parse::NodeId parse_node,
static auto CheckBaseType(Context& context, Parse::NodeId node_id,
SemIR::InstId base_expr_id) -> BaseInfo {
auto base_type_id = ExprAsType(context, parse_node, base_expr_id);
auto base_type_id = ExprAsType(context, node_id, base_expr_id);
base_type_id = context.AsCompleteType(base_type_id, [&] {
CARBON_DIAGNOSTIC(IncompleteTypeInBaseDecl, Error,
"Base `{0}` is an incomplete type.", SemIR::TypeId);
return context.emitter().Build(parse_node, IncompleteTypeInBaseDecl,
return context.emitter().Build(node_id, IncompleteTypeInBaseDecl,
base_type_id);
});
@@ -241,11 +240,11 @@ static auto CheckBaseType(Context& context, Parse::NodeId parse_node,
// declaration as being final classes.
// TODO: Once we have a better idea of which types are considered to be
// classes, produce a better diagnostic for deriving from a non-class type.
DiagnoseBaseIsFinal(context, parse_node, base_type_id);
DiagnoseBaseIsFinal(context, node_id, base_type_id);
return BaseInfo::Error;
}
if (base_class_info->inheritance_kind == SemIR::Class::Final) {
DiagnoseBaseIsFinal(context, parse_node, base_type_id);
DiagnoseBaseIsFinal(context, node_id, base_type_id);
}
CARBON_CHECK(base_class_info->scope_id.is_valid())
@@ -253,9 +252,9 @@ static auto CheckBaseType(Context& context, Parse::NodeId parse_node,
return {.type_id = base_type_id, .scope_id = base_class_info->scope_id};
}
auto HandleBaseDecl(Context& context, Parse::BaseDeclId parse_node) -> bool {
auto HandleBaseDecl(Context& context, Parse::BaseDeclId node_id) -> bool {
auto [base_type_node_id, base_type_expr_id] =
context.node_stack().PopExprWithParseNode();
context.node_stack().PopExprWithNodeId();
// Process modifiers. `extend` is required, none others are allowed.
LimitModifiersOnDecl(context, KeywordModifierSet::Extend,
@@ -264,7 +263,7 @@ auto HandleBaseDecl(Context& context, Parse::BaseDeclId parse_node) -> bool {
if (!(modifiers & KeywordModifierSet::Extend)) {
CARBON_DIAGNOSTIC(BaseMissingExtend, Error,
"Missing `extend` before `base` declaration in class.");
context.emitter().Emit(parse_node, BaseMissingExtend);
context.emitter().Emit(node_id, BaseMissingExtend);
}
context.decl_state_stack().Pop(DeclState::Base);
@@ -272,7 +271,7 @@ auto HandleBaseDecl(Context& context, Parse::BaseDeclId parse_node) -> bool {
if (!enclosing_class_decl) {
CARBON_DIAGNOSTIC(BaseOutsideClass, Error,
"`base` declaration can only be used in a class.");
context.emitter().Emit(parse_node, BaseOutsideClass);
context.emitter().Emit(node_id, BaseOutsideClass);
return true;
}
@@ -284,7 +283,7 @@ auto HandleBaseDecl(Context& context, Parse::BaseDeclId parse_node) -> bool {
CARBON_DIAGNOSTIC(BasePrevious, Note,
"Previous `base` declaration is here.");
context.emitter()
.Build(parse_node, BaseRepeated)
.Build(node_id, BaseRepeated)
.Note(class_info.base_id, BasePrevious)
.Emit();
return true;
@@ -297,7 +296,7 @@ auto HandleBaseDecl(Context& context, Parse::BaseDeclId parse_node) -> bool {
auto field_type_id =
context.GetUnboundElementType(class_info.self_type_id, base_info.type_id);
class_info.base_id = context.AddInst(
{parse_node,
{node_id,
SemIR::BaseDecl{field_type_id, base_info.type_id,
SemIR::ElementIndex(context.args_type_info_stack()
.PeekCurrentBlockContents()
@@ -306,12 +305,12 @@ auto HandleBaseDecl(Context& context, Parse::BaseDeclId parse_node) -> bool {
// Add a corresponding field to the object representation of the class.
// TODO: Consider whether we want to use `partial T` here.
context.args_type_info_stack().AddInstId(context.AddInstInNoBlock(
{parse_node,
{node_id,
SemIR::StructTypeField{SemIR::NameId::Base, base_info.type_id}}));
// Bind the name `base` in the class to the base field.
context.decl_name_stack().AddNameToLookup(
context.decl_name_stack().MakeUnqualifiedName(parse_node,
context.decl_name_stack().MakeUnqualifiedName(node_id,
SemIR::NameId::Base),
class_info.base_id);
@@ -328,7 +327,7 @@ auto HandleBaseDecl(Context& context, Parse::BaseDeclId parse_node) -> bool {
}
auto HandleClassDefinition(Context& context,
Parse::ClassDefinitionId /*parse_node*/) -> bool {
Parse::ClassDefinitionId /*node_id*/) -> bool {
auto fields_id = context.args_type_info_stack().Pop();
auto class_id =
context.node_stack().Pop<Parse::NodeKind::ClassDefinitionStart>();
+4 -5
View File
@@ -6,18 +6,17 @@
namespace Carbon::Check {
auto HandleCodeBlockStart(Context& context, Parse::CodeBlockStartId parse_node)
auto HandleCodeBlockStart(Context& context, Parse::CodeBlockStartId node_id)
-> bool {
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
context.scope_stack().Push();
return true;
}
auto HandleCodeBlock(Context& context, Parse::CodeBlockId /*parse_node*/)
-> bool {
auto HandleCodeBlock(Context& context, Parse::CodeBlockId /*node_id*/) -> bool {
context.scope_stack().Pop();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::CodeBlockStart>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::CodeBlockStart>();
return true;
}
+3 -3
View File
@@ -15,14 +15,14 @@ static auto HandleDiscardedExpr(Context& context, SemIR::InstId expr_id)
// If we discard an initializing expression, convert it to a value or
// reference so that it has something to initialize.
auto expr = context.insts().Get(expr_id);
Convert(context, context.insts().GetParseNode(expr_id), expr_id,
Convert(context, context.insts().GetNodeId(expr_id), expr_id,
{.kind = ConversionTarget::Discarded, .type_id = expr.type_id()});
// TODO: This will eventually need to do some "do not discard" analysis.
}
auto HandleExprStatement(Context& context,
Parse::ExprStatementId /*parse_node*/) -> bool {
auto HandleExprStatement(Context& context, Parse::ExprStatementId /*node_id*/)
-> bool {
HandleDiscardedExpr(context, context.node_stack().PopExpr());
return true;
}
+2 -3
View File
@@ -6,7 +6,7 @@
namespace Carbon::Check {
auto HandleFileStart(Context& /*context*/, Parse::FileStartId /*parse_node*/)
auto HandleFileStart(Context& /*context*/, Parse::FileStartId /*node_id*/)
-> bool {
// No action to perform.
// TODO: We may want to push `FileStart` as a sentinel so that `Peek`s can't
@@ -14,8 +14,7 @@ auto HandleFileStart(Context& /*context*/, Parse::FileStartId /*parse_node*/)
return true;
}
auto HandleFileEnd(Context& /*context*/, Parse::FileEndId /*parse_node*/)
-> bool {
auto HandleFileEnd(Context& /*context*/, Parse::FileEndId /*node_id*/) -> bool {
// No action to perform.
return true;
}
+21 -24
View File
@@ -17,27 +17,25 @@
namespace Carbon::Check {
auto HandleFunctionIntroducer(Context& context,
Parse::FunctionIntroducerId parse_node) -> bool {
Parse::FunctionIntroducerId node_id) -> bool {
// Create an instruction block to hold the instructions created as part of the
// function signature, such as parameter and return types.
context.inst_block_stack().Push();
// Push the bracketing node.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
// Optional modifiers and the name follow.
context.decl_state_stack().Push(DeclState::Fn);
context.decl_name_stack().PushScopeAndStartName();
return true;
}
auto HandleReturnType(Context& context, Parse::ReturnTypeId parse_node)
-> bool {
auto HandleReturnType(Context& context, Parse::ReturnTypeId node_id) -> bool {
// Propagate the type expression.
auto [type_parse_node, type_inst_id] =
context.node_stack().PopExprWithParseNode();
auto type_id = ExprAsType(context, type_parse_node, type_inst_id);
auto [type_node_id, type_inst_id] = context.node_stack().PopExprWithNodeId();
auto type_id = ExprAsType(context, type_node_id, type_inst_id);
// TODO: Use a dedicated instruction rather than VarStorage here.
context.AddInstAndPush(
{parse_node, SemIR::VarStorage{type_id, SemIR::NameId::ReturnSlot}});
{node_id, SemIR::VarStorage{type_id, SemIR::NameId::ReturnSlot}});
return true;
}
@@ -60,7 +58,7 @@ static auto DiagnoseModifiers(Context& context,
// handles the common logic shared by function declaration syntax and function
// definition syntax.
static auto BuildFunctionDecl(Context& context,
Parse::AnyFunctionDeclId parse_node,
Parse::AnyFunctionDeclId node_id,
bool is_definition)
-> std::pair<SemIR::FunctionId, SemIR::InstId> {
auto decl_block_id = context.inst_block_stack().Pop();
@@ -68,8 +66,7 @@ static auto BuildFunctionDecl(Context& context,
auto return_type_id = SemIR::TypeId::Invalid;
auto return_slot_id = SemIR::InstId::Invalid;
if (auto [return_node, return_storage_id] =
context.node_stack()
.PopWithParseNodeIf<Parse::NodeKind::ReturnType>();
context.node_stack().PopWithNodeIdIf<Parse::NodeKind::ReturnType>();
return_storage_id) {
return_type_id = context.insts().Get(*return_storage_id).type_id();
@@ -96,7 +93,7 @@ static auto BuildFunctionDecl(Context& context,
SemIR::InstBlockId::Empty);
auto name_context = context.decl_name_stack().FinishName();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::FunctionIntroducer>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::FunctionIntroducer>();
// Process modifiers.
auto modifiers = DiagnoseModifiers(context, name_context.target_scope_id);
@@ -131,7 +128,7 @@ static auto BuildFunctionDecl(Context& context,
auto function_info = SemIR::Function{
.name_id = name_context.name_id_for_new_inst(),
.enclosing_scope_id = name_context.enclosing_scope_id_for_new_inst(),
.decl_id = context.AddPlaceholderInst({parse_node, function_decl}),
.decl_id = context.AddPlaceholderInst({node_id, function_decl}),
.implicit_param_refs_id = implicit_param_refs_id,
.param_refs_id = param_refs_id,
.return_type_id = return_type_id,
@@ -161,7 +158,7 @@ static auto BuildFunctionDecl(Context& context,
if (existing_id.is_valid()) {
if (auto existing_function_decl =
context.insts().Get(existing_id).TryAs<SemIR::FunctionDecl>()) {
if (MergeFunctionRedecl(context, parse_node, function_info,
if (MergeFunctionRedecl(context, node_id, function_info,
existing_function_decl->function_id,
is_definition)) {
// When merging, use the existing function rather than adding a new one.
@@ -182,7 +179,7 @@ static auto BuildFunctionDecl(Context& context,
// Write the function ID into the FunctionDecl.
context.ReplaceInstBeforeConstantUse(function_info.decl_id,
{parse_node, function_decl});
{node_id, function_decl});
if (SemIR::IsEntryPoint(context.sem_ir(), function_decl.function_id)) {
// TODO: Update this once valid signatures for the entry point are decided.
@@ -195,26 +192,26 @@ static auto BuildFunctionDecl(Context& context,
CARBON_DIAGNOSTIC(InvalidMainRunSignature, Error,
"Invalid signature for `Main.Run` function. Expected "
"`fn ()` or `fn () -> i32`.");
context.emitter().Emit(parse_node, InvalidMainRunSignature);
context.emitter().Emit(node_id, InvalidMainRunSignature);
}
}
return {function_decl.function_id, function_info.decl_id};
}
auto HandleFunctionDecl(Context& context, Parse::FunctionDeclId parse_node)
auto HandleFunctionDecl(Context& context, Parse::FunctionDeclId node_id)
-> bool {
BuildFunctionDecl(context, parse_node, /*is_definition=*/false);
BuildFunctionDecl(context, node_id, /*is_definition=*/false);
context.decl_name_stack().PopScope();
return true;
}
auto HandleFunctionDefinitionStart(Context& context,
Parse::FunctionDefinitionStartId parse_node)
Parse::FunctionDefinitionStartId node_id)
-> bool {
// Process the declaration portion of the function.
auto [function_id, decl_id] =
BuildFunctionDecl(context, parse_node, /*is_definition=*/true);
BuildFunctionDecl(context, node_id, /*is_definition=*/true);
auto& function = context.functions().Get(function_id);
// Create the function scope and the entry block.
@@ -247,12 +244,12 @@ auto HandleFunctionDefinitionStart(Context& context,
});
}
context.node_stack().Push(parse_node, function_id);
context.node_stack().Push(node_id, function_id);
return true;
}
auto HandleFunctionDefinition(Context& context,
Parse::FunctionDefinitionId parse_node) -> bool {
Parse::FunctionDefinitionId node_id) -> bool {
SemIR::FunctionId function_id =
context.node_stack().Pop<Parse::NodeKind::FunctionDefinitionStart>();
@@ -263,9 +260,9 @@ auto HandleFunctionDefinition(Context& context,
CARBON_DIAGNOSTIC(
MissingReturnStatement, Error,
"Missing `return` at end of function with declared return type.");
context.emitter().Emit(TokenOnly(parse_node), MissingReturnStatement);
context.emitter().Emit(TokenOnly(node_id), MissingReturnStatement);
} else {
context.AddInst({parse_node, SemIR::Return{}});
context.AddInst({node_id, SemIR::Return{}});
}
}
+12 -14
View File
@@ -7,9 +7,9 @@
namespace Carbon::Check {
auto HandleIfExprIf(Context& context, Parse::IfExprIfId parse_node) -> bool {
// Alias parse_node for if/then/else consistency.
auto& if_node = parse_node;
auto HandleIfExprIf(Context& context, Parse::IfExprIfId node_id) -> bool {
// Alias node_id for if/then/else consistency.
auto& if_node = node_id;
auto cond_value_id = context.node_stack().PopExpr();
@@ -22,14 +22,13 @@ auto HandleIfExprIf(Context& context, Parse::IfExprIfId parse_node) -> bool {
// Start emitting the `then` block.
context.inst_block_stack().Pop();
context.inst_block_stack().Push(then_block_id);
context.AddCurrentCodeBlockToFunction(parse_node);
context.AddCurrentCodeBlockToFunction(node_id);
context.node_stack().Push(if_node, else_block_id);
return true;
}
auto HandleIfExprThen(Context& context, Parse::IfExprThenId parse_node)
-> bool {
auto HandleIfExprThen(Context& context, Parse::IfExprThenId node_id) -> bool {
auto then_value_id = context.node_stack().PopExpr();
auto else_block_id = context.node_stack().Peek<Parse::NodeKind::IfExprIf>();
@@ -38,21 +37,20 @@ auto HandleIfExprThen(Context& context, Parse::IfExprThenId parse_node)
// Start emitting the `else` block.
context.inst_block_stack().Push(else_block_id);
context.AddCurrentCodeBlockToFunction(parse_node);
context.AddCurrentCodeBlockToFunction(node_id);
context.node_stack().Push(parse_node, then_value_id);
context.node_stack().Push(node_id, then_value_id);
return true;
}
auto HandleIfExprElse(Context& context, Parse::IfExprElseId parse_node)
-> bool {
// Alias parse_node for if/then/else consistency.
auto& else_node = parse_node;
auto HandleIfExprElse(Context& context, Parse::IfExprElseId node_id) -> bool {
// Alias node_id for if/then/else consistency.
auto& else_node = node_id;
auto else_value_id = context.node_stack().PopExpr();
auto then_value_id = context.node_stack().Pop<Parse::NodeKind::IfExprThen>();
auto [if_node, _] =
context.node_stack().PopWithParseNode<Parse::NodeKind::IfExprIf>();
context.node_stack().PopWithNodeId<Parse::NodeKind::IfExprIf>();
// Convert the `else` value to the `then` value's type, and finish the `else`
// block.
@@ -64,7 +62,7 @@ auto HandleIfExprElse(Context& context, Parse::IfExprElseId parse_node)
// Create a resumption block and branches to it.
auto chosen_value_id = context.AddConvergenceBlockWithArgAndPush(
if_node, {else_value_id, then_value_id});
context.AddCurrentCodeBlockToFunction(parse_node);
context.AddCurrentCodeBlockToFunction(node_id);
// Push the result value.
context.node_stack().Push(else_node, chosen_value_id);
+14 -16
View File
@@ -8,53 +8,51 @@
namespace Carbon::Check {
auto HandleIfConditionStart(Context& /*context*/,
Parse::IfConditionStartId /*parse_node*/) -> bool {
Parse::IfConditionStartId /*node_id*/) -> bool {
return true;
}
auto HandleIfCondition(Context& context, Parse::IfConditionId parse_node)
-> bool {
auto HandleIfCondition(Context& context, Parse::IfConditionId node_id) -> bool {
// Convert the condition to `bool`.
auto cond_value_id = context.node_stack().PopExpr();
cond_value_id = ConvertToBoolValue(context, parse_node, cond_value_id);
cond_value_id = ConvertToBoolValue(context, node_id, cond_value_id);
// Create the then block and the else block, and branch to the right one. If
// there is no `else`, the then block will terminate with a branch to the
// else block, which will be reused as the resumption block.
auto then_block_id =
context.AddDominatedBlockAndBranchIf(parse_node, cond_value_id);
auto else_block_id = context.AddDominatedBlockAndBranch(parse_node);
context.AddDominatedBlockAndBranchIf(node_id, cond_value_id);
auto else_block_id = context.AddDominatedBlockAndBranch(node_id);
// Start emitting the `then` block.
context.inst_block_stack().Pop();
context.inst_block_stack().Push(then_block_id);
context.AddCurrentCodeBlockToFunction();
context.node_stack().Push(parse_node, else_block_id);
context.node_stack().Push(node_id, else_block_id);
return true;
}
auto HandleIfStatementElse(Context& context,
Parse::IfStatementElseId parse_node) -> bool {
auto HandleIfStatementElse(Context& context, Parse::IfStatementElseId node_id)
-> bool {
auto else_block_id = context.node_stack().Pop<Parse::NodeKind::IfCondition>();
// Switch to emitting the `else` block.
context.inst_block_stack().Push(else_block_id);
context.AddCurrentCodeBlockToFunction();
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
return true;
}
auto HandleIfStatement(Context& context, Parse::IfStatementId parse_node)
-> bool {
switch (auto kind = context.node_stack().PeekParseNodeKind()) {
auto HandleIfStatement(Context& context, Parse::IfStatementId node_id) -> bool {
switch (auto kind = context.node_stack().PeekNodeKind()) {
case Parse::NodeKind::IfCondition: {
// Branch from then block to else block, and start emitting the else
// block.
auto else_block_id =
context.node_stack().Pop<Parse::NodeKind::IfCondition>();
context.AddInst({parse_node, SemIR::Branch{else_block_id}});
context.AddInst({node_id, SemIR::Branch{else_block_id}});
context.inst_block_stack().Pop();
context.inst_block_stack().Push(else_block_id);
break;
@@ -63,8 +61,8 @@ auto HandleIfStatement(Context& context, Parse::IfStatementId parse_node)
case Parse::NodeKind::IfStatementElse: {
// Branch from the then and else blocks to a new resumption block.
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::IfStatementElse>();
context.AddConvergenceBlockAndPush(parse_node, /*num_blocks=*/2);
.PopAndDiscardSoloNodeId<Parse::NodeKind::IfStatementElse>();
context.AddConvergenceBlockAndPush(node_id, /*num_blocks=*/2);
break;
}
+29 -32
View File
@@ -13,14 +13,14 @@
namespace Carbon::Check {
auto HandleImplIntroducer(Context& context, Parse::ImplIntroducerId parse_node)
auto HandleImplIntroducer(Context& context, Parse::ImplIntroducerId node_id)
-> bool {
// Create an instruction block to hold the instructions created for the type
// and interface.
context.inst_block_stack().Push();
// Push the bracketing node.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
// Optional modifiers follow.
context.decl_state_stack().Push(DeclState::Impl);
@@ -32,19 +32,17 @@ auto HandleImplIntroducer(Context& context, Parse::ImplIntroducerId parse_node)
return true;
}
auto HandleImplForall(Context& context, Parse::ImplForallId parse_node)
-> bool {
auto HandleImplForall(Context& context, Parse::ImplForallId node_id) -> bool {
auto params_id =
context.node_stack().Pop<Parse::NodeKind::ImplicitParamList>();
context.node_stack().Push(parse_node, params_id);
context.node_stack().Push(node_id, params_id);
return true;
}
auto HandleTypeImplAs(Context& context, Parse::TypeImplAsId parse_node)
-> bool {
auto [self_node, self_id] = context.node_stack().PopExprWithParseNode();
auto HandleTypeImplAs(Context& context, Parse::TypeImplAsId node_id) -> bool {
auto [self_node, self_id] = context.node_stack().PopExprWithNodeId();
auto self_type_id = ExprAsType(context, self_node, self_id);
context.node_stack().Push(parse_node, self_type_id);
context.node_stack().Push(node_id, self_type_id);
// TODO: `Self` should come into scope here, at least if it's not already in
// scope. Check the design for the latter case.
return true;
@@ -78,23 +76,23 @@ static auto GetDefaultSelfType(Context& context) -> SemIR::TypeId {
}
auto HandleDefaultSelfImplAs(Context& context,
Parse::DefaultSelfImplAsId parse_node) -> bool {
Parse::DefaultSelfImplAsId node_id) -> bool {
auto self_type_id = GetDefaultSelfType(context);
if (!self_type_id.is_valid()) {
CARBON_DIAGNOSTIC(ImplAsOutsideClass, Error,
"`impl as` can only be used in a class.");
context.emitter().Emit(parse_node, ImplAsOutsideClass);
context.emitter().Emit(node_id, ImplAsOutsideClass);
self_type_id = SemIR::TypeId::Error;
}
context.node_stack().Push(parse_node, self_type_id);
context.node_stack().Push(node_id, self_type_id);
return true;
}
// Process an `extend impl` declaration by extending the impl scope with the
// `impl`'s scope.
static auto ExtendImpl(Context& context, Parse::NodeId extend_node,
Parse::AnyImplDeclId parse_node,
Parse::AnyImplDeclId node_id,
Parse::NodeId self_type_node, SemIR::TypeId self_type_id,
Parse::NodeId params_node, SemIR::TypeId constraint_id)
-> void {
@@ -105,7 +103,7 @@ static auto ExtendImpl(Context& context, Parse::NodeId extend_node,
if (!TryAsClassScope(context, enclosing_scope_id)) {
CARBON_DIAGNOSTIC(ExtendImplOutsideClass, Error,
"`extend impl` can only be used in a class.");
context.emitter().Emit(parse_node, ExtendImplOutsideClass);
context.emitter().Emit(node_id, ExtendImplOutsideClass);
return;
}
@@ -144,7 +142,7 @@ static auto ExtendImpl(Context& context, Parse::NodeId extend_node,
auto interface_type =
context.types().TryGetAs<SemIR::InterfaceType>(constraint_id);
if (!interface_type) {
context.TODO(parse_node, "extending non-interface constraint");
context.TODO(node_id, "extending non-interface constraint");
enclosing_scope.has_error = true;
return;
}
@@ -155,7 +153,7 @@ static auto ExtendImpl(Context& context, Parse::NodeId extend_node,
ExtendUndefinedInterface, Error,
"`extend impl` requires a definition for interface `{0}`.",
SemIR::TypeId);
auto diag = context.emitter().Build(parse_node, ExtendUndefinedInterface,
auto diag = context.emitter().Build(node_id, ExtendUndefinedInterface,
constraint_id);
context.NoteUndefinedInterface(interface_type->interface_id, diag);
diag.Emit();
@@ -168,16 +166,16 @@ static auto ExtendImpl(Context& context, Parse::NodeId extend_node,
// Build an ImplDecl describing the signature of an impl. This handles the
// common logic shared by impl forward declarations and impl definitions.
static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId parse_node)
static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId node_id)
-> std::pair<SemIR::ImplId, SemIR::InstId> {
auto [constraint_node, constraint_id] =
context.node_stack().PopExprWithParseNode();
context.node_stack().PopExprWithNodeId();
auto [self_type_node, self_type_id] =
context.node_stack().PopWithParseNode<Parse::NodeCategory::ImplAs>();
context.node_stack().PopWithNodeId<Parse::NodeCategory::ImplAs>();
auto [params_node, params_id] =
context.node_stack().PopWithParseNodeIf<Parse::NodeKind::ImplForall>();
context.node_stack().PopWithNodeIdIf<Parse::NodeKind::ImplForall>();
auto decl_block_id = context.inst_block_stack().Pop();
context.node_stack().PopForSoloParseNode<Parse::NodeKind::ImplIntroducer>();
context.node_stack().PopForSoloNodeId<Parse::NodeKind::ImplIntroducer>();
// Convert the constraint expression to a type.
// TODO: Check that its constant value is a constraint.
@@ -204,14 +202,14 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId parse_node)
// in the api file?
auto impl_id = context.impls().LookupOrAdd(self_type_id, constraint_type_id);
auto impl_decl = SemIR::ImplDecl{impl_id, decl_block_id};
auto impl_decl_id = context.AddInst({parse_node, impl_decl});
auto impl_decl_id = context.AddInst({node_id, impl_decl});
// For an `extend impl` declaration, mark the impl as extending this `impl`.
if (!!(context.decl_state_stack().innermost().modifier_set &
KeywordModifierSet::Extend)) {
auto extend_node = context.decl_state_stack().innermost().modifier_node_id(
ModifierOrder::Decl);
ExtendImpl(context, extend_node, parse_node, self_type_node, self_type_id,
ExtendImpl(context, extend_node, node_id, self_type_node, self_type_id,
params_node, constraint_type_id);
}
@@ -220,16 +218,15 @@ static auto BuildImplDecl(Context& context, Parse::AnyImplDeclId parse_node)
return {impl_decl.impl_id, impl_decl_id};
}
auto HandleImplDecl(Context& context, Parse::ImplDeclId parse_node) -> bool {
BuildImplDecl(context, parse_node);
auto HandleImplDecl(Context& context, Parse::ImplDeclId node_id) -> bool {
BuildImplDecl(context, node_id);
context.decl_name_stack().PopScope();
return true;
}
auto HandleImplDefinitionStart(Context& context,
Parse::ImplDefinitionStartId parse_node)
-> bool {
auto [impl_id, impl_decl_id] = BuildImplDecl(context, parse_node);
Parse::ImplDefinitionStartId node_id) -> bool {
auto [impl_id, impl_decl_id] = BuildImplDecl(context, node_id);
auto& impl_info = context.impls().Get(impl_id);
if (impl_info.is_defined()) {
@@ -239,7 +236,7 @@ auto HandleImplDefinitionStart(Context& context,
CARBON_DIAGNOSTIC(ImplPreviousDefinition, Note,
"Previous definition was here.");
context.emitter()
.Build(parse_node, ImplRedefinition, impl_info.self_id,
.Build(node_id, ImplRedefinition, impl_info.self_id,
impl_info.constraint_id)
.Note(impl_info.definition_id, ImplPreviousDefinition)
.Emit();
@@ -253,7 +250,7 @@ auto HandleImplDefinitionStart(Context& context,
context.scope_stack().Push(impl_decl_id, impl_info.scope_id);
context.inst_block_stack().Push();
context.node_stack().Push(parse_node, impl_id);
context.node_stack().Push(node_id, impl_id);
// TODO: Handle the case where there's control flow in the impl body. For
// example:
@@ -268,8 +265,8 @@ auto HandleImplDefinitionStart(Context& context,
return true;
}
auto HandleImplDefinition(Context& context,
Parse::ImplDefinitionId /*parse_node*/) -> bool {
auto HandleImplDefinition(Context& context, Parse::ImplDefinitionId /*node_id*/)
-> bool {
auto impl_id =
context.node_stack().Pop<Parse::NodeKind::ImplDefinitionStart>();
+25 -27
View File
@@ -10,64 +10,62 @@ namespace Carbon::Check {
// checking logic is needed here.
auto HandleImportIntroducer(Context& /*context*/,
Parse::ImportIntroducerId /*parse_node*/) -> bool {
Parse::ImportIntroducerId /*node_id*/) -> bool {
return true;
}
auto HandleImportDirective(Context& /*context*/,
Parse::ImportDirectiveId /*parse_node*/) -> bool {
Parse::ImportDirectiveId /*node_id*/) -> bool {
return true;
}
auto HandleLibraryIntroducer(Context& /*context*/,
Parse::LibraryIntroducerId /*parse_node*/)
-> bool {
Parse::LibraryIntroducerId /*node_id*/) -> bool {
return true;
}
auto HandleLibraryDirective(Context& /*context*/,
Parse::LibraryDirectiveId /*parse_node*/) -> bool {
Parse::LibraryDirectiveId /*node_id*/) -> bool {
return true;
}
auto HandlePackageIntroducer(Context& /*context*/,
Parse::PackageIntroducerId /*parse_node*/)
-> bool {
Parse::PackageIntroducerId /*node_id*/) -> bool {
return true;
}
auto HandlePackageDirective(Context& /*context*/,
Parse::PackageDirectiveId /*parse_node*/) -> bool {
Parse::PackageDirectiveId /*node_id*/) -> bool {
return true;
}
auto HandleLibrarySpecifier(Context& /*context*/,
Parse::LibrarySpecifierId /*parse_node*/) -> bool {
Parse::LibrarySpecifierId /*node_id*/) -> bool {
return true;
}
auto HandlePackageName(Context& /*context*/,
Parse::PackageNameId /*parse_node*/) -> bool {
return true;
}
auto HandleLibraryName(Context& /*context*/,
Parse::LibraryNameId /*parse_node*/) -> bool {
return true;
}
auto HandleDefaultLibrary(Context& /*context*/,
Parse::DefaultLibraryId /*parse_node*/) -> bool {
return true;
}
auto HandlePackageApi(Context& /*context*/, Parse::PackageApiId /*parse_node*/)
auto HandlePackageName(Context& /*context*/, Parse::PackageNameId /*node_id*/)
-> bool {
return true;
}
auto HandlePackageImpl(Context& /*context*/,
Parse::PackageImplId /*parse_node*/) -> bool {
auto HandleLibraryName(Context& /*context*/, Parse::LibraryNameId /*node_id*/)
-> bool {
return true;
}
auto HandleDefaultLibrary(Context& /*context*/,
Parse::DefaultLibraryId /*node_id*/) -> bool {
return true;
}
auto HandlePackageApi(Context& /*context*/, Parse::PackageApiId /*node_id*/)
-> bool {
return true;
}
auto HandlePackageImpl(Context& /*context*/, Parse::PackageImplId /*node_id*/)
-> bool {
return true;
}
+17 -17
View File
@@ -10,14 +10,14 @@
namespace Carbon::Check {
auto HandleIndexExprStart(Context& /*context*/,
Parse::IndexExprStartId /*parse_node*/) -> bool {
Parse::IndexExprStartId /*node_id*/) -> bool {
// Leave the expression on the stack for IndexExpr.
return true;
}
// Validates that the index (required to be an IntLiteral) is valid within the
// tuple size. Returns the index on success, or nullptr on failure.
static auto ValidateTupleIndex(Context& context, Parse::NodeId parse_node,
static auto ValidateTupleIndex(Context& context, Parse::NodeId node_id,
SemIR::Inst operand_inst,
SemIR::IntLiteral index_inst, int size)
-> const llvm::APInt* {
@@ -27,7 +27,7 @@ static auto ValidateTupleIndex(Context& context, Parse::NodeId parse_node,
TupleIndexOutOfBounds, Error,
"Tuple element index `{0}` is past the end of type `{1}`.",
llvm::APSInt, SemIR::TypeId);
context.emitter().Emit(parse_node, TupleIndexOutOfBounds,
context.emitter().Emit(node_id, TupleIndexOutOfBounds,
llvm::APSInt(index_val, /*isUnsigned=*/true),
operand_inst.type_id());
return nullptr;
@@ -35,7 +35,7 @@ static auto ValidateTupleIndex(Context& context, Parse::NodeId parse_node,
return &index_val;
}
auto HandleIndexExpr(Context& context, Parse::IndexExprId parse_node) -> bool {
auto HandleIndexExpr(Context& context, Parse::IndexExprId node_id) -> bool {
auto index_inst_id = context.node_stack().PopExpr();
auto operand_inst_id = context.node_stack().PopExpr();
operand_inst_id = ConvertToValueOrRefExpr(context, operand_inst_id);
@@ -46,9 +46,9 @@ auto HandleIndexExpr(Context& context, Parse::IndexExprId parse_node) -> bool {
switch (operand_type_inst.kind()) {
case SemIR::ArrayType::Kind: {
auto array_type = operand_type_inst.As<SemIR::ArrayType>();
auto index_parse_node = context.insts().GetParseNode(index_inst_id);
auto index_node_id = context.insts().GetNodeId(index_inst_id);
auto cast_index_id = ConvertToValueOfType(
context, index_parse_node, index_inst_id,
context, index_node_id, index_inst_id,
context.GetBuiltinType(SemIR::BuiltinKind::IntType));
auto array_cat =
SemIR::GetExprCategory(context.sem_ir(), operand_inst_id);
@@ -56,13 +56,13 @@ auto HandleIndexExpr(Context& context, Parse::IndexExprId parse_node) -> bool {
// If the operand is an array value, convert it to an ephemeral
// reference to an array so we can perform a primitive indexing into it.
operand_inst_id = context.AddInst(
{parse_node, SemIR::ValueAsRef{operand_type_id, operand_inst_id}});
{node_id, SemIR::ValueAsRef{operand_type_id, operand_inst_id}});
}
// Constant evaluation will perform a bounds check on this array indexing
// if the index is constant.
auto elem_id = context.AddInst(
{parse_node, SemIR::ArrayIndex{array_type.element_type_id,
operand_inst_id, cast_index_id}});
{node_id, SemIR::ArrayIndex{array_type.element_type_id,
operand_inst_id, cast_index_id}});
if (array_cat != SemIR::ExprCategory::DurableRef) {
// Indexing a durable reference gives a durable reference expression.
// Indexing anything else gives a value expression.
@@ -70,14 +70,14 @@ auto HandleIndexExpr(Context& context, Parse::IndexExprId parse_node) -> bool {
// and `IndirectIndexWith`.
elem_id = ConvertToValueExpr(context, elem_id);
}
context.node_stack().Push(parse_node, elem_id);
context.node_stack().Push(node_id, elem_id);
return true;
}
case SemIR::TupleType::Kind: {
SemIR::TypeId element_type_id = SemIR::TypeId::Error;
auto index_parse_node = context.insts().GetParseNode(index_inst_id);
auto index_node_id = context.insts().GetNodeId(index_inst_id);
index_inst_id = ConvertToValueOfType(
context, index_parse_node, index_inst_id,
context, index_node_id, index_inst_id,
context.GetBuiltinType(SemIR::BuiltinKind::IntType));
auto index_const_id = context.constant_values().Get(index_inst_id);
if (index_const_id == SemIR::ConstantId::Error) {
@@ -86,7 +86,7 @@ auto HandleIndexExpr(Context& context, Parse::IndexExprId parse_node) -> bool {
// TODO: Decide what to do if the index is a symbolic constant.
CARBON_DIAGNOSTIC(TupleIndexNotConstant, Error,
"Tuple index must be a constant.");
context.emitter().Emit(parse_node, TupleIndexNotConstant);
context.emitter().Emit(node_id, TupleIndexNotConstant);
index_inst_id = SemIR::InstId::BuiltinError;
} else {
auto index_literal =
@@ -94,7 +94,7 @@ auto HandleIndexExpr(Context& context, Parse::IndexExprId parse_node) -> bool {
auto type_block = context.type_blocks().Get(
operand_type_inst.As<SemIR::TupleType>().elements_id);
if (const auto* index_val =
ValidateTupleIndex(context, parse_node, operand_inst,
ValidateTupleIndex(context, node_id, operand_inst,
index_literal, type_block.size())) {
element_type_id = type_block[index_val->getZExtValue()];
} else {
@@ -102,7 +102,7 @@ auto HandleIndexExpr(Context& context, Parse::IndexExprId parse_node) -> bool {
}
}
context.AddInstAndPush(
{parse_node,
{node_id,
SemIR::TupleIndex{element_type_id, operand_inst_id, index_inst_id}});
return true;
}
@@ -111,9 +111,9 @@ auto HandleIndexExpr(Context& context, Parse::IndexExprId parse_node) -> bool {
CARBON_DIAGNOSTIC(TypeNotIndexable, Error,
"Type `{0}` does not support indexing.",
SemIR::TypeId);
context.emitter().Emit(parse_node, TypeNotIndexable, operand_type_id);
context.emitter().Emit(node_id, TypeNotIndexable, operand_type_id);
}
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinError);
return true;
}
}
+17 -18
View File
@@ -10,13 +10,12 @@
namespace Carbon::Check {
auto HandleInterfaceIntroducer(Context& context,
Parse::InterfaceIntroducerId parse_node)
-> bool {
Parse::InterfaceIntroducerId node_id) -> bool {
// Create an instruction block to hold the instructions created as part of the
// interface signature, such as generic parameters.
context.inst_block_stack().Push();
// Push the bracketing node.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
// Optional modifiers and the name follow.
context.decl_state_stack().Push(DeclState::Interface);
context.decl_name_stack().PushScopeAndStartName();
@@ -24,18 +23,18 @@ auto HandleInterfaceIntroducer(Context& context,
}
static auto BuildInterfaceDecl(Context& context,
Parse::AnyInterfaceDeclId parse_node)
Parse::AnyInterfaceDeclId node_id)
-> std::tuple<SemIR::InterfaceId, SemIR::InstId> {
if (context.node_stack().PopIf<Parse::NodeKind::TuplePattern>()) {
context.TODO(parse_node, "generic interface");
context.TODO(node_id, "generic interface");
}
if (context.node_stack().PopIf<Parse::NodeKind::ImplicitParamList>()) {
context.TODO(parse_node, "generic interface");
context.TODO(node_id, "generic interface");
}
auto name_context = context.decl_name_stack().FinishName();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::InterfaceIntroducer>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::InterfaceIntroducer>();
// Process modifiers.
CheckAccessModifiersOnDecl(context, Lex::TokenKind::Interface,
@@ -57,7 +56,7 @@ static auto BuildInterfaceDecl(Context& context,
auto interface_decl = SemIR::InterfaceDecl{
SemIR::TypeId::TypeType, SemIR::InterfaceId::Invalid, decl_block_id};
auto interface_decl_id =
context.AddPlaceholderInst({parse_node, interface_decl});
context.AddPlaceholderInst({node_id, interface_decl});
// Check whether this is a redeclaration.
auto existing_id = context.decl_name_stack().LookupOrAddName(
@@ -91,22 +90,22 @@ static auto BuildInterfaceDecl(Context& context,
// Write the interface ID into the InterfaceDecl.
context.ReplaceInstBeforeConstantUse(interface_decl_id,
{parse_node, interface_decl});
{node_id, interface_decl});
return {interface_decl.interface_id, interface_decl_id};
}
auto HandleInterfaceDecl(Context& context, Parse::InterfaceDeclId parse_node)
auto HandleInterfaceDecl(Context& context, Parse::InterfaceDeclId node_id)
-> bool {
BuildInterfaceDecl(context, parse_node);
BuildInterfaceDecl(context, node_id);
context.decl_name_stack().PopScope();
return true;
}
auto HandleInterfaceDefinitionStart(
Context& context, Parse::InterfaceDefinitionStartId parse_node) -> bool {
auto [interface_id, interface_decl_id] =
BuildInterfaceDecl(context, parse_node);
auto HandleInterfaceDefinitionStart(Context& context,
Parse::InterfaceDefinitionStartId node_id)
-> bool {
auto [interface_id, interface_decl_id] = BuildInterfaceDecl(context, node_id);
auto& interface_info = context.interfaces().Get(interface_id);
// Track that this declaration is the definition.
@@ -116,7 +115,7 @@ auto HandleInterfaceDefinitionStart(
CARBON_DIAGNOSTIC(InterfacePreviousDefinition, Note,
"Previous definition was here.");
context.emitter()
.Build(parse_node, InterfaceRedefinition, interface_info.name_id)
.Build(node_id, InterfaceRedefinition, interface_info.name_id)
.Note(interface_info.definition_id, InterfacePreviousDefinition)
.Emit();
} else {
@@ -130,7 +129,7 @@ auto HandleInterfaceDefinitionStart(
context.scope_stack().Push(interface_decl_id, interface_info.scope_id);
context.inst_block_stack().Push();
context.node_stack().Push(parse_node, interface_id);
context.node_stack().Push(node_id, interface_id);
// We use the arg stack to build the witness table type.
context.args_type_info_stack().Push();
@@ -171,7 +170,7 @@ auto HandleInterfaceDefinitionStart(
}
auto HandleInterfaceDefinition(Context& context,
Parse::InterfaceDefinitionId /*parse_node*/)
Parse::InterfaceDefinitionId /*node_id*/)
-> bool {
auto interface_id =
context.node_stack().Pop<Parse::NodeKind::InterfaceDefinitionStart>();
+19 -19
View File
@@ -12,23 +12,23 @@
namespace Carbon::Check {
auto HandleLetIntroducer(Context& context, Parse::LetIntroducerId parse_node)
auto HandleLetIntroducer(Context& context, Parse::LetIntroducerId node_id)
-> bool {
context.decl_state_stack().Push(DeclState::Let);
// Push a bracketing node to establish the pattern context.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
return true;
}
auto HandleLetInitializer(Context& context, Parse::LetInitializerId parse_node)
auto HandleLetInitializer(Context& context, Parse::LetInitializerId node_id)
-> bool {
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
return true;
}
static auto BuildAssociatedConstantDecl(
Context& context, Parse::LetDeclId parse_node, SemIR::InstId pattern_id,
SemIR::ParseNodeAndInst pattern, SemIR::InterfaceId interface_id) -> void {
Context& context, Parse::LetDeclId node_id, SemIR::InstId pattern_id,
SemIR::NodeIdAndInst pattern, SemIR::InterfaceId interface_id) -> void {
auto& interface_info = context.interfaces().Get(interface_id);
auto binding_pattern = pattern.inst.TryAs<SemIR::BindSymbolicName>();
@@ -36,7 +36,7 @@ static auto BuildAssociatedConstantDecl(
CARBON_DIAGNOSTIC(ExpectedSymbolicBindingInAssociatedConstant, Error,
"Pattern in associated constant declaration must be a "
"single `:!` binding.");
context.emitter().Emit(pattern.parse_node,
context.emitter().Emit(pattern.node_id,
ExpectedSymbolicBindingInAssociatedConstant);
context.name_scopes().Get(interface_info.scope_id).has_error = true;
return;
@@ -47,33 +47,33 @@ static auto BuildAssociatedConstantDecl(
auto name_id =
context.bind_names().Get(binding_pattern->bind_name_id).name_id;
context.ReplaceInstBeforeConstantUse(
pattern_id, {parse_node, SemIR::AssociatedConstantDecl{
binding_pattern->type_id, name_id}});
pattern_id, {node_id, SemIR::AssociatedConstantDecl{
binding_pattern->type_id, name_id}});
auto decl_id = pattern_id;
context.inst_block_stack().AddInstId(decl_id);
// Add an associated entity name to the interface scope.
auto assoc_id = BuildAssociatedEntity(context, interface_id, decl_id);
auto name_context = context.decl_name_stack().MakeUnqualifiedName(
pattern.parse_node, name_id);
auto name_context =
context.decl_name_stack().MakeUnqualifiedName(pattern.node_id, name_id);
context.decl_name_stack().AddNameToLookup(name_context, assoc_id);
}
auto HandleLetDecl(Context& context, Parse::LetDeclId parse_node) -> bool {
auto HandleLetDecl(Context& context, Parse::LetDeclId node_id) -> bool {
// Pop the optional initializer.
std::optional<SemIR::InstId> value_id;
if (context.node_stack().PeekNextIs<Parse::NodeKind::LetInitializer>()) {
value_id = context.node_stack().PopExpr();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::LetInitializer>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::LetInitializer>();
}
if (context.node_stack().PeekIs<Parse::NodeKind::TuplePattern>()) {
return context.TODO(parse_node, "tuple pattern in let");
return context.TODO(node_id, "tuple pattern in let");
}
SemIR::InstId pattern_id = context.node_stack().PopPattern();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::LetIntroducer>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::LetIntroducer>();
// Process declaration modifiers.
// TODO: For a qualified `let` declaration, this should use the target scope
// of the name introduced in the declaration. See #2590.
@@ -98,19 +98,19 @@ auto HandleLetDecl(Context& context, Parse::LetDeclId parse_node) -> bool {
}
context.decl_state_stack().Pop(DeclState::Let);
auto pattern = context.insts().GetWithParseNode(pattern_id);
auto pattern = context.insts().GetWithNodeId(pattern_id);
auto interface_scope = context.GetCurrentScopeAs<SemIR::InterfaceDecl>();
if (value_id) {
// Convert the value to match the type of the pattern.
value_id = ConvertToValueOfType(context, parse_node, *value_id,
value_id = ConvertToValueOfType(context, node_id, *value_id,
pattern.inst.type_id());
}
// At interface scope, we are forming an associated constant, which has
// different rules.
if (interface_scope) {
BuildAssociatedConstantDecl(context, parse_node, pattern_id, pattern,
BuildAssociatedConstantDecl(context, node_id, pattern_id, pattern,
interface_scope->interface_id);
return true;
}
@@ -119,7 +119,7 @@ auto HandleLetDecl(Context& context, Parse::LetDeclId parse_node) -> bool {
CARBON_DIAGNOSTIC(
ExpectedInitializerAfterLet, Error,
"Expected `=`; `let` declaration must have an initializer.");
context.emitter().Emit(Parse::TokenOnly(parse_node),
context.emitter().Emit(Parse::TokenOnly(node_id),
ExpectedInitializerAfterLet);
value_id = SemIR::InstId::BuiltinError;
}
+44 -46
View File
@@ -6,103 +6,101 @@
namespace Carbon::Check {
auto HandleBoolLiteralFalse(Context& context,
Parse::BoolLiteralFalseId parse_node) -> bool {
auto HandleBoolLiteralFalse(Context& context, Parse::BoolLiteralFalseId node_id)
-> bool {
context.AddInstAndPush(
{parse_node,
{node_id,
SemIR::BoolLiteral{context.GetBuiltinType(SemIR::BuiltinKind::BoolType),
SemIR::BoolValue::False}});
return true;
}
auto HandleBoolLiteralTrue(Context& context,
Parse::BoolLiteralTrueId parse_node) -> bool {
auto HandleBoolLiteralTrue(Context& context, Parse::BoolLiteralTrueId node_id)
-> bool {
context.AddInstAndPush(
{parse_node,
{node_id,
SemIR::BoolLiteral{context.GetBuiltinType(SemIR::BuiltinKind::BoolType),
SemIR::BoolValue::True}});
return true;
}
auto HandleIntLiteral(Context& context, Parse::IntLiteralId parse_node)
-> bool {
auto HandleIntLiteral(Context& context, Parse::IntLiteralId node_id) -> bool {
context.AddInstAndPush(
{parse_node,
{node_id,
SemIR::IntLiteral{context.GetBuiltinType(SemIR::BuiltinKind::IntType),
context.tokens().GetIntLiteral(
context.parse_tree().node_token(parse_node))}});
context.parse_tree().node_token(node_id))}});
return true;
}
auto HandleRealLiteral(Context& context, Parse::RealLiteralId parse_node)
-> bool {
auto HandleRealLiteral(Context& context, Parse::RealLiteralId node_id) -> bool {
context.AddInstAndPush(
{parse_node,
{node_id,
SemIR::RealLiteral{context.GetBuiltinType(SemIR::BuiltinKind::FloatType),
context.tokens().GetRealLiteral(
context.parse_tree().node_token(parse_node))}});
context.parse_tree().node_token(node_id))}});
return true;
}
auto HandleStringLiteral(Context& context, Parse::StringLiteralId parse_node)
auto HandleStringLiteral(Context& context, Parse::StringLiteralId node_id)
-> bool {
context.AddInstAndPush(
{parse_node, SemIR::StringLiteral{
context.GetBuiltinType(SemIR::BuiltinKind::StringType),
context.tokens().GetStringLiteralValue(
context.parse_tree().node_token(parse_node))}});
{node_id, SemIR::StringLiteral{
context.GetBuiltinType(SemIR::BuiltinKind::StringType),
context.tokens().GetStringLiteralValue(
context.parse_tree().node_token(node_id))}});
return true;
}
auto HandleBoolTypeLiteral(Context& context,
Parse::BoolTypeLiteralId parse_node) -> bool {
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinBoolType);
return true;
}
auto HandleIntTypeLiteral(Context& context, Parse::IntTypeLiteralId parse_node)
auto HandleBoolTypeLiteral(Context& context, Parse::BoolTypeLiteralId node_id)
-> bool {
auto text = context.tokens().GetTokenText(
context.parse_tree().node_token(parse_node));
context.node_stack().Push(node_id, SemIR::InstId::BuiltinBoolType);
return true;
}
auto HandleIntTypeLiteral(Context& context, Parse::IntTypeLiteralId node_id)
-> bool {
auto text =
context.tokens().GetTokenText(context.parse_tree().node_token(node_id));
if (text != "i32") {
return context.TODO(parse_node, "Currently only i32 is allowed");
return context.TODO(node_id, "Currently only i32 is allowed");
}
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinIntType);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinIntType);
return true;
}
auto HandleUnsignedIntTypeLiteral(Context& context,
Parse::UnsignedIntTypeLiteralId parse_node)
Parse::UnsignedIntTypeLiteralId node_id)
-> bool {
return context.TODO(parse_node, "Need to support unsigned type literals");
return context.TODO(node_id, "Need to support unsigned type literals");
}
auto HandleFloatTypeLiteral(Context& context,
Parse::FloatTypeLiteralId parse_node) -> bool {
auto text = context.tokens().GetTokenText(
context.parse_tree().node_token(parse_node));
auto HandleFloatTypeLiteral(Context& context, Parse::FloatTypeLiteralId node_id)
-> bool {
auto text =
context.tokens().GetTokenText(context.parse_tree().node_token(node_id));
if (text != "f64") {
return context.TODO(parse_node, "Currently only f64 is allowed");
return context.TODO(node_id, "Currently only f64 is allowed");
}
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinFloatType);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinFloatType);
return true;
}
auto HandleStringTypeLiteral(Context& context,
Parse::StringTypeLiteralId parse_node) -> bool {
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinStringType);
Parse::StringTypeLiteralId node_id) -> bool {
context.node_stack().Push(node_id, SemIR::InstId::BuiltinStringType);
return true;
}
auto HandleTypeTypeLiteral(Context& context,
Parse::TypeTypeLiteralId parse_node) -> bool {
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinTypeType);
auto HandleTypeTypeLiteral(Context& context, Parse::TypeTypeLiteralId node_id)
-> bool {
context.node_stack().Push(node_id, SemIR::InstId::BuiltinTypeType);
return true;
}
auto HandleAutoTypeLiteral(Context& context,
Parse::AutoTypeLiteralId parse_node) -> bool {
return context.TODO(parse_node, "HandleAutoTypeLiteral");
auto HandleAutoTypeLiteral(Context& context, Parse::AutoTypeLiteralId node_id)
-> bool {
return context.TODO(node_id, "HandleAutoTypeLiteral");
}
} // namespace Carbon::Check
+26 -29
View File
@@ -11,33 +11,32 @@ namespace Carbon::Check {
// -------
auto HandleWhileConditionStart(Context& context,
Parse::WhileConditionStartId parse_node)
-> bool {
Parse::WhileConditionStartId node_id) -> bool {
// Branch to the loop header block. Note that we create a new block here even
// if the current block is empty; this ensures that the loop always has a
// preheader block.
auto loop_header_id = context.AddDominatedBlockAndBranch(parse_node);
auto loop_header_id = context.AddDominatedBlockAndBranch(node_id);
context.inst_block_stack().Pop();
// Start emitting the loop header block.
context.inst_block_stack().Push(loop_header_id);
context.AddCurrentCodeBlockToFunction();
context.node_stack().Push(parse_node, loop_header_id);
context.node_stack().Push(node_id, loop_header_id);
return true;
}
auto HandleWhileCondition(Context& context, Parse::WhileConditionId parse_node)
auto HandleWhileCondition(Context& context, Parse::WhileConditionId node_id)
-> bool {
auto cond_value_id = context.node_stack().PopExpr();
auto loop_header_id =
context.node_stack().Peek<Parse::NodeKind::WhileConditionStart>();
cond_value_id = ConvertToBoolValue(context, parse_node, cond_value_id);
cond_value_id = ConvertToBoolValue(context, node_id, cond_value_id);
// Branch to either the loop body or the loop exit block.
auto loop_body_id =
context.AddDominatedBlockAndBranchIf(parse_node, cond_value_id);
auto loop_exit_id = context.AddDominatedBlockAndBranch(parse_node);
context.AddDominatedBlockAndBranchIf(node_id, cond_value_id);
auto loop_exit_id = context.AddDominatedBlockAndBranch(node_id);
context.inst_block_stack().Pop();
// Start emitting the loop body.
@@ -46,11 +45,11 @@ auto HandleWhileCondition(Context& context, Parse::WhileConditionId parse_node)
context.break_continue_stack().push_back(
{.break_target = loop_exit_id, .continue_target = loop_header_id});
context.node_stack().Push(parse_node, loop_exit_id);
context.node_stack().Push(node_id, loop_exit_id);
return true;
}
auto HandleWhileStatement(Context& context, Parse::WhileStatementId parse_node)
auto HandleWhileStatement(Context& context, Parse::WhileStatementId node_id)
-> bool {
auto loop_exit_id =
context.node_stack().Pop<Parse::NodeKind::WhileCondition>();
@@ -59,7 +58,7 @@ auto HandleWhileStatement(Context& context, Parse::WhileStatementId parse_node)
context.break_continue_stack().pop_back();
// Add the loop backedge.
context.AddInst({parse_node, SemIR::Branch{loop_header_id}});
context.AddInst({node_id, SemIR::Branch{loop_header_id}});
context.inst_block_stack().Pop();
// Start emitting the loop exit block.
@@ -71,38 +70,37 @@ auto HandleWhileStatement(Context& context, Parse::WhileStatementId parse_node)
// `for`
// -----
auto HandleForHeaderStart(Context& context, Parse::ForHeaderStartId parse_node)
auto HandleForHeaderStart(Context& context, Parse::ForHeaderStartId node_id)
-> bool {
return context.TODO(parse_node, "HandleForHeaderStart");
return context.TODO(node_id, "HandleForHeaderStart");
}
auto HandleForIn(Context& context, Parse::ForInId parse_node) -> bool {
auto HandleForIn(Context& context, Parse::ForInId node_id) -> bool {
context.decl_state_stack().Pop(DeclState::Var);
return context.TODO(parse_node, "HandleForIn");
return context.TODO(node_id, "HandleForIn");
}
auto HandleForHeader(Context& context, Parse::ForHeaderId parse_node) -> bool {
return context.TODO(parse_node, "HandleForHeader");
auto HandleForHeader(Context& context, Parse::ForHeaderId node_id) -> bool {
return context.TODO(node_id, "HandleForHeader");
}
auto HandleForStatement(Context& context, Parse::ForStatementId parse_node)
auto HandleForStatement(Context& context, Parse::ForStatementId node_id)
-> bool {
return context.TODO(parse_node, "HandleForStatement");
return context.TODO(node_id, "HandleForStatement");
}
// `break`
// -------
auto HandleBreakStatementStart(Context& context,
Parse::BreakStatementStartId parse_node)
-> bool {
Parse::BreakStatementStartId node_id) -> bool {
auto& stack = context.break_continue_stack();
if (stack.empty()) {
CARBON_DIAGNOSTIC(BreakOutsideLoop, Error,
"`break` can only be used in a loop.");
context.emitter().Emit(parse_node, BreakOutsideLoop);
context.emitter().Emit(node_id, BreakOutsideLoop);
} else {
context.AddInst({parse_node, SemIR::Branch{stack.back().break_target}});
context.AddInst({node_id, SemIR::Branch{stack.back().break_target}});
}
context.inst_block_stack().Pop();
@@ -111,7 +109,7 @@ auto HandleBreakStatementStart(Context& context,
}
auto HandleBreakStatement(Context& /*context*/,
Parse::BreakStatementId /*parse_node*/) -> bool {
Parse::BreakStatementId /*node_id*/) -> bool {
return true;
}
@@ -119,15 +117,15 @@ auto HandleBreakStatement(Context& /*context*/,
// ----------
auto HandleContinueStatementStart(Context& context,
Parse::ContinueStatementStartId parse_node)
Parse::ContinueStatementStartId node_id)
-> bool {
auto& stack = context.break_continue_stack();
if (stack.empty()) {
CARBON_DIAGNOSTIC(ContinueOutsideLoop, Error,
"`continue` can only be used in a loop.");
context.emitter().Emit(parse_node, ContinueOutsideLoop);
context.emitter().Emit(node_id, ContinueOutsideLoop);
} else {
context.AddInst({parse_node, SemIR::Branch{stack.back().continue_target}});
context.AddInst({node_id, SemIR::Branch{stack.back().continue_target}});
}
context.inst_block_stack().Pop();
@@ -136,8 +134,7 @@ auto HandleContinueStatementStart(Context& context,
}
auto HandleContinueStatement(Context& /*context*/,
Parse::ContinueStatementId /*parse_node*/)
-> bool {
Parse::ContinueStatementId /*node_id*/) -> bool {
return true;
}
+37 -39
View File
@@ -8,88 +8,86 @@
namespace Carbon::Check {
auto HandleMatchConditionStart(Context& context,
Parse::MatchConditionStartId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchConditionStart");
Parse::MatchConditionStartId node_id) -> bool {
return context.TODO(node_id, "HandleMatchConditionStart");
}
auto HandleMatchCondition(Context& context, Parse::MatchConditionId parse_node)
auto HandleMatchCondition(Context& context, Parse::MatchConditionId node_id)
-> bool {
return context.TODO(parse_node, "HandleMatchCondition");
return context.TODO(node_id, "HandleMatchCondition");
}
auto HandleMatchIntroducer(Context& context,
Parse::MatchIntroducerId parse_node) -> bool {
return context.TODO(parse_node, "HandleMatchIntroducer");
auto HandleMatchIntroducer(Context& context, Parse::MatchIntroducerId node_id)
-> bool {
return context.TODO(node_id, "HandleMatchIntroducer");
}
auto HandleMatchStatementStart(Context& context,
Parse::MatchStatementStartId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchStatementStart");
Parse::MatchStatementStartId node_id) -> bool {
return context.TODO(node_id, "HandleMatchStatementStart");
}
auto HandleMatchCaseIntroducer(Context& context,
Parse::MatchCaseIntroducerId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseIntroducer");
Parse::MatchCaseIntroducerId node_id) -> bool {
return context.TODO(node_id, "HandleMatchCaseIntroducer");
}
auto HandleMatchCaseGuardIntroducer(
Context& context, Parse::MatchCaseGuardIntroducerId parse_node) -> bool {
return context.TODO(parse_node, "HandleMatchCaseGuardIntroducer");
auto HandleMatchCaseGuardIntroducer(Context& context,
Parse::MatchCaseGuardIntroducerId node_id)
-> bool {
return context.TODO(node_id, "HandleMatchCaseGuardIntroducer");
}
auto HandleMatchCaseGuardStart(Context& context,
Parse::MatchCaseGuardStartId parse_node)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseGuardStart");
Parse::MatchCaseGuardStartId node_id) -> bool {
return context.TODO(node_id, "HandleMatchCaseGuardStart");
}
auto HandleMatchCaseGuard(Context& context, Parse::MatchCaseGuardId parse_node)
auto HandleMatchCaseGuard(Context& context, Parse::MatchCaseGuardId node_id)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseGuard");
return context.TODO(node_id, "HandleMatchCaseGuard");
}
auto HandleMatchCaseEqualGreater(Context& context,
Parse::MatchCaseEqualGreaterId parse_node)
Parse::MatchCaseEqualGreaterId node_id)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseEqualGreater");
return context.TODO(node_id, "HandleMatchCaseEqualGreater");
}
auto HandleMatchCaseStart(Context& context, Parse::MatchCaseStartId parse_node)
auto HandleMatchCaseStart(Context& context, Parse::MatchCaseStartId node_id)
-> bool {
return context.TODO(parse_node, "HandleMatchCaseStart");
return context.TODO(node_id, "HandleMatchCaseStart");
}
auto HandleMatchCase(Context& context, Parse::MatchCaseId parse_node) -> bool {
return context.TODO(parse_node, "HandleMatchCase");
auto HandleMatchCase(Context& context, Parse::MatchCaseId node_id) -> bool {
return context.TODO(node_id, "HandleMatchCase");
}
auto HandleMatchDefaultIntroducer(Context& context,
Parse::MatchDefaultIntroducerId parse_node)
Parse::MatchDefaultIntroducerId node_id)
-> bool {
return context.TODO(parse_node, "MatchDefaultIntroducer");
return context.TODO(node_id, "MatchDefaultIntroducer");
}
auto HandleMatchDefaultEqualGreater(
Context& context, Parse::MatchDefaultEqualGreaterId parse_node) -> bool {
return context.TODO(parse_node, "MatchDefaultEqualGreater");
auto HandleMatchDefaultEqualGreater(Context& context,
Parse::MatchDefaultEqualGreaterId node_id)
-> bool {
return context.TODO(node_id, "MatchDefaultEqualGreater");
}
auto HandleMatchDefaultStart(Context& context,
Parse::MatchDefaultStartId parse_node) -> bool {
return context.TODO(parse_node, "HandleMatchDefaultStart");
Parse::MatchDefaultStartId node_id) -> bool {
return context.TODO(node_id, "HandleMatchDefaultStart");
}
auto HandleMatchDefault(Context& context, Parse::MatchDefaultId parse_node)
auto HandleMatchDefault(Context& context, Parse::MatchDefaultId node_id)
-> bool {
return context.TODO(parse_node, "HandleMatchDefault");
return context.TODO(node_id, "HandleMatchDefault");
}
auto HandleMatchStatement(Context& context, Parse::MatchStatementId parse_node)
auto HandleMatchStatement(Context& context, Parse::MatchStatementId node_id)
-> bool {
return context.TODO(parse_node, "HandleMatchStatement");
return context.TODO(node_id, "HandleMatchStatement");
}
} // namespace Carbon::Check
+9 -10
View File
@@ -34,7 +34,7 @@ static auto EmitNotAllowedWithDiagnostic(Context& context,
.Emit();
}
static auto HandleModifier(Context& context, Parse::NodeId parse_node,
static auto HandleModifier(Context& context, Parse::NodeId node_id,
KeywordModifierSet keyword) -> bool {
auto& s = context.decl_state_stack().innermost();
@@ -53,9 +53,9 @@ static auto HandleModifier(Context& context, Parse::NodeId parse_node,
auto current_modifier_node_id = s.modifier_node_id(order);
if (!!(s.modifier_set & keyword)) {
EmitRepeatedDiagnostic(context, current_modifier_node_id, parse_node);
EmitRepeatedDiagnostic(context, current_modifier_node_id, node_id);
} else if (current_modifier_node_id.is_valid()) {
EmitNotAllowedWithDiagnostic(context, current_modifier_node_id, parse_node);
EmitNotAllowedWithDiagnostic(context, current_modifier_node_id, node_id);
} else if (auto later_modifier_set = s.modifier_set & later_modifiers;
!!later_modifier_set) {
// At least one later modifier is present. Diagnose using the closest.
@@ -74,24 +74,23 @@ static auto HandleModifier(Context& context, Parse::NodeId parse_node,
"`{0}` must appear before `{1}`.", Lex::TokenKind,
Lex::TokenKind);
context.emitter()
.Build(parse_node, ModifierMustAppearBefore,
context.token_kind(parse_node),
.Build(node_id, ModifierMustAppearBefore, context.token_kind(node_id),
context.token_kind(closest_later_modifier))
.Note(closest_later_modifier, ModifierPrevious,
context.token_kind(closest_later_modifier))
.Emit();
} else {
s.modifier_set |= keyword;
s.set_modifier_node_id(order, parse_node);
s.set_modifier_node_id(order, node_id);
}
return true;
}
#define CARBON_PARSE_NODE_KIND(...)
#define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name, ...) \
auto Handle##Name##Modifier(Context& context, \
Parse::Name##ModifierId parse_node) -> bool { \
return HandleModifier(context, parse_node, KeywordModifierSet::Name); \
#define CARBON_PARSE_NODE_KIND_TOKEN_MODIFIER(Name, ...) \
auto Handle##Name##Modifier(Context& context, \
Parse::Name##ModifierId node_id) -> bool { \
return HandleModifier(context, node_id, KeywordModifierSet::Name); \
}
#include "toolchain/parse/node_kind.def"
+54 -56
View File
@@ -89,8 +89,8 @@ static auto IsInstanceMethod(const SemIR::File& sem_ir,
return false;
}
auto HandleMemberAccessExpr(Context& context,
Parse::MemberAccessExprId parse_node) -> bool {
auto HandleMemberAccessExpr(Context& context, Parse::MemberAccessExprId node_id)
-> bool {
SemIR::NameId name_id = context.node_stack().PopName();
auto base_id = context.node_stack().PopExpr();
@@ -99,12 +99,12 @@ auto HandleMemberAccessExpr(Context& context,
if (auto name_scope_id = GetAsNameScope(context, base_id)) {
auto inst_id =
name_scope_id->is_valid()
? context.LookupQualifiedName(parse_node, name_id, *name_scope_id)
? context.LookupQualifiedName(node_id, name_id, *name_scope_id)
: SemIR::InstId::BuiltinError;
auto inst = context.insts().Get(inst_id);
// TODO: Track that this instruction was named within `base_id`.
context.AddInstAndPush(
{parse_node, SemIR::NameRef{inst.type_id(), name_id, inst_id}});
{node_id, SemIR::NameRef{inst.type_id(), name_id, inst_id}});
return true;
}
@@ -117,7 +117,7 @@ auto HandleMemberAccessExpr(Context& context,
return context.emitter().Build(base_id, IncompleteTypeInMemberAccess,
base_type_id);
})) {
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinError);
return true;
}
@@ -133,7 +133,7 @@ auto HandleMemberAccessExpr(Context& context,
.Get(base_type.As<SemIR::ClassType>().class_id)
.scope_id;
auto member_id =
context.LookupQualifiedName(parse_node, name_id, class_scope_id);
context.LookupQualifiedName(node_id, name_id, class_scope_id);
// Perform instance binding if we found an instance member.
auto member_type_id = context.insts().Get(member_id).type_id();
@@ -142,7 +142,7 @@ auto HandleMemberAccessExpr(Context& context,
member_type_id)) {
// Convert the base to the type of the element if necessary.
base_id = ConvertToValueOrRefOfType(
context, parse_node, base_id, unbound_element_type->class_type_id);
context, node_id, base_id, unbound_element_type->class_type_id);
// Find the specified element, which could be either a field or a base
// class, and build an element access expression.
@@ -151,10 +151,10 @@ auto HandleMemberAccessExpr(Context& context,
<< "Non-constant value " << context.insts().Get(member_id)
<< " of unbound element type";
auto index = GetClassElementIndex(context, element_id.inst_id());
auto access_id = context.AddInst(
{parse_node,
SemIR::ClassElementAccess{unbound_element_type->element_type_id,
base_id, index}});
auto access_id =
context.AddInst({node_id, SemIR::ClassElementAccess{
unbound_element_type->element_type_id,
base_id, index}});
if (SemIR::GetExprCategory(context.sem_ir(), base_id) ==
SemIR::ExprCategory::Value &&
SemIR::GetExprCategory(context.sem_ir(), access_id) !=
@@ -166,7 +166,7 @@ auto HandleMemberAccessExpr(Context& context,
// matches the expression category of the base.
access_id = ConvertToValueExpr(context, access_id);
}
context.node_stack().Push(parse_node, access_id);
context.node_stack().Push(node_id, access_id);
return true;
}
if (member_type_id ==
@@ -185,7 +185,7 @@ auto HandleMemberAccessExpr(Context& context,
<< " of function type";
if (IsInstanceMethod(context.sem_ir(), function_decl->function_id)) {
context.AddInstAndPush(
{parse_node,
{node_id,
SemIR::BoundMethod{
context.GetBuiltinType(SemIR::BuiltinKind::BoundMethodType),
base_id, member_id}});
@@ -196,7 +196,7 @@ auto HandleMemberAccessExpr(Context& context,
// For a non-instance member, the result is that member.
// TODO: Track that this was named within `base_id`.
context.AddInstAndPush(
{parse_node, SemIR::NameRef{member_type_id, name_id, member_id}});
{node_id, SemIR::NameRef{member_type_id, name_id, member_id}});
return true;
}
case SemIR::StructType::Kind: {
@@ -207,16 +207,16 @@ auto HandleMemberAccessExpr(Context& context,
auto field = context.insts().GetAs<SemIR::StructTypeField>(ref_id);
if (name_id == field.name_id) {
context.AddInstAndPush(
{parse_node, SemIR::StructAccess{field.field_type_id, base_id,
SemIR::ElementIndex(i)}});
{node_id, SemIR::StructAccess{field.field_type_id, base_id,
SemIR::ElementIndex(i)}});
return true;
}
}
CARBON_DIAGNOSTIC(QualifiedExprNameNotFound, Error,
"Type `{0}` does not have a member `{1}`.",
SemIR::TypeId, SemIR::NameId);
context.emitter().Emit(parse_node, QualifiedExprNameNotFound,
base_type_id, name_id);
context.emitter().Emit(node_id, QualifiedExprNameNotFound, base_type_id,
name_id);
break;
}
// TODO: `ConstType` should support member access just like the
@@ -227,29 +227,28 @@ auto HandleMemberAccessExpr(Context& context,
CARBON_DIAGNOSTIC(QualifiedExprUnsupported, Error,
"Type `{0}` does not support qualified expressions.",
SemIR::TypeId);
context.emitter().Emit(parse_node, QualifiedExprUnsupported,
base_type_id);
context.emitter().Emit(node_id, QualifiedExprUnsupported, base_type_id);
}
break;
}
}
// Should only be reached on error.
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinError);
return true;
}
auto HandlePointerMemberAccessExpr(Context& context,
Parse::PointerMemberAccessExprId parse_node)
Parse::PointerMemberAccessExprId node_id)
-> bool {
return context.TODO(parse_node, "HandlePointerMemberAccessExpr");
return context.TODO(node_id, "HandlePointerMemberAccessExpr");
}
static auto GetIdentifierAsName(Context& context, Parse::NodeId parse_node)
static auto GetIdentifierAsName(Context& context, Parse::NodeId node_id)
-> std::optional<SemIR::NameId> {
auto token = context.parse_tree().node_token(parse_node);
auto token = context.parse_tree().node_token(node_id);
if (context.tokens().GetKind(token) != Lex::TokenKind::Identifier) {
CARBON_CHECK(context.parse_tree().node_has_error(parse_node));
CARBON_CHECK(context.parse_tree().node_has_error(node_id));
return std::nullopt;
}
return SemIR::NameId::ForIdentifier(context.tokens().GetIdentifier(token));
@@ -257,62 +256,62 @@ static auto GetIdentifierAsName(Context& context, Parse::NodeId parse_node)
// Handle a name that is used as an expression by performing unqualified name
// lookup.
static auto HandleNameAsExpr(Context& context, Parse::NodeId parse_node,
static auto HandleNameAsExpr(Context& context, Parse::NodeId node_id,
SemIR::NameId name_id) -> bool {
auto value_id = context.LookupUnqualifiedName(parse_node, name_id);
auto value_id = context.LookupUnqualifiedName(node_id, name_id);
auto value = context.insts().Get(value_id);
context.AddInstAndPush(
{parse_node, SemIR::NameRef{value.type_id(), name_id, value_id}});
{node_id, SemIR::NameRef{value.type_id(), name_id, value_id}});
return true;
}
auto HandleIdentifierName(Context& context, Parse::IdentifierNameId parse_node)
auto HandleIdentifierName(Context& context, Parse::IdentifierNameId node_id)
-> bool {
// The parent is responsible for binding the name.
auto name_id = GetIdentifierAsName(context, parse_node);
auto name_id = GetIdentifierAsName(context, node_id);
if (!name_id) {
return context.TODO(parse_node, "Error recovery from keyword name.");
return context.TODO(node_id, "Error recovery from keyword name.");
}
context.node_stack().Push(parse_node, *name_id);
context.node_stack().Push(node_id, *name_id);
return true;
}
auto HandleIdentifierNameExpr(Context& context,
Parse::IdentifierNameExprId parse_node) -> bool {
auto name_id = GetIdentifierAsName(context, parse_node);
Parse::IdentifierNameExprId node_id) -> bool {
auto name_id = GetIdentifierAsName(context, node_id);
if (!name_id) {
return context.TODO(parse_node, "Error recovery from keyword name.");
return context.TODO(node_id, "Error recovery from keyword name.");
}
return HandleNameAsExpr(context, parse_node, *name_id);
return HandleNameAsExpr(context, node_id, *name_id);
}
auto HandleBaseName(Context& context, Parse::BaseNameId parse_node) -> bool {
context.node_stack().Push(parse_node, SemIR::NameId::Base);
auto HandleBaseName(Context& context, Parse::BaseNameId node_id) -> bool {
context.node_stack().Push(node_id, SemIR::NameId::Base);
return true;
}
auto HandleSelfTypeNameExpr(Context& context,
Parse::SelfTypeNameExprId parse_node) -> bool {
return HandleNameAsExpr(context, parse_node, SemIR::NameId::SelfType);
auto HandleSelfTypeNameExpr(Context& context, Parse::SelfTypeNameExprId node_id)
-> bool {
return HandleNameAsExpr(context, node_id, SemIR::NameId::SelfType);
}
auto HandleSelfValueName(Context& context, Parse::SelfValueNameId parse_node)
auto HandleSelfValueName(Context& context, Parse::SelfValueNameId node_id)
-> bool {
context.node_stack().Push(parse_node, SemIR::NameId::SelfValue);
context.node_stack().Push(node_id, SemIR::NameId::SelfValue);
return true;
}
auto HandleSelfValueNameExpr(Context& context,
Parse::SelfValueNameExprId parse_node) -> bool {
return HandleNameAsExpr(context, parse_node, SemIR::NameId::SelfValue);
Parse::SelfValueNameExprId node_id) -> bool {
return HandleNameAsExpr(context, node_id, SemIR::NameId::SelfValue);
}
auto HandleQualifiedName(Context& context, Parse::QualifiedNameId parse_node)
auto HandleQualifiedName(Context& context, Parse::QualifiedNameId node_id)
-> bool {
auto [parse_node2, name_id2] = context.node_stack().PopNameWithParseNode();
auto [node_id2, name_id2] = context.node_stack().PopNameWithNodeId();
Parse::NodeId parse_node1 = context.node_stack().PeekParseNode();
switch (context.parse_tree().node_kind(parse_node1)) {
Parse::NodeId node_id1 = context.node_stack().PeekNodeId();
switch (context.parse_tree().node_kind(node_id1)) {
case Parse::NodeKind::QualifiedName:
// This is the second or subsequent QualifiedName in a chain.
// Nothing to do: the first QualifiedName remains as a
@@ -324,9 +323,9 @@ auto HandleQualifiedName(Context& context, Parse::QualifiedNameId parse_node)
// identifier name.
auto name_id =
context.node_stack().Pop<Parse::NodeKind::IdentifierName>();
context.decl_name_stack().ApplyNameQualifier(parse_node1, name_id);
context.decl_name_stack().ApplyNameQualifier(node_id1, name_id);
// Add the QualifiedName so that it can be used for bracketing.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
break;
}
@@ -335,14 +334,13 @@ auto HandleQualifiedName(Context& context, Parse::QualifiedNameId parse_node)
"declaration name";
}
context.decl_name_stack().ApplyNameQualifier(parse_node2, name_id2);
context.decl_name_stack().ApplyNameQualifier(node_id2, name_id2);
return true;
}
auto HandlePackageExpr(Context& context, Parse::PackageExprId parse_node)
-> bool {
auto HandlePackageExpr(Context& context, Parse::PackageExprId node_id) -> bool {
context.AddInstAndPush(
{parse_node,
{node_id,
SemIR::NameRef{context.GetBuiltinType(SemIR::BuiltinKind::NamespaceType),
SemIR::NameId::PackageNamespace,
SemIR::InstId::PackageNamespace}});
+12 -12
View File
@@ -7,25 +7,25 @@
namespace Carbon::Check {
auto HandleNamedConstraintDecl(Context& context,
Parse::NamedConstraintDeclId parse_node)
-> bool {
return context.TODO(parse_node, "HandleNamedConstraintDecl");
Parse::NamedConstraintDeclId node_id) -> bool {
return context.TODO(node_id, "HandleNamedConstraintDecl");
}
auto HandleNamedConstraintDefinition(
Context& context, Parse::NamedConstraintDefinitionId parse_node) -> bool {
return context.TODO(parse_node, "HandleNamedConstraintDefinition");
auto HandleNamedConstraintDefinition(Context& context,
Parse::NamedConstraintDefinitionId node_id)
-> bool {
return context.TODO(node_id, "HandleNamedConstraintDefinition");
}
auto HandleNamedConstraintDefinitionStart(
Context& context, Parse::NamedConstraintDefinitionStartId parse_node)
-> bool {
return context.TODO(parse_node, "HandleNamedConstraintDefinitionStart");
Context& context, Parse::NamedConstraintDefinitionStartId node_id) -> bool {
return context.TODO(node_id, "HandleNamedConstraintDefinitionStart");
}
auto HandleNamedConstraintIntroducer(
Context& context, Parse::NamedConstraintIntroducerId parse_node) -> bool {
return context.TODO(parse_node, "HandleNamedConstraintIntroducer");
auto HandleNamedConstraintIntroducer(Context& context,
Parse::NamedConstraintIntroducerId node_id)
-> bool {
return context.TODO(node_id, "HandleNamedConstraintIntroducer");
}
} // namespace Carbon::Check
+7 -8
View File
@@ -9,27 +9,26 @@
namespace Carbon::Check {
auto HandleNamespaceStart(Context& context,
Parse::NamespaceStartId /*parse_node*/) -> bool {
auto HandleNamespaceStart(Context& context, Parse::NamespaceStartId /*node_id*/)
-> bool {
// Optional modifiers and the name follow.
context.decl_state_stack().Push(DeclState::Namespace);
context.decl_name_stack().PushScopeAndStartName();
return true;
}
auto HandleNamespace(Context& context, Parse::NamespaceId parse_node) -> bool {
auto HandleNamespace(Context& context, Parse::NamespaceId node_id) -> bool {
auto name_context = context.decl_name_stack().FinishName();
LimitModifiersOnDecl(context, KeywordModifierSet::None,
Lex::TokenKind::Namespace);
auto namespace_inst = SemIR::Namespace{
context.GetBuiltinType(SemIR::BuiltinKind::NamespaceType),
SemIR::NameScopeId::Invalid, SemIR::InstId::Invalid};
auto namespace_id = context.AddPlaceholderInst({parse_node, namespace_inst});
auto namespace_id = context.AddPlaceholderInst({node_id, namespace_inst});
namespace_inst.name_scope_id = context.name_scopes().Add(
namespace_id, name_context.name_id_for_new_inst(),
name_context.enclosing_scope_id_for_new_inst());
context.ReplaceInstBeforeConstantUse(namespace_id,
{parse_node, namespace_inst});
context.ReplaceInstBeforeConstantUse(namespace_id, {node_id, namespace_inst});
auto existing_inst_id =
context.decl_name_stack().LookupOrAddName(name_context, namespace_id);
@@ -41,8 +40,8 @@ auto HandleNamespace(Context& context, Parse::NamespaceId parse_node) -> bool {
// When the name conflict is an imported namespace, fill the parse node
// so that future diagnostics point at this declaration.
if (existing->import_id.is_valid() &&
!context.insts().GetParseNode(existing_inst_id).is_valid()) {
context.SetNamespaceParseNode(existing_inst_id, parse_node);
!context.insts().GetNodeId(existing_inst_id).is_valid()) {
context.SetNamespaceNodeId(existing_inst_id, node_id);
}
} else {
context.DiagnoseDuplicateName(namespace_id, existing_inst_id);
+9 -10
View File
@@ -6,30 +6,29 @@
namespace Carbon::Check {
auto HandleEmptyDecl(Context& /*context*/, Parse::EmptyDeclId /*parse_node*/)
auto HandleEmptyDecl(Context& /*context*/, Parse::EmptyDeclId /*node_id*/)
-> bool {
// Empty declarations have no actions associated.
return true;
}
auto HandleInvalidParse(Context& context, Parse::InvalidParseId parse_node)
auto HandleInvalidParse(Context& context, Parse::InvalidParseId node_id)
-> bool {
return context.TODO(parse_node, "HandleInvalidParse");
return context.TODO(node_id, "HandleInvalidParse");
}
auto HandleInvalidParseStart(Context& context,
Parse::InvalidParseStartId parse_node) -> bool {
return context.TODO(parse_node, "HandleInvalidParseStart");
Parse::InvalidParseStartId node_id) -> bool {
return context.TODO(node_id, "HandleInvalidParseStart");
}
auto HandleInvalidParseSubtree(Context& context,
Parse::InvalidParseSubtreeId parse_node)
-> bool {
return context.TODO(parse_node, "HandleInvalidParseSubtree");
Parse::InvalidParseSubtreeId node_id) -> bool {
return context.TODO(node_id, "HandleInvalidParseSubtree");
}
auto HandlePlaceholder(Context& /*context*/,
Parse::PlaceholderId /*parse_node*/) -> bool {
auto HandlePlaceholder(Context& /*context*/, Parse::PlaceholderId /*node_id*/)
-> bool {
CARBON_FATAL()
<< "Placeholder node should always be replaced before parse completes";
}
+127 -133
View File
@@ -7,44 +7,43 @@
namespace Carbon::Check {
auto HandleInfixOperatorAmp(Context& context,
Parse::InfixOperatorAmpId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorAmp");
auto HandleInfixOperatorAmp(Context& context, Parse::InfixOperatorAmpId node_id)
-> bool {
return context.TODO(node_id, "HandleInfixOperatorAmp");
}
auto HandleInfixOperatorAmpEqual(Context& context,
Parse::InfixOperatorAmpEqualId parse_node)
Parse::InfixOperatorAmpEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorAmpEqual");
return context.TODO(node_id, "HandleInfixOperatorAmpEqual");
}
auto HandleInfixOperatorAs(Context& context,
Parse::InfixOperatorAsId parse_node) -> bool {
auto [rhs_node, rhs_id] = context.node_stack().PopExprWithParseNode();
auto [lhs_node, lhs_id] = context.node_stack().PopExprWithParseNode();
auto HandleInfixOperatorAs(Context& context, Parse::InfixOperatorAsId node_id)
-> bool {
auto [rhs_node, rhs_id] = context.node_stack().PopExprWithNodeId();
auto [lhs_node, lhs_id] = context.node_stack().PopExprWithNodeId();
auto rhs_type_id = ExprAsType(context, rhs_node, rhs_id);
context.node_stack().Push(
parse_node,
ConvertForExplicitAs(context, parse_node, lhs_id, rhs_type_id));
node_id, ConvertForExplicitAs(context, node_id, lhs_id, rhs_type_id));
return true;
}
auto HandleInfixOperatorCaret(Context& context,
Parse::InfixOperatorCaretId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorCaret");
Parse::InfixOperatorCaretId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorCaret");
}
auto HandleInfixOperatorCaretEqual(Context& context,
Parse::InfixOperatorCaretEqualId parse_node)
Parse::InfixOperatorCaretEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorCaretEqual");
return context.TODO(node_id, "HandleInfixOperatorCaretEqual");
}
auto HandleInfixOperatorEqual(Context& context,
Parse::InfixOperatorEqualId parse_node) -> bool {
auto [rhs_node, rhs_id] = context.node_stack().PopExprWithParseNode();
auto [lhs_node, lhs_id] = context.node_stack().PopExprWithParseNode();
Parse::InfixOperatorEqualId node_id) -> bool {
auto [rhs_node, rhs_id] = context.node_stack().PopExprWithNodeId();
auto [lhs_node, lhs_id] = context.node_stack().PopExprWithNodeId();
// TODO: handle complex assignment expression such as `a += 1`.
if (auto lhs_cat = SemIR::GetExprCategory(context.sem_ir(), lhs_id);
@@ -56,155 +55,154 @@ auto HandleInfixOperatorEqual(Context& context,
}
// TODO: Destroy the old value before reinitializing. This will require
// building the destruction code before we build the RHS subexpression.
rhs_id = Initialize(context, parse_node, lhs_id, rhs_id);
context.AddInst({parse_node, SemIR::Assign{lhs_id, rhs_id}});
rhs_id = Initialize(context, node_id, lhs_id, rhs_id);
context.AddInst({node_id, SemIR::Assign{lhs_id, rhs_id}});
// We model assignment as an expression, so we need to push a value for
// it, even though it doesn't produce a value.
// TODO: Consider changing our parse tree to model assignment as a
// different kind of statement than an expression statement.
context.node_stack().Push(parse_node, lhs_id);
context.node_stack().Push(node_id, lhs_id);
return true;
}
auto HandleInfixOperatorEqualEqual(Context& context,
Parse::InfixOperatorEqualEqualId parse_node)
Parse::InfixOperatorEqualEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorEqualEqual");
return context.TODO(node_id, "HandleInfixOperatorEqualEqual");
}
auto HandleInfixOperatorExclaimEqual(
Context& context, Parse::InfixOperatorExclaimEqualId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorExclaimEqual");
auto HandleInfixOperatorExclaimEqual(Context& context,
Parse::InfixOperatorExclaimEqualId node_id)
-> bool {
return context.TODO(node_id, "HandleInfixOperatorExclaimEqual");
}
auto HandleInfixOperatorGreater(Context& context,
Parse::InfixOperatorGreaterId parse_node)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorGreater");
Parse::InfixOperatorGreaterId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorGreater");
}
auto HandleInfixOperatorGreaterEqual(
Context& context, Parse::InfixOperatorGreaterEqualId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorGreaterEqual");
auto HandleInfixOperatorGreaterEqual(Context& context,
Parse::InfixOperatorGreaterEqualId node_id)
-> bool {
return context.TODO(node_id, "HandleInfixOperatorGreaterEqual");
}
auto HandleInfixOperatorGreaterGreater(
Context& context, Parse::InfixOperatorGreaterGreaterId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorGreaterGreater");
Context& context, Parse::InfixOperatorGreaterGreaterId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorGreaterGreater");
}
auto HandleInfixOperatorGreaterGreaterEqual(
Context& context, Parse::InfixOperatorGreaterGreaterEqualId parse_node)
Context& context, Parse::InfixOperatorGreaterGreaterEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorGreaterGreaterEqual");
return context.TODO(node_id, "HandleInfixOperatorGreaterGreaterEqual");
}
auto HandleInfixOperatorLess(Context& context,
Parse::InfixOperatorLessId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorLess");
Parse::InfixOperatorLessId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorLess");
}
auto HandleInfixOperatorLessEqual(Context& context,
Parse::InfixOperatorLessEqualId parse_node)
Parse::InfixOperatorLessEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorLessEqual");
return context.TODO(node_id, "HandleInfixOperatorLessEqual");
}
auto HandleInfixOperatorLessEqualGreater(
Context& context, Parse::InfixOperatorLessEqualGreaterId parse_node)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorLessEqualGreater");
Context& context, Parse::InfixOperatorLessEqualGreaterId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorLessEqualGreater");
}
auto HandleInfixOperatorLessLess(Context& context,
Parse::InfixOperatorLessLessId parse_node)
Parse::InfixOperatorLessLessId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorLessLess");
return context.TODO(node_id, "HandleInfixOperatorLessLess");
}
auto HandleInfixOperatorLessLessEqual(
Context& context, Parse::InfixOperatorLessLessEqualId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorLessLessEqual");
Context& context, Parse::InfixOperatorLessLessEqualId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorLessLessEqual");
}
auto HandleInfixOperatorMinus(Context& context,
Parse::InfixOperatorMinusId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorMinus");
Parse::InfixOperatorMinusId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorMinus");
}
auto HandleInfixOperatorMinusEqual(Context& context,
Parse::InfixOperatorMinusEqualId parse_node)
Parse::InfixOperatorMinusEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorMinusEqual");
return context.TODO(node_id, "HandleInfixOperatorMinusEqual");
}
auto HandleInfixOperatorPercent(Context& context,
Parse::InfixOperatorPercentId parse_node)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorPercent");
Parse::InfixOperatorPercentId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorPercent");
}
auto HandleInfixOperatorPercentEqual(
Context& context, Parse::InfixOperatorPercentEqualId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorPercentEqual");
auto HandleInfixOperatorPercentEqual(Context& context,
Parse::InfixOperatorPercentEqualId node_id)
-> bool {
return context.TODO(node_id, "HandleInfixOperatorPercentEqual");
}
auto HandleInfixOperatorPipe(Context& context,
Parse::InfixOperatorPipeId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorPipe");
Parse::InfixOperatorPipeId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorPipe");
}
auto HandleInfixOperatorPipeEqual(Context& context,
Parse::InfixOperatorPipeEqualId parse_node)
Parse::InfixOperatorPipeEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorPipeEqual");
return context.TODO(node_id, "HandleInfixOperatorPipeEqual");
}
auto HandleInfixOperatorPlus(Context& context,
Parse::InfixOperatorPlusId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorPlus");
Parse::InfixOperatorPlusId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorPlus");
}
auto HandleInfixOperatorPlusEqual(Context& context,
Parse::InfixOperatorPlusEqualId parse_node)
Parse::InfixOperatorPlusEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorPlusEqual");
return context.TODO(node_id, "HandleInfixOperatorPlusEqual");
}
auto HandleInfixOperatorSlash(Context& context,
Parse::InfixOperatorSlashId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorSlash");
Parse::InfixOperatorSlashId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorSlash");
}
auto HandleInfixOperatorSlashEqual(Context& context,
Parse::InfixOperatorSlashEqualId parse_node)
Parse::InfixOperatorSlashEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorSlashEqual");
return context.TODO(node_id, "HandleInfixOperatorSlashEqual");
}
auto HandleInfixOperatorStar(Context& context,
Parse::InfixOperatorStarId parse_node) -> bool {
return context.TODO(parse_node, "HandleInfixOperatorStar");
Parse::InfixOperatorStarId node_id) -> bool {
return context.TODO(node_id, "HandleInfixOperatorStar");
}
auto HandleInfixOperatorStarEqual(Context& context,
Parse::InfixOperatorStarEqualId parse_node)
Parse::InfixOperatorStarEqualId node_id)
-> bool {
return context.TODO(parse_node, "HandleInfixOperatorStarEqual");
return context.TODO(node_id, "HandleInfixOperatorStarEqual");
}
auto HandlePostfixOperatorStar(Context& context,
Parse::PostfixOperatorStarId parse_node)
-> bool {
Parse::PostfixOperatorStarId node_id) -> bool {
auto value_id = context.node_stack().PopExpr();
auto inner_type_id = ExprAsType(context, parse_node, value_id);
auto inner_type_id = ExprAsType(context, node_id, value_id);
context.AddInstAndPush(
{parse_node, SemIR::PointerType{SemIR::TypeId::TypeType, inner_type_id}});
{node_id, SemIR::PointerType{SemIR::TypeId::TypeType, inner_type_id}});
return true;
}
auto HandlePrefixOperatorAmp(Context& context,
Parse::PrefixOperatorAmpId parse_node) -> bool {
Parse::PrefixOperatorAmpId node_id) -> bool {
auto value_id = context.node_stack().PopExpr();
auto type_id = context.insts().Get(value_id).type_id();
// Only durable reference expressions can have their address taken.
@@ -215,30 +213,28 @@ auto HandlePrefixOperatorAmp(Context& context,
case SemIR::ExprCategory::EphemeralRef:
CARBON_DIAGNOSTIC(AddrOfEphemeralRef, Error,
"Cannot take the address of a temporary object.");
context.emitter().Emit(TokenOnly(parse_node), AddrOfEphemeralRef);
context.emitter().Emit(TokenOnly(node_id), AddrOfEphemeralRef);
value_id = SemIR::InstId::BuiltinError;
break;
default:
CARBON_DIAGNOSTIC(AddrOfNonRef, Error,
"Cannot take the address of non-reference expression.");
context.emitter().Emit(TokenOnly(parse_node), AddrOfNonRef);
context.emitter().Emit(TokenOnly(node_id), AddrOfNonRef);
value_id = SemIR::InstId::BuiltinError;
break;
}
context.AddInstAndPush(
{parse_node, SemIR::AddrOf{context.GetPointerType(type_id), value_id}});
{node_id, SemIR::AddrOf{context.GetPointerType(type_id), value_id}});
return true;
}
auto HandlePrefixOperatorCaret(Context& context,
Parse::PrefixOperatorCaretId parse_node)
-> bool {
return context.TODO(parse_node, "HandlePrefixOperatorCaret");
Parse::PrefixOperatorCaretId node_id) -> bool {
return context.TODO(node_id, "HandlePrefixOperatorCaret");
}
auto HandlePrefixOperatorConst(Context& context,
Parse::PrefixOperatorConstId parse_node)
-> bool {
Parse::PrefixOperatorConstId node_id) -> bool {
auto value_id = context.node_stack().PopExpr();
// `const (const T)` is probably not what the developer intended.
@@ -248,43 +244,43 @@ auto HandlePrefixOperatorConst(Context& context,
CARBON_DIAGNOSTIC(RepeatedConst, Warning,
"`const` applied repeatedly to the same type has no "
"additional effect.");
context.emitter().Emit(parse_node, RepeatedConst);
context.emitter().Emit(node_id, RepeatedConst);
}
auto inner_type_id = ExprAsType(context, parse_node, value_id);
auto inner_type_id = ExprAsType(context, node_id, value_id);
context.AddInstAndPush(
{parse_node, SemIR::ConstType{SemIR::TypeId::TypeType, inner_type_id}});
{node_id, SemIR::ConstType{SemIR::TypeId::TypeType, inner_type_id}});
return true;
}
auto HandlePrefixOperatorMinus(Context& context,
Parse::PrefixOperatorMinusId parse_node)
-> bool {
return context.TODO(parse_node, "HandlePrefixOperatorMinus");
Parse::PrefixOperatorMinusId node_id) -> bool {
return context.TODO(node_id, "HandlePrefixOperatorMinus");
}
auto HandlePrefixOperatorMinusMinus(
Context& context, Parse::PrefixOperatorMinusMinusId parse_node) -> bool {
return context.TODO(parse_node, "HandlePrefixOperatorMinusMinus");
auto HandlePrefixOperatorMinusMinus(Context& context,
Parse::PrefixOperatorMinusMinusId node_id)
-> bool {
return context.TODO(node_id, "HandlePrefixOperatorMinusMinus");
}
auto HandlePrefixOperatorNot(Context& context,
Parse::PrefixOperatorNotId parse_node) -> bool {
Parse::PrefixOperatorNotId node_id) -> bool {
auto value_id = context.node_stack().PopExpr();
value_id = ConvertToBoolValue(context, parse_node, value_id);
value_id = ConvertToBoolValue(context, node_id, value_id);
context.AddInstAndPush(
{parse_node, SemIR::UnaryOperatorNot{
context.insts().Get(value_id).type_id(), value_id}});
{node_id, SemIR::UnaryOperatorNot{context.insts().Get(value_id).type_id(),
value_id}});
return true;
}
auto HandlePrefixOperatorPlusPlus(Context& context,
Parse::PrefixOperatorPlusPlusId parse_node)
Parse::PrefixOperatorPlusPlusId node_id)
-> bool {
return context.TODO(parse_node, "HandlePrefixOperatorPlusPlus");
return context.TODO(node_id, "HandlePrefixOperatorPlusPlus");
}
auto HandlePrefixOperatorStar(Context& context,
Parse::PrefixOperatorStarId parse_node) -> bool {
Parse::PrefixOperatorStarId node_id) -> bool {
auto value_id = context.node_stack().PopExpr();
value_id = ConvertToValueExpr(context, value_id);
auto type_id =
@@ -297,53 +293,51 @@ auto HandlePrefixOperatorStar(Context& context,
CARBON_DIAGNOSTIC(DerefOfNonPointer, Error,
"Cannot dereference operand of non-pointer type `{0}`.",
SemIR::TypeId);
auto builder = context.emitter().Build(TokenOnly(parse_node),
DerefOfNonPointer, type_id);
auto builder =
context.emitter().Build(TokenOnly(node_id), DerefOfNonPointer, type_id);
// TODO: Check for any facet here, rather than only a type.
if (type_id == SemIR::TypeId::TypeType) {
CARBON_DIAGNOSTIC(
DerefOfType, Note,
"To form a pointer type, write the `*` after the pointee type.");
builder.Note(TokenOnly(parse_node), DerefOfType);
builder.Note(TokenOnly(node_id), DerefOfType);
}
builder.Emit();
}
context.AddInstAndPush({parse_node, SemIR::Deref{result_type_id, value_id}});
context.AddInstAndPush({node_id, SemIR::Deref{result_type_id, value_id}});
return true;
}
// Adds the branch for a short circuit operand.
static auto HandleShortCircuitOperand(Context& context,
Parse::NodeId parse_node, bool is_or)
-> bool {
static auto HandleShortCircuitOperand(Context& context, Parse::NodeId node_id,
bool is_or) -> bool {
// Convert the condition to `bool`.
auto cond_value_id = context.node_stack().PopExpr();
cond_value_id = ConvertToBoolValue(context, parse_node, cond_value_id);
cond_value_id = ConvertToBoolValue(context, node_id, cond_value_id);
auto bool_type_id = context.insts().Get(cond_value_id).type_id();
// Compute the branch value: the condition for `and`, inverted for `or`.
SemIR::InstId branch_value_id =
is_or ? context.AddInst(
{parse_node,
SemIR::UnaryOperatorNot{bool_type_id, cond_value_id}})
is_or ? context.AddInst({node_id, SemIR::UnaryOperatorNot{bool_type_id,
cond_value_id}})
: cond_value_id;
auto short_circuit_result_id = context.AddInst(
{parse_node,
{node_id,
SemIR::BoolLiteral{bool_type_id, is_or ? SemIR::BoolValue::True
: SemIR::BoolValue::False}});
// Create a block for the right-hand side and for the continuation.
auto rhs_block_id =
context.AddDominatedBlockAndBranchIf(parse_node, branch_value_id);
context.AddDominatedBlockAndBranchIf(node_id, branch_value_id);
auto end_block_id = context.AddDominatedBlockAndBranchWithArg(
parse_node, short_circuit_result_id);
node_id, short_circuit_result_id);
// Push the resumption and the right-hand side blocks, and start emitting the
// right-hand operand.
context.inst_block_stack().Pop();
context.inst_block_stack().Push(end_block_id);
context.inst_block_stack().Push(rhs_block_id);
context.AddCurrentCodeBlockToFunction(parse_node);
context.AddCurrentCodeBlockToFunction(node_id);
// HandleShortCircuitOperator will follow, and doesn't need the operand on the
// node stack.
@@ -351,52 +345,52 @@ static auto HandleShortCircuitOperand(Context& context,
}
auto HandleShortCircuitOperandAnd(Context& context,
Parse::ShortCircuitOperandAndId parse_node)
Parse::ShortCircuitOperandAndId node_id)
-> bool {
return HandleShortCircuitOperand(context, parse_node, /*is_or=*/false);
return HandleShortCircuitOperand(context, node_id, /*is_or=*/false);
}
auto HandleShortCircuitOperandOr(Context& context,
Parse::ShortCircuitOperandOrId parse_node)
Parse::ShortCircuitOperandOrId node_id)
-> bool {
return HandleShortCircuitOperand(context, parse_node, /*is_or=*/true);
return HandleShortCircuitOperand(context, node_id, /*is_or=*/true);
}
// Short circuit operator handling is uniform because the branching logic
// occurs during operand handling.
static auto HandleShortCircuitOperator(Context& context,
Parse::NodeId parse_node) -> bool {
auto [rhs_node, rhs_id] = context.node_stack().PopExprWithParseNode();
static auto HandleShortCircuitOperator(Context& context, Parse::NodeId node_id)
-> bool {
auto [rhs_node, rhs_id] = context.node_stack().PopExprWithNodeId();
// The first operand is wrapped in a ShortCircuitOperand, which we
// already handled by creating a RHS block and a resumption block, which
// are the current block and its enclosing block.
rhs_id = ConvertToBoolValue(context, parse_node, rhs_id);
rhs_id = ConvertToBoolValue(context, node_id, rhs_id);
// When the second operand is evaluated, the result of `and` and `or` is
// its value.
auto resume_block_id = context.inst_block_stack().PeekOrAdd(/*depth=*/1);
context.AddInst({parse_node, SemIR::BranchWithArg{resume_block_id, rhs_id}});
context.AddInst({node_id, SemIR::BranchWithArg{resume_block_id, rhs_id}});
context.inst_block_stack().Pop();
context.AddCurrentCodeBlockToFunction(parse_node);
context.AddCurrentCodeBlockToFunction(node_id);
// Collect the result from either the first or second operand.
context.AddInstAndPush(
{parse_node, SemIR::BlockArg{context.insts().Get(rhs_id).type_id(),
resume_block_id}});
{node_id, SemIR::BlockArg{context.insts().Get(rhs_id).type_id(),
resume_block_id}});
return true;
}
auto HandleShortCircuitOperatorAnd(Context& context,
Parse::ShortCircuitOperatorAndId parse_node)
Parse::ShortCircuitOperatorAndId node_id)
-> bool {
return HandleShortCircuitOperator(context, parse_node);
return HandleShortCircuitOperator(context, node_id);
}
auto HandleShortCircuitOperatorOr(Context& context,
Parse::ShortCircuitOperatorOrId parse_node)
Parse::ShortCircuitOperatorOrId node_id)
-> bool {
return HandleShortCircuitOperator(context, parse_node);
return HandleShortCircuitOperator(context, node_id);
}
} // namespace Carbon::Check
+10 -11
View File
@@ -6,14 +6,14 @@
namespace Carbon::Check {
auto HandleExprOpenParen(Context& context, Parse::ExprOpenParenId parse_node)
auto HandleExprOpenParen(Context& context, Parse::ExprOpenParenId node_id)
-> bool {
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
context.param_and_arg_refs_stack().Push();
return true;
}
auto HandleParenExpr(Context& context, Parse::ParenExprId parse_node) -> bool {
auto HandleParenExpr(Context& context, Parse::ParenExprId node_id) -> bool {
auto value_id = context.node_stack().PopExpr();
// This always is always pushed at the open paren. It's only used for tuples,
@@ -21,25 +21,24 @@ auto HandleParenExpr(Context& context, Parse::ParenExprId parse_node) -> bool {
context.param_and_arg_refs_stack().PopAndDiscard();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ExprOpenParen>();
context.node_stack().Push(parse_node, value_id);
.PopAndDiscardSoloNodeId<Parse::NodeKind::ExprOpenParen>();
context.node_stack().Push(node_id, value_id);
return true;
}
auto HandleTupleLiteralComma(Context& context,
Parse::TupleLiteralCommaId /*parse_node*/)
-> bool {
Parse::TupleLiteralCommaId /*node_id*/) -> bool {
context.param_and_arg_refs_stack().ApplyComma();
return true;
}
auto HandleTupleLiteral(Context& context, Parse::TupleLiteralId parse_node)
auto HandleTupleLiteral(Context& context, Parse::TupleLiteralId node_id)
-> bool {
auto refs_id = context.param_and_arg_refs_stack().EndAndPop(
Parse::NodeKind::ExprOpenParen);
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ExprOpenParen>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::ExprOpenParen>();
const auto& inst_block = context.inst_blocks().Get(refs_id);
llvm::SmallVector<SemIR::TypeId> type_ids;
type_ids.reserve(inst_block.size());
@@ -49,8 +48,8 @@ auto HandleTupleLiteral(Context& context, Parse::TupleLiteralId parse_node)
auto type_id = context.GetTupleType(type_ids);
auto value_id =
context.AddInst({parse_node, SemIR::TupleLiteral{type_id, refs_id}});
context.node_stack().Push(parse_node, value_id);
context.AddInst({node_id, SemIR::TupleLiteral{type_id, refs_id}});
context.node_stack().Push(node_id, value_id);
return true;
}
+11 -11
View File
@@ -7,45 +7,45 @@
namespace Carbon::Check {
auto HandleImplicitParamListStart(Context& context,
Parse::ImplicitParamListStartId parse_node)
Parse::ImplicitParamListStartId node_id)
-> bool {
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
context.param_and_arg_refs_stack().Push();
return true;
}
auto HandleImplicitParamList(Context& context,
Parse::ImplicitParamListId parse_node) -> bool {
Parse::ImplicitParamListId node_id) -> bool {
auto refs_id = context.param_and_arg_refs_stack().EndAndPop(
Parse::NodeKind::ImplicitParamListStart);
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ImplicitParamListStart>();
context.node_stack().Push(parse_node, refs_id);
.PopAndDiscardSoloNodeId<Parse::NodeKind::ImplicitParamListStart>();
context.node_stack().Push(node_id, refs_id);
// The implicit parameter list's scope extends to the end of the following
// parameter list.
return true;
}
auto HandleTuplePatternStart(Context& context,
Parse::TuplePatternStartId parse_node) -> bool {
context.node_stack().Push(parse_node);
Parse::TuplePatternStartId node_id) -> bool {
context.node_stack().Push(node_id);
context.param_and_arg_refs_stack().Push();
return true;
}
auto HandlePatternListComma(Context& context,
Parse::PatternListCommaId /*parse_node*/) -> bool {
Parse::PatternListCommaId /*node_id*/) -> bool {
context.param_and_arg_refs_stack().ApplyComma();
return true;
}
auto HandleTuplePattern(Context& context, Parse::TuplePatternId parse_node)
auto HandleTuplePattern(Context& context, Parse::TuplePatternId node_id)
-> bool {
auto refs_id = context.param_and_arg_refs_stack().EndAndPop(
Parse::NodeKind::TuplePatternStart);
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::TuplePatternStart>();
context.node_stack().Push(parse_node, refs_id);
.PopAndDiscardSoloNodeId<Parse::NodeKind::TuplePatternStart>();
context.node_stack().Push(node_id, refs_id);
return true;
}
+14 -15
View File
@@ -8,45 +8,44 @@
namespace Carbon::Check {
auto HandleReturnStatementStart(Context& context,
Parse::ReturnStatementStartId parse_node)
-> bool {
Parse::ReturnStatementStartId node_id) -> bool {
// No action, just a bracketing node.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
return true;
}
auto HandleReturnVarModifier(Context& context,
Parse::ReturnVarModifierId parse_node) -> bool {
Parse::ReturnVarModifierId node_id) -> bool {
// No action, just a bracketing node.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
return true;
}
auto HandleReturnStatement(Context& context,
Parse::ReturnStatementId parse_node) -> bool {
switch (context.node_stack().PeekParseNodeKind()) {
auto HandleReturnStatement(Context& context, Parse::ReturnStatementId node_id)
-> bool {
switch (context.node_stack().PeekNodeKind()) {
case Parse::NodeKind::ReturnStatementStart:
// This is a `return;` statement.
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ReturnStatementStart>();
BuildReturnWithNoExpr(context, parse_node);
.PopAndDiscardSoloNodeId<Parse::NodeKind::ReturnStatementStart>();
BuildReturnWithNoExpr(context, node_id);
break;
case Parse::NodeKind::ReturnVarModifier:
// This is a `return var;` statement.
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ReturnVarModifier>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::ReturnVarModifier>();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ReturnStatementStart>();
BuildReturnVar(context, parse_node);
.PopAndDiscardSoloNodeId<Parse::NodeKind::ReturnStatementStart>();
BuildReturnVar(context, node_id);
break;
default:
// This is a `return <expression>;` statement.
auto expr_id = context.node_stack().PopExpr();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::ReturnStatementStart>();
BuildReturnWithExpr(context, parse_node, expr_id);
.PopAndDiscardSoloNodeId<Parse::NodeKind::ReturnStatementStart>();
BuildReturnWithExpr(context, node_id, expr_id);
break;
}
+22 -22
View File
@@ -8,10 +8,10 @@
namespace Carbon::Check {
auto HandleStructLiteralOrStructTypeLiteralStart(
Context& context, Parse::StructLiteralOrStructTypeLiteralStartId parse_node)
Context& context, Parse::StructLiteralOrStructTypeLiteralStartId node_id)
-> bool {
context.scope_stack().Push();
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
// At this point we aren't sure whether this will be a value or type literal,
// so we push onto args irrespective. It just won't be used for a type
// literal.
@@ -21,23 +21,23 @@ auto HandleStructLiteralOrStructTypeLiteralStart(
}
auto HandleStructFieldDesignator(Context& context,
Parse::StructFieldDesignatorId /*parse_node*/)
Parse::StructFieldDesignatorId /*node_id*/)
-> bool {
// This leaves the designated name on top because the `.` isn't interesting.
CARBON_CHECK(context.node_stack().PeekIsName());
return true;
}
auto HandleStructComma(Context& context, Parse::StructCommaId /*parse_node*/)
auto HandleStructComma(Context& context, Parse::StructCommaId /*node_id*/)
-> bool {
context.param_and_arg_refs_stack().ApplyComma();
return true;
}
auto HandleStructFieldValue(Context& context,
Parse::StructFieldValueId parse_node) -> bool {
auto HandleStructFieldValue(Context& context, Parse::StructFieldValueId node_id)
-> bool {
auto value_inst_id = context.node_stack().PopExpr();
auto [name_node, name_id] = context.node_stack().PopNameWithParseNode();
auto [name_node, name_id] = context.node_stack().PopNameWithNodeId();
// Store the name for the type.
context.args_type_info_stack().AddInstId(context.AddInstInNoBlock(
@@ -45,20 +45,20 @@ auto HandleStructFieldValue(Context& context,
name_id, context.insts().Get(value_inst_id).type_id()}}));
// Push the value back on the stack as an argument.
context.node_stack().Push(parse_node, value_inst_id);
context.node_stack().Push(node_id, value_inst_id);
return true;
}
auto HandleStructFieldType(Context& context,
Parse::StructFieldTypeId parse_node) -> bool {
auto [type_node, type_id] = context.node_stack().PopExprWithParseNode();
auto HandleStructFieldType(Context& context, Parse::StructFieldTypeId node_id)
-> bool {
auto [type_node, type_id] = context.node_stack().PopExprWithNodeId();
SemIR::TypeId cast_type_id = ExprAsType(context, type_node, type_id);
auto [name_node, name_id] = context.node_stack().PopNameWithParseNode();
auto [name_node, name_id] = context.node_stack().PopNameWithNodeId();
auto inst_id = context.AddInst(
{name_node, SemIR::StructTypeField{name_id, cast_type_id}});
context.node_stack().Push(parse_node, inst_id);
context.node_stack().Push(node_id, inst_id);
return true;
}
@@ -89,37 +89,37 @@ static auto DiagnoseDuplicateNames(Context& context,
return false;
}
auto HandleStructLiteral(Context& context, Parse::StructLiteralId parse_node)
auto HandleStructLiteral(Context& context, Parse::StructLiteralId node_id)
-> bool {
auto refs_id = context.param_and_arg_refs_stack().EndAndPop(
Parse::NodeKind::StructLiteralOrStructTypeLiteralStart);
context.scope_stack().Pop();
context.node_stack()
.PopAndDiscardSoloParseNode<
.PopAndDiscardSoloNodeId<
Parse::NodeKind::StructLiteralOrStructTypeLiteralStart>();
auto type_block_id = context.args_type_info_stack().Pop();
if (DiagnoseDuplicateNames(context, type_block_id, "struct literal")) {
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinError);
return true;
}
auto type_id = context.GetStructType(type_block_id);
auto value_id =
context.AddInst({parse_node, SemIR::StructLiteral{type_id, refs_id}});
context.node_stack().Push(parse_node, value_id);
context.AddInst({node_id, SemIR::StructLiteral{type_id, refs_id}});
context.node_stack().Push(node_id, value_id);
return true;
}
auto HandleStructTypeLiteral(Context& context,
Parse::StructTypeLiteralId parse_node) -> bool {
Parse::StructTypeLiteralId node_id) -> bool {
auto refs_id = context.param_and_arg_refs_stack().EndAndPop(
Parse::NodeKind::StructLiteralOrStructTypeLiteralStart);
context.scope_stack().Pop();
context.node_stack()
.PopAndDiscardSoloParseNode<
.PopAndDiscardSoloNodeId<
Parse::NodeKind::StructLiteralOrStructTypeLiteralStart>();
// This is only used for value literals.
context.args_type_info_stack().Pop();
@@ -128,11 +128,11 @@ auto HandleStructTypeLiteral(Context& context,
<< "{} is handled by StructLiteral.";
if (DiagnoseDuplicateNames(context, refs_id, "struct type literal")) {
context.node_stack().Push(parse_node, SemIR::InstId::BuiltinError);
context.node_stack().Push(node_id, SemIR::InstId::BuiltinError);
return true;
}
context.AddInstAndPush(
{parse_node, SemIR::StructType{SemIR::TypeId::TypeType, refs_id}});
{node_id, SemIR::StructType{SemIR::TypeId::TypeType, refs_id}});
return true;
}
+17 -18
View File
@@ -9,45 +9,44 @@
namespace Carbon::Check {
auto HandleVariableIntroducer(Context& context,
Parse::VariableIntroducerId parse_node) -> bool {
Parse::VariableIntroducerId node_id) -> bool {
// No action, just a bracketing node.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
context.decl_state_stack().Push(DeclState::Var);
return true;
}
auto HandleReturnedModifier(Context& context,
Parse::ReturnedModifierId parse_node) -> bool {
auto HandleReturnedModifier(Context& context, Parse::ReturnedModifierId node_id)
-> bool {
// No action, just a bracketing node.
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
return true;
}
auto HandleVariableInitializer(Context& context,
Parse::VariableInitializerId parse_node)
-> bool {
Parse::VariableInitializerId node_id) -> bool {
if (context.scope_stack().PeekIndex() == ScopeIndex::Package) {
context.inst_block_stack().PushGlobalInit();
}
context.node_stack().Push(parse_node);
context.node_stack().Push(node_id);
return true;
}
auto HandleVariableDecl(Context& context, Parse::VariableDeclId parse_node)
auto HandleVariableDecl(Context& context, Parse::VariableDeclId node_id)
-> bool {
// Handle the optional initializer.
std::optional<SemIR::InstId> init_id;
if (context.node_stack().PeekNextIs<Parse::NodeKind::VariableInitializer>()) {
init_id = context.node_stack().PopExpr();
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::VariableInitializer>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::VariableInitializer>();
}
if (context.node_stack().PeekIs<Parse::NodeKind::TuplePattern>()) {
if (init_id && context.scope_stack().PeekIndex() == ScopeIndex::Package) {
context.inst_block_stack().PopGlobalInit();
}
return context.TODO(parse_node, "tuple pattern in var");
return context.TODO(node_id, "tuple pattern in var");
}
// Extract the name binding.
@@ -56,7 +55,7 @@ auto HandleVariableDecl(Context& context, Parse::VariableDeclId parse_node)
// Form a corresponding name in the current context, and bind the name to
// the variable.
auto name_context = context.decl_name_stack().MakeUnqualifiedName(
context.insts().GetParseNode(value_id),
context.insts().GetNodeId(value_id),
context.bind_names().Get(bind_name->bind_name_id).name_id);
context.decl_name_stack().AddNameToLookup(name_context, value_id);
value_id = bind_name->value_id;
@@ -64,26 +63,26 @@ auto HandleVariableDecl(Context& context, Parse::VariableDeclId parse_node)
context.insts().TryGetAs<SemIR::FieldDecl>(value_id)) {
// Introduce the field name into the class.
auto name_context = context.decl_name_stack().MakeUnqualifiedName(
context.insts().GetParseNode(value_id), field_decl->name_id);
context.insts().GetNodeId(value_id), field_decl->name_id);
context.decl_name_stack().AddNameToLookup(name_context, value_id);
}
// TODO: Handle other kinds of pattern.
// Pop the `returned` specifier if present.
context.node_stack()
.PopAndDiscardSoloParseNodeIf<Parse::NodeKind::ReturnedModifier>();
.PopAndDiscardSoloNodeIdIf<Parse::NodeKind::ReturnedModifier>();
// If there was an initializer, assign it to the storage.
if (init_id) {
if (context.GetCurrentScopeAs<SemIR::ClassDecl>()) {
// TODO: In a class scope, we should instead save the initializer
// somewhere so that we can use it as a default.
context.TODO(parse_node, "Field initializer");
context.TODO(node_id, "Field initializer");
} else {
init_id = Initialize(context, parse_node, value_id, *init_id);
init_id = Initialize(context, node_id, value_id, *init_id);
// TODO: Consider using different instruction kinds for assignment versus
// initialization.
context.AddInst({parse_node, SemIR::Assign{value_id, *init_id}});
context.AddInst({node_id, SemIR::Assign{value_id, *init_id}});
}
if (context.scope_stack().PeekIndex() == ScopeIndex::Package) {
context.inst_block_stack().PopGlobalInit();
@@ -91,7 +90,7 @@ auto HandleVariableDecl(Context& context, Parse::VariableDeclId parse_node)
}
context.node_stack()
.PopAndDiscardSoloParseNode<Parse::NodeKind::VariableIntroducer>();
.PopAndDiscardSoloNodeId<Parse::NodeKind::VariableIntroducer>();
// Process declaration modifiers.
// TODO: For a qualified `var` declaration, this should use the target scope
+2 -2
View File
@@ -104,7 +104,7 @@ static auto BuildInterfaceWitness(
}
} else if (auto const_decl = decl.TryAs<SemIR::AssociatedConstantDecl>()) {
// TODO: Check we have a value for this constant in the constraint.
context.TODO(context.insts().GetParseNode(impl.definition_id),
context.TODO(context.insts().GetNodeId(impl.definition_id),
"impl of interface with associated constant");
return SemIR::InstId::BuiltinError;
} else {
@@ -127,7 +127,7 @@ auto BuildImplWitness(Context& context, SemIR::ImplId impl_id)
auto interface_type =
context.types().TryGetAs<SemIR::InterfaceType>(impl.constraint_id);
if (!interface_type) {
context.TODO(context.insts().GetParseNode(impl.definition_id),
context.TODO(context.insts().GetNodeId(impl.definition_id),
"impl as non-interface");
return SemIR::InstId::BuiltinError;
}
+1 -1
View File
@@ -29,7 +29,7 @@ auto BuildAssociatedEntity(Context& context, SemIR::InterfaceId interface_id,
// not the declaration itself.
auto type_id = context.GetAssociatedEntityType(
interface_id, context.insts().Get(decl_id).type_id());
return context.AddInst({context.insts().GetParseNode(decl_id),
return context.AddInst({context.insts().GetNodeId(decl_id),
SemIR::AssociatedEntity{type_id, index, decl_id}});
}
+2 -2
View File
@@ -121,12 +121,12 @@ auto CheckMethodModifiersOnFunction(Context& context,
if (inheritance_kind == SemIR::Class::Final) {
ForbidModifiersOnDecl(context, KeywordModifierSet::Virtual, decl_kind,
" in a non-abstract non-base `class` definition",
context.insts().GetParseNode(target_id));
context.insts().GetNodeId(target_id));
}
if (inheritance_kind != SemIR::Class::Abstract) {
ForbidModifiersOnDecl(context, KeywordModifierSet::Abstract, decl_kind,
" in a non-abstract `class` definition",
context.insts().GetParseNode(target_id));
context.insts().GetNodeId(target_id));
}
return;
}
+6 -7
View File
@@ -21,13 +21,12 @@ auto NodeStack::PrintForStackDump(llvm::raw_ostream& output) const -> void {
output << "NodeStack:\n";
for (auto [i, entry] : llvm::enumerate(stack_)) {
auto parse_node_kind = parse_tree_->node_kind(entry.parse_node);
output << "\t" << i << ".\t" << parse_node_kind;
switch (parse_node_kind) {
#define CARBON_PARSE_NODE_KIND(Kind) \
case Parse::NodeKind::Kind: \
print_id.operator()<ParseNodeKindToIdKind(Parse::NodeKind::Kind)>( \
entry.id); \
auto node_kind = parse_tree_->node_kind(entry.node_id);
output << "\t" << i << ".\t" << node_kind;
switch (node_kind) {
#define CARBON_PARSE_NODE_KIND(Kind) \
case Parse::NodeKind::Kind: \
print_id.operator()<NodeKindToIdKind(Parse::NodeKind::Kind)>(entry.id); \
break;
#include "toolchain/parse/node_kind.def"
}
+88 -96
View File
@@ -83,11 +83,11 @@ class IdUnion {
//
// Pop APIs will run basic verification:
//
// - If receiving a Parse::NodeKind, verify that the parse_node being popped has
// - If receiving a Parse::NodeKind, verify that the node_id being popped has
// that kind. Similarly, if receiving a Parse::NodeCategory, make sure the
// of the popped parse_node overlaps that category.
// of the popped node_id overlaps that category.
// - Validates the kind of id data in the node based on the kind or category of
// the parse_node.
// the node_id.
//
// These should be assumed API constraints unless otherwise mentioned on a
// method. The main exception is PopAndIgnore, which doesn't do verification.
@@ -99,36 +99,36 @@ class NodeStack {
// Pushes a solo parse tree node onto the stack. Used when there is no
// IR generated by the node.
auto Push(Parse::NodeId parse_node) -> void {
auto kind = parse_tree_->node_kind(parse_node);
CARBON_CHECK(ParseNodeKindToIdKind(kind) == Id::Kind::None)
auto Push(Parse::NodeId node_id) -> void {
auto kind = parse_tree_->node_kind(node_id);
CARBON_CHECK(NodeKindToIdKind(kind) == Id::Kind::None)
<< "Parse kind expects an Id: " << kind;
CARBON_VLOG() << "Node Push " << stack_.size() << ": " << kind
<< " -> <none>\n";
CARBON_CHECK(stack_.size() < (1 << 20))
<< "Excessive stack size: likely infinite loop";
stack_.push_back(Entry{parse_node, Id()});
stack_.push_back(Entry{node_id, Id()});
}
// Pushes a parse tree node onto the stack with an ID.
template <typename IdT>
auto Push(Parse::NodeId parse_node, IdT id) -> void {
auto kind = parse_tree_->node_kind(parse_node);
CARBON_CHECK(ParseNodeKindToIdKind(kind) == Id::KindFor<IdT>())
auto Push(Parse::NodeId node_id, IdT id) -> void {
auto kind = parse_tree_->node_kind(node_id);
CARBON_CHECK(NodeKindToIdKind(kind) == Id::KindFor<IdT>())
<< "Parse kind expected a different IdT: " << kind << " -> " << id
<< "\n";
CARBON_CHECK(id.is_valid()) << "Push called with invalid id: "
<< parse_tree_->node_kind(parse_node);
CARBON_CHECK(id.is_valid())
<< "Push called with invalid id: " << parse_tree_->node_kind(node_id);
CARBON_VLOG() << "Node Push " << stack_.size() << ": " << kind << " -> "
<< id << "\n";
CARBON_CHECK(stack_.size() < (1 << 20))
<< "Excessive stack size: likely infinite loop";
stack_.push_back(Entry{parse_node, Id(id)});
stack_.push_back(Entry{node_id, Id(id)});
}
// Returns whether there is a node of the specified kind on top of the stack.
auto PeekIs(Parse::NodeKind kind) const -> bool {
return !stack_.empty() && PeekParseNodeKind() == kind;
return !stack_.empty() && PeekNodeKind() == kind;
}
// Returns whether there is a node of the specified kind on top of the stack.
@@ -141,7 +141,7 @@ class NodeStack {
// Returns whether the node on the top of the stack has an overlapping
// category.
auto PeekIs(Parse::NodeCategory category) const -> bool {
return !stack_.empty() && !!(PeekParseNodeKind().category() & category);
return !stack_.empty() && !!(PeekNodeKind().category() & category);
}
// Returns whether the node on the top of the stack has an overlapping
@@ -154,8 +154,8 @@ class NodeStack {
// Returns whether there is a name on top of the stack.
auto PeekIsName() const -> bool {
return !stack_.empty() && ParseNodeKindToIdKind(PeekParseNodeKind()) ==
Id::KindFor<SemIR::NameId>();
return !stack_.empty() &&
NodeKindToIdKind(PeekNodeKind()) == Id::KindFor<SemIR::NameId>();
}
// Returns whether the *next* node on the stack is a given kind. This doesn't
@@ -165,7 +165,7 @@ class NodeStack {
template <const Parse::NodeKind& RequiredParseKind>
auto PeekNextIs() const -> bool {
CARBON_CHECK(stack_.size() >= 2);
return parse_tree_->node_kind(stack_[stack_.size() - 2].parse_node) ==
return parse_tree_->node_kind(stack_[stack_.size() - 2].node_id) ==
RequiredParseKind;
}
@@ -173,110 +173,107 @@ class NodeStack {
auto PopAndIgnore() -> void {
Entry back = stack_.pop_back_val();
CARBON_VLOG() << "Node Pop " << stack_.size() << ": "
<< parse_tree_->node_kind(back.parse_node)
<< " -> <ignored>\n";
<< parse_tree_->node_kind(back.node_id) << " -> <ignored>\n";
}
// Pops the top of the stack and returns the parse_node.
// Pops the top of the stack and returns the node_id.
template <const Parse::NodeKind& RequiredParseKind>
auto PopForSoloParseNode() -> Parse::NodeIdForKind<RequiredParseKind> {
auto PopForSoloNodeId() -> Parse::NodeIdForKind<RequiredParseKind> {
Entry back = PopEntry<SemIR::InstId>();
RequireIdKind(RequiredParseKind, Id::Kind::None);
RequireParseKind<RequiredParseKind>(back.parse_node);
return Parse::NodeIdForKind<RequiredParseKind>(back.parse_node);
RequireParseKind<RequiredParseKind>(back.node_id);
return Parse::NodeIdForKind<RequiredParseKind>(back.node_id);
}
// Pops the top of the stack if it is the given kind, and returns the
// parse_node. Otherwise, returns std::nullopt.
// node_id. Otherwise, returns std::nullopt.
template <const Parse::NodeKind& RequiredParseKind>
auto PopForSoloParseNodeIf()
auto PopForSoloNodeIdIf()
-> std::optional<Parse::NodeIdForKind<RequiredParseKind>> {
if (PeekIs<RequiredParseKind>()) {
return PopForSoloParseNode<RequiredParseKind>();
return PopForSoloNodeId<RequiredParseKind>();
}
return std::nullopt;
}
// Pops the top of the stack.
template <const Parse::NodeKind& RequiredParseKind>
auto PopAndDiscardSoloParseNode() -> void {
PopForSoloParseNode<RequiredParseKind>();
auto PopAndDiscardSoloNodeId() -> void {
PopForSoloNodeId<RequiredParseKind>();
}
// Pops the top of the stack if it is the given kind. Returns `true` if a node
// was popped.
template <const Parse::NodeKind& RequiredParseKind>
auto PopAndDiscardSoloParseNodeIf() -> bool {
auto PopAndDiscardSoloNodeIdIf() -> bool {
if (!PeekIs<RequiredParseKind>()) {
return false;
}
PopForSoloParseNode<RequiredParseKind>();
PopForSoloNodeId<RequiredParseKind>();
return true;
}
// Pops an expression from the top of the stack and returns the parse_node and
// Pops an expression from the top of the stack and returns the node_id and
// the ID.
auto PopExprWithParseNode() -> std::pair<Parse::AnyExprId, SemIR::InstId>;
auto PopExprWithNodeId() -> std::pair<Parse::AnyExprId, SemIR::InstId>;
// Pops a pattern from the top of the stack and returns the parse_node and
// Pops a pattern from the top of the stack and returns the node_id and
// the ID.
auto PopPatternWithParseNode() -> std::pair<Parse::NodeId, SemIR::InstId> {
return PopWithParseNode<SemIR::InstId>();
auto PopPatternWithNodeId() -> std::pair<Parse::NodeId, SemIR::InstId> {
return PopWithNodeId<SemIR::InstId>();
}
// Pops a name from the top of the stack and returns the parse_node and
// Pops a name from the top of the stack and returns the node_id and
// the ID.
auto PopNameWithParseNode() -> std::pair<Parse::NodeId, SemIR::NameId> {
return PopWithParseNode<SemIR::NameId>();
auto PopNameWithNodeId() -> std::pair<Parse::NodeId, SemIR::NameId> {
return PopWithNodeId<SemIR::NameId>();
}
// Pops the top of the stack and returns the parse_node and the ID.
// Pops the top of the stack and returns the node_id and the ID.
template <const Parse::NodeKind& RequiredParseKind>
auto PopWithParseNode() -> auto {
auto PopWithNodeId() -> auto {
auto id = Peek<RequiredParseKind>();
Parse::NodeIdForKind<RequiredParseKind> parse_node(
stack_.pop_back_val().parse_node);
return std::make_pair(parse_node, id);
Parse::NodeIdForKind<RequiredParseKind> node_id(
stack_.pop_back_val().node_id);
return std::make_pair(node_id, id);
}
// Pops the top of the stack and returns the parse_node and the ID.
// Pops the top of the stack and returns the node_id and the ID.
template <Parse::NodeCategory RequiredParseCategory>
auto PopWithParseNode() -> auto {
auto PopWithNodeId() -> auto {
auto id = Peek<RequiredParseCategory>();
Parse::NodeIdInCategory<RequiredParseCategory> parse_node(
stack_.pop_back_val().parse_node);
return std::make_pair(parse_node, id);
Parse::NodeIdInCategory<RequiredParseCategory> node_id(
stack_.pop_back_val().node_id);
return std::make_pair(node_id, id);
}
// Pops an expression from the top of the stack and returns the ID.
// Expressions always map Parse::NodeCategory::Expr nodes to SemIR::InstId.
auto PopExpr() -> SemIR::InstId { return PopExprWithParseNode().second; }
auto PopExpr() -> SemIR::InstId { return PopExprWithNodeId().second; }
// Pops a pattern from the top of the stack and returns the ID.
// Patterns map multiple Parse::NodeKinds to SemIR::InstId always.
auto PopPattern() -> SemIR::InstId {
return PopPatternWithParseNode().second;
}
auto PopPattern() -> SemIR::InstId { return PopPatternWithNodeId().second; }
// Pops a name from the top of the stack and returns the ID.
auto PopName() -> SemIR::NameId { return PopNameWithParseNode().second; }
auto PopName() -> SemIR::NameId { return PopNameWithNodeId().second; }
// Pops the top of the stack and returns the ID.
template <const Parse::NodeKind& RequiredParseKind>
auto Pop() -> auto {
return PopWithParseNode<RequiredParseKind>().second;
return PopWithNodeId<RequiredParseKind>().second;
}
// Pops the top of the stack and returns the ID.
template <Parse::NodeCategory RequiredParseCategory>
auto Pop() -> auto {
return PopWithParseNode<RequiredParseCategory>().second;
return PopWithNodeId<RequiredParseCategory>().second;
}
// Pops the top of the stack and returns the ID.
template <typename IdT>
auto Pop() -> IdT {
return PopWithParseNode<IdT>().second;
return PopWithNodeId<IdT>().second;
}
// Pops the top of the stack if it has the given kind, and returns the ID.
@@ -299,47 +296,43 @@ class NodeStack {
return std::nullopt;
}
// Pops the top of the stack and returns the parse_node and the ID if it is
// Pops the top of the stack and returns the node_id and the ID if it is
// of the specified kind.
template <const Parse::NodeKind& RequiredParseKind>
auto PopWithParseNodeIf()
-> std::pair<Parse::NodeIdForKind<RequiredParseKind>,
decltype(PopIf<RequiredParseKind>())> {
auto PopWithNodeIdIf() -> std::pair<Parse::NodeIdForKind<RequiredParseKind>,
decltype(PopIf<RequiredParseKind>())> {
if (!PeekIs<RequiredParseKind>()) {
return {Parse::NodeId::Invalid, std::nullopt};
}
return PopWithParseNode<RequiredParseKind>();
return PopWithNodeId<RequiredParseKind>();
}
// Pops the top of the stack and returns the parse_node and the ID if it is
// Pops the top of the stack and returns the node_id and the ID if it is
// of the specified category.
template <Parse::NodeCategory RequiredParseCategory>
auto PopWithParseNodeIf()
auto PopWithNodeIdIf()
-> std::pair<Parse::NodeIdInCategory<RequiredParseCategory>,
decltype(PopIf<RequiredParseCategory>())> {
if (!PeekIs<RequiredParseCategory>()) {
return {Parse::NodeId::Invalid, std::nullopt};
}
return PopWithParseNode<RequiredParseCategory>();
return PopWithNodeId<RequiredParseCategory>();
}
// Peeks at the parse node of the top of the node stack.
auto PeekParseNode() const -> Parse::NodeId {
return stack_.back().parse_node;
}
auto PeekNodeId() const -> Parse::NodeId { return stack_.back().node_id; }
// Peeks at the kind of the parse node of the top of the node stack.
auto PeekParseNodeKind() const -> Parse::NodeKind {
return parse_tree_->node_kind(PeekParseNode());
auto PeekNodeKind() const -> Parse::NodeKind {
return parse_tree_->node_kind(PeekNodeId());
}
// Peeks at the ID associated with the top of the name stack.
template <const Parse::NodeKind& RequiredParseKind>
auto Peek() const -> auto {
Entry back = stack_.back();
RequireParseKind<RequiredParseKind>(back.parse_node);
constexpr Id::Kind RequiredIdKind =
ParseNodeKindToIdKind(RequiredParseKind);
RequireParseKind<RequiredParseKind>(back.node_id);
constexpr Id::Kind RequiredIdKind = NodeKindToIdKind(RequiredParseKind);
return Peek<RequiredIdKind>();
}
@@ -347,9 +340,9 @@ class NodeStack {
template <Parse::NodeCategory RequiredParseCategory>
auto Peek() const -> auto {
Entry back = stack_.back();
RequireParseCategory<RequiredParseCategory>(back.parse_node);
RequireParseCategory<RequiredParseCategory>(back.node_id);
constexpr std::optional<Id::Kind> RequiredIdKind =
ParseNodeCategoryToIdKind(RequiredParseCategory, false);
NodeCategoryToIdKind(RequiredParseCategory, false);
static_assert(RequiredIdKind.has_value());
return Peek<*RequiredIdKind>();
}
@@ -364,8 +357,8 @@ class NodeStack {
// An ID that can be associated with a parse node.
//
// Each parse node kind has a corresponding Id::Kind indicating which kind of
// ID is stored, computed by ParseNodeKindToIdKind. Id::Kind::None indicates
// that the parse node has no associated ID, in which case the *SoloParseNode
// ID is stored, computed by NodeKindToIdKind. Id::Kind::None indicates
// that the parse node has no associated ID, in which case the *SoloNodeId
// functions should be used to push and pop it. Id::Kind::Invalid indicates
// that the parse node should not appear in the node stack at all.
using Id = IdUnion<SemIR::InstId, SemIR::InstBlockId, SemIR::FunctionId,
@@ -375,7 +368,7 @@ class NodeStack {
// An entry in stack_.
struct Entry {
// The parse node associated with the stack entry.
Parse::NodeId parse_node;
Parse::NodeId node_id;
// The ID associated with this parse node. The kind of ID is determined by
// the kind of the parse node, so a separate discriminiator is not needed.
@@ -385,8 +378,8 @@ class NodeStack {
// Translate a parse node category to the enum ID kind it should always
// provide, if it is consistent.
static constexpr auto ParseNodeCategoryToIdKind(Parse::NodeCategory category,
bool for_node_kind)
static constexpr auto NodeCategoryToIdKind(Parse::NodeCategory category,
bool for_node_kind)
-> std::optional<Id::Kind> {
std::optional<Id::Kind> result;
auto set_id_if_category_is = [&](Parse::NodeCategory cat, Id::Kind kind) {
@@ -422,7 +415,7 @@ class NodeStack {
using IdKindTableType = std::array<Id::Kind, Parse::NodeKind::ValidCount>;
// Lookup table to implement `ParseNodeKindToIdKind`. Initialized to the
// Lookup table to implement `NodeKindToIdKind`. Initialized to the
// return value of `ComputeIdKindTable()`.
static const IdKindTableType IdKindTable;
@@ -432,7 +425,7 @@ class NodeStack {
auto to_id_kind =
[](const Parse::NodeKind::Definition& node_kind) -> Id::Kind {
if (auto from_category =
ParseNodeCategoryToIdKind(node_kind.category(), true)) {
NodeCategoryToIdKind(node_kind.category(), true)) {
return *from_category;
}
switch (node_kind) {
@@ -498,8 +491,7 @@ class NodeStack {
}
// Translate a parse node kind to the enum ID kind it should always provide.
static constexpr auto ParseNodeKindToIdKind(Parse::NodeKind kind)
-> Id::Kind {
static constexpr auto NodeKindToIdKind(Parse::NodeKind kind) -> Id::Kind {
return IdKindTable[kind.AsInt()];
}
@@ -515,38 +507,38 @@ class NodeStack {
auto PopEntry() -> Entry {
Entry back = stack_.pop_back_val();
CARBON_VLOG() << "Node Pop " << stack_.size() << ": "
<< parse_tree_->node_kind(back.parse_node) << " -> "
<< parse_tree_->node_kind(back.node_id) << " -> "
<< back.id.template As<IdT>() << "\n";
return back;
}
// Pops the top of the stack and returns the parse_node and the ID.
// Pops the top of the stack and returns the node_id and the ID.
template <typename IdT>
auto PopWithParseNode() -> std::pair<Parse::NodeId, IdT> {
auto PopWithNodeId() -> std::pair<Parse::NodeId, IdT> {
Entry back = PopEntry<IdT>();
RequireIdKind(parse_tree_->node_kind(back.parse_node), Id::KindFor<IdT>());
return {back.parse_node, back.id.template As<IdT>()};
RequireIdKind(parse_tree_->node_kind(back.node_id), Id::KindFor<IdT>());
return {back.node_id, back.id.template As<IdT>()};
}
// Require a Parse::NodeKind be mapped to a particular Id::Kind.
auto RequireIdKind(Parse::NodeKind parse_kind, Id::Kind id_kind) const
-> void {
CARBON_CHECK(ParseNodeKindToIdKind(parse_kind) == id_kind)
CARBON_CHECK(NodeKindToIdKind(parse_kind) == id_kind)
<< "Unexpected Id::Kind mapping for " << parse_kind;
}
// Require an entry to have the given Parse::NodeKind.
template <const Parse::NodeKind& RequiredParseKind>
auto RequireParseKind(Parse::NodeId parse_node) const -> void {
auto actual_kind = parse_tree_->node_kind(parse_node);
auto RequireParseKind(Parse::NodeId node_id) const -> void {
auto actual_kind = parse_tree_->node_kind(node_id);
CARBON_CHECK(RequiredParseKind == actual_kind)
<< "Expected " << RequiredParseKind << ", found " << actual_kind;
}
// Require an entry to have the given Parse::NodeCategory.
template <Parse::NodeCategory RequiredParseCategory>
auto RequireParseCategory(Parse::NodeId parse_node) const -> void {
auto kind = parse_tree_->node_kind(parse_node);
auto RequireParseCategory(Parse::NodeId node_id) const -> void {
auto kind = parse_tree_->node_kind(node_id);
CARBON_CHECK(!!(RequiredParseCategory & kind.category()))
<< "Expected " << RequiredParseCategory << ", found " << kind
<< " with category " << kind.category();
@@ -567,9 +559,9 @@ class NodeStack {
constexpr NodeStack::IdKindTableType NodeStack::IdKindTable =
ComputeIdKindTable();
inline auto NodeStack::PopExprWithParseNode()
inline auto NodeStack::PopExprWithNodeId()
-> std::pair<Parse::AnyExprId, SemIR::InstId> {
return PopWithParseNode<Parse::NodeCategory::Expr>();
return PopWithNodeId<Parse::NodeCategory::Expr>();
}
} // namespace Carbon::Check
+5 -5
View File
@@ -39,8 +39,8 @@ class PendingBlock {
size_t size_;
};
auto AddInst(SemIR::ParseNodeAndInst parse_node_and_inst) -> SemIR::InstId {
auto inst_id = context_.AddInstInNoBlock(parse_node_and_inst);
auto AddInst(SemIR::NodeIdAndInst node_id_and_inst) -> SemIR::InstId {
auto inst_id = context_.AddInstInNoBlock(node_id_and_inst);
insts_.push_back(inst_id);
return inst_id;
}
@@ -56,7 +56,7 @@ class PendingBlock {
// Replace the instruction at target_id with the instructions in this block.
// The new value for target_id should be value_id.
auto MergeReplacing(SemIR::InstId target_id, SemIR::InstId value_id) -> void {
auto value = context_.insts().GetWithParseNode(value_id);
auto value = context_.insts().GetWithNodeId(value_id);
// There are three cases here:
@@ -64,7 +64,7 @@ class PendingBlock {
// 1) The block is empty. Replace `target_id` with an empty splice
// pointing at `value_id`.
context_.ReplaceInstBeforeConstantUse(
target_id, {value.parse_node,
target_id, {value.node_id,
SemIR::SpliceBlock{value.inst.type_id(),
SemIR::InstBlockId::Empty, value_id}});
} else if (insts_.size() == 1 && insts_[0] == value_id) {
@@ -75,7 +75,7 @@ class PendingBlock {
// 3) Anything else: splice it into the IR, replacing `target_id`.
context_.ReplaceInstBeforeConstantUse(
target_id,
{value.parse_node,
{value.node_id,
SemIR::SpliceBlock{value.inst.type_id(),
context_.inst_blocks().Add(insts_), value_id}});
}
+13 -14
View File
@@ -100,22 +100,22 @@ auto RegisterReturnedVar(Context& context, SemIR::InstId bind_id) -> void {
}
}
auto BuildReturnWithNoExpr(Context& context,
Parse::ReturnStatementId parse_node) -> void {
auto BuildReturnWithNoExpr(Context& context, Parse::ReturnStatementId node_id)
-> void {
const auto& function = GetCurrentFunction(context);
if (function.return_type_id.is_valid()) {
CARBON_DIAGNOSTIC(ReturnStatementMissingExpr, Error,
"Missing return value.");
auto diag = context.emitter().Build(parse_node, ReturnStatementMissingExpr);
auto diag = context.emitter().Build(node_id, ReturnStatementMissingExpr);
NoteReturnType(diag, function);
diag.Emit();
}
context.AddInst({parse_node, SemIR::Return{}});
context.AddInst({node_id, SemIR::Return{}});
}
auto BuildReturnWithExpr(Context& context, Parse::ReturnStatementId parse_node,
auto BuildReturnWithExpr(Context& context, Parse::ReturnStatementId node_id,
SemIR::InstId expr_id) -> void {
const auto& function = GetCurrentFunction(context);
auto returned_var_id = GetCurrentReturnedVar(context);
@@ -124,8 +124,7 @@ auto BuildReturnWithExpr(Context& context, Parse::ReturnStatementId parse_node,
CARBON_DIAGNOSTIC(
ReturnStatementDisallowExpr, Error,
"No return expression should be provided in this context.");
auto diag =
context.emitter().Build(parse_node, ReturnStatementDisallowExpr);
auto diag = context.emitter().Build(node_id, ReturnStatementDisallowExpr);
NoteNoReturnTypeProvided(diag, function);
diag.Emit();
expr_id = SemIR::InstId::BuiltinError;
@@ -133,21 +132,21 @@ auto BuildReturnWithExpr(Context& context, Parse::ReturnStatementId parse_node,
CARBON_DIAGNOSTIC(
ReturnExprWithReturnedVar, Error,
"Can only `return var;` in the scope of a `returned var`.");
auto diag = context.emitter().Build(parse_node, ReturnExprWithReturnedVar);
auto diag = context.emitter().Build(node_id, ReturnExprWithReturnedVar);
NoteReturnedVar(diag, returned_var_id);
diag.Emit();
expr_id = SemIR::InstId::BuiltinError;
} else if (function.return_slot_id.is_valid()) {
expr_id = Initialize(context, parse_node, function.return_slot_id, expr_id);
expr_id = Initialize(context, node_id, function.return_slot_id, expr_id);
} else {
expr_id = ConvertToValueOfType(context, parse_node, expr_id,
expr_id = ConvertToValueOfType(context, node_id, expr_id,
function.return_type_id);
}
context.AddInst({parse_node, SemIR::ReturnExpr{expr_id}});
context.AddInst({node_id, SemIR::ReturnExpr{expr_id}});
}
auto BuildReturnVar(Context& context, Parse::ReturnStatementId parse_node)
auto BuildReturnVar(Context& context, Parse::ReturnStatementId node_id)
-> void {
const auto& function = GetCurrentFunction(context);
auto returned_var_id = GetCurrentReturnedVar(context);
@@ -155,7 +154,7 @@ auto BuildReturnVar(Context& context, Parse::ReturnStatementId parse_node)
if (!returned_var_id.is_valid()) {
CARBON_DIAGNOSTIC(ReturnVarWithNoReturnedVar, Error,
"`return var;` with no `returned var` in scope.");
context.emitter().Emit(parse_node, ReturnVarWithNoReturnedVar);
context.emitter().Emit(node_id, ReturnVarWithNoReturnedVar);
returned_var_id = SemIR::InstId::BuiltinError;
}
@@ -165,7 +164,7 @@ auto BuildReturnVar(Context& context, Parse::ReturnStatementId parse_node)
returned_var_id = ConvertToValueExpr(context, returned_var_id);
}
context.AddInst({parse_node, SemIR::ReturnExpr{returned_var_id}});
context.AddInst({node_id, SemIR::ReturnExpr{returned_var_id}});
}
} // namespace Carbon::Check
+4 -5
View File
@@ -21,16 +21,15 @@ auto CheckReturnedVar(Context& context, Parse::NodeId returned_node,
auto RegisterReturnedVar(Context& context, SemIR::InstId bind_id) -> void;
// Checks and builds SemIR for a `return;` statement.
auto BuildReturnWithNoExpr(Context& context,
Parse::ReturnStatementId parse_node) -> void;
auto BuildReturnWithNoExpr(Context& context, Parse::ReturnStatementId node_id)
-> void;
// Checks and builds SemIR for a `return <expression>;` statement.
auto BuildReturnWithExpr(Context& context, Parse::ReturnStatementId parse_node,
auto BuildReturnWithExpr(Context& context, Parse::ReturnStatementId node_id,
SemIR::InstId expr_id) -> void;
// Checks and builds SemIR for a `return var;` statement.
auto BuildReturnVar(Context& context, Parse::ReturnStatementId parse_node)
-> void;
auto BuildReturnVar(Context& context, Parse::ReturnStatementId node_id) -> void;
} // namespace Carbon::Check
+2 -3
View File
@@ -402,14 +402,13 @@ auto Context::ConsumeListToken(NodeKind comma_kind, Lex::TokenKind close_kind,
}
}
auto Context::RecoverFromDeclError(StateStackEntry state,
NodeKind parse_node_kind,
auto Context::RecoverFromDeclError(StateStackEntry state, NodeKind node_kind,
bool skip_past_likely_end) -> void {
auto token = state.token;
if (skip_past_likely_end) {
token = SkipPastLikelyEnd(token);
}
AddNode(parse_node_kind, token, state.subtree_start,
AddNode(node_kind, token, state.subtree_start,
/*has_error=*/true);
}
+1 -1
View File
@@ -291,7 +291,7 @@ class Context {
// definition has started (although one could be present). Recover to a
// semicolon when it makes sense as a possible end, otherwise use the
// introducer token for the error.
auto RecoverFromDeclError(StateStackEntry state, NodeKind parse_node_kind,
auto RecoverFromDeclError(StateStackEntry state, NodeKind node_kind,
bool skip_past_likely_end) -> void;
// Sets the package directive information. Called at most once.
+4 -4
View File
@@ -53,14 +53,14 @@ auto HandlePatternListElementFinishAsTuple(Context& context) -> void {
}
// Handles PatternListAs(Implicit|Tuple).
static auto HandlePatternList(Context& context, NodeKind parse_node_kind,
static auto HandlePatternList(Context& context, NodeKind node_kind,
Lex::TokenKind open_token_kind,
Lex::TokenKind close_token_kind,
State param_state, State finish_state) -> void {
context.PopAndDiscardState();
context.PushState(finish_state);
context.AddLeafNode(parse_node_kind, context.ConsumeChecked(open_token_kind));
context.AddLeafNode(node_kind, context.ConsumeChecked(open_token_kind));
if (!context.PositionIs(close_token_kind)) {
context.PushState(param_state);
@@ -82,11 +82,11 @@ auto HandlePatternListAsTuple(Context& context) -> void {
}
// Handles PatternListFinishAs(Implicit|Tuple).
static auto HandlePatternListFinish(Context& context, NodeKind parse_node_kind,
static auto HandlePatternListFinish(Context& context, NodeKind node_kind,
Lex::TokenKind token_kind) -> void {
auto state = context.PopState();
context.AddNode(parse_node_kind, context.ConsumeChecked(token_kind),
context.AddNode(node_kind, context.ConsumeChecked(token_kind),
state.subtree_start, state.has_error);
}
+1 -1
View File
@@ -52,7 +52,7 @@ class NodeKind : public CARBON_ENUM_BASE(NodeKind) {
#define CARBON_PARSE_NODE_KIND(Name) CARBON_ENUM_CONSTANT_DECL(Name)
#include "toolchain/parse/node_kind.def"
// Validates that a `parse_node_kind` parser node can be generated for a
// Validates that a `node_kind` parser node can be generated for a
// `lex_token_kind` lexer token.
auto CheckMatchesTokenKind(Lex::TokenKind lex_token_kind, bool has_error)
-> void;
+1 -1
View File
@@ -26,7 +26,7 @@ auto ConstantStore::GetOrAdd(Inst inst, bool is_symbolic) -> ConstantId {
// Create the new inst and insert the new node.
auto inst_id = constants_.getContext()->insts().AddInNoBlock(
ParseNodeAndInst::Untyped(Parse::NodeId::Invalid, inst));
NodeIdAndInst::Untyped(Parse::NodeId::Invalid, inst));
auto constant_id = is_symbolic
? SemIR::ConstantId::ForSymbolicConstant(inst_id)
: SemIR::ConstantId::ForTemplateConstant(inst_id);
+13 -14
View File
@@ -78,9 +78,9 @@ class InstNamer {
CollectNamesInBlock(fn_scope, fn.param_refs_id);
if (fn.return_slot_id.is_valid()) {
insts[fn.return_slot_id.index] = {
fn_scope, GetScopeInfo(fn_scope).insts.AllocateName(
*this, sem_ir.insts().GetParseNode(fn.return_slot_id),
"return")};
fn_scope,
GetScopeInfo(fn_scope).insts.AllocateName(
*this, sem_ir.insts().GetNodeId(fn.return_slot_id), "return")};
}
if (!fn.body_block_ids.empty()) {
AddBlockLabel(fn_scope, fn.body_block_ids.front(), "entry", fn_loc);
@@ -341,30 +341,29 @@ class InstNamer {
auto AddBlockLabel(ScopeId scope_id, InstBlockId block_id,
std::string name = "",
Parse::NodeId parse_node = Parse::NodeId::Invalid)
-> void {
Parse::NodeId node_id = Parse::NodeId::Invalid) -> void {
if (!block_id.is_valid() || labels[block_id.index].second) {
return;
}
if (!parse_node.is_valid()) {
if (!node_id.is_valid()) {
if (const auto& block = sem_ir_.inst_blocks().Get(block_id);
!block.empty()) {
parse_node = sem_ir_.insts().GetParseNode(block.front());
node_id = sem_ir_.insts().GetNodeId(block.front());
}
}
labels[block_id.index] = {
scope_id, GetScopeInfo(scope_id).labels.AllocateName(*this, parse_node,
scope_id, GetScopeInfo(scope_id).labels.AllocateName(*this, node_id,
std::move(name))};
}
// Finds and adds a suitable block label for the given SemIR instruction that
// represents some kind of branch.
auto AddBlockLabel(ScopeId scope_id, Parse::NodeId parse_node,
AnyBranch branch) -> void {
auto AddBlockLabel(ScopeId scope_id, Parse::NodeId node_id, AnyBranch branch)
-> void {
llvm::StringRef name;
switch (parse_tree_.node_kind(parse_node)) {
switch (parse_tree_.node_kind(node_id)) {
case Parse::NodeKind::IfExprIf:
switch (branch.kind) {
case BranchIf::Kind:
@@ -426,7 +425,7 @@ class InstNamer {
break;
}
AddBlockLabel(scope_id, branch.target_id, name.str(), parse_node);
AddBlockLabel(scope_id, branch.target_id, name.str(), node_id);
}
auto CollectNamesInBlock(ScopeId scope_id, InstBlockId block_id) -> void {
@@ -449,7 +448,7 @@ class InstNamer {
auto add_inst_name = [&](std::string name) {
insts[inst_id.index] = {
scope_id, scope.insts.AllocateName(
*this, sem_ir_.insts().GetParseNode(inst_id), name)};
*this, sem_ir_.insts().GetNodeId(inst_id), name)};
};
auto add_inst_name_id = [&](NameId name_id, llvm::StringRef suffix = "") {
add_inst_name(
@@ -457,7 +456,7 @@ class InstNamer {
};
if (auto branch = inst.TryAs<AnyBranch>()) {
AddBlockLabel(scope_id, sem_ir_.insts().GetParseNode(inst_id), *branch);
AddBlockLabel(scope_id, sem_ir_.insts().GetNodeId(inst_id), *branch);
}
switch (inst.kind()) {
+26 -28
View File
@@ -268,38 +268,36 @@ inline auto operator<<(llvm::raw_ostream& out, TypedInst inst)
// Associates a NodeId and Inst in order to provide type-checking that the
// TypedNodeId corresponds to the InstT.
struct ParseNodeAndInst {
struct NodeIdAndInst {
// In cases where the NodeId is untyped or the InstT is unknown, the check
// can't be done at compile time.
// TODO: Consider runtime validation that InstT::Kind::TypedNodeId
// corresponds.
static auto Untyped(Parse::NodeId parse_node, Inst inst) -> ParseNodeAndInst {
return ParseNodeAndInst(parse_node, inst, /*is_untyped=*/true);
static auto Untyped(Parse::NodeId node_id, Inst inst) -> NodeIdAndInst {
return NodeIdAndInst(node_id, inst, /*is_untyped=*/true);
}
// For the common case, support construction as:
// context.AddInst({parse_node, SemIR::MyInst{...}});
// context.AddInst({node_id, SemIR::MyInst{...}});
template <typename InstT>
requires(Internal::HasParseNode<InstT>)
requires(Internal::HasNodeId<InstT>)
// NOLINTNEXTLINE(google-explicit-constructor)
ParseNodeAndInst(decltype(InstT::Kind)::TypedNodeId parse_node, InstT inst)
: parse_node(parse_node), inst(inst) {}
NodeIdAndInst(decltype(InstT::Kind)::TypedNodeId node_id, InstT inst)
: node_id(node_id), inst(inst) {}
// For cases with no parse node, support construction as:
// context.AddInst({SemIR::MyInst{...}});
template <typename InstT>
requires(!Internal::HasParseNode<InstT>)
requires(!Internal::HasNodeId<InstT>)
// NOLINTNEXTLINE(google-explicit-constructor)
ParseNodeAndInst(InstT inst)
: parse_node(Parse::NodeId::Invalid), inst(inst) {}
NodeIdAndInst(InstT inst) : node_id(Parse::NodeId::Invalid), inst(inst) {}
Parse::NodeId parse_node;
Parse::NodeId node_id;
Inst inst;
private:
explicit ParseNodeAndInst(Parse::NodeId parse_node, Inst inst,
bool /*is_untyped*/)
: parse_node(parse_node), inst(inst) {}
explicit NodeIdAndInst(Parse::NodeId node_id, Inst inst, bool /*is_untyped*/)
: node_id(node_id), inst(inst) {}
};
// Provides a ValueStore wrapper for an API specific to instructions.
@@ -310,17 +308,17 @@ class InstStore {
// instruction block. Check::Context::AddInst or InstBlockStack::AddInst
// should usually be used instead, to add the instruction to the current
// block.
auto AddInNoBlock(ParseNodeAndInst parse_node_and_inst) -> InstId {
parse_nodes_.push_back(parse_node_and_inst.parse_node);
return values_.Add(parse_node_and_inst.inst);
auto AddInNoBlock(NodeIdAndInst node_id_and_inst) -> InstId {
node_ids_.push_back(node_id_and_inst.node_id);
return values_.Add(node_id_and_inst.inst);
}
// Returns the requested instruction.
auto Get(InstId inst_id) const -> Inst { return values_.Get(inst_id); }
// Returns the requested instruction and its parse node.
auto GetWithParseNode(InstId inst_id) const -> ParseNodeAndInst {
return ParseNodeAndInst::Untyped(GetParseNode(inst_id), Get(inst_id));
auto GetWithNodeId(InstId inst_id) const -> NodeIdAndInst {
return NodeIdAndInst::Untyped(GetNodeId(inst_id), Get(inst_id));
}
// Returns whether the requested instruction is the specified type.
@@ -353,23 +351,23 @@ class InstStore {
return TryGetAs<InstT>(inst_id);
}
auto GetParseNode(InstId inst_id) const -> Parse::NodeId {
return parse_nodes_[inst_id.index];
auto GetNodeId(InstId inst_id) const -> Parse::NodeId {
return node_ids_[inst_id.index];
}
// Overwrites a given instruction and parse node with a new value.
auto Set(InstId inst_id, ParseNodeAndInst parse_node_and_inst) -> void {
values_.Get(inst_id) = parse_node_and_inst.inst;
parse_nodes_[inst_id.index] = parse_node_and_inst.parse_node;
auto Set(InstId inst_id, NodeIdAndInst node_id_and_inst) -> void {
values_.Get(inst_id) = node_id_and_inst.inst;
node_ids_[inst_id.index] = node_id_and_inst.node_id;
}
auto SetParseNode(InstId inst_id, Parse::NodeId parse_node) -> void {
parse_nodes_[inst_id.index] = parse_node;
auto SetNodeId(InstId inst_id, Parse::NodeId node_id) -> void {
node_ids_[inst_id.index] = node_id;
}
// Reserves space.
auto Reserve(size_t size) -> void {
parse_nodes_.reserve(size);
node_ids_.reserve(size);
values_.Reserve(size);
}
@@ -377,7 +375,7 @@ class InstStore {
auto size() const -> int { return values_.size(); }
private:
llvm::SmallVector<Parse::NodeId> parse_nodes_;
llvm::SmallVector<Parse::NodeId> node_ids_;
ValueStore<InstId> values_;
};
+3 -3
View File
@@ -826,10 +826,10 @@ struct VarStorage {
// These concepts are an implementation detail of the library, not public API.
namespace Internal {
// HasParseNode is true if T has an associated parse node.
// HasNodeId is true if T has an associated parse node.
template <typename T>
concept HasParseNode = !std::same_as<typename decltype(T::Kind)::TypedNodeId,
Parse::InvalidNodeId>;
concept HasNodeId = !std::same_as<typename decltype(T::Kind)::TypedNodeId,
Parse::InvalidNodeId>;
// HasKindMemberAsField<T> is true if T has a `InstKind kind` field, as opposed
// to a `static constexpr InstKind::Definition Kind` member or no kind at all.