From 6788ef1690ac5cf40d1b5f02f5465e8cda93f7d5 Mon Sep 17 00:00:00 2001 From: sofia Date: Tue, 15 Jul 2025 20:01:46 +0300 Subject: [PATCH] Use AvailableExternally-linkage for externs for imports --- reid-llvm-lib/src/compile.rs | 11 +++++++++-- reid/src/ast/process.rs | 2 +- reid/src/codegen.rs | 5 +++-- reid/src/mir/display.rs | 3 ++- reid/src/mir/linker.rs | 2 +- reid/src/mir/mod.rs | 7 ++++--- reid/src/mir/pass.rs | 2 +- reid/src/mir/typecheck.rs | 2 +- reid/src/mir/typeinference.rs | 2 +- reid/src/mir/types.rs | 33 +++++++++++++++++++++------------ 10 files changed, 44 insertions(+), 25 deletions(-) diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 48860b8..18e312d 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -265,8 +265,15 @@ impl FunctionHolder { return; } - if self.data.flags.is_imported && !in_main_module { - LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMExternalLinkage); + if self.data.flags.is_imported { + if self.data.flags.is_extern { + LLVMSetLinkage( + own_function.value_ref, + LLVMLinkage::LLVMAvailableExternallyLinkage, + ); + } else { + LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMExternalLinkage); + } } else { LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMPrivateLinkage); } diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 3e58dd2..c5bed72 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -58,7 +58,7 @@ impl ast::Module { .cloned() .map(|p| (p.0, p.1.into())) .collect(), - kind: mir::FunctionDefinitionKind::Extern, + kind: mir::FunctionDefinitionKind::Extern(false), }; functions.push(def); } diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index dc2ecd2..1186736 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -69,12 +69,13 @@ impl mir::Module { ..FunctionFlags::default() }, ), - mir::FunctionDefinitionKind::Extern => module.function( + mir::FunctionDefinitionKind::Extern(imported) => module.function( &function.name, function.return_type.get_type(), param_types, FunctionFlags { is_extern: true, + is_imported: *imported, ..FunctionFlags::default() }, ), @@ -117,7 +118,7 @@ impl mir::Module { } } } - mir::FunctionDefinitionKind::Extern => {} + mir::FunctionDefinitionKind::Extern(_) => {} } } diff --git a/reid/src/mir/display.rs b/reid/src/mir/display.rs index 9f43256..b6a6c78 100644 --- a/reid/src/mir/display.rs +++ b/reid/src/mir/display.rs @@ -61,7 +61,8 @@ impl Display for FunctionDefinitionKind { write!(f, "{}", block)?; Ok(()) } - Self::Extern => write!(f, ""), + Self::Extern(true) => write!(f, ""), + Self::Extern(false) => write!(f, ""), } } } diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index d605aa3..171205c 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -193,7 +193,7 @@ impl Pass for LinkerPass { is_imported: false, return_type: func.return_type.clone(), parameters: func.parameters.clone(), - kind: super::FunctionDefinitionKind::Extern, + kind: super::FunctionDefinitionKind::Extern(true), }); } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 29b650e..f130ac3 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -254,21 +254,22 @@ pub struct FunctionDefinition { pub enum FunctionDefinitionKind { /// Actual definition block and surrounding signature range Local(Block, Metadata), - Extern, + /// True = imported from other module, False = Is user defined extern + Extern(bool), } impl FunctionDefinition { fn block_meta(&self) -> Metadata { match &self.kind { FunctionDefinitionKind::Local(block, _) => block.meta, - FunctionDefinitionKind::Extern => Metadata::default(), + FunctionDefinitionKind::Extern(_) => Metadata::default(), } } fn signature(&self) -> Metadata { match &self.kind { FunctionDefinitionKind::Local(_, metadata) => *metadata, - FunctionDefinitionKind::Extern => Metadata::default(), + FunctionDefinitionKind::Extern(_) => Metadata::default(), } } } diff --git a/reid/src/mir/pass.rs b/reid/src/mir/pass.rs index e771b3e..777f783 100644 --- a/reid/src/mir/pass.rs +++ b/reid/src/mir/pass.rs @@ -261,7 +261,7 @@ impl FunctionDefinition { scope.return_type_hint = Some(self.return_type.clone()); block.pass(pass, state, scope); } - FunctionDefinitionKind::Extern => {} + FunctionDefinitionKind::Extern(_) => {} }; } } diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index 8ca0f8d..2bf37b3 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -94,7 +94,7 @@ impl FunctionDefinition { state.scope.return_type_hint = Some(self.return_type.clone()); block.typecheck(&mut state.inner(), &hints, Some(&return_type)) } - FunctionDefinitionKind::Extern => { + FunctionDefinitionKind::Extern(_) => { Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))) } }; diff --git a/reid/src/mir/typeinference.rs b/reid/src/mir/typeinference.rs index 56bacb2..2e2b90f 100644 --- a/reid/src/mir/typeinference.rs +++ b/reid/src/mir/typeinference.rs @@ -64,7 +64,7 @@ impl FunctionDefinition { ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap()); } } - FunctionDefinitionKind::Extern => {} + FunctionDefinitionKind::Extern(_) => {} }; Ok(()) diff --git a/reid/src/mir/types.rs b/reid/src/mir/types.rs index ab2b6da..0c66de5 100644 --- a/reid/src/mir/types.rs +++ b/reid/src/mir/types.rs @@ -181,14 +181,16 @@ impl IndexedVariableReference { } } -#[derive(Debug, Clone, Copy, thiserror::Error)] +#[derive(Debug, Clone, thiserror::Error)] pub enum EqualsIssue { #[error("Function is already defined locally at {:?}", (.0).range)] ExistsLocally(Metadata), - #[error("asd")] + #[error("Equals")] Equals, - #[error("asd")] - ConflictingImports, + #[error("Function {0} is already declared locally at {:?}", (.1).range)] + AlreadyExtern(String, Metadata), + #[error("Function {0} is already imported from another module")] + ConflictWithImport(String), } impl FunctionDefinition { @@ -197,15 +199,22 @@ impl FunctionDefinition { FunctionDefinitionKind::Local(_, metadata) => { Err(EqualsIssue::ExistsLocally(*metadata)) } - FunctionDefinitionKind::Extern => { - if self.is_pub == other.is_pub - && self.name == other.name - && self.parameters == other.parameters - && self.return_type == other.return_type - { - Ok(()) + FunctionDefinitionKind::Extern(imported) => { + if *imported { + Err(EqualsIssue::ConflictWithImport(self.name.clone())) } else { - Err(EqualsIssue::ConflictingImports) + if self.is_pub == other.is_pub + && self.name == other.name + && self.parameters == other.parameters + && self.return_type == other.return_type + { + Ok(()) + } else { + Err(EqualsIssue::AlreadyExtern( + self.name.clone(), + self.signature(), + )) + } } } }