| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- // Exceptions. See /LICENSE for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- #include "toolchain/lowering/lowering_function_context.h"
- namespace Carbon {
- auto LoweringHandleInvalid(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/, SemanticsNode /*node*/)
- -> void {
- llvm_unreachable("never in actual IR");
- }
- auto LoweringHandleCrossReference(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/,
- SemanticsNode node) -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleAssign(LoweringFunctionContext& context,
- SemanticsNodeId /*node_id*/, SemanticsNode node)
- -> void {
- auto [storage_id, value_id] = node.GetAsAssign();
- context.builder().CreateStore(context.GetLocalLoaded(value_id),
- context.GetLocal(storage_id));
- }
- auto LoweringHandleBinaryOperatorAdd(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/,
- SemanticsNode node) -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleBindName(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/, SemanticsNode /*node*/)
- -> void {
- // Probably need to do something here, but not necessary for now.
- }
- auto LoweringHandleBlockArg(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/, SemanticsNode node)
- -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleBoolLiteral(LoweringFunctionContext& context,
- SemanticsNodeId node_id, SemanticsNode node)
- -> void {
- llvm::Value* v = llvm::ConstantInt::get(context.builder().getInt1Ty(),
- node.GetAsBoolLiteral().index);
- context.SetLocal(node_id, v);
- }
- auto LoweringHandleBranch(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/, SemanticsNode node)
- -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleBranchIf(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/, SemanticsNode node)
- -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleBranchWithArg(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/,
- SemanticsNode node) -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleBuiltin(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/, SemanticsNode node)
- -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleCall(LoweringFunctionContext& context,
- SemanticsNodeId node_id, SemanticsNode node) -> void {
- auto [refs_id, function_id] = node.GetAsCall();
- auto* function = context.GetFunction(function_id);
- std::vector<llvm::Value*> args;
- for (auto ref_id : context.semantics_ir().GetNodeBlock(refs_id)) {
- args.push_back(context.GetLocalLoaded(ref_id));
- }
- auto* value =
- context.builder().CreateCall(function, args, function->getName());
- context.SetLocal(node_id, value);
- }
- auto LoweringHandleCodeBlock(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/, SemanticsNode node)
- -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleFunctionDeclaration(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/,
- SemanticsNode node) -> void {
- CARBON_FATAL()
- << "Should not be encountered. If that changes, we may want to change "
- "higher-level logic to skip them rather than calling this. "
- << node;
- }
- auto LoweringHandleIntegerLiteral(LoweringFunctionContext& context,
- SemanticsNodeId node_id, SemanticsNode node)
- -> void {
- llvm::APInt i =
- context.semantics_ir().GetIntegerLiteral(node.GetAsIntegerLiteral());
- // TODO: This won't offer correct semantics, but seems close enough for now.
- llvm::Value* v =
- llvm::ConstantInt::get(context.builder().getInt32Ty(), i.getSExtValue());
- context.SetLocal(node_id, v);
- }
- auto LoweringHandleRealLiteral(LoweringFunctionContext& context,
- SemanticsNodeId node_id, SemanticsNode node)
- -> void {
- SemanticsRealLiteral real =
- context.semantics_ir().GetRealLiteral(node.GetAsRealLiteral());
- // TODO: This will probably have overflow issues, and should be fixed.
- double val =
- real.mantissa.getSExtValue() *
- std::pow((real.is_decimal ? 10 : 2), real.exponent.getSExtValue());
- llvm::APFloat llvm_val(val);
- context.SetLocal(node_id, llvm::ConstantFP::get(
- context.builder().getDoubleTy(), llvm_val));
- }
- auto LoweringHandleReturn(LoweringFunctionContext& context,
- SemanticsNodeId /*node_id*/, SemanticsNode /*node*/)
- -> void {
- context.builder().CreateRetVoid();
- }
- auto LoweringHandleReturnExpression(LoweringFunctionContext& context,
- SemanticsNodeId /*node_id*/,
- SemanticsNode node) -> void {
- SemanticsNodeId expr_id = node.GetAsReturnExpression();
- context.builder().CreateRet(context.GetLocalLoaded(expr_id));
- }
- auto LoweringHandleStringLiteral(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/,
- SemanticsNode node) -> void {
- CARBON_FATAL() << "TODO: Add support: " << node;
- }
- auto LoweringHandleStructMemberAccess(LoweringFunctionContext& context,
- SemanticsNodeId node_id,
- SemanticsNode node) -> void {
- auto [struct_id, member_index] = node.GetAsStructMemberAccess();
- auto struct_type_id = context.semantics_ir().GetNode(struct_id).type_id();
- auto* llvm_type = context.GetType(struct_type_id);
- // Get type information for member names.
- auto type_refs = context.semantics_ir().GetNodeBlock(
- context.semantics_ir()
- .GetNode(context.semantics_ir().GetType(struct_type_id))
- .GetAsStructType());
- auto member_name = context.semantics_ir().GetString(
- context.semantics_ir()
- .GetNode(type_refs[member_index.index])
- .GetAsStructTypeField());
- auto* gep = context.builder().CreateStructGEP(
- llvm_type, context.GetLocal(struct_id), member_index.index, member_name);
- context.SetLocal(node_id, gep);
- }
- auto LoweringHandleStructType(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/,
- SemanticsNode /*node*/) -> void {
- // No action to take.
- }
- auto LoweringHandleStructTypeField(LoweringFunctionContext& /*context*/,
- SemanticsNodeId /*node_id*/,
- SemanticsNode /*node*/) -> void {
- // No action to take.
- }
- auto LoweringHandleStructValue(LoweringFunctionContext& context,
- SemanticsNodeId node_id, SemanticsNode node)
- -> void {
- auto* llvm_type = context.GetType(node.type_id());
- auto* alloca = context.builder().CreateAlloca(
- llvm_type, /*ArraySize=*/nullptr, "StructLiteralValue");
- context.SetLocal(node_id, alloca);
- auto refs = context.semantics_ir().GetNodeBlock(node.GetAsStructValue());
- // Get type information for member names.
- auto type_refs = context.semantics_ir().GetNodeBlock(
- context.semantics_ir()
- .GetNode(context.semantics_ir().GetType(node.type_id()))
- .GetAsStructType());
- for (int i = 0; i < static_cast<int>(refs.size()); ++i) {
- auto member_name = context.semantics_ir().GetString(
- context.semantics_ir().GetNode(type_refs[i]).GetAsStructTypeField());
- auto* gep =
- context.builder().CreateStructGEP(llvm_type, alloca, i, member_name);
- context.builder().CreateStore(context.GetLocal(refs[i]), gep);
- }
- }
- auto LoweringHandleStubReference(LoweringFunctionContext& context,
- SemanticsNodeId node_id, SemanticsNode node)
- -> void {
- context.SetLocal(node_id, context.GetLocal(node.GetAsStubReference()));
- }
- auto LoweringHandleUnaryOperatorNot(LoweringFunctionContext& context,
- SemanticsNodeId node_id, SemanticsNode node)
- -> void {
- context.SetLocal(node_id, context.builder().CreateNot(context.GetLocal(
- node.GetAsUnaryOperatorNot())));
- }
- auto LoweringHandleVarStorage(LoweringFunctionContext& context,
- SemanticsNodeId node_id, SemanticsNode node)
- -> void {
- // TODO: This should provide a name, not just `var`. Also, LLVM requires
- // globals to have a name. Do we want to generate a name, which would need to
- // be consistent across translation units, or use the given name, which
- // requires either looking ahead for BindName or restructuring semantics,
- // either of which affects the destructuring due to the difference in
- // storage?
- auto* alloca = context.builder().CreateAlloca(context.GetType(node.type_id()),
- /*ArraySize=*/nullptr, "var");
- context.SetLocal(node_id, alloca);
- }
- } // namespace Carbon
|