semantics_handle.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  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_context.h"
  5. #include "toolchain/semantics/semantics_node.h"
  6. namespace Carbon {
  7. auto SemanticsHandleAddress(SemanticsContext& context,
  8. ParseTree::Node parse_node) -> bool {
  9. return context.TODO(parse_node, "HandleAddress");
  10. }
  11. auto SemanticsHandleBreakStatement(SemanticsContext& context,
  12. ParseTree::Node parse_node) -> bool {
  13. return context.TODO(parse_node, "HandleBreakStatement");
  14. }
  15. auto SemanticsHandleBreakStatementStart(SemanticsContext& context,
  16. ParseTree::Node parse_node) -> bool {
  17. return context.TODO(parse_node, "HandleBreakStatementStart");
  18. }
  19. auto SemanticsHandleContinueStatement(SemanticsContext& context,
  20. ParseTree::Node parse_node) -> bool {
  21. return context.TODO(parse_node, "HandleContinueStatement");
  22. }
  23. auto SemanticsHandleContinueStatementStart(SemanticsContext& context,
  24. ParseTree::Node parse_node) -> bool {
  25. return context.TODO(parse_node, "HandleContinueStatementStart");
  26. }
  27. auto SemanticsHandleDeclaredName(SemanticsContext& context,
  28. ParseTree::Node parse_node) -> bool {
  29. // The parent is responsible for binding the name.
  30. context.node_stack().Push(parse_node);
  31. return true;
  32. }
  33. auto SemanticsHandleDeducedParameterList(SemanticsContext& context,
  34. ParseTree::Node parse_node) -> bool {
  35. return context.TODO(parse_node, "HandleDeducedParameterList");
  36. }
  37. auto SemanticsHandleDeducedParameterListStart(SemanticsContext& context,
  38. ParseTree::Node parse_node)
  39. -> bool {
  40. return context.TODO(parse_node, "HandleDeducedParameterListStart");
  41. }
  42. auto SemanticsHandleDesignatedName(SemanticsContext& context,
  43. ParseTree::Node parse_node) -> bool {
  44. auto name_str = context.parse_tree().GetNodeText(parse_node);
  45. auto name_id = context.semantics_ir().AddString(name_str);
  46. // The parent is responsible for binding the name.
  47. context.node_stack().Push(parse_node, name_id);
  48. return true;
  49. }
  50. auto SemanticsHandleDesignatorExpression(SemanticsContext& context,
  51. ParseTree::Node parse_node) -> bool {
  52. auto name_id = context.node_stack().Pop<SemanticsStringId>(
  53. ParseNodeKind::DesignatedName);
  54. auto base_id = context.node_stack().Pop<SemanticsNodeId>();
  55. auto base = context.semantics_ir().GetNode(base_id);
  56. auto base_type = context.semantics_ir().GetNode(
  57. context.semantics_ir().GetType(base.type_id()));
  58. switch (base_type.kind()) {
  59. case SemanticsNodeKind::StructType: {
  60. auto refs =
  61. context.semantics_ir().GetNodeBlock(base_type.GetAsStructType());
  62. // TODO: Do we need to optimize this with a lookup table for O(1)?
  63. for (int i = 0; i < static_cast<int>(refs.size()); ++i) {
  64. auto ref = context.semantics_ir().GetNode(refs[i]);
  65. if (name_id == ref.GetAsStructTypeField()) {
  66. context.AddNodeAndPush(
  67. parse_node,
  68. SemanticsNode::StructMemberAccess::Make(
  69. parse_node, ref.type_id(), base_id, SemanticsMemberIndex(i)));
  70. return true;
  71. }
  72. }
  73. CARBON_DIAGNOSTIC(DesignatorExpressionNameNotFound, Error,
  74. "Type `{0}` does not have a member `{1}`.", std::string,
  75. llvm::StringRef);
  76. context.emitter().Emit(
  77. parse_node, DesignatorExpressionNameNotFound,
  78. context.semantics_ir().StringifyType(base.type_id()),
  79. context.semantics_ir().GetString(name_id));
  80. break;
  81. }
  82. default: {
  83. CARBON_DIAGNOSTIC(DesignatorExpressionUnsupported, Error,
  84. "Type `{0}` does not support designator expressions.",
  85. std::string);
  86. context.emitter().Emit(
  87. parse_node, DesignatorExpressionUnsupported,
  88. context.semantics_ir().StringifyType(base.type_id()));
  89. break;
  90. }
  91. }
  92. // Should only be reached on error.
  93. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinInvalidType);
  94. return true;
  95. }
  96. auto SemanticsHandleEmptyDeclaration(SemanticsContext& /*context*/,
  97. ParseTree::Node /*parse_node*/) -> bool {
  98. // Empty declarations have no actions associated.
  99. return true;
  100. }
  101. auto SemanticsHandleExpressionStatement(SemanticsContext& context,
  102. ParseTree::Node /*parse_node*/)
  103. -> bool {
  104. // Pop the expression without investigating its contents.
  105. // TODO: This will probably eventually need to do some "do not discard"
  106. // analysis.
  107. context.node_stack().PopAndDiscardId();
  108. return true;
  109. }
  110. auto SemanticsHandleFileEnd(SemanticsContext& /*context*/,
  111. ParseTree::Node /*parse_node*/) -> bool {
  112. // Do nothing, no need to balance this node.
  113. return true;
  114. }
  115. auto SemanticsHandleForHeader(SemanticsContext& context,
  116. ParseTree::Node parse_node) -> bool {
  117. return context.TODO(parse_node, "HandleForHeader");
  118. }
  119. auto SemanticsHandleForHeaderStart(SemanticsContext& context,
  120. ParseTree::Node parse_node) -> bool {
  121. return context.TODO(parse_node, "HandleForHeaderStart");
  122. }
  123. auto SemanticsHandleForIn(SemanticsContext& context, ParseTree::Node parse_node)
  124. -> bool {
  125. return context.TODO(parse_node, "HandleForIn");
  126. }
  127. auto SemanticsHandleForStatement(SemanticsContext& context,
  128. ParseTree::Node parse_node) -> bool {
  129. return context.TODO(parse_node, "HandleForStatement");
  130. }
  131. auto SemanticsHandleGenericPatternBinding(SemanticsContext& context,
  132. ParseTree::Node parse_node) -> bool {
  133. return context.TODO(parse_node, "GenericPatternBinding");
  134. }
  135. auto SemanticsHandleInfixOperator(SemanticsContext& context,
  136. ParseTree::Node parse_node) -> bool {
  137. auto rhs_id = context.node_stack().Pop<SemanticsNodeId>();
  138. auto lhs_id = context.node_stack().Pop<SemanticsNodeId>();
  139. // Figure out the operator for the token.
  140. auto token = context.parse_tree().node_token(parse_node);
  141. switch (auto token_kind = context.tokens().GetKind(token)) {
  142. case TokenKind::Plus:
  143. // TODO: This should search for a compatible interface. For now, it's a
  144. // very trivial check of validity on the operation.
  145. lhs_id = context.ImplicitAsRequired(
  146. parse_node, lhs_id, context.semantics_ir().GetNode(rhs_id).type_id());
  147. context.AddNodeAndPush(
  148. parse_node,
  149. SemanticsNode::BinaryOperatorAdd::Make(
  150. parse_node, context.semantics_ir().GetNode(lhs_id).type_id(),
  151. lhs_id, rhs_id));
  152. break;
  153. case TokenKind::And:
  154. case TokenKind::Or: {
  155. // The first operand is wrapped in a ShortCircuitOperand, which we
  156. // already handled by creating a RHS block and a resumption block, which
  157. // are the current block and its enclosing block.
  158. rhs_id = context.ImplicitAsBool(parse_node, rhs_id);
  159. // When the second operand is evaluated, the result of `and` and `or` is
  160. // its value.
  161. auto rhs_block_id = context.node_block_stack().PopForAdd();
  162. auto resume_block_id = context.node_block_stack().PeekForAdd();
  163. context.AddNodeToBlock(rhs_block_id,
  164. SemanticsNode::BranchWithArg::Make(
  165. parse_node, resume_block_id, rhs_id));
  166. // Collect the result from either the first or second operand.
  167. context.AddNodeAndPush(
  168. parse_node,
  169. SemanticsNode::BlockArg::Make(
  170. parse_node, context.semantics_ir().GetNode(rhs_id).type_id(),
  171. resume_block_id));
  172. break;
  173. }
  174. default:
  175. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  176. }
  177. return true;
  178. }
  179. auto SemanticsHandleInvalidParse(SemanticsContext& context,
  180. ParseTree::Node parse_node) -> bool {
  181. return context.TODO(parse_node, "HandleInvalidParse");
  182. }
  183. auto SemanticsHandleLiteral(SemanticsContext& context,
  184. ParseTree::Node parse_node) -> bool {
  185. auto token = context.parse_tree().node_token(parse_node);
  186. switch (auto token_kind = context.tokens().GetKind(token)) {
  187. case TokenKind::False:
  188. case TokenKind::True: {
  189. context.AddNodeAndPush(
  190. parse_node,
  191. SemanticsNode::BoolLiteral::Make(
  192. parse_node,
  193. context.CanonicalizeType(SemanticsNodeId::BuiltinBoolType),
  194. token_kind == TokenKind::True ? SemanticsBoolValue::True
  195. : SemanticsBoolValue::False));
  196. break;
  197. }
  198. case TokenKind::IntegerLiteral: {
  199. auto id = context.semantics_ir().AddIntegerLiteral(
  200. context.tokens().GetIntegerLiteral(token));
  201. context.AddNodeAndPush(
  202. parse_node,
  203. SemanticsNode::IntegerLiteral::Make(
  204. parse_node,
  205. context.CanonicalizeType(SemanticsNodeId::BuiltinIntegerType),
  206. id));
  207. break;
  208. }
  209. case TokenKind::RealLiteral: {
  210. auto token_value = context.tokens().GetRealLiteral(token);
  211. auto id = context.semantics_ir().AddRealLiteral(
  212. {.mantissa = token_value.Mantissa(),
  213. .exponent = token_value.Exponent(),
  214. .is_decimal = token_value.IsDecimal()});
  215. context.AddNodeAndPush(parse_node,
  216. SemanticsNode::RealLiteral::Make(
  217. parse_node,
  218. context.CanonicalizeType(
  219. SemanticsNodeId::BuiltinFloatingPointType),
  220. id));
  221. break;
  222. }
  223. case TokenKind::StringLiteral: {
  224. auto id = context.semantics_ir().AddString(
  225. context.tokens().GetStringLiteral(token));
  226. context.AddNodeAndPush(
  227. parse_node,
  228. SemanticsNode::StringLiteral::Make(
  229. parse_node,
  230. context.CanonicalizeType(SemanticsNodeId::BuiltinStringType),
  231. id));
  232. break;
  233. }
  234. case TokenKind::Bool: {
  235. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinBoolType);
  236. break;
  237. }
  238. case TokenKind::IntegerTypeLiteral: {
  239. auto text = context.tokens().GetTokenText(token);
  240. if (text != "i32") {
  241. return context.TODO(parse_node, "Currently only i32 is allowed");
  242. }
  243. context.node_stack().Push(parse_node,
  244. SemanticsNodeId::BuiltinIntegerType);
  245. break;
  246. }
  247. case TokenKind::FloatingPointTypeLiteral: {
  248. auto text = context.tokens().GetTokenText(token);
  249. if (text != "f64") {
  250. return context.TODO(parse_node, "Currently only f64 is allowed");
  251. }
  252. context.node_stack().Push(parse_node,
  253. SemanticsNodeId::BuiltinFloatingPointType);
  254. break;
  255. }
  256. case TokenKind::StringTypeLiteral: {
  257. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinStringType);
  258. break;
  259. }
  260. default: {
  261. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  262. }
  263. }
  264. return true;
  265. }
  266. auto SemanticsHandleNameReference(SemanticsContext& context,
  267. ParseTree::Node parse_node) -> bool {
  268. auto name = context.parse_tree().GetNodeText(parse_node);
  269. context.node_stack().Push(parse_node, context.LookupName(parse_node, name));
  270. return true;
  271. }
  272. auto SemanticsHandleNamedConstraintDeclaration(SemanticsContext& context,
  273. ParseTree::Node parse_node)
  274. -> bool {
  275. return context.TODO(parse_node, "HandleNamedConstraintDeclaration");
  276. }
  277. auto SemanticsHandleNamedConstraintDefinition(SemanticsContext& context,
  278. ParseTree::Node parse_node)
  279. -> bool {
  280. return context.TODO(parse_node, "HandleNamedConstraintDefinition");
  281. }
  282. auto SemanticsHandleNamedConstraintDefinitionStart(SemanticsContext& context,
  283. ParseTree::Node parse_node)
  284. -> bool {
  285. return context.TODO(parse_node, "HandleNamedConstraintDefinitionStart");
  286. }
  287. auto SemanticsHandleNamedConstraintIntroducer(SemanticsContext& context,
  288. ParseTree::Node parse_node)
  289. -> bool {
  290. return context.TODO(parse_node, "HandleNamedConstraintIntroducer");
  291. }
  292. auto SemanticsHandleParameterList(SemanticsContext& context,
  293. ParseTree::Node parse_node) -> bool {
  294. auto refs_id = context.ParamOrArgEnd(
  295. /*for_args=*/false, ParseNodeKind::ParameterListStart);
  296. // TODO: This contains the IR block for parameters. At present, it's just
  297. // loose, but it's not strictly required for parameter refs; we should either
  298. // stop constructing it completely or, if it turns out to be needed, store it.
  299. // Note, the underlying issue is that the LLVM IR has nowhere clear to emit,
  300. // so changing storage would require addressing that problem. For comparison
  301. // with function calls, the IR needs to be emitted prior to the call.
  302. context.node_block_stack().Pop();
  303. context.PopScope();
  304. context.node_stack().PopAndDiscardSoloParseNode(
  305. ParseNodeKind::ParameterListStart);
  306. context.node_stack().Push(parse_node, refs_id);
  307. return true;
  308. }
  309. auto SemanticsHandleParameterListComma(SemanticsContext& context,
  310. ParseTree::Node /*parse_node*/) -> bool {
  311. context.ParamOrArgComma(/*for_args=*/false);
  312. return true;
  313. }
  314. auto SemanticsHandleParameterListStart(SemanticsContext& context,
  315. ParseTree::Node parse_node) -> bool {
  316. context.PushScope();
  317. context.node_stack().Push(parse_node);
  318. context.node_block_stack().Push();
  319. context.ParamOrArgStart();
  320. return true;
  321. }
  322. auto SemanticsHandleParenExpression(SemanticsContext& context,
  323. ParseTree::Node parse_node) -> bool {
  324. auto value_id = context.node_stack().Pop<SemanticsNodeId>();
  325. context.node_stack().PopAndDiscardSoloParseNode(
  326. ParseNodeKind::ParenExpressionOrTupleLiteralStart);
  327. context.node_stack().Push(parse_node, value_id);
  328. return true;
  329. }
  330. auto SemanticsHandleParenExpressionOrTupleLiteralStart(
  331. SemanticsContext& context, ParseTree::Node parse_node) -> bool {
  332. context.node_stack().Push(parse_node);
  333. return true;
  334. }
  335. auto SemanticsHandlePatternBinding(SemanticsContext& context,
  336. ParseTree::Node parse_node) -> bool {
  337. auto [type_node, parsed_type_id] =
  338. context.node_stack().PopWithParseNode<SemanticsNodeId>();
  339. auto cast_type_id = context.ExpressionAsType(type_node, parsed_type_id);
  340. // Get the name.
  341. auto name_node =
  342. context.node_stack().PopForSoloParseNode(ParseNodeKind::DeclaredName);
  343. auto name_str = context.parse_tree().GetNodeText(name_node);
  344. auto name_id = context.semantics_ir().AddString(name_str);
  345. // Allocate storage, linked to the name for error locations.
  346. auto storage_id =
  347. context.AddNode(SemanticsNode::VarStorage::Make(name_node, cast_type_id));
  348. // Bind the name to storage.
  349. context.AddNodeAndPush(parse_node,
  350. SemanticsNode::BindName::Make(name_node, cast_type_id,
  351. name_id, storage_id));
  352. return true;
  353. }
  354. auto SemanticsHandlePostfixOperator(SemanticsContext& context,
  355. ParseTree::Node parse_node) -> bool {
  356. return context.TODO(parse_node, "HandlePostfixOperator");
  357. }
  358. auto SemanticsHandlePrefixOperator(SemanticsContext& context,
  359. ParseTree::Node parse_node) -> bool {
  360. auto value_id = context.node_stack().Pop<SemanticsNodeId>();
  361. // Figure out the operator for the token.
  362. auto token = context.parse_tree().node_token(parse_node);
  363. switch (auto token_kind = context.tokens().GetKind(token)) {
  364. case TokenKind::Not:
  365. value_id = context.ImplicitAsBool(parse_node, value_id);
  366. context.AddNodeAndPush(
  367. parse_node,
  368. SemanticsNode::UnaryOperatorNot::Make(
  369. parse_node, context.semantics_ir().GetNode(value_id).type_id(),
  370. value_id));
  371. break;
  372. default:
  373. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  374. }
  375. return true;
  376. }
  377. auto SemanticsHandleReturnStatement(SemanticsContext& context,
  378. ParseTree::Node parse_node) -> bool {
  379. CARBON_CHECK(!context.return_scope_stack().empty());
  380. const auto& fn_node =
  381. context.semantics_ir().GetNode(context.return_scope_stack().back());
  382. const auto callable =
  383. context.semantics_ir().GetFunction(fn_node.GetAsFunctionDeclaration());
  384. if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) ==
  385. ParseNodeKind::ReturnStatementStart) {
  386. context.node_stack().PopAndDiscardSoloParseNode(
  387. ParseNodeKind::ReturnStatementStart);
  388. if (callable.return_type_id.is_valid()) {
  389. // TODO: Add a note pointing at the return type's parse node.
  390. CARBON_DIAGNOSTIC(ReturnStatementMissingExpression, Error,
  391. "Must return a {0}.", std::string);
  392. context.emitter()
  393. .Build(parse_node, ReturnStatementMissingExpression,
  394. context.semantics_ir().StringifyType(callable.return_type_id))
  395. .Emit();
  396. }
  397. context.AddNode(SemanticsNode::Return::Make(parse_node));
  398. } else {
  399. auto arg = context.node_stack().Pop<SemanticsNodeId>();
  400. context.node_stack().PopAndDiscardSoloParseNode(
  401. ParseNodeKind::ReturnStatementStart);
  402. if (!callable.return_type_id.is_valid()) {
  403. CARBON_DIAGNOSTIC(
  404. ReturnStatementDisallowExpression, Error,
  405. "No return expression should be provided in this context.");
  406. CARBON_DIAGNOSTIC(ReturnStatementImplicitNote, Note,
  407. "There was no return type provided.");
  408. context.emitter()
  409. .Build(parse_node, ReturnStatementDisallowExpression)
  410. .Note(fn_node.parse_node(), ReturnStatementImplicitNote)
  411. .Emit();
  412. } else {
  413. arg =
  414. context.ImplicitAsRequired(parse_node, arg, callable.return_type_id);
  415. }
  416. context.AddNode(SemanticsNode::ReturnExpression::Make(
  417. parse_node, context.semantics_ir().GetNode(arg).type_id(), arg));
  418. }
  419. return true;
  420. }
  421. auto SemanticsHandleReturnStatementStart(SemanticsContext& context,
  422. ParseTree::Node parse_node) -> bool {
  423. // No action, just a bracketing node.
  424. context.node_stack().Push(parse_node);
  425. return true;
  426. }
  427. auto SemanticsHandleReturnType(SemanticsContext& context,
  428. ParseTree::Node parse_node) -> bool {
  429. // Propagate the type expression.
  430. auto [type_parse_node, type_node_id] =
  431. context.node_stack().PopWithParseNode<SemanticsNodeId>();
  432. auto cast_node_id = context.ExpressionAsType(type_parse_node, type_node_id);
  433. context.node_stack().Push(parse_node, cast_node_id);
  434. return true;
  435. }
  436. auto SemanticsHandleSelfTypeIdentifier(SemanticsContext& context,
  437. ParseTree::Node parse_node) -> bool {
  438. return context.TODO(parse_node, "HandleSelfTypeIdentifier");
  439. }
  440. auto SemanticsHandleSelfValueIdentifier(SemanticsContext& context,
  441. ParseTree::Node parse_node) -> bool {
  442. return context.TODO(parse_node, "HandleSelfValueIdentifier");
  443. }
  444. auto SemanticsHandleShortCircuitOperand(SemanticsContext& context,
  445. ParseTree::Node parse_node) -> bool {
  446. // Convert the condition to `bool`.
  447. auto cond_value_id = context.node_stack().Pop<SemanticsNodeId>();
  448. cond_value_id = context.ImplicitAsBool(parse_node, cond_value_id);
  449. auto bool_type_id = context.semantics_ir().GetNode(cond_value_id).type_id();
  450. // Compute the branch value: the condition for `and`, inverted for `or`.
  451. auto token = context.parse_tree().node_token(parse_node);
  452. SemanticsNodeId branch_value_id = SemanticsNodeId::Invalid;
  453. auto short_circuit_result_id = SemanticsNodeId::Invalid;
  454. switch (auto token_kind = context.tokens().GetKind(token)) {
  455. case TokenKind::And:
  456. branch_value_id = cond_value_id;
  457. short_circuit_result_id =
  458. context.AddNode(SemanticsNode::BoolLiteral::Make(
  459. parse_node, bool_type_id, SemanticsBoolValue::False));
  460. break;
  461. case TokenKind::Or:
  462. branch_value_id = context.AddNode(SemanticsNode::UnaryOperatorNot::Make(
  463. parse_node, bool_type_id, cond_value_id));
  464. short_circuit_result_id =
  465. context.AddNode(SemanticsNode::BoolLiteral::Make(
  466. parse_node, bool_type_id, SemanticsBoolValue::True));
  467. break;
  468. default:
  469. CARBON_FATAL() << "Unexpected short-circuiting operator " << parse_node;
  470. }
  471. // Create a block for the right-hand side and for the continuation.
  472. auto lhs_block_id = context.node_block_stack().PopForAdd();
  473. auto end_block_id = context.node_block_stack().PushForAdd();
  474. auto rhs_block_id = context.node_block_stack().PushForAdd();
  475. context.AddNodeToBlock(
  476. lhs_block_id,
  477. SemanticsNode::BranchIf::Make(parse_node, rhs_block_id, branch_value_id));
  478. context.AddNodeToBlock(
  479. lhs_block_id, SemanticsNode::BranchWithArg::Make(
  480. parse_node, end_block_id, short_circuit_result_id));
  481. // Put the condition back on the stack for SemanticsHandleInfixOperator.
  482. context.node_stack().Push(parse_node, cond_value_id);
  483. return true;
  484. }
  485. auto SemanticsHandleTemplate(SemanticsContext& context,
  486. ParseTree::Node parse_node) -> bool {
  487. return context.TODO(parse_node, "HandleTemplate");
  488. }
  489. auto SemanticsHandleTupleLiteral(SemanticsContext& context,
  490. ParseTree::Node parse_node) -> bool {
  491. return context.TODO(parse_node, "HandleTupleLiteral");
  492. }
  493. auto SemanticsHandleTupleLiteralComma(SemanticsContext& context,
  494. ParseTree::Node parse_node) -> bool {
  495. return context.TODO(parse_node, "HandleTupleLiteralComma");
  496. }
  497. auto SemanticsHandleVariableDeclaration(SemanticsContext& context,
  498. ParseTree::Node parse_node) -> bool {
  499. // Handle the optional initializer.
  500. auto expr_node_id = SemanticsNodeId::Invalid;
  501. bool has_init =
  502. context.parse_tree().node_kind(context.node_stack().PeekParseNode()) !=
  503. ParseNodeKind::PatternBinding;
  504. if (has_init) {
  505. expr_node_id = context.node_stack().Pop<SemanticsNodeId>();
  506. context.node_stack().PopAndDiscardSoloParseNode(
  507. ParseNodeKind::VariableInitializer);
  508. }
  509. // Get the storage and add it to name lookup.
  510. auto binding_id =
  511. context.node_stack().Pop<SemanticsNodeId>(ParseNodeKind::PatternBinding);
  512. auto binding = context.semantics_ir().GetNode(binding_id);
  513. auto [name_id, storage_id] = binding.GetAsBindName();
  514. context.AddNameToLookup(binding.parse_node(), name_id, storage_id);
  515. // If there was an initializer, assign it to storage.
  516. if (has_init) {
  517. auto cast_value_id = context.ImplicitAsRequired(
  518. parse_node, expr_node_id,
  519. context.semantics_ir().GetNode(storage_id).type_id());
  520. context.AddNode(SemanticsNode::Assign::Make(
  521. parse_node, context.semantics_ir().GetNode(cast_value_id).type_id(),
  522. storage_id, cast_value_id));
  523. }
  524. context.node_stack().PopAndDiscardSoloParseNode(
  525. ParseNodeKind::VariableIntroducer);
  526. return true;
  527. }
  528. auto SemanticsHandleVariableIntroducer(SemanticsContext& context,
  529. ParseTree::Node parse_node) -> bool {
  530. // No action, just a bracketing node.
  531. context.node_stack().Push(parse_node);
  532. return true;
  533. }
  534. auto SemanticsHandleVariableInitializer(SemanticsContext& context,
  535. ParseTree::Node parse_node) -> bool {
  536. // No action, just a bracketing node.
  537. context.node_stack().Push(parse_node);
  538. return true;
  539. }
  540. auto SemanticsHandleWhileCondition(SemanticsContext& context,
  541. ParseTree::Node parse_node) -> bool {
  542. return context.TODO(parse_node, "HandleWhileCondition");
  543. }
  544. auto SemanticsHandleWhileConditionStart(SemanticsContext& context,
  545. ParseTree::Node parse_node) -> bool {
  546. return context.TODO(parse_node, "HandleWhileConditionStart");
  547. }
  548. auto SemanticsHandleWhileStatement(SemanticsContext& context,
  549. ParseTree::Node parse_node) -> bool {
  550. return context.TODO(parse_node, "HandleWhileStatement");
  551. }
  552. } // namespace Carbon