semantics_handle.cpp 21 KB

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