fix multi file function resolution

This commit is contained in:
Edgar 2024-03-12 17:46:11 +01:00
parent 9ca2e336eb
commit 79d0e2ca7e
No known key found for this signature in database
GPG key ID: 70ADAE8F35904387
2 changed files with 58 additions and 43 deletions

View file

@ -34,6 +34,7 @@ enum Commands {
#[arg(long, group = "binary", default_value_t = true)] #[arg(long, group = "binary", default_value_t = true)]
bin: bool, bin: bool,
/// Use a library template
#[arg(long, group = "binary")] #[arg(long, group = "binary")]
lib: bool, lib: bool,
}, },

View file

@ -1,4 +1,8 @@
use std::{collections::HashMap, error::Error, path::PathBuf}; use std::{
collections::{HashMap, VecDeque},
error::Error,
path::PathBuf,
};
use edlang_ir as ir; use edlang_ir as ir;
use edlang_ir::DefId; use edlang_ir::DefId;
@ -70,7 +74,7 @@ pub fn compile(session: &Session, program: &ProgramBody) -> Result<PathBuf, Box<
program, program,
}; };
let mut llvm_modules = Vec::new(); let mut llvm_modules = VecDeque::new();
Target::initialize_native(&InitializationConfig::default())?; Target::initialize_native(&InitializationConfig::default())?;
let triple = TargetMachine::get_default_triple(); let triple = TargetMachine::get_default_triple();
@ -96,7 +100,7 @@ pub fn compile(session: &Session, program: &ProgramBody) -> Result<PathBuf, Box<
inkwell::targets::CodeModel::Default, inkwell::targets::CodeModel::Default,
) )
.unwrap(); .unwrap();
machine.set_asm_verbosity(true); // machine.set_asm_verbosity(true);
info!("compiling for: {:?}", target.get_description()); info!("compiling for: {:?}", target.get_description());
@ -160,41 +164,45 @@ pub fn compile(session: &Session, program: &ProgramBody) -> Result<PathBuf, Box<
module_ctx.di_builder.finalize(); module_ctx.di_builder.finalize();
module_ctx.module.verify()?; module_ctx.module.verify()?;
let opt = match session.optlevel {
edlang_session::OptLevel::None => "0",
edlang_session::OptLevel::Less => "1",
edlang_session::OptLevel::Default => "2",
edlang_session::OptLevel::Aggressive => "3",
};
let passopt = PassBuilderOptions::create();
module_ctx
.module
.run_passes(&format!("default<O{}>", opt), &machine, passopt)?;
if session.output_llvm {
module_ctx
.module
.print_to_file(session.output_file.with_extension("ll"))?;
}
if session.output_asm {
machine.write_to_file(
&module_ctx.module,
inkwell::targets::FileType::Assembly,
&session.output_file.with_extension("asm"),
)?;
}
machine.write_to_file(
&module_ctx.module,
inkwell::targets::FileType::Object,
&session.output_file.with_extension("o"),
)?;
// todo link modules together // todo link modules together
llvm_modules.push(module_ctx.module); llvm_modules.push_back(module_ctx.module);
} }
let module = llvm_modules.pop_front().unwrap();
for x in llvm_modules.into_iter() {
module.link_in_module(x)?;
}
let opt = match session.optlevel {
edlang_session::OptLevel::None => "0",
edlang_session::OptLevel::Less => "1",
edlang_session::OptLevel::Default => "2",
edlang_session::OptLevel::Aggressive => "3",
};
let passopt = PassBuilderOptions::create();
module.run_passes(&format!("default<O{}>", opt), &machine, passopt)?;
if session.output_llvm {
module.print_to_file(session.output_file.with_extension("ll"))?;
}
if session.output_asm {
machine.write_to_file(
&module,
inkwell::targets::FileType::Assembly,
&session.output_file.with_extension("asm"),
)?;
}
machine.write_to_file(
&module,
inkwell::targets::FileType::Object,
&session.output_file.with_extension("o"),
)?;
Ok(session.output_file.with_extension("o")) Ok(session.output_file.with_extension("o"))
} }
@ -202,7 +210,7 @@ fn compile_module(ctx: &mut ModuleCompileCtx, module_id: DefId) {
let module = ctx.ctx.program.modules.get(&module_id).unwrap(); let module = ctx.ctx.program.modules.get(&module_id).unwrap();
trace!("compiling module: {:?}", module_id); trace!("compiling module: {:?}", module_id);
for id in module.functions.iter() { for id in module.functions.iter() {
compile_fn_signature(ctx, *id); compile_fn_signature(ctx, *id, true);
} }
for id in module.functions.iter() { for id in module.functions.iter() {
@ -210,7 +218,7 @@ fn compile_module(ctx: &mut ModuleCompileCtx, module_id: DefId) {
} }
} }
fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) { fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId, is_definition: bool) {
let (arg_types, ret_type) = ctx.ctx.program.function_signatures.get(&fn_id).unwrap(); let (arg_types, ret_type) = ctx.ctx.program.function_signatures.get(&fn_id).unwrap();
let body = ctx.ctx.program.functions.get(&fn_id).unwrap(); let body = ctx.ctx.program.functions.get(&fn_id).unwrap();
trace!("compiling fn sig: {}", body.name); trace!("compiling fn sig: {}", body.name);
@ -271,8 +279,8 @@ fn compile_fn_signature(ctx: &ModuleCompileCtx<'_, '_>, fn_id: DefId) {
ctx.di_unit.get_file(), ctx.di_unit.get_file(),
line as u32 + 1, line as u32 + 1,
di_type, di_type,
body.is_pub, !body.is_pub,
!body.is_extern, is_definition,
line as u32 + 1, line as u32 + 1,
0, 0,
false, false,
@ -544,10 +552,16 @@ fn compile_fn(ctx: &ModuleCompileCtx, fn_id: DefId) -> Result<(), BuilderError>
target, target,
} => { } => {
let target_fn_body = ctx.ctx.program.functions.get(func).unwrap(); let target_fn_body = ctx.ctx.program.functions.get(func).unwrap();
let fn_value = ctx // compile_fn_signature(ctx, *id, true);
.module let fn_value = match ctx.module.get_function(&target_fn_body.get_mangled_name()) {
.get_function(&target_fn_body.get_mangled_name()) Some(x) => x,
.unwrap(); None => {
compile_fn_signature(ctx, target_fn_body.def_id, false);
ctx.module
.get_function(&target_fn_body.get_mangled_name())
.unwrap()
}
};
let args: Vec<_> = args let args: Vec<_> = args
.iter() .iter()
.map(|x| compile_rvalue(ctx, fn_id, &locals, x).unwrap().0.into()) .map(|x| compile_rvalue(ctx, fn_id, &locals, x).unwrap().0.into())