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