Use AvailableExternally-linkage for externs for imports
This commit is contained in:
parent
6f8c02ac04
commit
6788ef1690
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ impl FunctionDefinition {
|
||||
scope.return_type_hint = Some(self.return_type.clone());
|
||||
block.pass(pass, state, scope);
|
||||
}
|
||||
FunctionDefinitionKind::Extern => {}
|
||||
FunctionDefinitionKind::Extern(_) => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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)))
|
||||
}
|
||||
};
|
||||
|
@ -64,7 +64,7 @@ impl FunctionDefinition {
|
||||
ret_ty.narrow(&scope_hints.from_type(&self.return_type).unwrap());
|
||||
}
|
||||
}
|
||||
FunctionDefinitionKind::Extern => {}
|
||||
FunctionDefinitionKind::Extern(_) => {}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
|
@ -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(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user