semantics_node_stack.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/semantics/semantics_node_stack.h"
  5. #include "common/vlog.h"
  6. #include "llvm/Support/PrettyStackTrace.h"
  7. #include "toolchain/semantics/semantics_node.h"
  8. namespace Carbon {
  9. auto SemanticsNodeStack::PushEntry(Entry entry, bool is_node_id) -> void {
  10. CARBON_VLOG() << "Push " << stack_.size() << ": "
  11. << parse_tree_->node_kind(entry.parse_node) << " -> ";
  12. if (is_node_id) {
  13. CARBON_VLOG() << entry.node_id;
  14. } else {
  15. CARBON_VLOG() << entry.name_id;
  16. }
  17. CARBON_VLOG() << "\n";
  18. CARBON_CHECK(stack_.size() < (1 << 20))
  19. << "Excessive stack size: likely infinite loop";
  20. stack_.push_back(entry);
  21. }
  22. auto SemanticsNodeStack::PopEntry() -> Entry {
  23. auto back = stack_.pop_back_val();
  24. CARBON_VLOG() << "Pop " << stack_.size() << ": any ("
  25. << parse_tree_->node_kind(back.parse_node) << ") -> "
  26. << back.node_id << "\n";
  27. return back;
  28. }
  29. auto SemanticsNodeStack::PopEntry(ParseNodeKind pop_parse_kind) -> Entry {
  30. auto back = stack_.pop_back_val();
  31. CARBON_VLOG() << "Pop " << stack_.size() << ": " << pop_parse_kind << " -> "
  32. << back.node_id << "\n";
  33. RequireParseKind(back, pop_parse_kind);
  34. return back;
  35. }
  36. auto SemanticsNodeStack::RequireParseKind(Entry entry,
  37. ParseNodeKind require_kind) -> void {
  38. auto actual_kind = parse_tree_->node_kind(entry.parse_node);
  39. CARBON_CHECK(require_kind == actual_kind)
  40. << "Expected " << require_kind << ", found " << actual_kind;
  41. }
  42. auto SemanticsNodeStack::RequireSoloParseNode(Entry entry) -> void {
  43. CARBON_CHECK(!entry.node_id.is_valid())
  44. << "Expected invalid node_id on "
  45. << parse_tree_->node_kind(entry.parse_node) << ", was " << entry.node_id;
  46. }
  47. auto SemanticsNodeStack::RequireNodeId(Entry entry) -> void {
  48. CARBON_CHECK(entry.node_id.is_valid())
  49. << "Expected valid node_id on "
  50. << parse_tree_->node_kind(entry.parse_node);
  51. }
  52. auto SemanticsNodeStack::PopAndDiscardSoloParseNode(
  53. ParseNodeKind pop_parse_kind) -> void {
  54. auto back = PopEntry(pop_parse_kind);
  55. RequireSoloParseNode(back);
  56. }
  57. auto SemanticsNodeStack::PopForSoloParseNode() -> ParseTree::Node {
  58. auto back = PopEntry();
  59. RequireSoloParseNode(back);
  60. return back.parse_node;
  61. }
  62. auto SemanticsNodeStack::PopForSoloParseNode(ParseNodeKind pop_parse_kind)
  63. -> ParseTree::Node {
  64. auto back = PopEntry(pop_parse_kind);
  65. RequireSoloParseNode(back);
  66. return back.parse_node;
  67. }
  68. auto SemanticsNodeStack::PopForNodeId() -> SemanticsNodeId {
  69. auto back = PopEntry();
  70. RequireNodeId(back);
  71. return back.node_id;
  72. }
  73. auto SemanticsNodeStack::PopForNodeId(ParseNodeKind pop_parse_kind)
  74. -> SemanticsNodeId {
  75. auto back = PopEntry(pop_parse_kind);
  76. RequireNodeId(back);
  77. return back.node_id;
  78. }
  79. auto SemanticsNodeStack::PopForParseNodeAndNodeId()
  80. -> std::pair<ParseTree::Node, SemanticsNodeId> {
  81. auto back = PopEntry();
  82. RequireNodeId(back);
  83. return {back.parse_node, back.node_id};
  84. }
  85. auto SemanticsNodeStack::PopForParseNodeAndNodeId(ParseNodeKind pop_parse_kind)
  86. -> std::pair<ParseTree::Node, SemanticsNodeId> {
  87. auto back = PopEntry(pop_parse_kind);
  88. RequireNodeId(back);
  89. return {back.parse_node, back.node_id};
  90. }
  91. auto SemanticsNodeStack::PopForParseNodeAndNameId()
  92. -> std::pair<ParseTree::Node, SemanticsStringId> {
  93. auto back = PopEntry(ParseNodeKind::PatternBinding);
  94. RequireNodeId(back);
  95. return {back.parse_node, back.name_id};
  96. }
  97. auto SemanticsNodeStack::PeekForNameId() -> SemanticsStringId {
  98. auto back = stack_.back();
  99. RequireParseKind(back, ParseNodeKind::PatternBinding);
  100. RequireNodeId(back);
  101. return back.name_id;
  102. }
  103. auto SemanticsNodeStack::PrintForStackDump(llvm::raw_ostream& output) const
  104. -> void {
  105. output << "node_stack_:\n";
  106. for (int i = 0; i < static_cast<int>(stack_.size()); ++i) {
  107. const auto& entry = stack_[i];
  108. auto parse_node_kind = parse_tree_->node_kind(entry.parse_node);
  109. output << "\t" << i << ".\t" << parse_node_kind;
  110. if (parse_node_kind == ParseNodeKind::PatternBinding) {
  111. output << " -> " << entry.name_id;
  112. } else {
  113. if (entry.node_id.is_valid()) {
  114. output << " -> " << entry.node_id;
  115. }
  116. }
  117. output << "\n";
  118. }
  119. }
  120. } // namespace Carbon