From 37dd96870903f2ceb0cf2815aba9b8d5fec77764 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Thu, 17 Nov 2022 08:58:13 -0800 Subject: [PATCH] Track the ParseTree::Node with SemanticsNode. (#2407) Longer term, I think this is going to be important as part of associating errors with code after the particular node has been processed, even though it isn't used here. --- toolchain/semantics/semantics_node.h | 73 ++++++++++++------- .../semantics_parse_tree_handler.cpp | 19 +++-- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/toolchain/semantics/semantics_node.h b/toolchain/semantics/semantics_node.h index a53b21095326..222ae2777637 100644 --- a/toolchain/semantics/semantics_node.h +++ b/toolchain/semantics/semantics_node.h @@ -9,6 +9,7 @@ #include "common/check.h" #include "common/ostream.h" +#include "toolchain/parser/parse_tree.h" #include "toolchain/semantics/semantics_builtin_kind.h" #include "toolchain/semantics/semantics_node_kind.h" @@ -89,9 +90,10 @@ class SemanticsNode { auto GetAsInvalid() const -> NoArgs { CARBON_FATAL() << "Invalid access"; } - static auto MakeBinaryOperatorAdd(SemanticsNodeId lhs, SemanticsNodeId rhs) + static auto MakeBinaryOperatorAdd(ParseTree::Node parse_node, + SemanticsNodeId lhs, SemanticsNodeId rhs) -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::BinaryOperatorAdd(), + return SemanticsNode(parse_node, SemanticsNodeKind::BinaryOperatorAdd(), SemanticsNodeId(), lhs.id, rhs.id); } auto GetAsBinaryOperatorAdd() const @@ -100,10 +102,11 @@ class SemanticsNode { return {SemanticsNodeId(arg0_), SemanticsNodeId(arg1_)}; } - static auto MakeBindName(SemanticsIdentifierId name, SemanticsNodeId node) + static auto MakeBindName(ParseTree::Node parse_node, + SemanticsIdentifierId name, SemanticsNodeId node) -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::BindName(), SemanticsNodeId(), - name.id, node.id); + return SemanticsNode(parse_node, SemanticsNodeKind::BindName(), + SemanticsNodeId(), name.id, node.id); } auto GetAsBindName() const -> std::pair { @@ -113,7 +116,9 @@ class SemanticsNode { static auto MakeBuiltin(SemanticsBuiltinKind builtin_kind, SemanticsNodeId type) -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::Builtin(), type, + // Builtins won't have a ParseTree node associated, so we provide the + // default invalid one. + return SemanticsNode(ParseTree::Node(), SemanticsNodeKind::Builtin(), type, builtin_kind.AsInt()); } auto GetAsBuiltin() const -> SemanticsBuiltinKind { @@ -121,9 +126,10 @@ class SemanticsNode { return SemanticsBuiltinKind::FromInt(arg0_); } - static auto MakeCodeBlock(SemanticsNodeBlockId node_block) -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::CodeBlock(), SemanticsNodeId(), - node_block.id); + static auto MakeCodeBlock(ParseTree::Node parse_node, + SemanticsNodeBlockId node_block) -> SemanticsNode { + return SemanticsNode(parse_node, SemanticsNodeKind::CodeBlock(), + SemanticsNodeId(), node_block.id); } auto GetAsCodeBlock() const -> SemanticsNodeBlockId { CARBON_CHECK(kind_ == SemanticsNodeKind::CodeBlock()); @@ -131,8 +137,9 @@ class SemanticsNode { } // TODO: The signature should be added as a parameter. - static auto MakeFunctionDeclaration() -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::FunctionDeclaration(), + static auto MakeFunctionDeclaration(ParseTree::Node parse_node) + -> SemanticsNode { + return SemanticsNode(parse_node, SemanticsNodeKind::FunctionDeclaration(), SemanticsNodeId()); } auto GetAsFunctionDeclaration() const -> NoArgs { @@ -140,10 +147,11 @@ class SemanticsNode { return {}; } - static auto MakeFunctionDefinition(SemanticsNodeId decl, + static auto MakeFunctionDefinition(ParseTree::Node parse_node, + SemanticsNodeId decl, SemanticsNodeBlockId node_block) -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::FunctionDefinition(), + return SemanticsNode(parse_node, SemanticsNodeKind::FunctionDefinition(), SemanticsNodeId(), decl.id, node_block.id); } auto GetAsFunctionDefinition() const @@ -152,9 +160,10 @@ class SemanticsNode { return {SemanticsNodeId(arg0_), SemanticsNodeBlockId(arg1_)}; } - static auto MakeIntegerLiteral(SemanticsIntegerLiteralId integer) + static auto MakeIntegerLiteral(ParseTree::Node parse_node, + SemanticsIntegerLiteralId integer) -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::IntegerLiteral(), + return SemanticsNode(parse_node, SemanticsNodeKind::IntegerLiteral(), SemanticsNodeId::MakeBuiltinReference( SemanticsBuiltinKind::IntegerLiteralType()), integer.id); @@ -164,16 +173,18 @@ class SemanticsNode { return SemanticsIntegerLiteralId(arg0_); } - static auto MakeReturn() -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::Return(), SemanticsNodeId()); + static auto MakeReturn(ParseTree::Node parse_node) -> SemanticsNode { + return SemanticsNode(parse_node, SemanticsNodeKind::Return(), + SemanticsNodeId()); } auto GetAsReturn() const -> NoArgs { CARBON_CHECK(kind_ == SemanticsNodeKind::Return()); return {}; } - static auto MakeReturnExpression(SemanticsNodeId expr) -> SemanticsNode { - return SemanticsNode(SemanticsNodeKind::ReturnExpression(), + static auto MakeReturnExpression(ParseTree::Node parse_node, + SemanticsNodeId expr) -> SemanticsNode { + return SemanticsNode(parse_node, SemanticsNodeKind::ReturnExpression(), SemanticsNodeId(), expr.id); } auto GetAsReturnExpression() const -> SemanticsNodeId { @@ -182,29 +193,37 @@ class SemanticsNode { } SemanticsNode() - : SemanticsNode(SemanticsNodeKind::Invalid(), SemanticsNodeId()) {} + : SemanticsNode(ParseTree::Node(), SemanticsNodeKind::Invalid(), + SemanticsNodeId()) {} - auto kind() -> SemanticsNodeKind { return kind_; } - auto type() -> SemanticsNodeId { return type_; } + auto parse_node() const -> ParseTree::Node { return parse_node_; } + auto kind() const -> SemanticsNodeKind { return kind_; } + auto type() const -> SemanticsNodeId { return type_; } auto Print(llvm::raw_ostream& out) const -> void; private: - explicit SemanticsNode(SemanticsNodeKind kind, SemanticsNodeId type, - int32_t arg0 = -1, int32_t arg1 = -1) - : kind_(kind), type_(type), arg0_(arg0), arg1_(arg1) {} + explicit SemanticsNode(ParseTree::Node parse_node, SemanticsNodeKind kind, + SemanticsNodeId type, int32_t arg0 = -1, + int32_t arg1 = -1) + : parse_node_(parse_node), + kind_(kind), + type_(type), + arg0_(arg0), + arg1_(arg1) {} + ParseTree::Node parse_node_; SemanticsNodeKind kind_; SemanticsNodeId type_; int32_t arg0_; int32_t arg1_; }; -// TODO: This is currently 16 bytes because we sometimes have 2 arguments for a +// TODO: This is currently 20 bytes because we sometimes have 2 arguments for a // pair of SemanticsNodes. However, SemanticsNodeKind is 1 byte; if args // were 3.5 bytes, we could potentially shrink SemanticsNode by 4 bytes. This // may be worth investigating further. -static_assert(sizeof(SemanticsNode) == 16, "Unexpected SemanticsNode size"); +static_assert(sizeof(SemanticsNode) == 20, "Unexpected SemanticsNode size"); } // namespace Carbon diff --git a/toolchain/semantics/semantics_parse_tree_handler.cpp b/toolchain/semantics/semantics_parse_tree_handler.cpp index 07d16833cb2d..a380d8fac4ce 100644 --- a/toolchain/semantics/semantics_parse_tree_handler.cpp +++ b/toolchain/semantics/semantics_parse_tree_handler.cpp @@ -200,14 +200,16 @@ auto SemanticsParseTreeHandler::HandleFunctionDefinition( auto SemanticsParseTreeHandler::HandleFunctionDefinitionStart( ParseTree::Node parse_node) -> void { Pop(ParseNodeKind::ParameterList()); - auto name = AddIdentifier(node_stack_.back().parse_node); + auto name_node = node_stack_.back().parse_node; + auto name = AddIdentifier(name_node); node_stack_.pop_back(); + auto fn_node = node_stack_.back().parse_node; Pop(ParseNodeKind::FunctionIntroducer()); - auto decl_id = AddNode(SemanticsNode::MakeFunctionDeclaration()); - AddNode(SemanticsNode::MakeBindName(name, decl_id)); + auto decl_id = AddNode(SemanticsNode::MakeFunctionDeclaration(fn_node)); + AddNode(SemanticsNode::MakeBindName(name_node, name, decl_id)); auto block_id = semantics_->AddNodeBlock(); - AddNode(SemanticsNode::MakeFunctionDefinition(decl_id, block_id)); + AddNode(SemanticsNode::MakeFunctionDefinition(parse_node, decl_id, block_id)); node_block_stack_.push_back(block_id); Push(parse_node); } @@ -221,7 +223,8 @@ auto SemanticsParseTreeHandler::HandleInfixOperator(ParseTree::Node parse_node) auto token = parse_tree_->node_token(parse_node); switch (auto token_kind = tokens_->GetKind(token)) { case TokenKind::Plus(): - Push(parse_node, SemanticsNode::MakeBinaryOperatorAdd(lhs_id, rhs_id)); + Push(parse_node, + SemanticsNode::MakeBinaryOperatorAdd(parse_node, lhs_id, rhs_id)); break; default: CARBON_FATAL() << "Unrecognized token kind: " << token_kind.Name(); @@ -235,7 +238,7 @@ auto SemanticsParseTreeHandler::HandleLiteral(ParseTree::Node parse_node) case TokenKind::IntegerLiteral(): { auto id = semantics_->AddIntegerLiteral(tokens_->GetIntegerLiteral(token)); - Push(parse_node, SemanticsNode::MakeIntegerLiteral(id)); + Push(parse_node, SemanticsNode::MakeIntegerLiteral(parse_node, id)); break; } default: @@ -258,11 +261,11 @@ auto SemanticsParseTreeHandler::HandleReturnStatement( if (parse_tree_->node_kind(node_stack_.back().parse_node) == ParseNodeKind::ReturnStatementStart()) { Pop(ParseNodeKind::ReturnStatementStart()); - Push(parse_node, SemanticsNode::MakeReturn()); + Push(parse_node, SemanticsNode::MakeReturn(parse_node)); } else { auto arg = PopWithResult(); Pop(ParseNodeKind::ReturnStatementStart()); - Push(parse_node, SemanticsNode::MakeReturnExpression(arg)); + Push(parse_node, SemanticsNode::MakeReturnExpression(parse_node, arg)); } }