semantics_handle.cpp 21 KB

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