1 use std::borrow::Cow; 2 use std::ffi::CString; 3 use std::path::Path; 4 5 use crate::fluent_generated as fluent; 6 use rustc_data_structures::small_c_str::SmallCStr; 7 use rustc_errors::{ 8 DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic, 9 }; 10 use rustc_macros::{Diagnostic, Subdiagnostic}; 11 use rustc_span::Span; 12 13 #[derive(Diagnostic)] 14 #[diag(codegen_llvm_unknown_ctarget_feature_prefix)] 15 #[note] 16 pub(crate) struct UnknownCTargetFeaturePrefix<'a> { 17 pub feature: &'a str, 18 } 19 20 #[derive(Diagnostic)] 21 #[diag(codegen_llvm_unknown_ctarget_feature)] 22 #[note] 23 pub(crate) struct UnknownCTargetFeature<'a> { 24 pub feature: &'a str, 25 #[subdiagnostic] 26 pub rust_feature: PossibleFeature<'a>, 27 } 28 29 #[derive(Subdiagnostic)] 30 pub(crate) enum PossibleFeature<'a> { 31 #[help(codegen_llvm_possible_feature)] 32 Some { rust_feature: &'a str }, 33 #[help(codegen_llvm_consider_filing_feature_request)] 34 None, 35 } 36 37 #[derive(Diagnostic)] 38 #[diag(codegen_llvm_error_creating_import_library)] 39 pub(crate) struct ErrorCreatingImportLibrary<'a> { 40 pub lib_name: &'a str, 41 pub error: String, 42 } 43 44 #[derive(Diagnostic)] 45 #[diag(codegen_llvm_symbol_already_defined)] 46 pub(crate) struct SymbolAlreadyDefined<'a> { 47 #[primary_span] 48 pub span: Span, 49 pub symbol_name: &'a str, 50 } 51 52 #[derive(Diagnostic)] 53 #[diag(codegen_llvm_invalid_minimum_alignment_not_power_of_two)] 54 pub(crate) struct InvalidMinimumAlignmentNotPowerOfTwo { 55 pub align: u64, 56 } 57 58 #[derive(Diagnostic)] 59 #[diag(codegen_llvm_invalid_minimum_alignment_too_large)] 60 pub(crate) struct InvalidMinimumAlignmentTooLarge { 61 pub align: u64, 62 } 63 64 #[derive(Diagnostic)] 65 #[diag(codegen_llvm_sanitizer_memtag_requires_mte)] 66 pub(crate) struct SanitizerMemtagRequiresMte; 67 68 #[derive(Diagnostic)] 69 #[diag(codegen_llvm_error_writing_def_file)] 70 pub(crate) struct ErrorWritingDEFFile { 71 pub error: std::io::Error, 72 } 73 74 #[derive(Diagnostic)] 75 #[diag(codegen_llvm_error_calling_dlltool)] 76 pub(crate) struct ErrorCallingDllTool<'a> { 77 pub dlltool_path: Cow<'a, str>, 78 pub error: std::io::Error, 79 } 80 81 #[derive(Diagnostic)] 82 #[diag(codegen_llvm_dlltool_fail_import_library)] 83 pub(crate) struct DlltoolFailImportLibrary<'a> { 84 pub stdout: Cow<'a, str>, 85 pub stderr: Cow<'a, str>, 86 } 87 88 #[derive(Diagnostic)] 89 #[diag(codegen_llvm_dynamic_linking_with_lto)] 90 #[note] 91 pub(crate) struct DynamicLinkingWithLTO; 92 93 pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>); 94 95 impl<EM: EmissionGuarantee> IntoDiagnostic<'_, EM> for ParseTargetMachineConfig<'_> { into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, EM>96 fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, EM> { 97 let diag: DiagnosticBuilder<'_, EM> = self.0.into_diagnostic(sess); 98 let (message, _) = diag.styled_message().first().expect("`LlvmError` with no message"); 99 let message = sess.eagerly_translate_to_string(message.clone(), diag.args()); 100 101 let mut diag = sess.struct_diagnostic(fluent::codegen_llvm_parse_target_machine_config); 102 diag.set_arg("error", message); 103 diag 104 } 105 } 106 107 pub(crate) struct TargetFeatureDisableOrEnable<'a> { 108 pub features: &'a [&'a str], 109 pub span: Option<Span>, 110 pub missing_features: Option<MissingFeatures>, 111 } 112 113 #[derive(Subdiagnostic)] 114 #[help(codegen_llvm_missing_features)] 115 pub(crate) struct MissingFeatures; 116 117 impl IntoDiagnostic<'_, ErrorGuaranteed> for TargetFeatureDisableOrEnable<'_> { into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed>118 fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { 119 let mut diag = sess.struct_err(fluent::codegen_llvm_target_feature_disable_or_enable); 120 if let Some(span) = self.span { 121 diag.set_span(span); 122 }; 123 if let Some(missing_features) = self.missing_features { 124 diag.subdiagnostic(missing_features); 125 } 126 diag.set_arg("features", self.features.join(", ")); 127 diag 128 } 129 } 130 131 #[derive(Diagnostic)] 132 #[diag(codegen_llvm_lto_disallowed)] 133 pub(crate) struct LtoDisallowed; 134 135 #[derive(Diagnostic)] 136 #[diag(codegen_llvm_lto_dylib)] 137 pub(crate) struct LtoDylib; 138 139 #[derive(Diagnostic)] 140 #[diag(codegen_llvm_lto_bitcode_from_rlib)] 141 pub(crate) struct LtoBitcodeFromRlib { 142 pub llvm_err: String, 143 } 144 145 #[derive(Diagnostic)] 146 pub enum LlvmError<'a> { 147 #[diag(codegen_llvm_write_output)] 148 WriteOutput { path: &'a Path }, 149 #[diag(codegen_llvm_target_machine)] 150 CreateTargetMachine { triple: SmallCStr }, 151 #[diag(codegen_llvm_run_passes)] 152 RunLlvmPasses, 153 #[diag(codegen_llvm_serialize_module)] 154 SerializeModule { name: &'a str }, 155 #[diag(codegen_llvm_write_ir)] 156 WriteIr { path: &'a Path }, 157 #[diag(codegen_llvm_prepare_thin_lto_context)] 158 PrepareThinLtoContext, 159 #[diag(codegen_llvm_load_bitcode)] 160 LoadBitcode { name: CString }, 161 #[diag(codegen_llvm_write_thinlto_key)] 162 WriteThinLtoKey { err: std::io::Error }, 163 #[diag(codegen_llvm_multiple_source_dicompileunit)] 164 MultipleSourceDiCompileUnit, 165 #[diag(codegen_llvm_prepare_thin_lto_module)] 166 PrepareThinLtoModule, 167 #[diag(codegen_llvm_parse_bitcode)] 168 ParseBitcode, 169 } 170 171 pub(crate) struct WithLlvmError<'a>(pub LlvmError<'a>, pub String); 172 173 impl<EM: EmissionGuarantee> IntoDiagnostic<'_, EM> for WithLlvmError<'_> { into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, EM>174 fn into_diagnostic(self, sess: &'_ Handler) -> DiagnosticBuilder<'_, EM> { 175 use LlvmError::*; 176 let msg_with_llvm_err = match &self.0 { 177 WriteOutput { .. } => fluent::codegen_llvm_write_output_with_llvm_err, 178 CreateTargetMachine { .. } => fluent::codegen_llvm_target_machine_with_llvm_err, 179 RunLlvmPasses => fluent::codegen_llvm_run_passes_with_llvm_err, 180 SerializeModule { .. } => fluent::codegen_llvm_serialize_module_with_llvm_err, 181 WriteIr { .. } => fluent::codegen_llvm_write_ir_with_llvm_err, 182 PrepareThinLtoContext => fluent::codegen_llvm_prepare_thin_lto_context_with_llvm_err, 183 LoadBitcode { .. } => fluent::codegen_llvm_load_bitcode_with_llvm_err, 184 WriteThinLtoKey { .. } => fluent::codegen_llvm_write_thinlto_key_with_llvm_err, 185 MultipleSourceDiCompileUnit => { 186 fluent::codegen_llvm_multiple_source_dicompileunit_with_llvm_err 187 } 188 PrepareThinLtoModule => fluent::codegen_llvm_prepare_thin_lto_module_with_llvm_err, 189 ParseBitcode => fluent::codegen_llvm_parse_bitcode_with_llvm_err, 190 }; 191 let mut diag = self.0.into_diagnostic(sess); 192 diag.set_primary_message(msg_with_llvm_err); 193 diag.set_arg("llvm_err", self.1); 194 diag 195 } 196 } 197 198 #[derive(Diagnostic)] 199 #[diag(codegen_llvm_from_llvm_optimization_diag)] 200 pub(crate) struct FromLlvmOptimizationDiag<'a> { 201 pub filename: &'a str, 202 pub line: std::ffi::c_uint, 203 pub column: std::ffi::c_uint, 204 pub pass_name: &'a str, 205 pub kind: &'a str, 206 pub message: &'a str, 207 } 208 209 #[derive(Diagnostic)] 210 #[diag(codegen_llvm_from_llvm_diag)] 211 pub(crate) struct FromLlvmDiag { 212 pub message: String, 213 } 214 215 #[derive(Diagnostic)] 216 #[diag(codegen_llvm_write_bytecode)] 217 pub(crate) struct WriteBytecode<'a> { 218 pub path: &'a Path, 219 pub err: std::io::Error, 220 } 221 222 #[derive(Diagnostic)] 223 #[diag(codegen_llvm_copy_bitcode)] 224 pub(crate) struct CopyBitcode { 225 pub err: std::io::Error, 226 } 227