semantics_handle.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  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 SemanticsHandleDeducedParameterList(SemanticsContext& context,
  12. ParseTree::Node parse_node) -> bool {
  13. return context.TODO(parse_node, "HandleDeducedParameterList");
  14. }
  15. auto SemanticsHandleDeducedParameterListStart(SemanticsContext& context,
  16. ParseTree::Node parse_node)
  17. -> bool {
  18. return context.TODO(parse_node, "HandleDeducedParameterListStart");
  19. }
  20. auto SemanticsHandleDesignatorExpression(SemanticsContext& context,
  21. ParseTree::Node parse_node) -> bool {
  22. auto name_id =
  23. context.node_stack().Pop<SemanticsStringId>(ParseNodeKind::Name);
  24. auto base_id = context.node_stack().Pop<SemanticsNodeId>();
  25. auto base = context.semantics_ir().GetNode(base_id);
  26. auto base_type = context.semantics_ir().GetNode(
  27. context.semantics_ir().GetType(base.type_id()));
  28. switch (base_type.kind()) {
  29. case SemanticsNodeKind::StructType: {
  30. auto refs =
  31. context.semantics_ir().GetNodeBlock(base_type.GetAsStructType());
  32. // TODO: Do we need to optimize this with a lookup table for O(1)?
  33. for (int i = 0; i < static_cast<int>(refs.size()); ++i) {
  34. auto ref = context.semantics_ir().GetNode(refs[i]);
  35. if (name_id == ref.GetAsStructTypeField()) {
  36. context.AddNodeAndPush(
  37. parse_node,
  38. SemanticsNode::StructMemberAccess::Make(
  39. parse_node, ref.type_id(), base_id, SemanticsMemberIndex(i)));
  40. return true;
  41. }
  42. }
  43. CARBON_DIAGNOSTIC(DesignatorExpressionNameNotFound, Error,
  44. "Type `{0}` does not have a member `{1}`.", std::string,
  45. llvm::StringRef);
  46. context.emitter().Emit(
  47. parse_node, DesignatorExpressionNameNotFound,
  48. context.semantics_ir().StringifyType(base.type_id()),
  49. context.semantics_ir().GetString(name_id));
  50. break;
  51. }
  52. default: {
  53. CARBON_DIAGNOSTIC(DesignatorExpressionUnsupported, Error,
  54. "Type `{0}` does not support designator expressions.",
  55. std::string);
  56. context.emitter().Emit(
  57. parse_node, DesignatorExpressionUnsupported,
  58. context.semantics_ir().StringifyType(base.type_id()));
  59. break;
  60. }
  61. }
  62. // Should only be reached on error.
  63. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinInvalidType);
  64. return true;
  65. }
  66. auto SemanticsHandleEmptyDeclaration(SemanticsContext& /*context*/,
  67. ParseTree::Node /*parse_node*/) -> bool {
  68. // Empty declarations have no actions associated.
  69. return true;
  70. }
  71. auto SemanticsHandleFileEnd(SemanticsContext& /*context*/,
  72. ParseTree::Node /*parse_node*/) -> bool {
  73. // Do nothing, no need to balance this node.
  74. return true;
  75. }
  76. auto SemanticsHandleGenericPatternBinding(SemanticsContext& context,
  77. ParseTree::Node parse_node) -> bool {
  78. return context.TODO(parse_node, "GenericPatternBinding");
  79. }
  80. auto SemanticsHandleInfixOperator(SemanticsContext& context,
  81. ParseTree::Node parse_node) -> bool {
  82. auto rhs_id = context.node_stack().Pop<SemanticsNodeId>();
  83. auto lhs_id = context.node_stack().Pop<SemanticsNodeId>();
  84. // Figure out the operator for the token.
  85. auto token = context.parse_tree().node_token(parse_node);
  86. switch (auto token_kind = context.tokens().GetKind(token)) {
  87. case TokenKind::Plus:
  88. // TODO: This should search for a compatible interface. For now, it's a
  89. // very trivial check of validity on the operation.
  90. lhs_id = context.ImplicitAsRequired(
  91. parse_node, lhs_id, context.semantics_ir().GetNode(rhs_id).type_id());
  92. context.AddNodeAndPush(
  93. parse_node,
  94. SemanticsNode::BinaryOperatorAdd::Make(
  95. parse_node, context.semantics_ir().GetNode(lhs_id).type_id(),
  96. lhs_id, rhs_id));
  97. break;
  98. case TokenKind::And:
  99. case TokenKind::Or: {
  100. // The first operand is wrapped in a ShortCircuitOperand, which we
  101. // already handled by creating a RHS block and a resumption block, which
  102. // are the current block and its enclosing block.
  103. rhs_id = context.ImplicitAsBool(parse_node, rhs_id);
  104. // When the second operand is evaluated, the result of `and` and `or` is
  105. // its value.
  106. auto rhs_block_id = context.node_block_stack().PopForAdd();
  107. auto resume_block_id = context.node_block_stack().PeekForAdd();
  108. context.AddNodeToBlock(rhs_block_id,
  109. SemanticsNode::BranchWithArg::Make(
  110. parse_node, resume_block_id, rhs_id));
  111. context.AddCurrentCodeBlockToFunction();
  112. // Collect the result from either the first or second operand.
  113. context.AddNodeAndPush(
  114. parse_node,
  115. SemanticsNode::BlockArg::Make(
  116. parse_node, context.semantics_ir().GetNode(rhs_id).type_id(),
  117. resume_block_id));
  118. break;
  119. }
  120. default:
  121. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  122. }
  123. return true;
  124. }
  125. auto SemanticsHandleInvalidParse(SemanticsContext& context,
  126. ParseTree::Node parse_node) -> bool {
  127. return context.TODO(parse_node, "HandleInvalidParse");
  128. }
  129. auto SemanticsHandleLiteral(SemanticsContext& context,
  130. ParseTree::Node parse_node) -> bool {
  131. auto token = context.parse_tree().node_token(parse_node);
  132. switch (auto token_kind = context.tokens().GetKind(token)) {
  133. case TokenKind::False:
  134. case TokenKind::True: {
  135. context.AddNodeAndPush(
  136. parse_node,
  137. SemanticsNode::BoolLiteral::Make(
  138. parse_node,
  139. context.CanonicalizeType(SemanticsNodeId::BuiltinBoolType),
  140. token_kind == TokenKind::True ? SemanticsBoolValue::True
  141. : SemanticsBoolValue::False));
  142. break;
  143. }
  144. case TokenKind::IntegerLiteral: {
  145. auto id = context.semantics_ir().AddIntegerLiteral(
  146. context.tokens().GetIntegerLiteral(token));
  147. context.AddNodeAndPush(
  148. parse_node,
  149. SemanticsNode::IntegerLiteral::Make(
  150. parse_node,
  151. context.CanonicalizeType(SemanticsNodeId::BuiltinIntegerType),
  152. id));
  153. break;
  154. }
  155. case TokenKind::RealLiteral: {
  156. auto token_value = context.tokens().GetRealLiteral(token);
  157. auto id = context.semantics_ir().AddRealLiteral(
  158. {.mantissa = token_value.Mantissa(),
  159. .exponent = token_value.Exponent(),
  160. .is_decimal = token_value.IsDecimal()});
  161. context.AddNodeAndPush(parse_node,
  162. SemanticsNode::RealLiteral::Make(
  163. parse_node,
  164. context.CanonicalizeType(
  165. SemanticsNodeId::BuiltinFloatingPointType),
  166. id));
  167. break;
  168. }
  169. case TokenKind::StringLiteral: {
  170. auto id = context.semantics_ir().AddString(
  171. context.tokens().GetStringLiteral(token));
  172. context.AddNodeAndPush(
  173. parse_node,
  174. SemanticsNode::StringLiteral::Make(
  175. parse_node,
  176. context.CanonicalizeType(SemanticsNodeId::BuiltinStringType),
  177. id));
  178. break;
  179. }
  180. case TokenKind::Bool: {
  181. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinBoolType);
  182. break;
  183. }
  184. case TokenKind::IntegerTypeLiteral: {
  185. auto text = context.tokens().GetTokenText(token);
  186. if (text != "i32") {
  187. return context.TODO(parse_node, "Currently only i32 is allowed");
  188. }
  189. context.node_stack().Push(parse_node,
  190. SemanticsNodeId::BuiltinIntegerType);
  191. break;
  192. }
  193. case TokenKind::FloatingPointTypeLiteral: {
  194. auto text = context.tokens().GetTokenText(token);
  195. if (text != "f64") {
  196. return context.TODO(parse_node, "Currently only f64 is allowed");
  197. }
  198. context.node_stack().Push(parse_node,
  199. SemanticsNodeId::BuiltinFloatingPointType);
  200. break;
  201. }
  202. case TokenKind::StringTypeLiteral: {
  203. context.node_stack().Push(parse_node, SemanticsNodeId::BuiltinStringType);
  204. break;
  205. }
  206. default: {
  207. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  208. }
  209. }
  210. return true;
  211. }
  212. auto SemanticsHandleName(SemanticsContext& context, ParseTree::Node parse_node)
  213. -> bool {
  214. auto name_str = context.parse_tree().GetNodeText(parse_node);
  215. auto name_id = context.semantics_ir().AddString(name_str);
  216. // The parent is responsible for binding the name.
  217. context.node_stack().Push(parse_node, name_id);
  218. return true;
  219. }
  220. auto SemanticsHandleNameExpression(SemanticsContext& context,
  221. ParseTree::Node parse_node) -> bool {
  222. auto name = context.parse_tree().GetNodeText(parse_node);
  223. context.node_stack().Push(parse_node, context.LookupName(parse_node, name));
  224. return true;
  225. }
  226. auto SemanticsHandleNamedConstraintDeclaration(SemanticsContext& context,
  227. ParseTree::Node parse_node)
  228. -> bool {
  229. return context.TODO(parse_node, "HandleNamedConstraintDeclaration");
  230. }
  231. auto SemanticsHandleNamedConstraintDefinition(SemanticsContext& context,
  232. ParseTree::Node parse_node)
  233. -> bool {
  234. return context.TODO(parse_node, "HandleNamedConstraintDefinition");
  235. }
  236. auto SemanticsHandleNamedConstraintDefinitionStart(SemanticsContext& context,
  237. ParseTree::Node parse_node)
  238. -> bool {
  239. return context.TODO(parse_node, "HandleNamedConstraintDefinitionStart");
  240. }
  241. auto SemanticsHandleNamedConstraintIntroducer(SemanticsContext& context,
  242. ParseTree::Node parse_node)
  243. -> bool {
  244. return context.TODO(parse_node, "HandleNamedConstraintIntroducer");
  245. }
  246. auto SemanticsHandleParameterList(SemanticsContext& context,
  247. ParseTree::Node parse_node) -> bool {
  248. auto refs_id = context.ParamOrArgEnd(
  249. /*for_args=*/false, ParseNodeKind::ParameterListStart);
  250. // TODO: This contains the IR block for parameters. At present, it's just
  251. // loose, but it's not strictly required for parameter refs; we should either
  252. // stop constructing it completely or, if it turns out to be needed, store it.
  253. // Note, the underlying issue is that the LLVM IR has nowhere clear to emit,
  254. // so changing storage would require addressing that problem. For comparison
  255. // with function calls, the IR needs to be emitted prior to the call.
  256. context.node_block_stack().Pop();
  257. context.PopScope();
  258. context.node_stack().PopAndDiscardSoloParseNode(
  259. ParseNodeKind::ParameterListStart);
  260. context.node_stack().Push(parse_node, refs_id);
  261. return true;
  262. }
  263. auto SemanticsHandleParameterListComma(SemanticsContext& context,
  264. ParseTree::Node /*parse_node*/) -> bool {
  265. context.ParamOrArgComma(/*for_args=*/false);
  266. return true;
  267. }
  268. auto SemanticsHandleParameterListStart(SemanticsContext& context,
  269. ParseTree::Node parse_node) -> bool {
  270. context.PushScope();
  271. context.node_stack().Push(parse_node);
  272. context.node_block_stack().Push();
  273. context.ParamOrArgStart();
  274. return true;
  275. }
  276. auto SemanticsHandleParenExpression(SemanticsContext& context,
  277. ParseTree::Node parse_node) -> bool {
  278. auto value_id = context.node_stack().Pop<SemanticsNodeId>();
  279. context.node_stack().PopAndDiscardSoloParseNode(
  280. ParseNodeKind::ParenExpressionOrTupleLiteralStart);
  281. context.node_stack().Push(parse_node, value_id);
  282. return true;
  283. }
  284. auto SemanticsHandleParenExpressionOrTupleLiteralStart(
  285. SemanticsContext& context, ParseTree::Node parse_node) -> bool {
  286. context.node_stack().Push(parse_node);
  287. return true;
  288. }
  289. auto SemanticsHandlePatternBinding(SemanticsContext& context,
  290. ParseTree::Node parse_node) -> bool {
  291. auto [type_node, parsed_type_id] =
  292. context.node_stack().PopWithParseNode<SemanticsNodeId>();
  293. auto cast_type_id = context.ExpressionAsType(type_node, parsed_type_id);
  294. // Get the name.
  295. auto [name_node, name_id] =
  296. context.node_stack().PopWithParseNode<SemanticsStringId>(
  297. ParseNodeKind::Name);
  298. // Allocate storage, linked to the name for error locations.
  299. auto storage_id =
  300. context.AddNode(SemanticsNode::VarStorage::Make(name_node, cast_type_id));
  301. // Bind the name to storage.
  302. context.AddNodeAndPush(parse_node,
  303. SemanticsNode::BindName::Make(name_node, cast_type_id,
  304. name_id, storage_id));
  305. return true;
  306. }
  307. auto SemanticsHandlePostfixOperator(SemanticsContext& context,
  308. ParseTree::Node parse_node) -> bool {
  309. return context.TODO(parse_node, "HandlePostfixOperator");
  310. }
  311. auto SemanticsHandlePrefixOperator(SemanticsContext& context,
  312. ParseTree::Node parse_node) -> bool {
  313. auto value_id = context.node_stack().Pop<SemanticsNodeId>();
  314. // Figure out the operator for the token.
  315. auto token = context.parse_tree().node_token(parse_node);
  316. switch (auto token_kind = context.tokens().GetKind(token)) {
  317. case TokenKind::Not:
  318. value_id = context.ImplicitAsBool(parse_node, value_id);
  319. context.AddNodeAndPush(
  320. parse_node,
  321. SemanticsNode::UnaryOperatorNot::Make(
  322. parse_node, context.semantics_ir().GetNode(value_id).type_id(),
  323. value_id));
  324. break;
  325. default:
  326. return context.TODO(parse_node, llvm::formatv("Handle {0}", token_kind));
  327. }
  328. return true;
  329. }
  330. auto SemanticsHandleReturnType(SemanticsContext& context,
  331. ParseTree::Node parse_node) -> bool {
  332. // Propagate the type expression.
  333. auto [type_parse_node, type_node_id] =
  334. context.node_stack().PopWithParseNode<SemanticsNodeId>();
  335. auto cast_node_id = context.ExpressionAsType(type_parse_node, type_node_id);
  336. context.node_stack().Push(parse_node, cast_node_id);
  337. return true;
  338. }
  339. auto SemanticsHandleSelfTypeNameExpression(SemanticsContext& context,
  340. ParseTree::Node parse_node) -> bool {
  341. return context.TODO(parse_node, "HandleSelfTypeNameExpression");
  342. }
  343. auto SemanticsHandleSelfValueName(SemanticsContext& context,
  344. ParseTree::Node parse_node) -> bool {
  345. return context.TODO(parse_node, "HandleSelfValueName");
  346. }
  347. auto SemanticsHandleShortCircuitOperand(SemanticsContext& context,
  348. ParseTree::Node parse_node) -> bool {
  349. // Convert the condition to `bool`.
  350. auto cond_value_id = context.node_stack().Pop<SemanticsNodeId>();
  351. cond_value_id = context.ImplicitAsBool(parse_node, cond_value_id);
  352. auto bool_type_id = context.semantics_ir().GetNode(cond_value_id).type_id();
  353. // Compute the branch value: the condition for `and`, inverted for `or`.
  354. auto token = context.parse_tree().node_token(parse_node);
  355. SemanticsNodeId branch_value_id = SemanticsNodeId::Invalid;
  356. auto short_circuit_result_id = SemanticsNodeId::Invalid;
  357. switch (auto token_kind = context.tokens().GetKind(token)) {
  358. case TokenKind::And:
  359. branch_value_id = cond_value_id;
  360. short_circuit_result_id =
  361. context.AddNode(SemanticsNode::BoolLiteral::Make(
  362. parse_node, bool_type_id, SemanticsBoolValue::False));
  363. break;
  364. case TokenKind::Or:
  365. branch_value_id = context.AddNode(SemanticsNode::UnaryOperatorNot::Make(
  366. parse_node, bool_type_id, cond_value_id));
  367. short_circuit_result_id =
  368. context.AddNode(SemanticsNode::BoolLiteral::Make(
  369. parse_node, bool_type_id, SemanticsBoolValue::True));
  370. break;
  371. default:
  372. CARBON_FATAL() << "Unexpected short-circuiting operator " << parse_node;
  373. }
  374. // Create a block for the right-hand side and for the continuation.
  375. auto rhs_block_id =
  376. context.AddDominatedBlockAndBranchIf(parse_node, branch_value_id);
  377. auto end_block_id = context.AddDominatedBlockAndBranchWithArg(
  378. parse_node, short_circuit_result_id);
  379. // Push the resumption and the right-hand side blocks, and start emitting the
  380. // right-hand operand.
  381. context.node_block_stack().Pop();
  382. context.node_block_stack().Push(end_block_id);
  383. context.node_block_stack().Push(rhs_block_id);
  384. context.AddCurrentCodeBlockToFunction();
  385. // Put the condition back on the stack for SemanticsHandleInfixOperator.
  386. context.node_stack().Push(parse_node, cond_value_id);
  387. return true;
  388. }
  389. auto SemanticsHandleTemplate(SemanticsContext& context,
  390. ParseTree::Node parse_node) -> bool {
  391. return context.TODO(parse_node, "HandleTemplate");
  392. }
  393. auto SemanticsHandleTupleLiteral(SemanticsContext& context,
  394. ParseTree::Node parse_node) -> bool {
  395. return context.TODO(parse_node, "HandleTupleLiteral");
  396. }
  397. auto SemanticsHandleTupleLiteralComma(SemanticsContext& context,
  398. ParseTree::Node parse_node) -> bool {
  399. return context.TODO(parse_node, "HandleTupleLiteralComma");
  400. }
  401. auto SemanticsHandleVariableDeclaration(SemanticsContext& context,
  402. ParseTree::Node parse_node) -> bool {
  403. // Handle the optional initializer.
  404. auto expr_node_id = SemanticsNodeId::Invalid;
  405. bool has_init =
  406. context.parse_tree().node_kind(context.node_stack().PeekParseNode()) !=
  407. ParseNodeKind::PatternBinding;
  408. if (has_init) {
  409. expr_node_id = context.node_stack().Pop<SemanticsNodeId>();
  410. context.node_stack().PopAndDiscardSoloParseNode(
  411. ParseNodeKind::VariableInitializer);
  412. }
  413. // Get the storage and add it to name lookup.
  414. auto binding_id =
  415. context.node_stack().Pop<SemanticsNodeId>(ParseNodeKind::PatternBinding);
  416. auto binding = context.semantics_ir().GetNode(binding_id);
  417. auto [name_id, storage_id] = binding.GetAsBindName();
  418. context.AddNameToLookup(binding.parse_node(), name_id, storage_id);
  419. // If there was an initializer, assign it to storage.
  420. if (has_init) {
  421. auto cast_value_id = context.ImplicitAsRequired(
  422. parse_node, expr_node_id,
  423. context.semantics_ir().GetNode(storage_id).type_id());
  424. context.AddNode(SemanticsNode::Assign::Make(
  425. parse_node, context.semantics_ir().GetNode(cast_value_id).type_id(),
  426. storage_id, cast_value_id));
  427. }
  428. context.node_stack().PopAndDiscardSoloParseNode(
  429. ParseNodeKind::VariableIntroducer);
  430. return true;
  431. }
  432. auto SemanticsHandleVariableIntroducer(SemanticsContext& context,
  433. ParseTree::Node parse_node) -> bool {
  434. // No action, just a bracketing node.
  435. context.node_stack().Push(parse_node);
  436. return true;
  437. }
  438. auto SemanticsHandleVariableInitializer(SemanticsContext& context,
  439. ParseTree::Node parse_node) -> bool {
  440. // No action, just a bracketing node.
  441. context.node_stack().Push(parse_node);
  442. return true;
  443. }
  444. } // namespace Carbon