diff --git a/crates/mun_codegen/src/code_gen.rs b/crates/mun_codegen/src/code_gen.rs index 93fec907a..d14c103f4 100644 --- a/crates/mun_codegen/src/code_gen.rs +++ b/crates/mun_codegen/src/code_gen.rs @@ -6,16 +6,18 @@ use inkwell::targets::TargetData; use inkwell::{ module::{Linkage, Module}, passes::{PassManager, PassManagerBuilder}, - targets::{CodeModel, FileType, InitializationConfig, RelocMode, Target}, + targets::{CodeModel, FileType, InitializationConfig, RelocMode, Target, TargetMachine}, types::StructType, values::{BasicValue, GlobalValue, IntValue, PointerValue, UnnamedAddress}, AddressSpace, OptimizationLevel, }; +use mun_target::spec; use std::io::{self, Write}; use std::{ path::{Path, PathBuf}, sync::Arc, }; +use tempfile::NamedTempFile; mod linker; pub mod symbols; @@ -42,6 +44,51 @@ impl From for CodeGenerationError { } } +pub struct ObjectFile { + target: spec::Target, + src_path: RelativePathBuf, + obj_file: NamedTempFile, +} + +impl ObjectFile { + pub fn new( + target: &spec::Target, + target_machine: &TargetMachine, + src_path: RelativePathBuf, + module: Arc, + ) -> Result { + let obj = target_machine + .write_to_memory_buffer(&module, FileType::Object) + .map_err(|e| CodeGenerationError::CodeGenerationError(e.to_string()))?; + + let mut obj_file = tempfile::NamedTempFile::new() + .map_err(CodeGenerationError::CouldNotCreateObjectFile)?; + obj_file + .write(obj.as_slice()) + .map_err(CodeGenerationError::CouldNotCreateObjectFile)?; + + Ok(Self { + target: target.clone(), + src_path, + obj_file, + }) + } + + pub fn into_shared_object(self, out_dir: Option<&Path>) -> Result { + // Construct a linker for the target + let mut linker = linker::create_with_target(&self.target); + linker.add_object(self.obj_file.path())?; + + let output_path = assembly_output_path(&self.src_path, out_dir); + + // Link the object + linker.build_shared_object(&output_path)?; + linker.finalize()?; + + Ok(output_path) + } +} + /// A struct that can be used to build an LLVM `Module`. pub struct ModuleBuilder<'a, D: IrDatabase> { db: &'a D, @@ -52,8 +99,8 @@ pub struct ModuleBuilder<'a, D: IrDatabase> { } impl<'a, D: IrDatabase> ModuleBuilder<'a, D> { - /// Construct module for the given `hir::FileId` at the specified output file location. - pub fn new(db: &'a mut D, file_id: FileId) -> Result { + /// Constructs module for the given `hir::FileId` at the specified output file location. + pub fn new(db: &'a D, file_id: FileId) -> Result { let target = db.target(); // Construct a module for the assembly @@ -91,8 +138,8 @@ impl<'a, D: IrDatabase> ModuleBuilder<'a, D> { }) } - /// Construct a shared object at the specified output file location. - pub fn finalize(&self, out_dir: Option<&Path>) -> Result { + /// Constructs an object file. + pub fn build(self) -> Result { let group_ir = self.db.group_ir(self.file_id); let file = self.db.file_ir(self.file_id); @@ -120,39 +167,18 @@ impl<'a, D: IrDatabase> ModuleBuilder<'a, D> { // Debug print the IR //println!("{}", assembly_module.print_to_string().to_string()); - // Generate object file - let obj_file = { - let obj = self - .target_machine - .write_to_memory_buffer(&self.assembly_module, FileType::Object) - .map_err(|e| CodeGenerationError::CodeGenerationError(e.to_string()))?; - let mut obj_file = tempfile::NamedTempFile::new() - .map_err(CodeGenerationError::CouldNotCreateObjectFile)?; - obj_file - .write(obj.as_slice()) - .map_err(CodeGenerationError::CouldNotCreateObjectFile)?; - obj_file - }; - - let target = self.db.target(); - - // Construct a linker for the target - let mut linker = linker::create_with_target(&target); - linker.add_object(obj_file.path())?; - - let output_path = assembly_output_path(self.db, self.file_id, out_dir); - - // Link the object - linker.build_shared_object(&output_path)?; - linker.finalize()?; - - Ok(output_path) + ObjectFile::new( + &self.db.target(), + &self.target_machine, + self.db.file_relative_path(self.file_id), + self.assembly_module, + ) } } + /// Computes the output path for the assembly of the specified file. -fn assembly_output_path(db: &D, file_id: FileId, out_dir: Option<&Path>) -> PathBuf { - let relative_path: RelativePathBuf = db.file_relative_path(file_id); - let original_filename = Path::new(relative_path.file_name().unwrap()); +fn assembly_output_path(src_path: &RelativePathBuf, out_dir: Option<&Path>) -> PathBuf { + let original_filename = Path::new(src_path.file_name().unwrap()); // Add the `munlib` suffix to the original filename let output_file_name = original_filename.with_extension("munlib"); diff --git a/crates/mun_codegen/src/ir/body.rs b/crates/mun_codegen/src/ir/body.rs index ce81138e8..737eed185 100644 --- a/crates/mun_codegen/src/ir/body.rs +++ b/crates/mun_codegen/src/ir/body.rs @@ -775,7 +775,7 @@ impl<'a, 'b, D: IrDatabase> BodyIrGenerator<'a, 'b, D> { /// Generates IR for a function call. fn gen_call(&mut self, function: hir::Function, args: &[BasicValueEnum]) -> CallSiteValue { - if self.should_use_dispatch_table() { + if self.dispatch_table.contains(function) && self.should_use_dispatch_table() { let ptr_value = self.dispatch_table.gen_function_lookup( self.db, self.external_globals.dispatch_table, diff --git a/crates/mun_codegen/src/ir/dispatch_table.rs b/crates/mun_codegen/src/ir/dispatch_table.rs index 6bd708413..1a24a9faa 100644 --- a/crates/mun_codegen/src/ir/dispatch_table.rs +++ b/crates/mun_codegen/src/ir/dispatch_table.rs @@ -60,6 +60,11 @@ pub struct DispatchableFunction { } impl DispatchTable { + /// Returns whether the `DispatchTable` contains the specified `function`. + pub fn contains(&self, function: hir::Function) -> bool { + self.function_to_idx.contains_key(&function) + } + /// Returns a slice containing all the functions in the dispatch table. pub fn entries(&self) -> &[DispatchableFunction] { &self.entries @@ -174,7 +179,7 @@ impl<'a, D: IrDatabase> DispatchTableBuilder<'a, D> { pub fn new( db: &'a D, module: &'a Module, - intrinsics: BTreeMap, + intrinsics: &BTreeMap, ) -> Self { let mut table = DispatchTableBuilder { db, @@ -192,17 +197,17 @@ impl<'a, D: IrDatabase> DispatchTableBuilder<'a, D> { table.ensure_table_ref(); // Use a `BTreeMap` to guarantee deterministically ordered output - for (prototype, ir_type) in intrinsics.into_iter() { + for (prototype, ir_type) in intrinsics.iter() { let index = table.entries.len(); table.entries.push(TypedDispatchableFunction { function: DispatchableFunction { prototype: prototype.clone(), hir: None, }, - ir_type, + ir_type: *ir_type, }); - table.prototype_to_idx.insert(prototype, index); + table.prototype_to_idx.insert(prototype.clone(), index); } } table diff --git a/crates/mun_codegen/src/ir/file.rs b/crates/mun_codegen/src/ir/file.rs index 9347a4d89..88d35b3f9 100644 --- a/crates/mun_codegen/src/ir/file.rs +++ b/crates/mun_codegen/src/ir/file.rs @@ -25,13 +25,15 @@ pub(crate) fn ir_query(db: &impl IrDatabase, file_id: FileId) -> Arc { let group_ir = db.group_ir(file_id); - // Generate all function and wrapper function signatures. + // Generate all exposed function and wrapper function signatures. // Use a `BTreeMap` to guarantee deterministically ordered output.ures let mut functions = HashMap::new(); let mut wrapper_functions = BTreeMap::new(); for def in db.module_data(file_id).definitions() { if let ModuleDef::Function(f) = def { - if !f.is_extern(db) { + if (!f.data(db).visibility().is_private() || group_ir.dispatch_table.contains(*f)) + && !f.is_extern(db) + { let fun = function::gen_signature( db, *f, diff --git a/crates/mun_codegen/src/ir/file_group.rs b/crates/mun_codegen/src/ir/file_group.rs index ac1dd8f9f..ec9419923 100644 --- a/crates/mun_codegen/src/ir/file_group.rs +++ b/crates/mun_codegen/src/ir/file_group.rs @@ -61,9 +61,28 @@ pub(crate) fn ir_query(db: &impl IrDatabase, file_id: hir::FileId) -> Arc Arc { target_data: Arc, module: &'a Module, abi_types: &'a AbiTypes, + dispatch_table: &'a DispatchTable, entries: BTreeSet, // Use a `BTreeSet` to guarantee deterministically ordered output } @@ -93,12 +97,14 @@ impl<'a, D: IrDatabase> TypeTableBuilder<'a, D> { module: &'a Module, abi_types: &'a AbiTypes, intrinsics: impl Iterator, + dispatch_table: &'a DispatchTable, ) -> Self { let mut builder = Self { db, target_data: db.target_data(), module, abi_types, + dispatch_table, entries: BTreeSet::new(), }; @@ -136,7 +142,7 @@ impl<'a, D: IrDatabase> TypeTableBuilder<'a, D> { /// Collects unique `TypeInfo` from the specified function signature and body. pub fn collect_fn(&mut self, hir_fn: hir::Function) { // Collect type info for exposed function - if !hir_fn.data(self.db).visibility().is_private() || hir_fn.is_extern(self.db) { + if !hir_fn.data(self.db).visibility().is_private() || self.dispatch_table.contains(hir_fn) { let fn_sig = hir_fn.ty(self.db).callable_sig(self.db).unwrap(); // Collect argument types diff --git a/crates/mun_codegen/src/snapshots/test__binary_expressions.snap b/crates/mun_codegen/src/snapshots/test__binary_expressions.snap index d289bedf5..27fcfc974 100644 --- a/crates/mun_codegen/src/snapshots/test__binary_expressions.snap +++ b/crates/mun_codegen/src/snapshots/test__binary_expressions.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn add(a:int, b:int)->int {\n a+b\n}\n\nfn subtract(a:int, b:int)->int {\n a-b\n}\n\nfn multiply(a:int, b:int)->int {\n a*b\n}" +expression: "pub fn add(a:int, b:int) -> int {\n a+b\n}\n\npub fn subtract(a:int, b:int) -> int {\n a-b\n}\n\npub fn multiply(a:int, b:int) -> int {\n a*b\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @add(i64, i64) { body: %add = add i64 %0, %1 @@ -29,3 +33,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__conditional_return_expr.snap b/crates/mun_codegen/src/snapshots/test__conditional_return_expr.snap index c8eb7e782..e9908f06c 100644 --- a/crates/mun_codegen/src/snapshots/test__conditional_return_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__conditional_return_expr.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn main(a:int)->int {\n if a > 4 {\n return a;\n }\n a - 1\n}" +expression: "pub fn main(a:int) -> int {\n if a > 4 {\n return a;\n }\n a - 1\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @main(i64) { body: %greater = icmp sgt i64 %0, 4 @@ -24,3 +28,9 @@ if_merge: ; preds = %body ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__equality_operands.snap b/crates/mun_codegen/src/snapshots/test__equality_operands.snap index 928669ba5..ea61d9871 100644 --- a/crates/mun_codegen/src/snapshots/test__equality_operands.snap +++ b/crates/mun_codegen/src/snapshots/test__equality_operands.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn equals(a:int, b:int)->bool { a == b }\nfn not_equals(a:int, b:int)->bool { a != b }\nfn less(a:int, b:int)->bool { a < b }\nfn less_equal(a:int, b:int)->bool { a <= b }\nfn greater(a:int, b:int)->bool { a > b }\nfn greater_equal(a:int, b:int)->bool { a >= b }\nfn equalsf(a:float, b:float)->bool { a == b }\nfn not_equalsf(a:float, b:float)->bool { a != b }\nfn lessf(a:float, b:float)->bool { a < b }\nfn less_equalf(a:float, b:float)->bool { a <= b }\nfn greaterf(a:float, b:float)->bool { a > b }\nfn greater_equalf(a:float, b:float)->bool { a >= b }" +expression: "pub fn equals(a:int, b:int) -> bool { a == b }\npub fn not_equals(a:int, b:int) -> bool { a != b }\npub fn less(a:int, b:int) -> bool { a < b }\npub fn less_equal(a:int, b:int) -> bool { a <= b }\npub fn greater(a:int, b:int) -> bool { a > b }\npub fn greater_equal(a:int, b:int) -> bool { a >= b }\npub fn equalsf(a:float, b:float) -> bool { a == b }\npub fn not_equalsf(a:float, b:float) -> bool { a != b }\npub fn lessf(a:float, b:float) -> bool { a < b }\npub fn less_equalf(a:float, b:float) -> bool { a <= b }\npub fn greaterf(a:float, b:float) -> bool { a > b }\npub fn greater_equalf(a:float, b:float) -> bool { a >= b }" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [3 x %struct.MunTypeInfo addrspace(4)*] + define i1 @equals(i64, i64) { body: %eq = icmp eq i64 %0, %1 @@ -83,3 +87,13 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::f64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@"type_info::::name" = private unnamed_addr constant [11 x i8] c"core::bool\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i32 1, i8 1, i8 0 } +@global_type_table = global [3 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__extern_fn.snap b/crates/mun_codegen/src/snapshots/test__extern_fn.snap index f1c30f0f2..597f72a71 100644 --- a/crates/mun_codegen/src/snapshots/test__extern_fn.snap +++ b/crates/mun_codegen/src/snapshots/test__extern_fn.snap @@ -1,6 +1,6 @@ --- source: crates/mun_codegen/src/test.rs -expression: "extern fn add(a:int, b:int) -> int;\nfn main() {\n add(3,4);\n}" +expression: "extern fn add(a:int, b:int) -> int;\npub fn main() {\n add(3,4);\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' @@ -24,11 +24,11 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %DispatchTable = type { i64 (i64, i64)* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } +@dispatchTable = global %DispatchTable zeroinitializer @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" @"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } @global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] -@dispatchTable = global %DispatchTable zeroinitializer diff --git a/crates/mun_codegen/src/snapshots/test__fibonacci.snap b/crates/mun_codegen/src/snapshots/test__fibonacci.snap index 125e03f6e..b183a24e5 100644 --- a/crates/mun_codegen/src/snapshots/test__fibonacci.snap +++ b/crates/mun_codegen/src/snapshots/test__fibonacci.snap @@ -1,14 +1,16 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn fibonacci(n:int)->int {\n if n <= 1 {\n n\n } else {\n fibonacci(n-1) + fibonacci(n-2)\n }\n}" +expression: "pub fn fibonacci(n:int) -> int {\n if n <= 1 {\n n\n } else {\n fibonacci(n-1) + fibonacci(n-2)\n }\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" %DispatchTable = type { i64 (i64)* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } @dispatchTable = external global %DispatchTable +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] define i64 @fibonacci(i64) { body: @@ -36,8 +38,12 @@ if_merge: ; preds = %body, %else source_filename = "group_name" %DispatchTable = type { i64 (i64)* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } @dispatchTable = global %DispatchTable { i64 (i64)* @fibonacci } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] declare i64 @fibonacci(i64) diff --git a/crates/mun_codegen/src/snapshots/test__fibonacci_loop.snap b/crates/mun_codegen/src/snapshots/test__fibonacci_loop.snap index afe05faf3..75c942d58 100644 --- a/crates/mun_codegen/src/snapshots/test__fibonacci_loop.snap +++ b/crates/mun_codegen/src/snapshots/test__fibonacci_loop.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn fibonacci(n:int)->int {\n let a = 0;\n let b = 1;\n let i = 1;\n loop {\n if i > n {\n return a\n }\n let sum = a + b;\n a = b;\n b = sum;\n i += 1;\n }\n}" +expression: "pub fn fibonacci(n:int) -> int {\n let a = 0;\n let b = 1;\n let i = 1;\n loop {\n if i > n {\n return a\n }\n let sum = a + b;\n a = b;\n b = sum;\n i += 1;\n }\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @fibonacci(i64) { body: br label %loop @@ -31,3 +35,9 @@ if_merge: ; preds = %loop ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__field_crash.snap b/crates/mun_codegen/src/snapshots/test__field_crash.snap index ed1472963..c5a193d7b 100644 --- a/crates/mun_codegen/src/snapshots/test__field_crash.snap +++ b/crates/mun_codegen/src/snapshots/test__field_crash.snap @@ -1,6 +1,6 @@ --- source: crates/mun_codegen/src/test.rs -expression: "struct(gc) Foo { a: int };\n\nfn main(c:int)->int {\n let b = Foo { a: c + 5 }\n b.a\n}" +expression: "struct(gc) Foo { a: int };\n\npub fn main(c:int) -> int {\n let b = Foo { a: c + 5 }\n b.a\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' @@ -43,10 +43,11 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %struct.MunStructInfo = type { i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } -%DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } +@dispatchTable = global %DispatchTable zeroinitializer @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Foo\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @@ -62,6 +63,5 @@ source_filename = "group_name" @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" @"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i32 64, i8 8, i8 0 } @global_type_table = global [5 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] -@dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__field_expr.snap b/crates/mun_codegen/src/snapshots/test__field_expr.snap index 2e2500b9d..cb190bf86 100644 --- a/crates/mun_codegen/src/snapshots/test__field_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__field_expr.snap @@ -1,6 +1,6 @@ --- source: crates/mun_codegen/src/test.rs -expression: "struct(value) Bar(float, Foo);\nstruct(value) Foo { a: int };\n\nfn bar_0(bar: Bar) -> float {\n bar.0\n}\n\nfn bar_1(bar: Bar) -> Foo {\n bar.1\n}\n\nfn bar_1_a(bar: Bar) -> int {\n bar.1.a\n}\n\nfn foo_a(foo: Foo) -> int {\n foo.a\n}\n\nfn bar_1_foo_a(bar: Bar) -> int {\n foo_a(bar_1(bar))\n}\n\nfn main() -> int {\n let a: Foo = Foo { a: 5 };\n let b: Bar = Bar(1.23, a);\n let aa_lhs = a.a + 2;\n let aa_rhs = 2 + a.a;\n aa_lhs + aa_rhs\n}" +expression: "struct(value) Bar(float, Foo);\nstruct(value) Foo { a: int };\n\nfn bar_1(bar: Bar) -> Foo {\n bar.1\n}\n\nfn foo_a(foo: Foo) -> int {\n foo.a\n}\n\npub fn bar_1_foo_a(bar: Bar) -> int {\n foo_a(bar_1(bar))\n}\n\npub fn main() -> int {\n let a: Foo = Foo { a: 5 };\n let b: Bar = Bar(1.23, a);\n let aa_lhs = a.a + 2;\n let aa_rhs = 2 + a.a;\n aa_lhs + aa_rhs\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' @@ -15,12 +15,6 @@ source_filename = "main.mun" @dispatchTable = external global %DispatchTable @global_type_table = external global [7 x %struct.MunTypeInfo addrspace(4)*] -define double @bar_0(%Bar) { -body: - %.fca.0.extract = extractvalue %Bar %0, 0 - ret double %.fca.0.extract -} - define %Foo @bar_1(%Bar) { body: %.fca.1.0.extract = extractvalue %Bar %0, 1, 0 @@ -28,12 +22,6 @@ body: ret %Foo %"1.fca.0.insert" } -define i64 @bar_1_a(%Bar) { -body: - %.fca.1.0.extract = extractvalue %Bar %0, 1, 0 - ret i64 %.fca.1.0.extract -} - define i64 @foo_a(%Foo) { body: %.fca.0.extract = extractvalue %Foo %0, 0 @@ -51,6 +39,14 @@ body: ret i64 %foo_a } +define i64 @bar_1_foo_a_wrapper(%Bar* addrspace(4)*) { +body: + %mem_ptr = load %Bar*, %Bar* addrspace(4)* %0 + %deref = load %Bar, %Bar* %mem_ptr + %bar_1_foo_a = call i64 @bar_1_foo_a(%Bar %deref) + ret i64 %bar_1_foo_a +} + define i64 @main() { body: ret i64 14 @@ -61,12 +57,13 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } -%struct.MunStructInfo = type { i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i64 (%Foo)*, %Foo (%Bar)* } %Foo = type { i64 } %Bar = type { double, %Foo } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } +%struct.MunStructInfo = type { i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } +@dispatchTable = global %DispatchTable { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* null, i64 (%Foo)* @foo_a, %Foo (%Bar)* @bar_1 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Foo\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @@ -91,7 +88,6 @@ source_filename = "group_name" @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" @"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i32 64, i8 8, i8 0 } @global_type_table = global [7 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] -@dispatchTable = global %DispatchTable { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* null, i64 (%Foo)* @foo_a, %Foo (%Bar)* @bar_1 } @allocatorHandle = unnamed_addr global i8* null declare i64 @foo_a(%Foo) diff --git a/crates/mun_codegen/src/snapshots/test__function_arguments.snap b/crates/mun_codegen/src/snapshots/test__function_arguments.snap index 462337fca..6dcd695a9 100644 --- a/crates/mun_codegen/src/snapshots/test__function_arguments.snap +++ b/crates/mun_codegen/src/snapshots/test__function_arguments.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn main(a:int)->int {\n a\n}" +expression: "pub fn main(a:int) -> int {\n a\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @main(i64) { body: ret i64 %0 @@ -16,3 +20,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__function_calls.snap b/crates/mun_codegen/src/snapshots/test__function_calls.snap index 1a3898852..17161b42f 100644 --- a/crates/mun_codegen/src/snapshots/test__function_calls.snap +++ b/crates/mun_codegen/src/snapshots/test__function_calls.snap @@ -1,14 +1,16 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn add_impl(a:int, b:int)->int {\n a+b\n}\n\nfn add(a:int, b:int)->int {\n add_impl(a,b)\n}\n\nfn test()->int {\n add(4,5)\n add_impl(4,5)\n add(4,5)\n}" +expression: "fn add_impl(a:int, b:int) -> int {\n a+b\n}\n\nfn add(a:int, b:int) -> int {\n add_impl(a,b)\n}\n\npub fn test() -> int {\n add(4,5)\n add_impl(4,5)\n add(4,5)\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" %DispatchTable = type { i64 (i64, i64)*, i64 (i64, i64)* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } @dispatchTable = external global %DispatchTable +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] define i64 @add_impl(i64, i64) { body: @@ -18,18 +20,18 @@ body: define i64 @add(i64, i64) { body: - %add_impl_ptr = load i64 (i64, i64)*, i64 (i64, i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 0) + %add_impl_ptr = load i64 (i64, i64)*, i64 (i64, i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 1) %add_impl = call i64 %add_impl_ptr(i64 %0, i64 %1) ret i64 %add_impl } define i64 @test() { body: - %add_ptr = load i64 (i64, i64)*, i64 (i64, i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 1) + %add_ptr = load i64 (i64, i64)*, i64 (i64, i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 0) %add = call i64 %add_ptr(i64 4, i64 5) - %add_impl_ptr = load i64 (i64, i64)*, i64 (i64, i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 0) + %add_impl_ptr = load i64 (i64, i64)*, i64 (i64, i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 1) %add_impl = call i64 %add_impl_ptr(i64 4, i64 5) - %add_ptr1 = load i64 (i64, i64)*, i64 (i64, i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 1) + %add_ptr1 = load i64 (i64, i64)*, i64 (i64, i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 0) %add2 = call i64 %add_ptr1(i64 4, i64 5) ret i64 %add2 } @@ -40,10 +42,14 @@ body: source_filename = "group_name" %DispatchTable = type { i64 (i64, i64)*, i64 (i64, i64)* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } -@dispatchTable = global %DispatchTable { i64 (i64, i64)* @add_impl, i64 (i64, i64)* @add } - -declare i64 @add_impl(i64, i64) +@dispatchTable = global %DispatchTable { i64 (i64, i64)* @add, i64 (i64, i64)* @add_impl } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] declare i64 @add(i64, i64) +declare i64 @add_impl(i64, i64) + diff --git a/crates/mun_codegen/src/snapshots/test__gc_struct.snap b/crates/mun_codegen/src/snapshots/test__gc_struct.snap index 81005a669..2229f77b9 100644 --- a/crates/mun_codegen/src/snapshots/test__gc_struct.snap +++ b/crates/mun_codegen/src/snapshots/test__gc_struct.snap @@ -1,6 +1,6 @@ --- source: crates/mun_codegen/src/test.rs -expression: "struct(gc) Foo { a: int, b: int };\n\nfn foo() {\n let a = Foo { a: 3, b: 4 };\n a.b += 3;\n let b = a;\n}" +expression: "struct(gc) Foo { a: int, b: int };\n\npub fn foo() {\n let a = Foo { a: 3, b: 4 };\n a.b += 3;\n let b = a;\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' @@ -46,10 +46,11 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %struct.MunStructInfo = type { i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } -%DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } +@dispatchTable = global %DispatchTable zeroinitializer @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Foo\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @"struct_info::::field_names.1" = private unnamed_addr constant [2 x i8] c"b\00" @@ -66,6 +67,5 @@ source_filename = "group_name" @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" @"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i32 64, i8 8, i8 0 } @global_type_table = global [5 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] -@dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__if_statement.snap b/crates/mun_codegen/src/snapshots/test__if_statement.snap index 359de5c6b..4de96172a 100644 --- a/crates/mun_codegen/src/snapshots/test__if_statement.snap +++ b/crates/mun_codegen/src/snapshots/test__if_statement.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn foo(a:int)->int {\n let b = if a > 3 {\n let c = if a > 4 {\n a+1\n } else {\n a+3\n }\n c\n } else {\n a-1\n }\n b\n}" +expression: "pub fn foo(a:int) -> int {\n let b = if a > 3 {\n let c = if a > 4 {\n a+1\n } else {\n a+3\n }\n c\n } else {\n a-1\n }\n b\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @foo(i64) { body: %greater = icmp sgt i64 %0, 3 @@ -32,3 +36,9 @@ if_merge: ; preds = %else, %then ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__issue_128.snap b/crates/mun_codegen/src/snapshots/test__issue_128.snap index 516df285d..fc70e3a4c 100644 --- a/crates/mun_codegen/src/snapshots/test__issue_128.snap +++ b/crates/mun_codegen/src/snapshots/test__issue_128.snap @@ -30,11 +30,11 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %DispatchTable = type { i64 (i64)*, void (i64)* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } +@dispatchTable = global %DispatchTable zeroinitializer @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" @"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } @global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] -@dispatchTable = global %DispatchTable zeroinitializer diff --git a/crates/mun_codegen/src/snapshots/test__issue_133.snap b/crates/mun_codegen/src/snapshots/test__issue_133.snap new file mode 100644 index 000000000..f01257837 --- /dev/null +++ b/crates/mun_codegen/src/snapshots/test__issue_133.snap @@ -0,0 +1,42 @@ +--- +source: crates/mun_codegen/src/test.rs +expression: "fn do_the_things(n: int) -> int {\n n + 7\n}\n\npub fn main() {\n do_the_things(3);\n}" +--- +; == FILE IR ===================================== +; ModuleID = 'main.mun' +source_filename = "main.mun" + +%DispatchTable = type { i64 (i64)* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@dispatchTable = external global %DispatchTable +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + +define i64 @do_the_things(i64) { +body: + %add = add i64 %0, 7 + ret i64 %add +} + +define void @main() { +body: + %do_the_things_ptr = load i64 (i64)*, i64 (i64)** getelementptr inbounds (%DispatchTable, %DispatchTable* @dispatchTable, i32 0, i32 0) + %do_the_things = call i64 %do_the_things_ptr(i64 3) + ret void +} + + +; == GROUP IR ==================================== +; ModuleID = 'group_name' +source_filename = "group_name" + +%DispatchTable = type { i64 (i64)* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@dispatchTable = global %DispatchTable { i64 (i64)* @do_the_things } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + +declare i64 @do_the_things(i64) + diff --git a/crates/mun_codegen/src/snapshots/test__let_statement.snap b/crates/mun_codegen/src/snapshots/test__let_statement.snap index f13466609..13e956315 100644 --- a/crates/mun_codegen/src/snapshots/test__let_statement.snap +++ b/crates/mun_codegen/src/snapshots/test__let_statement.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn main(a:int)->int {\n let b = a+1\n b\n}" +expression: "pub fn main(a:int) -> int {\n let b = a+1\n b\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @main(i64) { body: %add = add i64 %0, 1 @@ -17,3 +21,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__loop_break_expr.snap b/crates/mun_codegen/src/snapshots/test__loop_break_expr.snap index d1767097e..8feaccb4e 100644 --- a/crates/mun_codegen/src/snapshots/test__loop_break_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__loop_break_expr.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn foo(n:int)->int {\n loop {\n if n > 5 {\n break n;\n }\n if n > 10 {\n break 10;\n }\n n += 1;\n }\n}" +expression: "pub fn foo(n:int) -> int {\n loop {\n if n > 5 {\n break n;\n }\n if n > 10 {\n break 10;\n }\n n += 1;\n }\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @foo(i64) { body: br label %loop @@ -33,3 +37,9 @@ if_merge6: ; preds = %if_merge ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__never_conditional_return_expr.snap b/crates/mun_codegen/src/snapshots/test__never_conditional_return_expr.snap index e8693872a..633f8c367 100644 --- a/crates/mun_codegen/src/snapshots/test__never_conditional_return_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__never_conditional_return_expr.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn main(a:int)->int {\n if a > 4 {\n return a;\n } else {\n return a - 1;\n }\n}" +expression: "pub fn main(a:int) -> int {\n if a > 4 {\n return a;\n } else {\n return a - 1;\n }\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @main(i64) { body: %greater = icmp sgt i64 %0, 4 @@ -24,3 +28,9 @@ else: ; preds = %body ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__primitive_types.snap b/crates/mun_codegen/src/snapshots/test__primitive_types.snap index 3901fcd83..c956e363f 100644 --- a/crates/mun_codegen/src/snapshots/test__primitive_types.snap +++ b/crates/mun_codegen/src/snapshots/test__primitive_types.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn add(a: u8, b: u8) -> u8 { a+b }\n fn less(a: u16, b: u16) -> bool { a bool { a>b }\n fn equal(a: u64, b: u64) -> bool { a==b }\n fn nequal(a: u128, b: u128) -> bool { a!=b }\n fn greater_equal(a: usize, b: usize) -> bool { a>=b }\n fn less_equal(a: uint, b: uint) -> bool { a<=b }\n\n fn iadd(a: i8, b: i8) -> i8 { a+b }\n fn iless(a: i16, b: i16) -> bool { a bool { a>b }\n fn iequal(a: i64, b: i64) -> bool { a==b }\n fn inequal(a: i128, b: i128) -> bool { a!=b }\n fn igreater_equal(a: isize, b: isize) -> bool { a>=b }\n fn iless_equal(a: int, b: int) -> bool { a<=b }" +expression: "pub fn add(a: u8, b: u8) -> u8 { a+b }\n pub fn less(a: u16, b: u16) -> bool { a bool { a>b }\n pub fn equal(a: u64, b: u64) -> bool { a==b }\n pub fn nequal(a: u128, b: u128) -> bool { a!=b }\n pub fn greater_equal(a: usize, b: usize) -> bool { a>=b }\n pub fn less_equal(a: uint, b: uint) -> bool { a<=b }\n\n pub fn iadd(a: i8, b: i8) -> i8 { a+b }\n pub fn iless(a: i16, b: i16) -> bool { a bool { a>b }\n pub fn iequal(a: i64, b: i64) -> bool { a==b }\n pub fn inequal(a: i128, b: i128) -> bool { a!=b }\n pub fn igreater_equal(a: isize, b: isize) -> bool { a>=b }\n pub fn iless_equal(a: int, b: int) -> bool { a<=b }" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [11 x %struct.MunTypeInfo addrspace(4)*] + define i8 @add(i8, i8) { body: %add = add i8 %0, %1 @@ -95,3 +99,29 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i16\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\05\CD|\F8Bv\D8\B1\E8\8B\8C\D8\8D\B5\89\B0", [10 x i8]* @"type_info::::name", i32 16, i8 2, i8 0 } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i32\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\17yzt\19\D62\17\D25\95C\17\88[\FA", [10 x i8]* @"type_info::::name", i32 32, i8 4, i8 0 } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::u16\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"0\01\BC\BBK\E0\F2\7F&l\01\CD|q\F2\B3", [10 x i8]* @"type_info::::name", i32 16, i8 2, i8 0 } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::u32\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"daz5d\A6\BE\88\81=&Y\A1+\C6\1D", [10 x i8]* @"type_info::::name", i32 32, i8 4, i8 0 } +@"type_info::::name" = private unnamed_addr constant [11 x i8] c"core::bool\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i32 1, i8 1, i8 0 } +@"type_info::::name" = private unnamed_addr constant [9 x i8] c"core::u8\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\A0y\A7S\B6(n\F7f&H\E1\F9\AD\04>", [9 x i8]* @"type_info::::name", i32 8, i8 1, i8 0 } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::u64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\A6\E7g \D1\8B\1Aq`\1F\1E\07\BB5@q", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@"type_info::::name" = private unnamed_addr constant [11 x i8] c"core::i128\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\BDkp\09RRM\EBc\02\A0\DB47\A7\E3", [11 x i8]* @"type_info::::name", i32 128, i8 8, i8 0 } +@"type_info::::name" = private unnamed_addr constant [11 x i8] c"core::u128\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\E67\1BU\E9k\95\93d\14}\1C\96S\95\F0", [11 x i8]* @"type_info::::name", i32 128, i8 8, i8 0 } +@"type_info::::name" = private unnamed_addr constant [9 x i8] c"core::i8\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\C4\B1Z\E7\12\B1\91q\F1\0B\80U\FC\A6\0F", [9 x i8]* @"type_info::::name", i32 8, i8 1, i8 0 } +@global_type_table = global [11 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__private_fn_only.snap b/crates/mun_codegen/src/snapshots/test__private_fn_only.snap new file mode 100644 index 000000000..6720cf7c0 --- /dev/null +++ b/crates/mun_codegen/src/snapshots/test__private_fn_only.snap @@ -0,0 +1,13 @@ +--- +source: crates/mun_codegen/src/test.rs +expression: "fn private_main() {\n let a = 1;\n}" +--- +; == FILE IR ===================================== +; ModuleID = 'main.mun' +source_filename = "main.mun" + + +; == GROUP IR ==================================== +; ModuleID = 'group_name' +source_filename = "group_name" + diff --git a/crates/mun_codegen/src/snapshots/test__return_expr.snap b/crates/mun_codegen/src/snapshots/test__return_expr.snap index a31cb699b..a8c42af42 100644 --- a/crates/mun_codegen/src/snapshots/test__return_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__return_expr.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn main()->int {\n return 5;\n let a = 3; // Nothing regarding this statement should be in the IR\n}" +expression: "pub fn main() -> int {\n return 5;\n let a = 3; // Nothing regarding this statement should be in the IR\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @main() { body: ret i64 5 @@ -16,3 +20,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__return_type.snap b/crates/mun_codegen/src/snapshots/test__return_type.snap index 802a6e537..b62ac595c 100644 --- a/crates/mun_codegen/src/snapshots/test__return_type.snap +++ b/crates/mun_codegen/src/snapshots/test__return_type.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn main()->int {\n 0\n}" +expression: "pub fn main() -> int {\n 0\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @main() { body: ret i64 0 @@ -16,3 +20,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__shadowing.snap b/crates/mun_codegen/src/snapshots/test__shadowing.snap index 2c0d59c02..0b2e8db45 100644 --- a/crates/mun_codegen/src/snapshots/test__shadowing.snap +++ b/crates/mun_codegen/src/snapshots/test__shadowing.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn foo(a:int)->int {\n let a = a+1;\n {\n let a = a+2;\n }\n a+3\n}\n\nfn bar(a:int)->int {\n let a = a+1;\n let a = {\n let a = a+2;\n a\n }\n a+3\n}" +expression: "pub fn foo(a:int) -> int {\n let a = a+1;\n {\n let a = a+2;\n }\n a+3\n}\n\npub fn bar(a:int) -> int {\n let a = a+1;\n let a = {\n let a = a+2;\n a\n }\n a+3\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @foo(i64) { body: %add = add i64 %0, 1 @@ -26,3 +30,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__struct_test.snap b/crates/mun_codegen/src/snapshots/test__struct_test.snap index 72dd45b5d..cdc650e6f 100644 --- a/crates/mun_codegen/src/snapshots/test__struct_test.snap +++ b/crates/mun_codegen/src/snapshots/test__struct_test.snap @@ -1,6 +1,6 @@ --- source: crates/mun_codegen/src/test.rs -expression: "struct(value) Bar(float, int, bool, Foo);\nstruct(value) Foo { a: int };\nstruct(value) Baz;\nfn foo() {\n let a: Foo = Foo { a: 5 };\n let b: Bar = Bar(1.23, a.a, true, a);\n let c: Baz = Baz;\n}" +expression: "struct(value) Bar(float, int, bool, Foo);\nstruct(value) Foo { a: int };\nstruct(value) Baz;\npub fn foo() {\n let a: Foo = Foo { a: 5 };\n let b: Bar = Bar(1.23, a.a, true, a);\n let c: Baz = Baz;\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' @@ -38,10 +38,11 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %struct.MunStructInfo = type { i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } -%DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } +@dispatchTable = global %DispatchTable zeroinitializer @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Foo\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @@ -72,6 +73,5 @@ source_filename = "group_name" @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Baz\00" @"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\F8\DC\E6\7F,\948\82\82\ED?\A7\97\96\8A|", [4 x i8]* @"type_info::::name", i32 0, i8 1, i8 1 }, %struct.MunStructInfo { i8 addrspace(4)* addrspace(4)* null, %struct.MunTypeInfo addrspace(4)* addrspace(4)* null, i16 addrspace(4)* null, i16 0, i8 1 } } @global_type_table = global [9 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::"] -@dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__true_is_true.snap b/crates/mun_codegen/src/snapshots/test__true_is_true.snap index 409b7c0ae..59039f13c 100644 --- a/crates/mun_codegen/src/snapshots/test__true_is_true.snap +++ b/crates/mun_codegen/src/snapshots/test__true_is_true.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn test_true()->bool {\n true\n}\n\nfn test_false()->bool {\n false\n}" +expression: "pub fn test_true() -> bool {\n true\n}\n\npub fn test_false() -> bool {\n false\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i1 @test_true() { body: ret i1 true @@ -21,3 +25,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [11 x i8] c"core::bool\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i32 1, i8 1, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__update_operators.snap b/crates/mun_codegen/src/snapshots/test__update_operators.snap index b3d09a007..8bb8d382e 100644 --- a/crates/mun_codegen/src/snapshots/test__update_operators.snap +++ b/crates/mun_codegen/src/snapshots/test__update_operators.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn add(a:int, b:int)->int {\n let result = a\n result += b\n result\n}\n\nfn subtract(a:int, b:int)->int {\n let result = a\n result -= b\n result\n}\n\nfn multiply(a:int, b:int)->int {\n let result = a\n result *= b\n result\n}\n\nfn divide(a:int, b:int)->int {\n let result = a\n result /= b\n result\n}" +expression: "pub fn add(a:int, b:int) -> int {\n let result = a\n result += b\n result\n}\n\npub fn subtract(a:int, b:int) -> int {\n let result = a\n result -= b\n result\n}\n\npub fn multiply(a:int, b:int) -> int {\n let result = a\n result *= b\n result\n}\n\npub fn divide(a:int, b:int) -> int {\n let result = a\n result /= b\n result\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @add(i64, i64) { body: %add = add i64 %0, %1 @@ -35,3 +39,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__update_parameter.snap b/crates/mun_codegen/src/snapshots/test__update_parameter.snap index 4ab8612e3..a0d8d7d98 100644 --- a/crates/mun_codegen/src/snapshots/test__update_parameter.snap +++ b/crates/mun_codegen/src/snapshots/test__update_parameter.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn add_three(a:int)->int {\n a += 3;\n a\n}" +expression: "pub fn add_three(a:int) -> int {\n a += 3;\n a\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define i64 @add_three(i64) { body: %add = add i64 %0, 3 @@ -17,3 +21,9 @@ body: ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/snapshots/test__void_return.snap b/crates/mun_codegen/src/snapshots/test__void_return.snap index 50b2fc56e..1f8a14472 100644 --- a/crates/mun_codegen/src/snapshots/test__void_return.snap +++ b/crates/mun_codegen/src/snapshots/test__void_return.snap @@ -1,14 +1,16 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn bar() {\n let a = 3;\n}\nfn foo(a:int) {\n let c = bar()\n}" +expression: "fn bar() {\n let a = 3;\n}\npub fn foo(a:int) {\n let c = bar()\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" %DispatchTable = type { void ()* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } @dispatchTable = external global %DispatchTable +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] define void @bar() { body: @@ -28,8 +30,12 @@ body: source_filename = "group_name" %DispatchTable = type { void ()* } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } @dispatchTable = global %DispatchTable { void ()* @bar } +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] declare void @bar() diff --git a/crates/mun_codegen/src/snapshots/test__while_expr.snap b/crates/mun_codegen/src/snapshots/test__while_expr.snap index 3d32f4ba5..e54dcddd0 100644 --- a/crates/mun_codegen/src/snapshots/test__while_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__while_expr.snap @@ -1,11 +1,15 @@ --- source: crates/mun_codegen/src/test.rs -expression: "fn foo(n:int) {\n while n<3 {\n n += 1;\n };\n\n // This will be completely optimized out\n while n<4 {\n break;\n };\n}" +expression: "pub fn foo(n:int) {\n while n<3 {\n n += 1;\n };\n\n // This will be completely optimized out\n while n<4 {\n break;\n };\n}" --- ; == FILE IR ===================================== ; ModuleID = 'main.mun' source_filename = "main.mun" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@global_type_table = external global [1 x %struct.MunTypeInfo addrspace(4)*] + define void @foo(i64) { body: br label %whilecond @@ -28,3 +32,9 @@ whilecond3: ; preds = %whilecond ; ModuleID = 'group_name' source_filename = "group_name" +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } + +@"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } +@global_type_table = global [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] + diff --git a/crates/mun_codegen/src/test.rs b/crates/mun_codegen/src/test.rs index ba7e16dcc..c81d0c01e 100644 --- a/crates/mun_codegen/src/test.rs +++ b/crates/mun_codegen/src/test.rs @@ -26,11 +26,26 @@ fn issue_128() { ) } +#[test] +fn issue_133() { + test_snapshot( + r#" + fn do_the_things(n: int) -> int { + n + 7 + } + + pub fn main() { + do_the_things(3); + } + "#, + ); +} + #[test] fn function() { test_snapshot( r#" - fn main() { + pub fn main() { } "#, ); @@ -40,7 +55,7 @@ fn function() { fn return_type() { test_snapshot( r#" - fn main()->int { + pub fn main() -> int { 0 } "#, @@ -51,7 +66,7 @@ fn return_type() { fn function_arguments() { test_snapshot( r#" - fn main(a:int)->int { + pub fn main(a:int) -> int { a } "#, @@ -62,15 +77,15 @@ fn function_arguments() { fn binary_expressions() { test_snapshot( r#" - fn add(a:int, b:int)->int { + pub fn add(a:int, b:int) -> int { a+b } - fn subtract(a:int, b:int)->int { + pub fn subtract(a:int, b:int) -> int { a-b } - fn multiply(a:int, b:int)->int { + pub fn multiply(a:int, b:int) -> int { a*b } "#, @@ -81,7 +96,7 @@ fn binary_expressions() { fn let_statement() { test_snapshot( r#" - fn main(a:int)->int { + pub fn main(a:int) -> int { let b = a+1 b } @@ -93,7 +108,7 @@ fn let_statement() { fn invalid_binary_ops() { test_snapshot( r#" - fn main() { + pub fn main() { let a = 3+3.0; let b = 3.0+3; } @@ -105,25 +120,25 @@ fn invalid_binary_ops() { fn update_operators() { test_snapshot( r#" - fn add(a:int, b:int)->int { + pub fn add(a:int, b:int) -> int { let result = a result += b result } - fn subtract(a:int, b:int)->int { + pub fn subtract(a:int, b:int) -> int { let result = a result -= b result } - fn multiply(a:int, b:int)->int { + pub fn multiply(a:int, b:int) -> int { let result = a result *= b result } - fn divide(a:int, b:int)->int { + pub fn divide(a:int, b:int) -> int { let result = a result /= b result @@ -136,7 +151,7 @@ fn update_operators() { fn update_parameter() { test_snapshot( r#" - fn add_three(a:int)->int { + pub fn add_three(a:int) -> int { a += 3; a } @@ -148,15 +163,15 @@ fn update_parameter() { fn function_calls() { test_snapshot( r#" - fn add_impl(a:int, b:int)->int { + fn add_impl(a:int, b:int) -> int { a+b } - fn add(a:int, b:int)->int { + fn add(a:int, b:int) -> int { add_impl(a,b) } - fn test()->int { + pub fn test() -> int { add(4,5) add_impl(4,5) add(4,5) @@ -169,18 +184,18 @@ fn function_calls() { fn equality_operands() { test_snapshot( r#" - fn equals(a:int, b:int)->bool { a == b } - fn not_equals(a:int, b:int)->bool { a != b } - fn less(a:int, b:int)->bool { a < b } - fn less_equal(a:int, b:int)->bool { a <= b } - fn greater(a:int, b:int)->bool { a > b } - fn greater_equal(a:int, b:int)->bool { a >= b } - fn equalsf(a:float, b:float)->bool { a == b } - fn not_equalsf(a:float, b:float)->bool { a != b } - fn lessf(a:float, b:float)->bool { a < b } - fn less_equalf(a:float, b:float)->bool { a <= b } - fn greaterf(a:float, b:float)->bool { a > b } - fn greater_equalf(a:float, b:float)->bool { a >= b } + pub fn equals(a:int, b:int) -> bool { a == b } + pub fn not_equals(a:int, b:int) -> bool { a != b } + pub fn less(a:int, b:int) -> bool { a < b } + pub fn less_equal(a:int, b:int) -> bool { a <= b } + pub fn greater(a:int, b:int) -> bool { a > b } + pub fn greater_equal(a:int, b:int) -> bool { a >= b } + pub fn equalsf(a:float, b:float) -> bool { a == b } + pub fn not_equalsf(a:float, b:float) -> bool { a != b } + pub fn lessf(a:float, b:float) -> bool { a < b } + pub fn less_equalf(a:float, b:float) -> bool { a <= b } + pub fn greaterf(a:float, b:float) -> bool { a > b } + pub fn greater_equalf(a:float, b:float) -> bool { a >= b } "#, ); } @@ -189,7 +204,7 @@ fn equality_operands() { fn if_statement() { test_snapshot( r#" - fn foo(a:int)->int { + pub fn foo(a:int) -> int { let b = if a > 3 { let c = if a > 4 { a+1 @@ -213,7 +228,7 @@ fn void_return() { fn bar() { let a = 3; } - fn foo(a:int) { + pub fn foo(a:int) { let c = bar() } "#, @@ -224,7 +239,7 @@ fn void_return() { fn fibonacci() { test_snapshot( r#" - fn fibonacci(n:int)->int { + pub fn fibonacci(n:int) -> int { if n <= 1 { n } else { @@ -239,7 +254,7 @@ fn fibonacci() { fn fibonacci_loop() { test_snapshot( r#" - fn fibonacci(n:int)->int { + pub fn fibonacci(n:int) -> int { let a = 0; let b = 1; let i = 1; @@ -261,7 +276,7 @@ fn fibonacci_loop() { fn shadowing() { test_snapshot( r#" - fn foo(a:int)->int { + pub fn foo(a:int) -> int { let a = a+1; { let a = a+2; @@ -269,7 +284,7 @@ fn shadowing() { a+3 } - fn bar(a:int)->int { + pub fn bar(a:int) -> int { let a = a+1; let a = { let a = a+2; @@ -285,7 +300,7 @@ fn shadowing() { fn return_expr() { test_snapshot( r#" - fn main()->int { + pub fn main() -> int { return 5; let a = 3; // Nothing regarding this statement should be in the IR } @@ -297,7 +312,7 @@ fn return_expr() { fn conditional_return_expr() { test_snapshot( r#" - fn main(a:int)->int { + pub fn main(a:int) -> int { if a > 4 { return a; } @@ -311,7 +326,7 @@ fn conditional_return_expr() { fn never_conditional_return_expr() { test_snapshot( r#" - fn main(a:int)->int { + pub fn main(a:int) -> int { if a > 4 { return a; } else { @@ -326,11 +341,11 @@ fn never_conditional_return_expr() { fn true_is_true() { test_snapshot( r#" - fn test_true()->bool { + pub fn test_true() -> bool { true } - fn test_false()->bool { + pub fn test_false() -> bool { false }"#, ); @@ -340,7 +355,7 @@ fn true_is_true() { fn loop_expr() { test_snapshot( r#" - fn foo() { + pub fn foo() { loop {} } "#, @@ -351,7 +366,7 @@ fn loop_expr() { fn loop_break_expr() { test_snapshot( r#" - fn foo(n:int)->int { + pub fn foo(n:int) -> int { loop { if n > 5 { break n; @@ -370,7 +385,7 @@ fn loop_break_expr() { fn while_expr() { test_snapshot( r#" - fn foo(n:int) { + pub fn foo(n:int) { while n<3 { n += 1; }; @@ -391,7 +406,7 @@ fn struct_test() { struct(value) Bar(float, int, bool, Foo); struct(value) Foo { a: int }; struct(value) Baz; - fn foo() { + pub fn foo() { let a: Foo = Foo { a: 5 }; let b: Bar = Bar(1.23, a.a, true, a); let c: Baz = Baz; @@ -407,27 +422,19 @@ fn field_expr() { struct(value) Bar(float, Foo); struct(value) Foo { a: int }; - fn bar_0(bar: Bar) -> float { - bar.0 - } - fn bar_1(bar: Bar) -> Foo { bar.1 } - fn bar_1_a(bar: Bar) -> int { - bar.1.a - } - fn foo_a(foo: Foo) -> int { foo.a } - fn bar_1_foo_a(bar: Bar) -> int { + pub fn bar_1_foo_a(bar: Bar) -> int { foo_a(bar_1(bar)) } - fn main() -> int { + pub fn main() -> int { let a: Foo = Foo { a: 5 }; let b: Bar = Bar(1.23, a); let aa_lhs = a.a + 2; @@ -444,7 +451,7 @@ fn field_crash() { r#" struct(gc) Foo { a: int }; - fn main(c:int)->int { + pub fn main(c:int) -> int { let b = Foo { a: c + 5 } b.a } @@ -458,7 +465,7 @@ fn gc_struct() { r#" struct(gc) Foo { a: int, b: int }; - fn foo() { + pub fn foo() { let a = Foo { a: 3, b: 4 }; a.b += 3; let b = a; @@ -471,21 +478,21 @@ fn gc_struct() { fn primitive_types() { test_snapshot( r#" - fn add(a: u8, b: u8) -> u8 { a+b } - fn less(a: u16, b: u16) -> bool { a bool { a>b } - fn equal(a: u64, b: u64) -> bool { a==b } - fn nequal(a: u128, b: u128) -> bool { a!=b } - fn greater_equal(a: usize, b: usize) -> bool { a>=b } - fn less_equal(a: uint, b: uint) -> bool { a<=b } - - fn iadd(a: i8, b: i8) -> i8 { a+b } - fn iless(a: i16, b: i16) -> bool { a bool { a>b } - fn iequal(a: i64, b: i64) -> bool { a==b } - fn inequal(a: i128, b: i128) -> bool { a!=b } - fn igreater_equal(a: isize, b: isize) -> bool { a>=b } - fn iless_equal(a: int, b: int) -> bool { a<=b } + pub fn add(a: u8, b: u8) -> u8 { a+b } + pub fn less(a: u16, b: u16) -> bool { a bool { a>b } + pub fn equal(a: u64, b: u64) -> bool { a==b } + pub fn nequal(a: u128, b: u128) -> bool { a!=b } + pub fn greater_equal(a: usize, b: usize) -> bool { a>=b } + pub fn less_equal(a: uint, b: uint) -> bool { a<=b } + + pub fn iadd(a: i8, b: i8) -> i8 { a+b } + pub fn iless(a: i16, b: i16) -> bool { a bool { a>b } + pub fn iequal(a: i64, b: i64) -> bool { a==b } + pub fn inequal(a: i128, b: i128) -> bool { a!=b } + pub fn igreater_equal(a: isize, b: isize) -> bool { a>=b } + pub fn iless_equal(a: int, b: int) -> bool { a<=b } "#, ) } @@ -495,13 +502,24 @@ fn extern_fn() { test_snapshot( r#" extern fn add(a:int, b:int) -> int; - fn main() { + pub fn main() { add(3,4); } "#, ) } +#[test] +fn private_fn_only() { + test_snapshot( + r#" + fn private_main() { + let a = 1; + } + "#, + ); +} + #[test] fn incremental_compilation() { let (mut db, file_id) = MockDatabase::with_single_file( @@ -577,8 +595,8 @@ fn test_snapshot_with_optimization(text: &str, opt: OptimizationLevel) { drop(sink); let messages = messages.into_inner(); - let _module_builder = - ModuleBuilder::new(&mut db, file_id).expect("Failed to initialize module builder"); + let module_builder = + ModuleBuilder::new(&db, file_id).expect("Failed to initialize module builder"); // The thread is named after the test case, so we can use it to name our snapshots. let thread_name = std::thread::current() @@ -610,6 +628,11 @@ fn test_snapshot_with_optimization(text: &str, opt: OptimizationLevel) { ) }; + // To ensure that we test symbol generation + if messages.is_empty() { + let _obj_file = module_builder.build().expect("Failed to build object file"); + } + let value = format!( r"; == FILE IR ===================================== {} diff --git a/crates/mun_compiler/src/driver.rs b/crates/mun_compiler/src/driver.rs index 1f641eab5..038dea9fa 100644 --- a/crates/mun_compiler/src/driver.rs +++ b/crates/mun_compiler/src/driver.rs @@ -134,7 +134,8 @@ impl Driver { impl Driver { /// Generate an assembly for the given file pub fn write_assembly(&mut self, file_id: FileId) -> Result { - let module_builder = ModuleBuilder::new(&mut self.db, file_id)?; - module_builder.finalize(self.out_dir.as_deref()) + let module_builder = ModuleBuilder::new(&self.db, file_id)?; + let obj_file = module_builder.build()?; + obj_file.into_shared_object(self.out_dir.as_deref()) } }