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.
This commit is contained in:
Jon Ross-Perkins
2022-11-17 08:58:13 -08:00
committed by GitHub
parent 242b191317
commit 37dd968709
2 changed files with 57 additions and 35 deletions
+46 -27
View File
@@ -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<SemanticsIdentifierId, SemanticsNodeId> {
@@ -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
@@ -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));
}
}