mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:10:12 +01:00
Refactoring lowering logic into separate files. (#2820)
This echoes https://github.com/carbon-language/carbon-lang/pull/2818 and the philosophy is mostly covered there. This isn't necessary for lowering right now, but things are likely to head in that direction and maintaining the context boundary will reduce blurring of lines. For now I'm just putting all the handlers in one file.
This commit is contained in:
@@ -12,7 +12,7 @@ cc_library(
|
||||
srcs = ["lower_to_llvm.cpp"],
|
||||
hdrs = ["lower_to_llvm.h"],
|
||||
deps = [
|
||||
":lowering",
|
||||
":lowering_context",
|
||||
"//toolchain/semantics:semantics_ir",
|
||||
"@llvm-project//llvm:Core",
|
||||
"@llvm-project//llvm:Support",
|
||||
@@ -20,9 +20,12 @@ cc_library(
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "lowering",
|
||||
srcs = ["lowering.cpp"],
|
||||
hdrs = ["lowering.h"],
|
||||
name = "lowering_context",
|
||||
srcs = [
|
||||
"lowering_context.cpp",
|
||||
"lowering_handle.cpp",
|
||||
],
|
||||
hdrs = ["lowering_context.h"],
|
||||
deps = [
|
||||
"//common:check",
|
||||
"//toolchain/semantics:semantics_ir",
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
|
||||
#include "toolchain/lowering/lower_to_llvm.h"
|
||||
|
||||
#include "toolchain/lowering/lowering.h"
|
||||
#include "toolchain/lowering/lowering_context.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto LowerToLLVM(llvm::LLVMContext& llvm_context, llvm::StringRef module_name,
|
||||
const SemanticsIR& semantics_ir)
|
||||
-> std::unique_ptr<llvm::Module> {
|
||||
Lowering lowering(llvm_context, module_name, semantics_ir);
|
||||
return lowering.Run();
|
||||
LoweringContext context(llvm_context, module_name, semantics_ir);
|
||||
return context.Run();
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
// 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.h"
|
||||
|
||||
#include "toolchain/semantics/semantics_ir.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
Lowering::Lowering(llvm::LLVMContext& llvm_context, llvm::StringRef module_name,
|
||||
const SemanticsIR& semantics_ir)
|
||||
: llvm_context_(&llvm_context),
|
||||
llvm_module_(std::make_unique<llvm::Module>(module_name, llvm_context)),
|
||||
builder_(llvm_context),
|
||||
semantics_ir_(&semantics_ir),
|
||||
lowered_nodes_(semantics_ir_->nodes_size(), nullptr) {
|
||||
CARBON_CHECK(!semantics_ir.has_errors())
|
||||
<< "Generating LLVM IR from invalid SemanticsIR is unsupported.";
|
||||
}
|
||||
|
||||
auto Lowering::Run() -> std::unique_ptr<llvm::Module> {
|
||||
CARBON_CHECK(llvm_module_) << "Run can only be called once.";
|
||||
|
||||
LowerBlock(semantics_ir_->top_node_block_id());
|
||||
|
||||
while (!todo_blocks_.empty()) {
|
||||
auto [llvm_block, block_id] = todo_blocks_.pop_back_val();
|
||||
builder_.SetInsertPoint(llvm_block);
|
||||
LowerBlock(block_id);
|
||||
}
|
||||
|
||||
return std::move(llvm_module_);
|
||||
}
|
||||
|
||||
auto Lowering::LowerBlock(SemanticsNodeBlockId block_id) -> void {
|
||||
for (const auto& node_id : semantics_ir_->GetNodeBlock(block_id)) {
|
||||
auto node = semantics_ir_->GetNode(node_id);
|
||||
switch (node.kind()) {
|
||||
#define CARBON_SEMANTICS_NODE_KIND(Name) \
|
||||
case SemanticsNodeKind::Name: \
|
||||
Handle##Name##Node(node_id, node); \
|
||||
break;
|
||||
#include "toolchain/semantics/semantics_node_kind.def"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto Lowering::LowerNodeToType(SemanticsNodeId node_id) -> llvm::Type* {
|
||||
CARBON_CHECK(node_id.is_valid());
|
||||
switch (node_id.index) {
|
||||
case SemanticsBuiltinKind::EmptyTuple.AsInt():
|
||||
// TODO: Should probably switch this to an actual empty tuple in the
|
||||
// future, but it's implemented as void for now.
|
||||
return builder_.getVoidTy();
|
||||
case SemanticsBuiltinKind::IntegerType.AsInt():
|
||||
// TODO: Handle different sizes.
|
||||
return builder_.getInt32Ty();
|
||||
default:
|
||||
CARBON_FATAL() << "Cannot use node as type: " << node_id;
|
||||
}
|
||||
}
|
||||
|
||||
auto Lowering::HandleInvalidNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode /*node*/) -> void {
|
||||
llvm_unreachable("never in actual IR");
|
||||
}
|
||||
|
||||
auto Lowering::HandleCrossReferenceNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleAssignNode(SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleBinaryOperatorAddNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleBindNameNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleBuiltinNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleCallNode(SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleCodeBlockNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleFunctionDeclarationNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
auto [name_id, callable_id] = node.GetAsFunctionDeclaration();
|
||||
auto callable = semantics_ir_->GetCallable(callable_id);
|
||||
|
||||
// TODO: Lower type information for the arguments prior to building args.
|
||||
auto param_refs = semantics_ir_->GetNodeBlock(callable.param_refs_id);
|
||||
llvm::SmallVector<llvm::Type*> args;
|
||||
args.resize_for_overwrite(param_refs.size());
|
||||
for (int i = 0; i < static_cast<int>(param_refs.size()); ++i) {
|
||||
args[i] = LowerNodeToType(semantics_ir_->GetNode(param_refs[i]).type_id());
|
||||
}
|
||||
|
||||
llvm::Type* return_type = LowerNodeToType(
|
||||
callable.return_type_id.is_valid() ? callable.return_type_id
|
||||
: SemanticsNodeId::BuiltinEmptyTuple);
|
||||
llvm::FunctionType* function_type =
|
||||
llvm::FunctionType::get(return_type, args, /*isVarArg=*/false);
|
||||
auto* function = llvm::Function::Create(
|
||||
function_type, llvm::Function::ExternalLinkage,
|
||||
semantics_ir_->GetString(name_id), llvm_module_.get());
|
||||
|
||||
// Set parameter names.
|
||||
for (int i = 0; i < static_cast<int>(param_refs.size()); ++i) {
|
||||
auto [param_name_id, _] =
|
||||
semantics_ir_->GetNode(param_refs[i]).GetAsBindName();
|
||||
function->getArg(i)->setName(semantics_ir_->GetString(param_name_id));
|
||||
}
|
||||
}
|
||||
|
||||
auto Lowering::HandleFunctionDefinitionNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
auto [declaration_id, body_block_id] = node.GetAsFunctionDefinition();
|
||||
auto [name_id, callable_id] =
|
||||
semantics_ir_->GetNode(declaration_id).GetAsFunctionDeclaration();
|
||||
|
||||
llvm::Function* function =
|
||||
llvm_module_->getFunction(semantics_ir_->GetString(name_id));
|
||||
|
||||
// Create a new basic block to start insertion into.
|
||||
llvm::BasicBlock* body =
|
||||
llvm::BasicBlock::Create(*llvm_context_, "entry", function);
|
||||
todo_blocks_.push_back({body, body_block_id});
|
||||
}
|
||||
|
||||
auto Lowering::HandleIntegerLiteralNode(SemanticsNodeId node_id,
|
||||
SemanticsNode node) -> void {
|
||||
SemanticsIntegerLiteralId int_id = node.GetAsIntegerLiteral();
|
||||
llvm::APInt i = semantics_ir_->GetIntegerLiteral(int_id);
|
||||
llvm::Value* v =
|
||||
llvm::ConstantInt::get(builder_.getInt32Ty(), i.getLimitedValue());
|
||||
lowered_nodes_[node_id.index] = v;
|
||||
}
|
||||
|
||||
auto Lowering::HandleRealLiteralNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleReturnNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode /*node*/) -> void {
|
||||
builder_.CreateRetVoid();
|
||||
}
|
||||
|
||||
auto Lowering::HandleReturnExpressionNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
SemanticsNodeId expr_id = node.GetAsReturnExpression();
|
||||
builder_.CreateRet(lowered_nodes_[expr_id.index]);
|
||||
}
|
||||
|
||||
auto Lowering::HandleStringLiteralNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleStructMemberAccessNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleStructTypeNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleStructTypeFieldNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleStructValueNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleStubReferenceNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto Lowering::HandleVarStorageNode(SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
@@ -0,0 +1,65 @@
|
||||
// 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_context.h"
|
||||
|
||||
#include "toolchain/semantics/semantics_ir.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
LoweringContext::LoweringContext(llvm::LLVMContext& llvm_context,
|
||||
llvm::StringRef module_name,
|
||||
const SemanticsIR& semantics_ir)
|
||||
: llvm_context_(&llvm_context),
|
||||
llvm_module_(std::make_unique<llvm::Module>(module_name, llvm_context)),
|
||||
builder_(llvm_context),
|
||||
semantics_ir_(&semantics_ir),
|
||||
lowered_nodes_(semantics_ir_->nodes_size(), nullptr) {
|
||||
CARBON_CHECK(!semantics_ir.has_errors())
|
||||
<< "Generating LLVM IR from invalid SemanticsIR is unsupported.";
|
||||
}
|
||||
|
||||
auto LoweringContext::Run() -> std::unique_ptr<llvm::Module> {
|
||||
CARBON_CHECK(llvm_module_) << "Run can only be called once.";
|
||||
|
||||
LowerBlock(semantics_ir_->top_node_block_id());
|
||||
|
||||
while (!todo_blocks_.empty()) {
|
||||
auto [llvm_block, block_id] = todo_blocks_.pop_back_val();
|
||||
builder_.SetInsertPoint(llvm_block);
|
||||
LowerBlock(block_id);
|
||||
}
|
||||
|
||||
return std::move(llvm_module_);
|
||||
}
|
||||
|
||||
auto LoweringContext::LowerBlock(SemanticsNodeBlockId block_id) -> void {
|
||||
for (const auto& node_id : semantics_ir_->GetNodeBlock(block_id)) {
|
||||
auto node = semantics_ir_->GetNode(node_id);
|
||||
switch (node.kind()) {
|
||||
#define CARBON_SEMANTICS_NODE_KIND(Name) \
|
||||
case SemanticsNodeKind::Name: \
|
||||
LoweringHandle##Name(*this, node_id, node); \
|
||||
break;
|
||||
#include "toolchain/semantics/semantics_node_kind.def"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto LoweringContext::LowerNodeToType(SemanticsNodeId node_id) -> llvm::Type* {
|
||||
CARBON_CHECK(node_id.is_valid());
|
||||
switch (node_id.index) {
|
||||
case SemanticsBuiltinKind::EmptyTuple.AsInt():
|
||||
// TODO: Should probably switch this to an actual empty tuple in the
|
||||
// future, but it's implemented as void for now.
|
||||
return builder_.getVoidTy();
|
||||
case SemanticsBuiltinKind::IntegerType.AsInt():
|
||||
// TODO: Handle different sizes.
|
||||
return builder_.getInt32Ty();
|
||||
default:
|
||||
CARBON_FATAL() << "Cannot use node as type: " << node_id;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
@@ -2,8 +2,8 @@
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef CARBON_TOOLCHAIN_LOWERING_LOWERING_H_
|
||||
#define CARBON_TOOLCHAIN_LOWERING_LOWERING_H_
|
||||
#ifndef CARBON_TOOLCHAIN_LOWERING_LOWERING_CONTEXT_H_
|
||||
#define CARBON_TOOLCHAIN_LOWERING_LOWERING_CONTEXT_H_
|
||||
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
@@ -13,31 +13,36 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
// Use LowerToLLVM rather than calling this directly.
|
||||
//
|
||||
// This carries state for lowering. `Run()` should only be called once, and
|
||||
// handles the main execution.
|
||||
class Lowering {
|
||||
// Context and shared functionality for lowering handlers.
|
||||
class LoweringContext {
|
||||
public:
|
||||
explicit Lowering(llvm::LLVMContext& llvm_context,
|
||||
llvm::StringRef module_name,
|
||||
const SemanticsIR& semantics_ir);
|
||||
explicit LoweringContext(llvm::LLVMContext& llvm_context,
|
||||
llvm::StringRef module_name,
|
||||
const SemanticsIR& semantics_ir);
|
||||
|
||||
// Lowers the SemanticsIR to LLVM IR.
|
||||
// Lowers the SemanticsIR to LLVM IR. Should only be called once, and handles
|
||||
// the main execution loop.
|
||||
auto Run() -> std::unique_ptr<llvm::Module>;
|
||||
|
||||
private:
|
||||
// Declare handlers for each SemanticsIR node.
|
||||
#define CARBON_SEMANTICS_NODE_KIND(Name) \
|
||||
auto Handle##Name##Node(SemanticsNodeId node_id, SemanticsNode node)->void;
|
||||
#include "toolchain/semantics/semantics_node_kind.def"
|
||||
|
||||
// Runs lowering for a block.
|
||||
auto LowerBlock(SemanticsNodeBlockId block_id) -> void;
|
||||
|
||||
// Returns a type for the given node.
|
||||
auto LowerNodeToType(SemanticsNodeId node_id) -> llvm::Type*;
|
||||
|
||||
auto llvm_context() -> llvm::LLVMContext& { return *llvm_context_; }
|
||||
auto llvm_module() -> llvm::Module& { return *llvm_module_; }
|
||||
auto builder() -> llvm::IRBuilder<>& { return builder_; }
|
||||
auto semantics_ir() -> const SemanticsIR& { return *semantics_ir_; }
|
||||
auto todo_blocks() -> llvm::SmallVector<
|
||||
std::pair<llvm::BasicBlock*, SemanticsNodeBlockId>>& {
|
||||
return todo_blocks_;
|
||||
}
|
||||
auto lowered_nodes() -> llvm::SmallVector<llvm::Value*>& {
|
||||
return lowered_nodes_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Runs lowering for a block.
|
||||
auto LowerBlock(SemanticsNodeBlockId block_id) -> void;
|
||||
|
||||
// State for building the LLVM IR.
|
||||
llvm::LLVMContext* llvm_context_;
|
||||
std::unique_ptr<llvm::Module> llvm_module_;
|
||||
@@ -61,6 +66,13 @@ class Lowering {
|
||||
llvm::SmallVector<llvm::Value*> lowered_nodes_;
|
||||
};
|
||||
|
||||
// Declare handlers for each SemanticsIR node.
|
||||
#define CARBON_SEMANTICS_NODE_KIND(Name) \
|
||||
auto LoweringHandle##Name(LoweringContext& context, SemanticsNodeId node_id, \
|
||||
SemanticsNode node) \
|
||||
->void;
|
||||
#include "toolchain/semantics/semantics_node_kind.def"
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
#endif // CARBON_TOOLCHAIN_LOWERING_LOWERING_H_
|
||||
#endif // CARBON_TOOLCHAIN_LOWERING_LOWERING_CONTEXT_H_
|
||||
@@ -0,0 +1,176 @@
|
||||
// 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_context.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
auto LoweringHandleInvalid(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode /*node*/)
|
||||
-> void {
|
||||
llvm_unreachable("never in actual IR");
|
||||
}
|
||||
|
||||
auto LoweringHandleCrossReference(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleAssign(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleBinaryOperatorAdd(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleBindName(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleBuiltin(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleCall(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleCodeBlock(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleFunctionDeclaration(LoweringContext& context,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
auto [name_id, callable_id] = node.GetAsFunctionDeclaration();
|
||||
auto callable = context.semantics_ir().GetCallable(callable_id);
|
||||
|
||||
// TODO: Lower type information for the arguments prior to building args.
|
||||
auto param_refs = context.semantics_ir().GetNodeBlock(callable.param_refs_id);
|
||||
llvm::SmallVector<llvm::Type*> args;
|
||||
args.resize_for_overwrite(param_refs.size());
|
||||
for (int i = 0; i < static_cast<int>(param_refs.size()); ++i) {
|
||||
args[i] = context.LowerNodeToType(
|
||||
context.semantics_ir().GetNode(param_refs[i]).type_id());
|
||||
}
|
||||
|
||||
llvm::Type* return_type = context.LowerNodeToType(
|
||||
callable.return_type_id.is_valid() ? callable.return_type_id
|
||||
: SemanticsNodeId::BuiltinEmptyTuple);
|
||||
llvm::FunctionType* function_type =
|
||||
llvm::FunctionType::get(return_type, args, /*isVarArg=*/false);
|
||||
auto* function = llvm::Function::Create(
|
||||
function_type, llvm::Function::ExternalLinkage,
|
||||
context.semantics_ir().GetString(name_id), context.llvm_module());
|
||||
|
||||
// Set parameter names.
|
||||
for (int i = 0; i < static_cast<int>(param_refs.size()); ++i) {
|
||||
auto [param_name_id, _] =
|
||||
context.semantics_ir().GetNode(param_refs[i]).GetAsBindName();
|
||||
function->getArg(i)->setName(
|
||||
context.semantics_ir().GetString(param_name_id));
|
||||
}
|
||||
}
|
||||
|
||||
auto LoweringHandleFunctionDefinition(LoweringContext& context,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
auto [declaration_id, body_block_id] = node.GetAsFunctionDefinition();
|
||||
auto [name_id, callable_id] =
|
||||
context.semantics_ir().GetNode(declaration_id).GetAsFunctionDeclaration();
|
||||
|
||||
llvm::Function* function = context.llvm_module().getFunction(
|
||||
context.semantics_ir().GetString(name_id));
|
||||
|
||||
// Create a new basic block to start insertion into.
|
||||
llvm::BasicBlock* body =
|
||||
llvm::BasicBlock::Create(context.llvm_context(), "entry", function);
|
||||
context.todo_blocks().push_back({body, body_block_id});
|
||||
}
|
||||
|
||||
auto LoweringHandleIntegerLiteral(LoweringContext& context,
|
||||
SemanticsNodeId node_id, SemanticsNode node)
|
||||
-> void {
|
||||
SemanticsIntegerLiteralId int_id = node.GetAsIntegerLiteral();
|
||||
llvm::APInt i = context.semantics_ir().GetIntegerLiteral(int_id);
|
||||
llvm::Value* v = llvm::ConstantInt::get(context.builder().getInt32Ty(),
|
||||
i.getLimitedValue());
|
||||
context.lowered_nodes()[node_id.index] = v;
|
||||
}
|
||||
|
||||
auto LoweringHandleRealLiteral(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleReturn(LoweringContext& context, SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode /*node*/) -> void {
|
||||
context.builder().CreateRetVoid();
|
||||
}
|
||||
|
||||
auto LoweringHandleReturnExpression(LoweringContext& context,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
SemanticsNodeId expr_id = node.GetAsReturnExpression();
|
||||
context.builder().CreateRet(context.lowered_nodes()[expr_id.index]);
|
||||
}
|
||||
|
||||
auto LoweringHandleStringLiteral(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleStructMemberAccess(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleStructType(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleStructTypeField(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleStructValue(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleStubReference(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/,
|
||||
SemanticsNode node) -> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
auto LoweringHandleVarStorage(LoweringContext& /*context*/,
|
||||
SemanticsNodeId /*node_id*/, SemanticsNode node)
|
||||
-> void {
|
||||
CARBON_FATAL() << "TODO: Add support: " << node;
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
Reference in New Issue
Block a user