Skip to content

Commit 8434933

Browse files
authored
Merge pull request rust-lang#152 from willtunnels/set_target-fix
Set target fix
2 parents af4cf4e + a7ec1f1 commit 8434933

File tree

5 files changed

+161
-81
lines changed

5 files changed

+161
-81
lines changed

src/module.rs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use llvm_sys::LLVMLinkage;
1616
use llvm_sys::LLVMModuleFlagBehavior;
1717

1818
use std::cell::{Cell, RefCell, Ref};
19-
#[llvm_versions(3.9..=latest)]
2019
use std::ffi::CStr;
2120
use std::ffi::CString;
2221
use std::fs::File;
@@ -35,7 +34,7 @@ use crate::data_layout::DataLayout;
3534
use crate::execution_engine::ExecutionEngine;
3635
use crate::memory_buffer::MemoryBuffer;
3736
use crate::support::LLVMString;
38-
use crate::targets::{Target, InitializationConfig};
37+
use crate::targets::{InitializationConfig, Target, TargetTriple};
3938
use crate::types::{AsTypeRef, BasicType, FunctionType, BasicTypeEnum};
4039
use crate::values::{AsValueRef, FunctionValue, GlobalValue, MetadataValue};
4140
#[llvm_versions(7.0..=latest)]
@@ -321,59 +320,58 @@ impl<'ctx> Module<'ctx> {
321320
Some(BasicTypeEnum::new(type_))
322321
}
323322

324-
/// Sets a `Target` to this `Module`.
323+
/// Assigns a `TargetTriple` to this `Module`.
325324
///
326325
/// # Example
327326
///
328327
/// ```rust,no_run
329328
/// use inkwell::context::Context;
330-
/// use inkwell::targets::Target;
329+
/// use inkwell::targets::{Target, TargetTriple};
331330
///
332331
/// Target::initialize_x86(&Default::default());
333-
///
334332
/// let context = Context::create();
335333
/// let module = context.create_module("mod");
336-
/// let target = Target::from_name("x86-64").unwrap();
334+
/// let triple = TargetTriple::create("x86_64-pc-linux-gnu");
337335
///
338-
/// assert!(module.get_target().is_none());
336+
/// assert_eq!(module.get_triple(), TargetTriple::create(""));
339337
///
340-
/// module.set_target(&target);
338+
/// module.set_triple(&triple);
341339
///
342-
/// assert_eq!(module.get_target().unwrap(), target);
340+
/// assert_eq!(module.get_triple(), triple);
343341
/// ```
344-
pub fn set_target(&self, target: &Target) {
342+
pub fn set_triple(&self, triple: &TargetTriple) {
345343
unsafe {
346-
LLVMSetTarget(self.module.get(), target.get_name().as_ptr())
344+
LLVMSetTarget(self.module.get(), triple.as_ptr())
347345
}
348346
}
349347

350-
/// Gets the `Target` assigned to this `Module`, if any.
348+
/// Gets the `TargetTriple` assigned to this `Module`. If none has been
349+
/// assigned, the triple will default to "".
351350
///
352351
/// # Example
353352
///
354353
/// ```rust,no_run
355354
/// use inkwell::context::Context;
356-
/// use inkwell::targets::Target;
355+
/// use inkwell::targets::{Target, TargetTriple};
357356
///
358357
/// Target::initialize_x86(&Default::default());
359-
///
360358
/// let context = Context::create();
361359
/// let module = context.create_module("mod");
362-
/// let target = Target::from_name("x86-64").unwrap();
360+
/// let triple = TargetTriple::create("x86_64-pc-linux-gnu");
363361
///
364-
/// assert!(module.get_target().is_none());
362+
/// assert_eq!(module.get_triple(), TargetTriple::create(""));
365363
///
366-
/// module.set_target(&target);
364+
/// module.set_triple(&triple);
367365
///
368-
/// assert_eq!(module.get_target().unwrap(), target);
366+
/// assert_eq!(module.get_triple(), triple);
369367
/// ```
370-
pub fn get_target(&self) -> Option<Target> {
368+
pub fn get_triple(&self) -> TargetTriple {
371369
// REVIEW: This isn't an owned LLVMString, is it? If so, need to deallocate.
372370
let target_str = unsafe {
373371
LLVMGetTarget(self.module.get())
374372
};
375373

376-
Target::from_name_raw(target_str)
374+
TargetTriple::new(LLVMString::create_from_c_str(unsafe { CStr::from_ptr(target_str) }))
377375
}
378376

379377
/// Creates an `ExecutionEngine` from this `Module`.
@@ -398,12 +396,12 @@ impl<'ctx> Module<'ctx> {
398396
.map_err(|mut err_string| {
399397
err_string.push('\0');
400398

401-
LLVMString::create(&err_string)
399+
LLVMString::create_from_str(&err_string)
402400
})?;
403401

404402
if self.owned_by_ee.borrow().is_some() {
405403
let string = "This module is already owned by an ExecutionEngine.\0";
406-
return Err(LLVMString::create(string));
404+
return Err(LLVMString::create_from_str(string));
407405
}
408406

409407
let mut execution_engine = MaybeUninit::uninit();
@@ -449,12 +447,12 @@ impl<'ctx> Module<'ctx> {
449447
.map_err(|mut err_string| {
450448
err_string.push('\0');
451449

452-
LLVMString::create(&err_string)
450+
LLVMString::create_from_str(&err_string)
453451
})?;
454452

455453
if self.owned_by_ee.borrow().is_some() {
456454
let string = "This module is already owned by an ExecutionEngine.\0";
457-
return Err(LLVMString::create(string));
455+
return Err(LLVMString::create_from_str(string));
458456
}
459457

460458
let mut execution_engine = MaybeUninit::uninit();
@@ -502,12 +500,12 @@ impl<'ctx> Module<'ctx> {
502500
.map_err(|mut err_string| {
503501
err_string.push('\0');
504502

505-
LLVMString::create(&err_string)
503+
LLVMString::create_from_str(&err_string)
506504
})?;
507505

508506
if self.owned_by_ee.borrow().is_some() {
509507
let string = "This module is already owned by an ExecutionEngine.\0";
510-
return Err(LLVMString::create(string));
508+
return Err(LLVMString::create_from_str(string));
511509
}
512510

513511
let mut execution_engine = MaybeUninit::uninit();
@@ -1212,7 +1210,7 @@ impl<'ctx> Module<'ctx> {
12121210
pub fn link_in_module(&self, other: Self) -> Result<(), LLVMString> {
12131211
if other.owned_by_ee.borrow().is_some() {
12141212
let string = "Cannot link a module which is already owned by an ExecutionEngine.\0";
1215-
return Err(LLVMString::create(string));
1213+
return Err(LLVMString::create_from_str(string));
12161214
}
12171215

12181216
#[cfg(any(feature = "llvm3-6", feature = "llvm3-7"))]

src/support/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,16 @@ impl LLVMString {
3333
}
3434

3535
/// This method will allocate a c string through LLVM
36-
pub(crate) fn create(string: &str) -> LLVMString {
36+
pub(crate) fn create_from_c_str(string: &CStr) -> LLVMString {
37+
let ptr = unsafe {
38+
LLVMCreateMessage(string.as_ptr() as *const _)
39+
};
40+
41+
LLVMString::new(ptr)
42+
}
43+
44+
/// This method will allocate a c string through LLVM
45+
pub(crate) fn create_from_str(string: &str) -> LLVMString {
3746
debug_assert_eq!(string.as_bytes()[string.as_bytes().len() - 1], 0);
3847

3948
let ptr = unsafe {

src/targets.rs

Lines changed: 79 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#[llvm_versions(7.0..=latest)]
2-
use either::Either;
31
use llvm_sys::target::{
42
LLVMABIAlignmentOfType, LLVMABISizeOfType, LLVMByteOrder, LLVMByteOrdering,
53
LLVMCallFrameAlignmentOfType, LLVMCopyStringRepOfTargetData, LLVMCreateTargetData,
@@ -35,6 +33,7 @@ use crate::{AddressSpace, OptimizationLevel};
3533

3634
use std::default::Default;
3735
use std::ffi::{CStr, CString};
36+
use std::fmt;
3837
use std::mem::MaybeUninit;
3938
use std::path::Path;
4039
use std::ptr;
@@ -96,6 +95,53 @@ impl Default for InitializationConfig {
9695
}
9796
}
9897

98+
#[derive(Eq)]
99+
pub struct TargetTriple {
100+
pub(crate) triple: LLVMString,
101+
}
102+
103+
impl TargetTriple {
104+
pub(crate) fn new(triple: LLVMString) -> TargetTriple {
105+
TargetTriple {
106+
triple,
107+
}
108+
}
109+
110+
pub fn create(triple: &str) -> TargetTriple {
111+
let c_string = CString::new(triple).expect("Conversion to CString failed unexpectedly");
112+
113+
TargetTriple {
114+
triple: LLVMString::create_from_c_str(c_string.as_c_str())
115+
}
116+
}
117+
118+
pub fn as_str(&self) -> &CStr {
119+
unsafe { CStr::from_ptr(self.as_ptr()) }
120+
}
121+
122+
pub fn as_ptr(&self) -> *const ::libc::c_char {
123+
self.triple.as_ptr()
124+
}
125+
}
126+
127+
impl PartialEq for TargetTriple {
128+
fn eq(&self, other: &TargetTriple) -> bool {
129+
self.triple == other.triple
130+
}
131+
}
132+
133+
impl fmt::Debug for TargetTriple {
134+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135+
write!(f, "TargetTriple({:?})", self.triple)
136+
}
137+
}
138+
139+
impl fmt::Display for TargetTriple {
140+
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
141+
write!(f, "TargetTriple({:?})", self.triple)
142+
}
143+
}
144+
99145
static TARGET_LOCK: Lazy<RwLock<()>> = Lazy::new(|| RwLock::new(()));
100146

101147
// NOTE: Versions verified as target-complete: 3.6, 3.7, 3.8, 3.9, 4.0
@@ -858,14 +904,13 @@ impl Target {
858904

859905
pub fn create_target_machine(
860906
&self,
861-
triple: &str,
907+
triple: &TargetTriple,
862908
cpu: &str,
863909
features: &str,
864910
level: OptimizationLevel,
865911
reloc_mode: RelocMode,
866912
code_model: CodeModel,
867913
) -> Option<TargetMachine> {
868-
let triple = CString::new(triple).expect("Conversion to CString failed unexpectedly");
869914
let cpu = CString::new(cpu).expect("Conversion to CString failed unexpectedly");
870915
let features = CString::new(features).expect("Conversion to CString failed unexpectedly");
871916
let level = match level {
@@ -957,14 +1002,13 @@ impl Target {
9571002
Some(Target::new(target))
9581003
}
9591004

960-
pub fn from_triple(triple: &str) -> Result<Self, LLVMString> {
961-
let c_string = CString::new(triple).expect("Conversion to CString failed unexpectedly");
1005+
pub fn from_triple(triple: &TargetTriple) -> Result<Self, LLVMString> {
9621006
let mut target = ptr::null_mut();
9631007
let mut err_string = MaybeUninit::uninit();
9641008

9651009
let code = {
9661010
let _guard = TARGET_LOCK.read();
967-
unsafe { LLVMGetTargetFromTriple(c_string.as_ptr(), &mut target, err_string.as_mut_ptr()) }
1011+
unsafe { LLVMGetTargetFromTriple(triple.as_ptr(), &mut target, err_string.as_mut_ptr()) }
9681012
};
9691013

9701014
if code == 1 {
@@ -1006,10 +1050,10 @@ impl TargetMachine {
10061050
Target::new(target)
10071051
}
10081052

1009-
pub fn get_triple(&self) -> LLVMString {
1053+
pub fn get_triple(&self) -> TargetTriple {
10101054
let ptr = unsafe { LLVMGetTargetMachineTriple(self.target_machine) };
10111055

1012-
LLVMString::new(ptr)
1056+
TargetTriple::new(LLVMString::new(ptr))
10131057
}
10141058

10151059
/// Gets the default triple for the current system.
@@ -1023,31 +1067,21 @@ impl TargetMachine {
10231067
///
10241068
/// let default_triple = TargetMachine::get_default_triple();
10251069
///
1026-
/// assert_eq!(*default_triple, *CString::new("x86_64-pc-linux-gnu").unwrap());
1070+
/// assert_eq!(default_triple.as_str(), CString::new("x86_64-pc-linux-gnu").unwrap().as_c_str());
10271071
/// ```
1028-
pub fn get_default_triple() -> LLVMString {
1072+
pub fn get_default_triple() -> TargetTriple {
10291073
let llvm_string = unsafe { LLVMGetDefaultTargetTriple() };
10301074

1031-
LLVMString::new(llvm_string)
1075+
TargetTriple::new(LLVMString::new(llvm_string))
10321076
}
10331077

10341078
#[llvm_versions(7.0..=latest)]
1035-
pub fn normalize_target_triple(triple: Either<&str, &CStr>) -> LLVMString {
1079+
pub fn normalize_triple(triple: &TargetTriple) -> TargetTriple {
10361080
use llvm_sys::target_machine::LLVMNormalizeTargetTriple;
10371081

1038-
let ptr = match triple {
1039-
Either::Left(triple_str) => {
1040-
let c_string =
1041-
CString::new(triple_str).expect("Conversion to CString failed unexpectedly");
1082+
let normalized = unsafe { LLVMNormalizeTargetTriple(triple.as_ptr()) };
10421083

1043-
unsafe { LLVMNormalizeTargetTriple(c_string.as_ptr()) }
1044-
}
1045-
Either::Right(triple_cstr) => unsafe {
1046-
LLVMNormalizeTargetTriple(triple_cstr.as_ptr())
1047-
},
1048-
};
1049-
1050-
LLVMString::new(ptr)
1084+
TargetTriple::new(LLVMString::new(normalized))
10511085
}
10521086

10531087
/// Gets a string containing the host CPU's name (triple).
@@ -1112,15 +1146,23 @@ impl TargetMachine {
11121146
/// ```no_run
11131147
/// use inkwell::OptimizationLevel;
11141148
/// use inkwell::context::Context;
1115-
/// use inkwell::targets::{CodeModel, RelocMode, FileType, Target, TargetMachine, InitializationConfig};
1149+
/// use inkwell::targets::{CodeModel, RelocMode, FileType, Target, TargetMachine, TargetTriple, InitializationConfig};
11161150
///
11171151
/// Target::initialize_x86(&InitializationConfig::default());
11181152
///
11191153
/// let opt = OptimizationLevel::Default;
11201154
/// let reloc = RelocMode::Default;
11211155
/// let model = CodeModel::Default;
11221156
/// let target = Target::from_name("x86-64").unwrap();
1123-
/// let target_machine = target.create_target_machine("x86_64-pc-linux-gnu", "x86-64", "+avx2", opt, reloc, model).unwrap();
1157+
/// let target_machine = target.create_target_machine(
1158+
/// &TargetTriple::create("x86_64-pc-linux-gnu"),
1159+
/// "x86-64",
1160+
/// "+avx2",
1161+
/// opt,
1162+
/// reloc,
1163+
/// model
1164+
/// )
1165+
/// .unwrap();
11241166
///
11251167
/// let context = Context::create();
11261168
/// let module = context.create_module("my_module");
@@ -1166,7 +1208,7 @@ impl TargetMachine {
11661208
/// ```no_run
11671209
/// use inkwell::OptimizationLevel;
11681210
/// use inkwell::context::Context;
1169-
/// use inkwell::targets::{CodeModel, RelocMode, FileType, Target, TargetMachine, InitializationConfig};
1211+
/// use inkwell::targets::{CodeModel, RelocMode, FileType, Target, TargetMachine, TargetTriple, InitializationConfig};
11701212
///
11711213
/// use std::path::Path;
11721214
///
@@ -1177,7 +1219,15 @@ impl TargetMachine {
11771219
/// let model = CodeModel::Default;
11781220
/// let path = Path::new("/tmp/some/path/main.asm");
11791221
/// let target = Target::from_name("x86-64").unwrap();
1180-
/// let target_machine = target.create_target_machine("x86_64-pc-linux-gnu", "x86-64", "+avx2", opt, reloc, model).unwrap();
1222+
/// let target_machine = target.create_target_machine(
1223+
/// &TargetTriple::create("x86_64-pc-linux-gnu"),
1224+
/// "x86-64",
1225+
/// "+avx2",
1226+
/// opt,
1227+
/// reloc,
1228+
/// model
1229+
/// )
1230+
/// .unwrap();
11811231
///
11821232
/// let context = Context::create();
11831233
/// let module = context.create_module("my_module");

0 commit comments

Comments
 (0)