Use AvailableExternally-linkage for externs for imports

This commit is contained in:
Sofia 2025-07-15 20:01:46 +03:00
parent 6f8c02ac04
commit 6788ef1690
10 changed files with 44 additions and 25 deletions

View File

@ -265,8 +265,15 @@ impl FunctionHolder {
return;
}
if self.data.flags.is_imported && !in_main_module {
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);
}

View File

@ -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);
}

View File

@ -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(_) => {}
}
}

View File

@ -61,7 +61,8 @@ impl Display for FunctionDefinitionKind {
write!(f, "{}", block)?;
Ok(())
}
Self::Extern => write!(f, "<External>"),
Self::Extern(true) => write!(f, "<Classical Extern>"),
Self::Extern(false) => write!(f, "<Imported Extern>"),
}
}
}

View File

@ -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),
});
}
}

View File

@ -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(),
}
}
}

View File

@ -261,7 +261,7 @@ impl FunctionDefinition {
scope.return_type_hint = Some(self.return_type.clone());
block.pass(pass, state, scope);
}
FunctionDefinitionKind::Extern => {}
FunctionDefinitionKind::Extern(_) => {}
};
}
}

View File

@ -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)))
}
};

View File

@ -64,7 +64,7 @@ impl FunctionDefinition {
ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap());
}
}
FunctionDefinitionKind::Extern => {}
FunctionDefinitionKind::Extern(_) => {}
};
Ok(())

View File

@ -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,7 +199,10 @@ impl FunctionDefinition {
FunctionDefinitionKind::Local(_, metadata) => {
Err(EqualsIssue::ExistsLocally(*metadata))
}
FunctionDefinitionKind::Extern => {
FunctionDefinitionKind::Extern(imported) => {
if *imported {
Err(EqualsIssue::ConflictWithImport(self.name.clone()))
} else {
if self.is_pub == other.is_pub
&& self.name == other.name
&& self.parameters == other.parameters
@ -205,7 +210,11 @@ impl FunctionDefinition {
{
Ok(())
} else {
Err(EqualsIssue::ConflictingImports)
Err(EqualsIssue::AlreadyExtern(
self.name.clone(),
self.signature(),
))
}
}
}
}