#include "ast.h" #include "codegen.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Module.h" using namespace llvm; namespace tdl{ /* Context */ context::context() { } LLVMContext *context::handle() { return &handle_; } /* Module */ module::module(const std::string &name, context *ctx) : handle_(name.c_str(), *ctx->handle()), builder_(*ctx->handle()) { } llvm::Module* module::handle() { return &handle_; } llvm::IRBuilder<>& module::builder() { return builder_; } namespace ast{ /* Translation unit */ void translation_unit::codegen(module *mod) const{ decls_->codegen(mod); } /* Declaration specifier */ Type* declaration_specifier::type(module *mod) const { LLVMContext &ctx = mod->handle()->getContext(); switch (spec_) { case VOID_T: return Type::getVoidTy(ctx); case INT8_T: return IntegerType::get(ctx, 8); case INT16_T: return IntegerType::get(ctx, 16); case INT32_T: return IntegerType::get(ctx, 32); case INT64_T: return IntegerType::get(ctx, 64); case FLOAT32_T: return Type::getFloatTy(ctx); case FLOAT64_T: return Type::getDoubleTy(ctx); default: assert(false && "unreachable"); throw; } } /* Parameter */ Type* parameter::type(module *mod) const { return decl_->type(mod, spec_->type(mod)); } /* Declarators */ Type* declarator::type(module *mod, Type *type) const{ if(ptr_) return type_impl(mod, ptr_->type(mod, type)); return type_impl(mod, type); } // Identifier Type* identifier::type_impl(module *, Type *type) const{ return type; } const std::string &identifier::name() const{ return name_; } // Tile Type* tile::type_impl(module*, Type *type) const{ return TileType::get(type, shapes_->values().size()); } // Initializer Type* initializer::type_impl(module *mod, Type *type) const{ return decl_->type(mod, type); } // Pointer Type* pointer::type_impl(module*, Type *type) const{ return PointerType::get(type, 1); } // Function Type* function::type_impl(module*mod, Type *type) const{ SmallVector types; for(parameter* param: args_->values()){ types.push_back(param->type(mod)); } return FunctionType::get(type, types, false); } /* Function definition */ void function_definition::codegen(module *mod) const{ FunctionType *prototype = (FunctionType *)header_->type(mod, spec_->type(mod)); const std::string &name = header_->id()->name(); Function *fn = Function::Create(prototype, Function::ExternalLinkage, name, mod->handle()); BasicBlock *entry = BasicBlock::Create(mod->handle()->getContext(), "entry", fn); mod->builder().SetInsertPoint(entry); body_->codegen(mod); } /* Statements */ void compound_statement::codegen(module* mod) const{ decls_->codegen(mod); statements_->codegen(mod); } /* Declaration */ void declaration::codegen(module* mod) const{ } /* Initializat */ void initializer::codegen(module *) const{ } } }