semantics_handle.cpp 21 KB

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