node_stack.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  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. #ifndef CARBON_TOOLCHAIN_CHECK_NODE_STACK_H_
  5. #define CARBON_TOOLCHAIN_CHECK_NODE_STACK_H_
  6. #include "common/vlog.h"
  7. #include "llvm/ADT/SmallVector.h"
  8. #include "toolchain/parse/node_ids.h"
  9. #include "toolchain/parse/node_kind.h"
  10. #include "toolchain/parse/tree.h"
  11. #include "toolchain/parse/typed_nodes.h"
  12. #include "toolchain/sem_ir/formatter.h"
  13. #include "toolchain/sem_ir/id_kind.h"
  14. #include "toolchain/sem_ir/ids.h"
  15. namespace Carbon::Check {
  16. // A non-discriminated union of ID types.
  17. class IdUnion {
  18. public:
  19. // The default constructor forms an invalid ID.
  20. explicit constexpr IdUnion() : index(IdBase::InvalidIndex) {}
  21. template <typename IdT>
  22. requires SemIR::IdKind::Contains<IdT>
  23. explicit constexpr IdUnion(IdT id) : index(id.index) {}
  24. using Kind = SemIR::IdKind::RawEnumType;
  25. // Returns the ID given its type.
  26. template <typename IdT>
  27. requires SemIR::IdKind::Contains<IdT>
  28. constexpr auto As() const -> IdT {
  29. return IdT(index);
  30. }
  31. // Returns the ID given its kind.
  32. template <SemIR::IdKind::RawEnumType K>
  33. constexpr auto As() const -> SemIR::IdKind::TypeFor<K> {
  34. return As<SemIR::IdKind::TypeFor<K>>();
  35. }
  36. // Translates an ID type to the enum ID kind. Returns Invalid if `IdT` isn't
  37. // a type that can be stored in this union.
  38. template <typename IdT>
  39. static constexpr auto KindFor() -> Kind {
  40. return SemIR::IdKind::For<IdT>;
  41. }
  42. private:
  43. decltype(IdBase::index) index;
  44. };
  45. // The stack of parse nodes representing the current state of a Check::Context.
  46. // Each parse node can have an associated id of some kind (instruction,
  47. // instruction block, function, class, ...).
  48. //
  49. // All pushes and pops will be vlogged.
  50. //
  51. // Pop APIs will run basic verification:
  52. //
  53. // - If receiving a Parse::NodeKind, verify that the node_id being popped has
  54. // that kind. Similarly, if receiving a Parse::NodeCategory, make sure the
  55. // of the popped node_id overlaps that category.
  56. // - Validates the kind of id data in the node based on the kind or category of
  57. // the node_id.
  58. //
  59. // These should be assumed API constraints unless otherwise mentioned on a
  60. // method. The main exception is PopAndIgnore, which doesn't do verification.
  61. class NodeStack {
  62. public:
  63. explicit NodeStack(const Parse::Tree& parse_tree,
  64. llvm::raw_ostream* vlog_stream)
  65. : parse_tree_(&parse_tree), vlog_stream_(vlog_stream) {}
  66. // Pushes a solo parse tree node onto the stack. Used when there is no
  67. // IR generated by the node.
  68. auto Push(Parse::NodeId node_id) -> void {
  69. auto kind = parse_tree_->node_kind(node_id);
  70. CARBON_CHECK(NodeKindToIdKind(kind) == Id::Kind::None,
  71. "Parse kind expects an Id: {0}", kind);
  72. CARBON_VLOG("Node Push {0}: {1} -> <none>\n", stack_.size(), kind);
  73. CARBON_CHECK(stack_.size() < (1 << 20),
  74. "Excessive stack size: likely infinite loop");
  75. stack_.push_back({.node_id = node_id, .id = Id()});
  76. }
  77. // Pushes a parse tree node onto the stack with an ID.
  78. template <typename IdT>
  79. auto Push(Parse::NodeId node_id, IdT id) -> void {
  80. auto kind = parse_tree_->node_kind(node_id);
  81. CARBON_CHECK(NodeKindToIdKind(kind) == Id::KindFor<IdT>(),
  82. "Parse kind expected a different IdT: {0} -> {1}\n", kind, id);
  83. CARBON_CHECK(id.is_valid(), "Push called with invalid id: {0}",
  84. parse_tree_->node_kind(node_id));
  85. CARBON_VLOG("Node Push {0}: {1} -> {2}\n", stack_.size(), kind, id);
  86. CARBON_CHECK(stack_.size() < (1 << 20),
  87. "Excessive stack size: likely infinite loop");
  88. stack_.push_back({.node_id = node_id, .id = Id(id)});
  89. }
  90. // Returns whether there is a node of the specified kind on top of the stack.
  91. auto PeekIs(Parse::NodeKind kind) const -> bool {
  92. return !stack_.empty() && PeekNodeKind() == kind;
  93. }
  94. // Returns whether there is a node of the specified kind on top of the stack.
  95. // Templated for consistency with other functions taking a parse node kind.
  96. template <const Parse::NodeKind& RequiredParseKind>
  97. auto PeekIs() const -> bool {
  98. return PeekIs(RequiredParseKind);
  99. }
  100. // Returns whether the node on the top of the stack has an overlapping
  101. // category.
  102. auto PeekIs(Parse::NodeCategory category) const -> bool {
  103. return !stack_.empty() && PeekNodeKind().category().HasAnyOf(category);
  104. }
  105. // Returns whether the node on the top of the stack has an overlapping
  106. // category. Templated for consistency with other functions taking a parse
  107. // node category.
  108. template <Parse::NodeCategory::RawEnumType RequiredParseCategory>
  109. auto PeekIs() const -> bool {
  110. return PeekIs(RequiredParseCategory);
  111. }
  112. // Returns whether there is a node with the corresponding ID on top of the
  113. // stack.
  114. template <typename IdT>
  115. auto PeekIs() const -> bool {
  116. return !stack_.empty() &&
  117. NodeKindToIdKind(PeekNodeKind()) == Id::KindFor<IdT>();
  118. }
  119. // Returns whether the *next* node on the stack is a given kind. This doesn't
  120. // have the breadth of support versus other Peek functions because it's
  121. // expected to be used in narrow circumstances when determining how to treat
  122. // the *current* top of the stack.
  123. template <const Parse::NodeKind& RequiredParseKind>
  124. auto PeekNextIs() const -> bool {
  125. CARBON_CHECK(stack_.size() >= 2);
  126. return parse_tree_->node_kind(stack_[stack_.size() - 2].node_id) ==
  127. RequiredParseKind;
  128. }
  129. // Pops the top of the stack without any verification.
  130. auto PopAndIgnore() -> void {
  131. Entry back = stack_.pop_back_val();
  132. CARBON_VLOG("Node Pop {0}: {1} -> <ignored>\n", stack_.size(),
  133. parse_tree_->node_kind(back.node_id));
  134. }
  135. // Pops the top of the stack and returns the node_id.
  136. template <const Parse::NodeKind& RequiredParseKind>
  137. auto PopForSoloNodeId() -> Parse::NodeIdForKind<RequiredParseKind> {
  138. Entry back = PopEntry<SemIR::InstId>();
  139. RequireIdKind(RequiredParseKind, Id::Kind::None);
  140. RequireParseKind<RequiredParseKind>(back.node_id);
  141. return Parse::NodeIdForKind<RequiredParseKind>(back.node_id);
  142. }
  143. // Pops the top of the stack if it is the given kind, and returns the
  144. // node_id. Otherwise, returns std::nullopt.
  145. template <const Parse::NodeKind& RequiredParseKind>
  146. auto PopForSoloNodeIdIf()
  147. -> std::optional<Parse::NodeIdForKind<RequiredParseKind>> {
  148. if (PeekIs<RequiredParseKind>()) {
  149. return PopForSoloNodeId<RequiredParseKind>();
  150. }
  151. return std::nullopt;
  152. }
  153. // Pops the top of the stack.
  154. template <const Parse::NodeKind& RequiredParseKind>
  155. auto PopAndDiscardSoloNodeId() -> void {
  156. PopForSoloNodeId<RequiredParseKind>();
  157. }
  158. // Pops the top of the stack if it is the given kind. Returns `true` if a node
  159. // was popped.
  160. template <const Parse::NodeKind& RequiredParseKind>
  161. auto PopAndDiscardSoloNodeIdIf() -> bool {
  162. if (!PeekIs<RequiredParseKind>()) {
  163. return false;
  164. }
  165. PopForSoloNodeId<RequiredParseKind>();
  166. return true;
  167. }
  168. // Pops an expression from the top of the stack and returns the node_id and
  169. // the ID.
  170. auto PopExprWithNodeId() -> std::pair<Parse::AnyExprId, SemIR::InstId>;
  171. // Pops a pattern from the top of the stack and returns the node_id and
  172. // the ID.
  173. auto PopPatternWithNodeId() -> std::pair<Parse::NodeId, SemIR::InstId> {
  174. return PopWithNodeId<SemIR::InstId>();
  175. }
  176. // Pops a name from the top of the stack and returns the node_id and
  177. // the ID.
  178. auto PopNameWithNodeId() -> std::pair<Parse::NodeId, SemIR::NameId> {
  179. return PopWithNodeId<SemIR::NameId>();
  180. }
  181. // Pops the top of the stack and returns the node_id and the ID.
  182. template <const Parse::NodeKind& RequiredParseKind>
  183. auto PopWithNodeId() -> auto {
  184. auto id = Peek<RequiredParseKind>();
  185. Parse::NodeIdForKind<RequiredParseKind> node_id(
  186. stack_.pop_back_val().node_id);
  187. return std::make_pair(node_id, id);
  188. }
  189. // Pops the top of the stack and returns the node_id and the ID.
  190. template <Parse::NodeCategory::RawEnumType RequiredParseCategory>
  191. auto PopWithNodeId() -> auto {
  192. auto id = Peek<RequiredParseCategory>();
  193. Parse::NodeIdInCategory<RequiredParseCategory> node_id(
  194. stack_.pop_back_val().node_id);
  195. return std::make_pair(node_id, id);
  196. }
  197. // Pops an expression from the top of the stack and returns the ID.
  198. // Expressions always map Parse::NodeCategory::Expr nodes to SemIR::InstId.
  199. auto PopExpr() -> SemIR::InstId { return PopExprWithNodeId().second; }
  200. // Pops a pattern from the top of the stack and returns the ID.
  201. // Patterns map multiple Parse::NodeKinds to SemIR::InstId always.
  202. auto PopPattern() -> SemIR::InstId { return PopPatternWithNodeId().second; }
  203. // Pops a name from the top of the stack and returns the ID.
  204. auto PopName() -> SemIR::NameId { return PopNameWithNodeId().second; }
  205. // Pops the top of the stack and returns the ID.
  206. template <const Parse::NodeKind& RequiredParseKind>
  207. auto Pop() -> auto {
  208. return PopWithNodeId<RequiredParseKind>().second;
  209. }
  210. // Pops the top of the stack and returns the ID.
  211. template <Parse::NodeCategory::RawEnumType RequiredParseCategory>
  212. auto Pop() -> auto {
  213. return PopWithNodeId<RequiredParseCategory>().second;
  214. }
  215. // Pops the top of the stack and returns the ID.
  216. template <typename IdT>
  217. auto Pop() -> IdT {
  218. return PopWithNodeId<IdT>().second;
  219. }
  220. // Pops the top of the stack if it has the given kind, and returns the ID.
  221. // Otherwise returns std::nullopt.
  222. template <const Parse::NodeKind& RequiredParseKind>
  223. auto PopIf() -> std::optional<decltype(Pop<RequiredParseKind>())> {
  224. if (PeekIs<RequiredParseKind>()) {
  225. return Pop<RequiredParseKind>();
  226. }
  227. return std::nullopt;
  228. }
  229. // Pops the top of the stack if it has the given category, and returns the ID.
  230. // Otherwise returns std::nullopt.
  231. template <Parse::NodeCategory::RawEnumType RequiredParseCategory>
  232. auto PopIf() -> std::optional<decltype(Pop<RequiredParseCategory>())> {
  233. if (PeekIs<RequiredParseCategory>()) {
  234. return Pop<RequiredParseCategory>();
  235. }
  236. return std::nullopt;
  237. }
  238. // Pops the top of the stack if it has the given category, and returns the ID.
  239. // Otherwise returns std::nullopt.
  240. template <typename IdT>
  241. auto PopIf() -> std::optional<IdT> {
  242. if (PeekIs<IdT>()) {
  243. return Pop<IdT>();
  244. }
  245. return std::nullopt;
  246. }
  247. // Pops the top of the stack and returns the node_id and the ID if it is
  248. // of the specified kind.
  249. template <const Parse::NodeKind& RequiredParseKind>
  250. auto PopWithNodeIdIf() -> std::pair<Parse::NodeIdForKind<RequiredParseKind>,
  251. decltype(PopIf<RequiredParseKind>())> {
  252. if (!PeekIs<RequiredParseKind>()) {
  253. return {Parse::NodeId::Invalid, std::nullopt};
  254. }
  255. return PopWithNodeId<RequiredParseKind>();
  256. }
  257. // Pops the top of the stack and returns the node_id and the ID if it is
  258. // of the specified category.
  259. template <Parse::NodeCategory::RawEnumType RequiredParseCategory>
  260. auto PopWithNodeIdIf()
  261. -> std::pair<Parse::NodeIdInCategory<RequiredParseCategory>,
  262. decltype(PopIf<RequiredParseCategory>())> {
  263. if (!PeekIs<RequiredParseCategory>()) {
  264. return {Parse::NodeId::Invalid, std::nullopt};
  265. }
  266. return PopWithNodeId<RequiredParseCategory>();
  267. }
  268. // Peeks at the parse node of the top of the node stack.
  269. auto PeekNodeId() const -> Parse::NodeId { return stack_.back().node_id; }
  270. // Peeks at the kind of the parse node of the top of the node stack.
  271. auto PeekNodeKind() const -> Parse::NodeKind {
  272. return parse_tree_->node_kind(PeekNodeId());
  273. }
  274. // Peeks at the ID associated with the top of the name stack.
  275. template <const Parse::NodeKind& RequiredParseKind>
  276. auto Peek() const -> auto {
  277. Entry back = stack_.back();
  278. RequireParseKind<RequiredParseKind>(back.node_id);
  279. constexpr Id::Kind RequiredIdKind = NodeKindToIdKind(RequiredParseKind);
  280. return Peek<RequiredIdKind>();
  281. }
  282. // Peeks at the ID associated with the top of the name stack.
  283. template <Parse::NodeCategory::RawEnumType RequiredParseCategory>
  284. auto Peek() const -> auto {
  285. Entry back = stack_.back();
  286. RequireParseCategory<RequiredParseCategory>(back.node_id);
  287. constexpr std::optional<Id::Kind> RequiredIdKind =
  288. NodeCategoryToIdKind(RequiredParseCategory, false);
  289. static_assert(RequiredIdKind.has_value());
  290. return Peek<*RequiredIdKind>();
  291. }
  292. // Prints the stack for a stack dump.
  293. auto PrintForStackDump(SemIR::Formatter& formatter, int indent,
  294. llvm::raw_ostream& output) const -> void;
  295. auto empty() const -> bool { return stack_.empty(); }
  296. auto size() const -> size_t { return stack_.size(); }
  297. protected:
  298. // An ID that can be associated with a parse node.
  299. //
  300. // Each parse node kind has a corresponding Id::Kind indicating which kind of
  301. // ID is stored, computed by NodeKindToIdKind. Id::Kind::None indicates
  302. // that the parse node has no associated ID, in which case the *SoloNodeId
  303. // functions should be used to push and pop it. Id::Kind::Invalid indicates
  304. // that the parse node should not appear in the node stack at all.
  305. using Id = IdUnion;
  306. // An entry in stack_.
  307. struct Entry {
  308. // The parse node associated with the stack entry.
  309. Parse::NodeId node_id;
  310. // The ID associated with this parse node. The kind of ID is determined by
  311. // the kind of the parse node, so a separate discriminiator is not needed.
  312. Id id;
  313. };
  314. static_assert(sizeof(Entry) == 8, "Unexpected Entry size");
  315. // Translate a parse node category to the enum ID kind it should always
  316. // provide, if it is consistent.
  317. static constexpr auto NodeCategoryToIdKind(Parse::NodeCategory category,
  318. bool for_node_kind)
  319. -> std::optional<Id::Kind> {
  320. std::optional<Id::Kind> result;
  321. auto set_id_if_category_is = [&](Parse::NodeCategory cat, Id::Kind kind) {
  322. if (category.HasAnyOf(cat)) {
  323. // Check for no consistent Id::Kind due to category with multiple bits
  324. // set. When computing the Id::Kind for a node kind, a partial category
  325. // match is OK, so long as we don't match two inconsistent categories.
  326. // When computing the Id::Kind for a category query, the query can't
  327. // have any extra bits set or we could be popping a node that is not in
  328. // this category.
  329. if (for_node_kind ? result.has_value() : category.HasAnyOf(~cat)) {
  330. result = Id::Kind::Invalid;
  331. } else {
  332. result = kind;
  333. }
  334. }
  335. };
  336. // TODO: Patterns should also produce an `InstId`, but currently
  337. // `TuplePattern` produces an `InstBlockId`.
  338. set_id_if_category_is(Parse::NodeCategory::Expr,
  339. Id::KindFor<SemIR::InstId>());
  340. set_id_if_category_is(Parse::NodeCategory::MemberName,
  341. Id::KindFor<SemIR::NameId>());
  342. set_id_if_category_is(Parse::NodeCategory::ImplAs,
  343. Id::KindFor<SemIR::InstId>());
  344. set_id_if_category_is(Parse::NodeCategory::Decl |
  345. Parse::NodeCategory::Statement |
  346. Parse::NodeCategory::Modifier,
  347. Id::Kind::None);
  348. return result;
  349. }
  350. using IdKindTableType = std::array<Id::Kind, Parse::NodeKind::ValidCount>;
  351. // Lookup table to implement `NodeKindToIdKind`. Initialized to the
  352. // return value of `ComputeIdKindTable()`.
  353. static const IdKindTableType IdKindTable;
  354. static constexpr auto ComputeIdKindTable() -> IdKindTableType {
  355. IdKindTableType table = {};
  356. auto to_id_kind =
  357. [](const Parse::NodeKind::Definition& node_kind) -> Id::Kind {
  358. if (auto from_category =
  359. NodeCategoryToIdKind(node_kind.category(), true)) {
  360. return *from_category;
  361. }
  362. switch (node_kind) {
  363. case Parse::NodeKind::Addr:
  364. case Parse::NodeKind::BindingPattern:
  365. case Parse::NodeKind::CallExprStart:
  366. case Parse::NodeKind::CompileTimeBindingPattern:
  367. case Parse::NodeKind::IfExprThen:
  368. case Parse::NodeKind::ReturnType:
  369. case Parse::NodeKind::ShortCircuitOperandAnd:
  370. case Parse::NodeKind::ShortCircuitOperandOr:
  371. case Parse::NodeKind::StructLiteralField:
  372. case Parse::NodeKind::StructTypeLiteralField:
  373. case Parse::NodeKind::WhereOperand:
  374. return Id::KindFor<SemIR::InstId>();
  375. case Parse::NodeKind::IfCondition:
  376. case Parse::NodeKind::IfExprIf:
  377. case Parse::NodeKind::ImplForall:
  378. case Parse::NodeKind::ImplicitParamList:
  379. case Parse::NodeKind::TuplePattern:
  380. case Parse::NodeKind::WhileCondition:
  381. case Parse::NodeKind::WhileConditionStart:
  382. return Id::KindFor<SemIR::InstBlockId>();
  383. case Parse::NodeKind::FunctionDefinitionStart:
  384. case Parse::NodeKind::BuiltinFunctionDefinitionStart:
  385. return Id::KindFor<SemIR::FunctionId>();
  386. case Parse::NodeKind::ClassDefinitionStart:
  387. return Id::KindFor<SemIR::ClassId>();
  388. case Parse::NodeKind::InterfaceDefinitionStart:
  389. return Id::KindFor<SemIR::InterfaceId>();
  390. case Parse::NodeKind::ImplDefinitionStart:
  391. return Id::KindFor<SemIR::ImplId>();
  392. case Parse::NodeKind::SelfTypeName:
  393. case Parse::NodeKind::SelfValueName:
  394. return Id::KindFor<SemIR::NameId>();
  395. case Parse::NodeKind::DefaultLibrary:
  396. case Parse::NodeKind::LibraryName:
  397. return Id::KindFor<SemIR::LibraryNameId>();
  398. case Parse::NodeKind::ArrayExprSemi:
  399. case Parse::NodeKind::BuiltinName:
  400. case Parse::NodeKind::ClassIntroducer:
  401. case Parse::NodeKind::CodeBlockStart:
  402. case Parse::NodeKind::FunctionIntroducer:
  403. case Parse::NodeKind::IfStatementElse:
  404. case Parse::NodeKind::ImplicitParamListStart:
  405. case Parse::NodeKind::ImplIntroducer:
  406. case Parse::NodeKind::InterfaceIntroducer:
  407. case Parse::NodeKind::LetInitializer:
  408. case Parse::NodeKind::LetIntroducer:
  409. case Parse::NodeKind::ReturnedModifier:
  410. case Parse::NodeKind::ReturnStatementStart:
  411. case Parse::NodeKind::ReturnVarModifier:
  412. case Parse::NodeKind::StructLiteralStart:
  413. case Parse::NodeKind::StructTypeLiteralStart:
  414. case Parse::NodeKind::TupleLiteralStart:
  415. case Parse::NodeKind::TuplePatternStart:
  416. case Parse::NodeKind::VariableInitializer:
  417. case Parse::NodeKind::VariableIntroducer:
  418. return Id::Kind::None;
  419. case Parse::NodeKind::AbstractModifier:
  420. case Parse::NodeKind::AdaptDecl:
  421. case Parse::NodeKind::AdaptIntroducer:
  422. case Parse::NodeKind::Alias:
  423. case Parse::NodeKind::AliasInitializer:
  424. case Parse::NodeKind::AliasIntroducer:
  425. case Parse::NodeKind::ArrayExpr:
  426. case Parse::NodeKind::ArrayExprStart:
  427. case Parse::NodeKind::AutoTypeLiteral:
  428. case Parse::NodeKind::BaseColon:
  429. case Parse::NodeKind::BaseDecl:
  430. case Parse::NodeKind::BaseIntroducer:
  431. case Parse::NodeKind::BaseModifier:
  432. case Parse::NodeKind::BaseName:
  433. case Parse::NodeKind::BoolLiteralFalse:
  434. case Parse::NodeKind::BoolLiteralTrue:
  435. case Parse::NodeKind::BoolTypeLiteral:
  436. case Parse::NodeKind::BreakStatement:
  437. case Parse::NodeKind::BreakStatementStart:
  438. case Parse::NodeKind::BuiltinFunctionDefinition:
  439. case Parse::NodeKind::CallExpr:
  440. case Parse::NodeKind::CallExprComma:
  441. case Parse::NodeKind::ChoiceAlternativeListComma:
  442. case Parse::NodeKind::ChoiceDefinition:
  443. case Parse::NodeKind::ChoiceDefinitionStart:
  444. case Parse::NodeKind::ChoiceIntroducer:
  445. case Parse::NodeKind::ClassDecl:
  446. case Parse::NodeKind::ClassDefinition:
  447. case Parse::NodeKind::CodeBlock:
  448. case Parse::NodeKind::ContinueStatement:
  449. case Parse::NodeKind::ContinueStatementStart:
  450. case Parse::NodeKind::DefaultModifier:
  451. case Parse::NodeKind::DefaultSelfImplAs:
  452. case Parse::NodeKind::DesignatorExpr:
  453. case Parse::NodeKind::EmptyDecl:
  454. case Parse::NodeKind::ExportDecl:
  455. case Parse::NodeKind::ExportIntroducer:
  456. case Parse::NodeKind::ExportModifier:
  457. case Parse::NodeKind::ExprStatement:
  458. case Parse::NodeKind::ExtendModifier:
  459. case Parse::NodeKind::ExternModifier:
  460. case Parse::NodeKind::ExternModifierWithLibrary:
  461. case Parse::NodeKind::FileEnd:
  462. case Parse::NodeKind::FileStart:
  463. case Parse::NodeKind::FinalModifier:
  464. case Parse::NodeKind::FloatTypeLiteral:
  465. case Parse::NodeKind::ForHeader:
  466. case Parse::NodeKind::ForHeaderStart:
  467. case Parse::NodeKind::ForIn:
  468. case Parse::NodeKind::ForStatement:
  469. case Parse::NodeKind::FunctionDecl:
  470. case Parse::NodeKind::FunctionDefinition:
  471. case Parse::NodeKind::IdentifierName:
  472. case Parse::NodeKind::IdentifierNameExpr:
  473. case Parse::NodeKind::IfConditionStart:
  474. case Parse::NodeKind::IfExprElse:
  475. case Parse::NodeKind::IfStatement:
  476. case Parse::NodeKind::ImplDecl:
  477. case Parse::NodeKind::ImplDefinition:
  478. case Parse::NodeKind::ImplModifier:
  479. case Parse::NodeKind::ImportDecl:
  480. case Parse::NodeKind::ImportIntroducer:
  481. case Parse::NodeKind::IndexExpr:
  482. case Parse::NodeKind::IndexExprStart:
  483. case Parse::NodeKind::InfixOperatorAmp:
  484. case Parse::NodeKind::InfixOperatorAmpEqual:
  485. case Parse::NodeKind::InfixOperatorAs:
  486. case Parse::NodeKind::InfixOperatorCaret:
  487. case Parse::NodeKind::InfixOperatorCaretEqual:
  488. case Parse::NodeKind::InfixOperatorEqual:
  489. case Parse::NodeKind::InfixOperatorEqualEqual:
  490. case Parse::NodeKind::InfixOperatorExclaimEqual:
  491. case Parse::NodeKind::InfixOperatorGreater:
  492. case Parse::NodeKind::InfixOperatorGreaterEqual:
  493. case Parse::NodeKind::InfixOperatorGreaterGreater:
  494. case Parse::NodeKind::InfixOperatorGreaterGreaterEqual:
  495. case Parse::NodeKind::InfixOperatorLess:
  496. case Parse::NodeKind::InfixOperatorLessEqual:
  497. case Parse::NodeKind::InfixOperatorLessEqualGreater:
  498. case Parse::NodeKind::InfixOperatorLessLess:
  499. case Parse::NodeKind::InfixOperatorLessLessEqual:
  500. case Parse::NodeKind::InfixOperatorMinus:
  501. case Parse::NodeKind::InfixOperatorMinusEqual:
  502. case Parse::NodeKind::InfixOperatorPercent:
  503. case Parse::NodeKind::InfixOperatorPercentEqual:
  504. case Parse::NodeKind::InfixOperatorPipe:
  505. case Parse::NodeKind::InfixOperatorPipeEqual:
  506. case Parse::NodeKind::InfixOperatorPlus:
  507. case Parse::NodeKind::InfixOperatorPlusEqual:
  508. case Parse::NodeKind::InfixOperatorSlash:
  509. case Parse::NodeKind::InfixOperatorSlashEqual:
  510. case Parse::NodeKind::InfixOperatorStar:
  511. case Parse::NodeKind::InfixOperatorStarEqual:
  512. case Parse::NodeKind::InterfaceDecl:
  513. case Parse::NodeKind::InterfaceDefinition:
  514. case Parse::NodeKind::IntLiteral:
  515. case Parse::NodeKind::IntTypeLiteral:
  516. case Parse::NodeKind::InvalidParse:
  517. case Parse::NodeKind::InvalidParseStart:
  518. case Parse::NodeKind::InvalidParseSubtree:
  519. case Parse::NodeKind::LetDecl:
  520. case Parse::NodeKind::LibraryDecl:
  521. case Parse::NodeKind::LibraryIntroducer:
  522. case Parse::NodeKind::LibrarySpecifier:
  523. case Parse::NodeKind::MatchCase:
  524. case Parse::NodeKind::MatchCaseEqualGreater:
  525. case Parse::NodeKind::MatchCaseGuard:
  526. case Parse::NodeKind::MatchCaseGuardIntroducer:
  527. case Parse::NodeKind::MatchCaseGuardStart:
  528. case Parse::NodeKind::MatchCaseIntroducer:
  529. case Parse::NodeKind::MatchCaseStart:
  530. case Parse::NodeKind::MatchCondition:
  531. case Parse::NodeKind::MatchConditionStart:
  532. case Parse::NodeKind::MatchDefault:
  533. case Parse::NodeKind::MatchDefaultEqualGreater:
  534. case Parse::NodeKind::MatchDefaultIntroducer:
  535. case Parse::NodeKind::MatchDefaultStart:
  536. case Parse::NodeKind::MatchIntroducer:
  537. case Parse::NodeKind::MatchStatement:
  538. case Parse::NodeKind::MatchStatementStart:
  539. case Parse::NodeKind::MemberAccessExpr:
  540. case Parse::NodeKind::NamedConstraintDecl:
  541. case Parse::NodeKind::NamedConstraintDefinition:
  542. case Parse::NodeKind::NamedConstraintDefinitionStart:
  543. case Parse::NodeKind::NamedConstraintIntroducer:
  544. case Parse::NodeKind::NameQualifier:
  545. case Parse::NodeKind::Namespace:
  546. case Parse::NodeKind::NamespaceStart:
  547. case Parse::NodeKind::PackageDecl:
  548. case Parse::NodeKind::PackageExpr:
  549. case Parse::NodeKind::PackageIntroducer:
  550. case Parse::NodeKind::PackageName:
  551. case Parse::NodeKind::ParenExpr:
  552. case Parse::NodeKind::ParenExprStart:
  553. case Parse::NodeKind::PatternListComma:
  554. case Parse::NodeKind::Placeholder:
  555. case Parse::NodeKind::PointerMemberAccessExpr:
  556. case Parse::NodeKind::PostfixOperatorStar:
  557. case Parse::NodeKind::PrefixOperatorAmp:
  558. case Parse::NodeKind::PrefixOperatorCaret:
  559. case Parse::NodeKind::PrefixOperatorConst:
  560. case Parse::NodeKind::PrefixOperatorMinus:
  561. case Parse::NodeKind::PrefixOperatorMinusMinus:
  562. case Parse::NodeKind::PrefixOperatorNot:
  563. case Parse::NodeKind::PrefixOperatorPlusPlus:
  564. case Parse::NodeKind::PrefixOperatorStar:
  565. case Parse::NodeKind::PrivateModifier:
  566. case Parse::NodeKind::ProtectedModifier:
  567. case Parse::NodeKind::RealLiteral:
  568. case Parse::NodeKind::RequirementAnd:
  569. case Parse::NodeKind::RequirementEqual:
  570. case Parse::NodeKind::RequirementEqualEqual:
  571. case Parse::NodeKind::RequirementImpls:
  572. case Parse::NodeKind::ReturnStatement:
  573. case Parse::NodeKind::SelfTypeNameExpr:
  574. case Parse::NodeKind::SelfValueNameExpr:
  575. case Parse::NodeKind::ShortCircuitOperatorAnd:
  576. case Parse::NodeKind::ShortCircuitOperatorOr:
  577. case Parse::NodeKind::StringLiteral:
  578. case Parse::NodeKind::StringTypeLiteral:
  579. case Parse::NodeKind::StructLiteralComma:
  580. case Parse::NodeKind::StructFieldDesignator:
  581. case Parse::NodeKind::StructTypeLiteralComma:
  582. case Parse::NodeKind::StructLiteral:
  583. case Parse::NodeKind::StructTypeLiteral:
  584. case Parse::NodeKind::Template:
  585. case Parse::NodeKind::TupleLiteral:
  586. case Parse::NodeKind::TupleLiteralComma:
  587. case Parse::NodeKind::TypeImplAs:
  588. case Parse::NodeKind::TypeTypeLiteral:
  589. case Parse::NodeKind::UnsignedIntTypeLiteral:
  590. case Parse::NodeKind::VariableDecl:
  591. case Parse::NodeKind::VirtualModifier:
  592. case Parse::NodeKind::WhereExpr:
  593. case Parse::NodeKind::WhileStatement:
  594. return Id::Kind::Invalid;
  595. }
  596. };
  597. #define CARBON_PARSE_NODE_KIND(Name) \
  598. table[Parse::Name::Kind.AsInt()] = to_id_kind(Parse::Name::Kind);
  599. #include "toolchain/parse/node_kind.def"
  600. return table;
  601. }
  602. // Translate a parse node kind to the enum ID kind it should always provide.
  603. static constexpr auto NodeKindToIdKind(Parse::NodeKind kind) -> Id::Kind {
  604. return IdKindTable[kind.AsInt()];
  605. }
  606. // Peeks at the ID associated with the top of the name stack.
  607. template <Id::Kind RequiredIdKind>
  608. auto Peek() const -> auto {
  609. Id id = stack_.back().id;
  610. return id.As<RequiredIdKind>();
  611. }
  612. // Pops an entry.
  613. template <typename IdT>
  614. auto PopEntry() -> Entry {
  615. Entry back = stack_.pop_back_val();
  616. CARBON_VLOG("Node Pop {0}: {1} -> {2}\n", stack_.size(),
  617. parse_tree_->node_kind(back.node_id),
  618. back.id.template As<IdT>());
  619. return back;
  620. }
  621. // Pops the top of the stack and returns the node_id and the ID.
  622. template <typename IdT>
  623. auto PopWithNodeId() -> std::pair<Parse::NodeId, IdT> {
  624. Entry back = PopEntry<IdT>();
  625. RequireIdKind(parse_tree_->node_kind(back.node_id), Id::KindFor<IdT>());
  626. return {back.node_id, back.id.template As<IdT>()};
  627. }
  628. // Require a Parse::NodeKind be mapped to a particular Id::Kind.
  629. auto RequireIdKind(Parse::NodeKind parse_kind, Id::Kind id_kind) const
  630. -> void {
  631. CARBON_CHECK(NodeKindToIdKind(parse_kind) == id_kind,
  632. "Unexpected Id::Kind mapping for {0}: expected {1}, found {2}",
  633. parse_kind, static_cast<int>(id_kind),
  634. static_cast<int>(NodeKindToIdKind(parse_kind)));
  635. }
  636. // Require an entry to have the given Parse::NodeKind.
  637. template <const Parse::NodeKind& RequiredParseKind>
  638. auto RequireParseKind(Parse::NodeId node_id) const -> void {
  639. auto actual_kind = parse_tree_->node_kind(node_id);
  640. CARBON_CHECK(RequiredParseKind == actual_kind, "Expected {0}, found {1}",
  641. RequiredParseKind, actual_kind);
  642. }
  643. // Require an entry to have the given Parse::NodeCategory.
  644. template <Parse::NodeCategory::RawEnumType RequiredParseCategory>
  645. auto RequireParseCategory(Parse::NodeId node_id) const -> void {
  646. auto kind = parse_tree_->node_kind(node_id);
  647. CARBON_CHECK(kind.category().HasAnyOf(RequiredParseCategory),
  648. "Expected {0}, found {1} with category {2}",
  649. RequiredParseCategory, kind, kind.category());
  650. }
  651. // The file's parse tree.
  652. const Parse::Tree* parse_tree_;
  653. // Whether to print verbose output.
  654. llvm::raw_ostream* vlog_stream_;
  655. // The actual stack.
  656. // PushEntry and PopEntry control modification in order to centralize
  657. // vlogging.
  658. llvm::SmallVector<Entry> stack_;
  659. };
  660. constexpr NodeStack::IdKindTableType NodeStack::IdKindTable =
  661. ComputeIdKindTable();
  662. inline auto NodeStack::PopExprWithNodeId()
  663. -> std::pair<Parse::AnyExprId, SemIR::InstId> {
  664. return PopWithNodeId<Parse::NodeCategory::Expr>();
  665. }
  666. } // namespace Carbon::Check
  667. #endif // CARBON_TOOLCHAIN_CHECK_NODE_STACK_H_