lowering_handle.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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/lowering/lowering_context.h"
  5. namespace Carbon {
  6. auto LoweringHandleInvalid(LoweringContext& /*context*/,
  7. SemanticsNodeId /*node_id*/, SemanticsNode /*node*/)
  8. -> void {
  9. llvm_unreachable("never in actual IR");
  10. }
  11. auto LoweringHandleCrossReference(LoweringContext& /*context*/,
  12. SemanticsNodeId /*node_id*/,
  13. SemanticsNode node) -> void {
  14. CARBON_FATAL() << "TODO: Add support: " << node;
  15. }
  16. auto LoweringHandleAssign(LoweringContext& context, SemanticsNodeId /*node_id*/,
  17. SemanticsNode node) -> void {
  18. auto [storage_id, value_id] = node.GetAsAssign();
  19. context.builder().CreateStore(context.GetLocalLoaded(value_id),
  20. context.GetLocal(storage_id));
  21. }
  22. auto LoweringHandleBinaryOperatorAdd(LoweringContext& /*context*/,
  23. SemanticsNodeId /*node_id*/,
  24. SemanticsNode node) -> void {
  25. CARBON_FATAL() << "TODO: Add support: " << node;
  26. }
  27. auto LoweringHandleBindName(LoweringContext& /*context*/,
  28. SemanticsNodeId /*node_id*/, SemanticsNode /*node*/)
  29. -> void {
  30. // Probably need to do something here, but not necessary for now.
  31. }
  32. auto LoweringHandleBlockArg(LoweringContext& /*context*/,
  33. SemanticsNodeId /*node_id*/, SemanticsNode node)
  34. -> void {
  35. CARBON_FATAL() << "TODO: Add support: " << node;
  36. }
  37. auto LoweringHandleBranch(LoweringContext& /*context*/,
  38. SemanticsNodeId /*node_id*/, SemanticsNode node)
  39. -> void {
  40. CARBON_FATAL() << "TODO: Add support: " << node;
  41. }
  42. auto LoweringHandleBranchIf(LoweringContext& /*context*/,
  43. SemanticsNodeId /*node_id*/, SemanticsNode node)
  44. -> void {
  45. CARBON_FATAL() << "TODO: Add support: " << node;
  46. }
  47. auto LoweringHandleBranchWithArg(LoweringContext& /*context*/,
  48. SemanticsNodeId /*node_id*/,
  49. SemanticsNode node) -> void {
  50. CARBON_FATAL() << "TODO: Add support: " << node;
  51. }
  52. auto LoweringHandleBuiltin(LoweringContext& /*context*/,
  53. SemanticsNodeId /*node_id*/, SemanticsNode node)
  54. -> void {
  55. CARBON_FATAL() << "TODO: Add support: " << node;
  56. }
  57. auto LoweringHandleCall(LoweringContext& context, SemanticsNodeId node_id,
  58. SemanticsNode node) -> void {
  59. auto [refs_id, function_id] = node.GetAsCall();
  60. auto* function = context.GetFunction(function_id);
  61. std::vector<llvm::Value*> args;
  62. for (auto ref_id : context.semantics_ir().GetNodeBlock(refs_id)) {
  63. args.push_back(context.GetLocalLoaded(ref_id));
  64. }
  65. auto* value =
  66. context.builder().CreateCall(function, args, function->getName());
  67. context.SetLocal(node_id, value);
  68. }
  69. auto LoweringHandleCodeBlock(LoweringContext& /*context*/,
  70. SemanticsNodeId /*node_id*/, SemanticsNode node)
  71. -> void {
  72. CARBON_FATAL() << "TODO: Add support: " << node;
  73. }
  74. auto LoweringHandleFunctionDeclaration(LoweringContext& /*context*/,
  75. SemanticsNodeId /*node_id*/,
  76. SemanticsNode node) -> void {
  77. CARBON_FATAL()
  78. << "Should not be encountered. If that changes, we may want to change "
  79. "higher-level logic to skip them rather than calling this. "
  80. << node;
  81. }
  82. auto LoweringHandleIntegerLiteral(LoweringContext& context,
  83. SemanticsNodeId node_id, SemanticsNode node)
  84. -> void {
  85. llvm::APInt i =
  86. context.semantics_ir().GetIntegerLiteral(node.GetAsIntegerLiteral());
  87. // TODO: This won't offer correct semantics, but seems close enough for now.
  88. llvm::Value* v =
  89. llvm::ConstantInt::get(context.builder().getInt32Ty(), i.getSExtValue());
  90. context.SetLocal(node_id, v);
  91. }
  92. auto LoweringHandleRealLiteral(LoweringContext& context,
  93. SemanticsNodeId node_id, SemanticsNode node)
  94. -> void {
  95. SemanticsRealLiteral real =
  96. context.semantics_ir().GetRealLiteral(node.GetAsRealLiteral());
  97. // TODO: This will probably have overflow issues, and should be fixed.
  98. double val =
  99. real.mantissa.getSExtValue() *
  100. std::pow((real.is_decimal ? 10 : 2), real.exponent.getSExtValue());
  101. llvm::APFloat llvm_val(val);
  102. context.SetLocal(node_id, llvm::ConstantFP::get(
  103. context.builder().getDoubleTy(), llvm_val));
  104. }
  105. auto LoweringHandleReturn(LoweringContext& context, SemanticsNodeId /*node_id*/,
  106. SemanticsNode /*node*/) -> void {
  107. context.builder().CreateRetVoid();
  108. }
  109. auto LoweringHandleReturnExpression(LoweringContext& context,
  110. SemanticsNodeId /*node_id*/,
  111. SemanticsNode node) -> void {
  112. SemanticsNodeId expr_id = node.GetAsReturnExpression();
  113. context.builder().CreateRet(context.GetLocalLoaded(expr_id));
  114. }
  115. auto LoweringHandleStringLiteral(LoweringContext& /*context*/,
  116. SemanticsNodeId /*node_id*/,
  117. SemanticsNode node) -> void {
  118. CARBON_FATAL() << "TODO: Add support: " << node;
  119. }
  120. auto LoweringHandleStructMemberAccess(LoweringContext& context,
  121. SemanticsNodeId node_id,
  122. SemanticsNode node) -> void {
  123. auto [struct_id, member_index] = node.GetAsStructMemberAccess();
  124. auto struct_type_id = context.semantics_ir().GetNode(struct_id).type_id();
  125. auto* llvm_type = context.GetType(struct_type_id);
  126. // Get type information for member names.
  127. auto type_refs = context.semantics_ir().GetNodeBlock(
  128. context.semantics_ir()
  129. .GetNode(context.semantics_ir().GetType(struct_type_id))
  130. .GetAsStructType());
  131. auto member_name = context.semantics_ir().GetString(
  132. context.semantics_ir()
  133. .GetNode(type_refs[member_index.index])
  134. .GetAsStructTypeField());
  135. auto* gep = context.builder().CreateStructGEP(
  136. llvm_type, context.GetLocal(struct_id), member_index.index, member_name);
  137. context.SetLocal(node_id, gep);
  138. }
  139. auto LoweringHandleStructType(LoweringContext& /*context*/,
  140. SemanticsNodeId /*node_id*/,
  141. SemanticsNode /*node*/) -> void {
  142. // No action to take.
  143. }
  144. auto LoweringHandleStructTypeField(LoweringContext& /*context*/,
  145. SemanticsNodeId /*node_id*/,
  146. SemanticsNode /*node*/) -> void {
  147. // No action to take.
  148. }
  149. auto LoweringHandleStructValue(LoweringContext& context,
  150. SemanticsNodeId node_id, SemanticsNode node)
  151. -> void {
  152. auto* llvm_type = context.GetType(node.type_id());
  153. auto* alloca = context.builder().CreateAlloca(
  154. llvm_type, /*ArraySize=*/nullptr, "StructLiteralValue");
  155. context.SetLocal(node_id, alloca);
  156. auto refs = context.semantics_ir().GetNodeBlock(node.GetAsStructValue());
  157. // Get type information for member names.
  158. auto type_refs = context.semantics_ir().GetNodeBlock(
  159. context.semantics_ir()
  160. .GetNode(context.semantics_ir().GetType(node.type_id()))
  161. .GetAsStructType());
  162. for (int i = 0; i < static_cast<int>(refs.size()); ++i) {
  163. auto member_name = context.semantics_ir().GetString(
  164. context.semantics_ir().GetNode(type_refs[i]).GetAsStructTypeField());
  165. auto* gep =
  166. context.builder().CreateStructGEP(llvm_type, alloca, i, member_name);
  167. context.builder().CreateStore(context.GetLocal(refs[i]), gep);
  168. }
  169. }
  170. auto LoweringHandleStubReference(LoweringContext& context,
  171. SemanticsNodeId node_id, SemanticsNode node)
  172. -> void {
  173. context.SetLocal(node_id, context.GetLocal(node.GetAsStubReference()));
  174. }
  175. auto LoweringHandleVarStorage(LoweringContext& context, SemanticsNodeId node_id,
  176. SemanticsNode node) -> void {
  177. // TODO: This should provide a name, not just `var`. Also, LLVM requires
  178. // globals to have a name. Do we want to generate a name, which would need to
  179. // be consistent across translation units, or use the given name, which
  180. // requires either looking ahead for BindName or restructuring semantics,
  181. // either of which affects the destructuring due to the difference in
  182. // storage?
  183. auto* alloca = context.builder().CreateAlloca(context.GetType(node.type_id()),
  184. /*ArraySize=*/nullptr, "var");
  185. context.SetLocal(node_id, alloca);
  186. }
  187. } // namespace Carbon