From 288ad9f8e539c8aec9d52a027de23d3a1091a409 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 27 Jun 2023 09:26:59 -0700 Subject: [PATCH] Split statement-specific parts of `semantics_handle.cpp` into separate files. (#2949) `semantics_handle.cpp` is a little on the large side, and is going to grow as we add new nodes. Some of the statement-specific parts have already been split into their own files. Split out the remaining such parts. --- toolchain/semantics/semantics_handle.cpp | 128 ------------------ ....cpp => semantics_handle_if_statement.cpp} | 0 .../semantics_handle_loop_statement.cpp | 65 +++++++++ .../semantics/semantics_handle_statement.cpp | 83 ++++++++++++ 4 files changed, 148 insertions(+), 128 deletions(-) rename toolchain/semantics/{semantics_handle_if.cpp => semantics_handle_if_statement.cpp} (100%) create mode 100644 toolchain/semantics/semantics_handle_loop_statement.cpp create mode 100644 toolchain/semantics/semantics_handle_statement.cpp diff --git a/toolchain/semantics/semantics_handle.cpp b/toolchain/semantics/semantics_handle.cpp index f1b7c40007e0..310372b72009 100644 --- a/toolchain/semantics/semantics_handle.cpp +++ b/toolchain/semantics/semantics_handle.cpp @@ -12,26 +12,6 @@ auto SemanticsHandleAddress(SemanticsContext& context, return context.TODO(parse_node, "HandleAddress"); } -auto SemanticsHandleBreakStatement(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleBreakStatement"); -} - -auto SemanticsHandleBreakStatementStart(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleBreakStatementStart"); -} - -auto SemanticsHandleContinueStatement(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleContinueStatement"); -} - -auto SemanticsHandleContinueStatementStart(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleContinueStatementStart"); -} - auto SemanticsHandleDeducedParameterList(SemanticsContext& context, ParseTree::Node parse_node) -> bool { return context.TODO(parse_node, "HandleDeducedParameterList"); @@ -99,42 +79,12 @@ auto SemanticsHandleEmptyDeclaration(SemanticsContext& /*context*/, return true; } -auto SemanticsHandleExpressionStatement(SemanticsContext& context, - ParseTree::Node /*parse_node*/) - -> bool { - // Pop the expression without investigating its contents. - // TODO: This will probably eventually need to do some "do not discard" - // analysis. - context.node_stack().PopAndDiscardId(); - return true; -} - auto SemanticsHandleFileEnd(SemanticsContext& /*context*/, ParseTree::Node /*parse_node*/) -> bool { // Do nothing, no need to balance this node. return true; } -auto SemanticsHandleForHeader(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleForHeader"); -} - -auto SemanticsHandleForHeaderStart(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleForHeaderStart"); -} - -auto SemanticsHandleForIn(SemanticsContext& context, ParseTree::Node parse_node) - -> bool { - return context.TODO(parse_node, "HandleForIn"); -} - -auto SemanticsHandleForStatement(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleForStatement"); -} - auto SemanticsHandleGenericPatternBinding(SemanticsContext& context, ParseTree::Node parse_node) -> bool { return context.TODO(parse_node, "GenericPatternBinding"); @@ -422,69 +372,6 @@ auto SemanticsHandlePrefixOperator(SemanticsContext& context, return true; } -auto SemanticsHandleReturnStatement(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - CARBON_CHECK(!context.return_scope_stack().empty()); - const auto& fn_node = - context.semantics_ir().GetNode(context.return_scope_stack().back()); - const auto callable = - context.semantics_ir().GetFunction(fn_node.GetAsFunctionDeclaration()); - - if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) == - ParseNodeKind::ReturnStatementStart) { - context.node_stack().PopAndDiscardSoloParseNode( - ParseNodeKind::ReturnStatementStart); - - if (callable.return_type_id.is_valid()) { - // TODO: Add a note pointing at the return type's parse node. - CARBON_DIAGNOSTIC(ReturnStatementMissingExpression, Error, - "Must return a {0}.", std::string); - context.emitter() - .Build(parse_node, ReturnStatementMissingExpression, - context.semantics_ir().StringifyType(callable.return_type_id)) - .Emit(); - } - - context.AddNode(SemanticsNode::Return::Make(parse_node)); - } else { - auto arg = context.node_stack().Pop(); - context.node_stack().PopAndDiscardSoloParseNode( - ParseNodeKind::ReturnStatementStart); - - if (!callable.return_type_id.is_valid()) { - CARBON_DIAGNOSTIC( - ReturnStatementDisallowExpression, Error, - "No return expression should be provided in this context."); - CARBON_DIAGNOSTIC(ReturnStatementImplicitNote, Note, - "There was no return type provided."); - context.emitter() - .Build(parse_node, ReturnStatementDisallowExpression) - .Note(fn_node.parse_node(), ReturnStatementImplicitNote) - .Emit(); - } else { - arg = - context.ImplicitAsRequired(parse_node, arg, callable.return_type_id); - } - - context.AddNode(SemanticsNode::ReturnExpression::Make( - parse_node, context.semantics_ir().GetNode(arg).type_id(), arg)); - } - - // Switch to a new, unreachable, empty node block. This typically won't - // contain any semantics IR, but it can do if there are statements following - // the `return` statement. - context.node_block_stack().Pop(); - context.node_block_stack().PushUnreachable(); - return true; -} - -auto SemanticsHandleReturnStatementStart(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - // No action, just a bracketing node. - context.node_stack().Push(parse_node); - return true; -} - auto SemanticsHandleReturnType(SemanticsContext& context, ParseTree::Node parse_node) -> bool { // Propagate the type expression. @@ -619,19 +506,4 @@ auto SemanticsHandleVariableInitializer(SemanticsContext& context, return true; } -auto SemanticsHandleWhileCondition(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleWhileCondition"); -} - -auto SemanticsHandleWhileConditionStart(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleWhileConditionStart"); -} - -auto SemanticsHandleWhileStatement(SemanticsContext& context, - ParseTree::Node parse_node) -> bool { - return context.TODO(parse_node, "HandleWhileStatement"); -} - } // namespace Carbon diff --git a/toolchain/semantics/semantics_handle_if.cpp b/toolchain/semantics/semantics_handle_if_statement.cpp similarity index 100% rename from toolchain/semantics/semantics_handle_if.cpp rename to toolchain/semantics/semantics_handle_if_statement.cpp diff --git a/toolchain/semantics/semantics_handle_loop_statement.cpp b/toolchain/semantics/semantics_handle_loop_statement.cpp new file mode 100644 index 000000000000..4d5295cd1081 --- /dev/null +++ b/toolchain/semantics/semantics_handle_loop_statement.cpp @@ -0,0 +1,65 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/semantics/semantics_context.h" +#include "toolchain/semantics/semantics_node.h" + +namespace Carbon { + +auto SemanticsHandleBreakStatement(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleBreakStatement"); +} + +auto SemanticsHandleBreakStatementStart(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleBreakStatementStart"); +} + +auto SemanticsHandleContinueStatement(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleContinueStatement"); +} + +auto SemanticsHandleContinueStatementStart(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleContinueStatementStart"); +} + +auto SemanticsHandleForHeader(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleForHeader"); +} + +auto SemanticsHandleForHeaderStart(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleForHeaderStart"); +} + +auto SemanticsHandleForIn(SemanticsContext& context, ParseTree::Node parse_node) + -> bool { + return context.TODO(parse_node, "HandleForIn"); +} + +auto SemanticsHandleForStatement(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleForStatement"); +} + +auto SemanticsHandleWhileCondition(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleWhileCondition"); +} + +auto SemanticsHandleWhileConditionStart(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleWhileConditionStart"); +} + +auto SemanticsHandleWhileStatement(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + return context.TODO(parse_node, "HandleWhileStatement"); +} + +} // namespace Carbon diff --git a/toolchain/semantics/semantics_handle_statement.cpp b/toolchain/semantics/semantics_handle_statement.cpp new file mode 100644 index 000000000000..2dfe35010c37 --- /dev/null +++ b/toolchain/semantics/semantics_handle_statement.cpp @@ -0,0 +1,83 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/semantics/semantics_context.h" +#include "toolchain/semantics/semantics_node.h" + +namespace Carbon { + +auto SemanticsHandleExpressionStatement(SemanticsContext& context, + ParseTree::Node /*parse_node*/) + -> bool { + // Pop the expression without investigating its contents. + // TODO: This will probably eventually need to do some "do not discard" + // analysis. + context.node_stack().PopAndDiscardId(); + return true; +} + +auto SemanticsHandleReturnStatement(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + CARBON_CHECK(!context.return_scope_stack().empty()); + const auto& fn_node = + context.semantics_ir().GetNode(context.return_scope_stack().back()); + const auto callable = + context.semantics_ir().GetFunction(fn_node.GetAsFunctionDeclaration()); + + if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) == + ParseNodeKind::ReturnStatementStart) { + context.node_stack().PopAndDiscardSoloParseNode( + ParseNodeKind::ReturnStatementStart); + + if (callable.return_type_id.is_valid()) { + // TODO: Add a note pointing at the return type's parse node. + CARBON_DIAGNOSTIC(ReturnStatementMissingExpression, Error, + "Must return a {0}.", std::string); + context.emitter() + .Build(parse_node, ReturnStatementMissingExpression, + context.semantics_ir().StringifyType(callable.return_type_id)) + .Emit(); + } + + context.AddNode(SemanticsNode::Return::Make(parse_node)); + } else { + auto arg = context.node_stack().Pop(); + context.node_stack().PopAndDiscardSoloParseNode( + ParseNodeKind::ReturnStatementStart); + + if (!callable.return_type_id.is_valid()) { + CARBON_DIAGNOSTIC( + ReturnStatementDisallowExpression, Error, + "No return expression should be provided in this context."); + CARBON_DIAGNOSTIC(ReturnStatementImplicitNote, Note, + "There was no return type provided."); + context.emitter() + .Build(parse_node, ReturnStatementDisallowExpression) + .Note(fn_node.parse_node(), ReturnStatementImplicitNote) + .Emit(); + } else { + arg = + context.ImplicitAsRequired(parse_node, arg, callable.return_type_id); + } + + context.AddNode(SemanticsNode::ReturnExpression::Make( + parse_node, context.semantics_ir().GetNode(arg).type_id(), arg)); + } + + // Switch to a new, unreachable, empty node block. This typically won't + // contain any semantics IR, but it can do if there are statements following + // the `return` statement. + context.node_block_stack().Pop(); + context.node_block_stack().PushUnreachable(); + return true; +} + +auto SemanticsHandleReturnStatementStart(SemanticsContext& context, + ParseTree::Node parse_node) -> bool { + // No action, just a bracketing node. + context.node_stack().Push(parse_node); + return true; +} + +} // namespace Carbon