lowering_handle.cpp 9.5 KB

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