1
- #[ llvm_versions( 7.0 ..=latest) ]
2
- use either:: Either ;
3
1
use llvm_sys:: target:: {
4
2
LLVMABIAlignmentOfType , LLVMABISizeOfType , LLVMByteOrder , LLVMByteOrdering ,
5
3
LLVMCallFrameAlignmentOfType , LLVMCopyStringRepOfTargetData , LLVMCreateTargetData ,
@@ -35,6 +33,7 @@ use crate::{AddressSpace, OptimizationLevel};
35
33
36
34
use std:: default:: Default ;
37
35
use std:: ffi:: { CStr , CString } ;
36
+ use std:: fmt;
38
37
use std:: mem:: MaybeUninit ;
39
38
use std:: path:: Path ;
40
39
use std:: ptr;
@@ -96,6 +95,53 @@ impl Default for InitializationConfig {
96
95
}
97
96
}
98
97
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
+
99
145
static TARGET_LOCK : Lazy < RwLock < ( ) > > = Lazy :: new ( || RwLock :: new ( ( ) ) ) ;
100
146
101
147
// NOTE: Versions verified as target-complete: 3.6, 3.7, 3.8, 3.9, 4.0
@@ -858,14 +904,13 @@ impl Target {
858
904
859
905
pub fn create_target_machine (
860
906
& self ,
861
- triple : & str ,
907
+ triple : & TargetTriple ,
862
908
cpu : & str ,
863
909
features : & str ,
864
910
level : OptimizationLevel ,
865
911
reloc_mode : RelocMode ,
866
912
code_model : CodeModel ,
867
913
) -> Option < TargetMachine > {
868
- let triple = CString :: new ( triple) . expect ( "Conversion to CString failed unexpectedly" ) ;
869
914
let cpu = CString :: new ( cpu) . expect ( "Conversion to CString failed unexpectedly" ) ;
870
915
let features = CString :: new ( features) . expect ( "Conversion to CString failed unexpectedly" ) ;
871
916
let level = match level {
@@ -957,14 +1002,13 @@ impl Target {
957
1002
Some ( Target :: new ( target) )
958
1003
}
959
1004
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 > {
962
1006
let mut target = ptr:: null_mut ( ) ;
963
1007
let mut err_string = MaybeUninit :: uninit ( ) ;
964
1008
965
1009
let code = {
966
1010
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 ( ) ) }
968
1012
} ;
969
1013
970
1014
if code == 1 {
@@ -1006,10 +1050,10 @@ impl TargetMachine {
1006
1050
Target :: new ( target)
1007
1051
}
1008
1052
1009
- pub fn get_triple ( & self ) -> LLVMString {
1053
+ pub fn get_triple ( & self ) -> TargetTriple {
1010
1054
let ptr = unsafe { LLVMGetTargetMachineTriple ( self . target_machine ) } ;
1011
1055
1012
- LLVMString :: new ( ptr)
1056
+ TargetTriple :: new ( LLVMString :: new ( ptr) )
1013
1057
}
1014
1058
1015
1059
/// Gets the default triple for the current system.
@@ -1023,31 +1067,21 @@ impl TargetMachine {
1023
1067
///
1024
1068
/// let default_triple = TargetMachine::get_default_triple();
1025
1069
///
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 ());
1027
1071
/// ```
1028
- pub fn get_default_triple ( ) -> LLVMString {
1072
+ pub fn get_default_triple ( ) -> TargetTriple {
1029
1073
let llvm_string = unsafe { LLVMGetDefaultTargetTriple ( ) } ;
1030
1074
1031
- LLVMString :: new ( llvm_string)
1075
+ TargetTriple :: new ( LLVMString :: new ( llvm_string) )
1032
1076
}
1033
1077
1034
1078
#[ llvm_versions( 7.0 ..=latest) ]
1035
- pub fn normalize_target_triple ( triple : Either < & str , & CStr > ) -> LLVMString {
1079
+ pub fn normalize_triple ( triple : & TargetTriple ) -> TargetTriple {
1036
1080
use llvm_sys:: target_machine:: LLVMNormalizeTargetTriple ;
1037
1081
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 ( ) ) } ;
1042
1083
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) )
1051
1085
}
1052
1086
1053
1087
/// Gets a string containing the host CPU's name (triple).
@@ -1112,15 +1146,23 @@ impl TargetMachine {
1112
1146
/// ```no_run
1113
1147
/// use inkwell::OptimizationLevel;
1114
1148
/// 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};
1116
1150
///
1117
1151
/// Target::initialize_x86(&InitializationConfig::default());
1118
1152
///
1119
1153
/// let opt = OptimizationLevel::Default;
1120
1154
/// let reloc = RelocMode::Default;
1121
1155
/// let model = CodeModel::Default;
1122
1156
/// 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();
1124
1166
///
1125
1167
/// let context = Context::create();
1126
1168
/// let module = context.create_module("my_module");
@@ -1166,7 +1208,7 @@ impl TargetMachine {
1166
1208
/// ```no_run
1167
1209
/// use inkwell::OptimizationLevel;
1168
1210
/// 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};
1170
1212
///
1171
1213
/// use std::path::Path;
1172
1214
///
@@ -1177,7 +1219,15 @@ impl TargetMachine {
1177
1219
/// let model = CodeModel::Default;
1178
1220
/// let path = Path::new("/tmp/some/path/main.asm");
1179
1221
/// 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();
1181
1231
///
1182
1232
/// let context = Context::create();
1183
1233
/// let module = context.create_module("my_module");
0 commit comments