|
|
@@ -39,10 +39,11 @@ 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 {
|
|
|
- CARBON_CHECK(ParseNodeIdKind(parse_node) == IdKind::SoloParseNode)
|
|
|
- << "Parse kind expects an Id: " << parse_tree_->node_kind(parse_node);
|
|
|
- CARBON_VLOG() << "Node Push " << stack_.size() << ": "
|
|
|
- << parse_tree_->node_kind(parse_node) << " -> <none>\n";
|
|
|
+ auto kind = parse_tree_->node_kind(parse_node);
|
|
|
+ CARBON_CHECK(ParseNodeKindToIdKind(kind) == IdKind::SoloParseNode)
|
|
|
+ << "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, SemIR::InstId::Invalid));
|
|
|
@@ -51,47 +52,57 @@ class NodeStack {
|
|
|
// Pushes a parse tree node onto the stack with an ID.
|
|
|
template <typename IdT>
|
|
|
auto Push(Parse::NodeId parse_node, IdT id) -> void {
|
|
|
- CARBON_CHECK(ParseNodeIdKind(parse_node) == IdTypeToIdKind<IdT>())
|
|
|
- << "Parse kind expected a different IdT: "
|
|
|
- << parse_tree_->node_kind(parse_node) << " -> " << id << "\n";
|
|
|
+ auto kind = parse_tree_->node_kind(parse_node);
|
|
|
+ CARBON_CHECK(ParseNodeKindToIdKind(kind) == IdTypeToIdKind<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_VLOG() << "Node Push " << stack_.size() << ": "
|
|
|
- << parse_tree_->node_kind(parse_node) << " -> " << id << "\n";
|
|
|
+ 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));
|
|
|
}
|
|
|
|
|
|
- // Returns whether the node on the top of the stack is the specified kind.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ // 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Returns whether there is a node of the specified kind on top of the stack.
|
|
|
+ // Templated for consistency with other functions taking a parse node kind.
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto PeekIs() const -> bool {
|
|
|
- return !stack_.empty() &&
|
|
|
- parse_tree_->node_kind(PeekParseNode()) == RequiredParseKind;
|
|
|
+ return PeekIs(RequiredParseKind);
|
|
|
}
|
|
|
|
|
|
- // Returns whether the node on the top of the stack is a name.
|
|
|
+ // Returns whether there is a name on top of the stack.
|
|
|
auto PeekIsName() const -> bool {
|
|
|
return !stack_.empty() &&
|
|
|
- ParseNodeIdKind(PeekParseNode()) == IdKind::NameId;
|
|
|
+ ParseNodeKindToIdKind(PeekParseNodeKind()) == IdKind::NameId;
|
|
|
}
|
|
|
|
|
|
// Pops the top of the stack without any verification.
|
|
|
- auto PopAndIgnore() -> void { PopEntry<SemIR::InstId>(); }
|
|
|
+ auto PopAndIgnore() -> void {
|
|
|
+ Entry back = stack_.pop_back_val();
|
|
|
+ CARBON_VLOG() << "Node Pop " << stack_.size() << ": "
|
|
|
+ << parse_tree_->node_kind(back.parse_node)
|
|
|
+ << " -> <ignored>\n";
|
|
|
+ }
|
|
|
|
|
|
// Pops the top of the stack and returns the parse_node.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto PopForSoloParseNode() -> Parse::NodeId {
|
|
|
Entry back = PopEntry<SemIR::InstId>();
|
|
|
- RequireIdKind(Parse::NodeKind::Create(RequiredParseKind),
|
|
|
- IdKind::SoloParseNode);
|
|
|
+ RequireIdKind(RequiredParseKind, IdKind::SoloParseNode);
|
|
|
RequireParseKind<RequiredParseKind>(back.parse_node);
|
|
|
return back.parse_node;
|
|
|
}
|
|
|
|
|
|
// Pops the top of the stack if it is the given kind, and returns the
|
|
|
// parse_node. Otherwise, returns std::nullopt.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto PopForSoloParseNodeIf() -> std::optional<Parse::NodeId> {
|
|
|
if (PeekIs<RequiredParseKind>()) {
|
|
|
return PopForSoloParseNode<RequiredParseKind>();
|
|
|
@@ -100,14 +111,14 @@ class NodeStack {
|
|
|
}
|
|
|
|
|
|
// Pops the top of the stack.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto PopAndDiscardSoloParseNode() -> void {
|
|
|
PopForSoloParseNode<RequiredParseKind>();
|
|
|
}
|
|
|
|
|
|
// Pops the top of the stack if it is the given kind. Returns `true` if a node
|
|
|
// was popped.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto PopAndDiscardSoloParseNodeIf() -> bool {
|
|
|
if (!PeekIs<RequiredParseKind>()) {
|
|
|
return false;
|
|
|
@@ -129,10 +140,9 @@ class NodeStack {
|
|
|
}
|
|
|
|
|
|
// Pops the top of the stack and returns the parse_node and the ID.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto PopWithParseNode() -> auto {
|
|
|
- constexpr IdKind RequiredIdKind =
|
|
|
- ParseNodeKindToIdKind(Parse::NodeKind::Create(RequiredParseKind));
|
|
|
+ constexpr IdKind RequiredIdKind = ParseNodeKindToIdKind(RequiredParseKind);
|
|
|
if constexpr (RequiredIdKind == IdKind::InstId) {
|
|
|
auto back = PopWithParseNode<SemIR::InstId>();
|
|
|
RequireParseKind<RequiredParseKind>(back.first);
|
|
|
@@ -168,11 +178,21 @@ class NodeStack {
|
|
|
RequireParseKind<RequiredParseKind>(back.first);
|
|
|
return back;
|
|
|
}
|
|
|
- CARBON_FATAL() << "Unpoppable IdKind for parse kind: "
|
|
|
- << Parse::NodeKind::Create(RequiredParseKind)
|
|
|
+ CARBON_FATAL() << "Unpoppable IdKind for parse kind: " << RequiredParseKind
|
|
|
<< "; see value in ParseNodeKindToIdKind";
|
|
|
}
|
|
|
|
|
|
+ // Pops the top of the stack and returns the parse_node and the ID if it is
|
|
|
+ // of the specified kind.
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
+ auto PopWithParseNodeIf()
|
|
|
+ -> std::optional<decltype(PopWithParseNode<RequiredParseKind>())> {
|
|
|
+ if (!PeekIs<RequiredParseKind>()) {
|
|
|
+ return std::nullopt;
|
|
|
+ }
|
|
|
+ return PopWithParseNode<RequiredParseKind>();
|
|
|
+ }
|
|
|
+
|
|
|
// Pops an expression from the top of the stack and returns the ID.
|
|
|
// Expressions map multiple Parse::NodeKinds to SemIR::InstId always.
|
|
|
auto PopExpr() -> SemIR::InstId { return PopExprWithParseNode().second; }
|
|
|
@@ -181,14 +201,14 @@ class NodeStack {
|
|
|
auto PopName() -> SemIR::NameId { return PopNameWithParseNode().second; }
|
|
|
|
|
|
// Pops the top of the stack and returns the ID.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto Pop() -> auto {
|
|
|
return PopWithParseNode<RequiredParseKind>().second;
|
|
|
}
|
|
|
|
|
|
// Pops the top of the stack if it has the given kind, and returns the ID.
|
|
|
// Otherwise returns std::nullopt.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto PopIf() -> std::optional<decltype(Pop<RequiredParseKind>())> {
|
|
|
if (PeekIs<RequiredParseKind>()) {
|
|
|
return Pop<RequiredParseKind>();
|
|
|
@@ -196,18 +216,22 @@ class NodeStack {
|
|
|
return std::nullopt;
|
|
|
}
|
|
|
|
|
|
- // Peeks at the parse node of the top of the name stack.
|
|
|
+ // Peeks at the parse node of the top of the node stack.
|
|
|
auto PeekParseNode() const -> Parse::NodeId {
|
|
|
return stack_.back().parse_node;
|
|
|
}
|
|
|
|
|
|
+ // 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());
|
|
|
+ }
|
|
|
+
|
|
|
// Peeks at the ID associated with the top of the name stack.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto Peek() const -> auto {
|
|
|
Entry back = stack_.back();
|
|
|
RequireParseKind<RequiredParseKind>(back.parse_node);
|
|
|
- constexpr IdKind RequiredIdKind =
|
|
|
- ParseNodeKindToIdKind(Parse::NodeKind::Create(RequiredParseKind));
|
|
|
+ constexpr IdKind RequiredIdKind = ParseNodeKindToIdKind(RequiredParseKind);
|
|
|
if constexpr (RequiredIdKind == IdKind::InstId) {
|
|
|
return back.id<SemIR::InstId>();
|
|
|
}
|
|
|
@@ -229,8 +253,7 @@ class NodeStack {
|
|
|
if constexpr (RequiredIdKind == IdKind::TypeId) {
|
|
|
return back.id<SemIR::TypeId>();
|
|
|
}
|
|
|
- CARBON_FATAL() << "Unpeekable IdKind for parse kind: "
|
|
|
- << Parse::NodeKind::Create(RequiredParseKind)
|
|
|
+ CARBON_FATAL() << "Unpeekable IdKind for parse kind: " << RequiredParseKind
|
|
|
<< "; see value in ParseNodeKindToIdKind";
|
|
|
}
|
|
|
|
|
|
@@ -405,10 +428,6 @@ class NodeStack {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- auto ParseNodeIdKind(Parse::NodeId node) const -> IdKind {
|
|
|
- return ParseNodeKindToIdKind(parse_tree_->node_kind(node));
|
|
|
- }
|
|
|
-
|
|
|
// Translates an ID type to the enum ID kind for comparison with
|
|
|
// ParseNodeKindToIdKind.
|
|
|
template <typename IdT>
|
|
|
@@ -462,12 +481,11 @@ class NodeStack {
|
|
|
}
|
|
|
|
|
|
// Require an entry to have the given Parse::NodeKind.
|
|
|
- template <Parse::NodeKind::RawEnumType RequiredParseKind>
|
|
|
+ template <const Parse::NodeKind& RequiredParseKind>
|
|
|
auto RequireParseKind(Parse::NodeId parse_node) const -> void {
|
|
|
auto actual_kind = parse_tree_->node_kind(parse_node);
|
|
|
CARBON_CHECK(RequiredParseKind == actual_kind)
|
|
|
- << "Expected " << Parse::NodeKind::Create(RequiredParseKind)
|
|
|
- << ", found " << actual_kind;
|
|
|
+ << "Expected " << RequiredParseKind << ", found " << actual_kind;
|
|
|
}
|
|
|
|
|
|
// The file's parse tree.
|