Skip to content

Commit 696691e

Browse files
arielb1Ariel Ben-Yehuda
authored and
Ariel Ben-Yehuda
committedAug 3, 2016
audit LLVM C++ types in ArchiveWrapper and PassWrapper
1 parent 81df89f commit 696691e

File tree

8 files changed

+275
-114
lines changed

8 files changed

+275
-114
lines changed
 

‎src/librustc_llvm/lib.rs

+48-28
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,9 @@ pub use self::TypeKind::*;
4040
pub use self::AtomicBinOp::*;
4141
pub use self::AtomicOrdering::*;
4242
pub use self::SynchronizationScope::*;
43-
pub use self::FileType::*;
4443
pub use self::MetadataType::*;
4544
pub use self::AsmDialect::*;
46-
pub use self::CodeGenOptLevel::*;
4745
pub use self::CodeGenOptSize::*;
48-
pub use self::RelocMode::*;
49-
pub use self::CodeGenModel::*;
5046
pub use self::DiagnosticKind::*;
5147
pub use self::CallConv::*;
5248
pub use self::Visibility::*;
@@ -75,9 +71,26 @@ pub type Bool = c_uint;
7571
pub const True: Bool = 1 as Bool;
7672
pub const False: Bool = 0 as Bool;
7773

74+
#[repr(C)]
75+
#[derive(Copy, Clone, PartialEq)]
76+
pub enum LLVMRustResult {
77+
Success = 0,
78+
Failure = 1
79+
}
80+
81+
impl LLVMRustResult {
82+
pub fn into_result(self) -> Result<(), ()> {
83+
match self {
84+
LLVMRustResult::Success => Ok(()),
85+
LLVMRustResult::Failure => Err(()),
86+
}
87+
}
88+
}
89+
7890
// Consts for the LLVM CallConv type, pre-cast to usize.
7991

8092
#[derive(Copy, Clone, PartialEq)]
93+
#[repr(C)]
8194
pub enum CallConv {
8295
CCallConv = 0,
8396
FastCallConv = 8,
@@ -89,6 +102,7 @@ pub enum CallConv {
89102
}
90103

91104
#[derive(Copy, Clone)]
105+
#[repr(C)]
92106
pub enum Visibility {
93107
LLVMDefaultVisibility = 0,
94108
HiddenVisibility = 1,
@@ -100,6 +114,7 @@ pub enum Visibility {
100114
// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
101115
// they've been removed in upstream LLVM commit r203866.
102116
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
117+
#[repr(C)]
103118
pub enum Linkage {
104119
ExternalLinkage = 0,
105120
AvailableExternallyLinkage = 1,
@@ -337,12 +352,12 @@ pub enum SynchronizationScope {
337352
CrossThread = 1
338353
}
339354

340-
// Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
341355
#[repr(C)]
342356
#[derive(Copy, Clone)]
343357
pub enum FileType {
344-
AssemblyFileType = 0,
345-
ObjectFileType = 1
358+
Other,
359+
AssemblyFile,
360+
ObjectFile,
346361
}
347362

348363
#[derive(Copy, Clone)]
@@ -371,10 +386,11 @@ pub enum AsmDialect {
371386
#[derive(Copy, Clone, PartialEq)]
372387
#[repr(C)]
373388
pub enum CodeGenOptLevel {
374-
CodeGenLevelNone = 0,
375-
CodeGenLevelLess = 1,
376-
CodeGenLevelDefault = 2,
377-
CodeGenLevelAggressive = 3,
389+
Other,
390+
None,
391+
Less,
392+
Default,
393+
Aggressive,
378394
}
379395

380396
#[derive(Copy, Clone, PartialEq)]
@@ -388,21 +404,22 @@ pub enum CodeGenOptSize {
388404
#[derive(Copy, Clone, PartialEq)]
389405
#[repr(C)]
390406
pub enum RelocMode {
391-
RelocDefault = 0,
392-
RelocStatic = 1,
393-
RelocPIC = 2,
394-
RelocDynamicNoPic = 3,
407+
Default = 0,
408+
Static = 1,
409+
PIC = 2,
410+
DynamicNoPic = 3,
395411
}
396412

397413
#[repr(C)]
398414
#[derive(Copy, Clone)]
399-
pub enum CodeGenModel {
400-
CodeModelDefault = 0,
401-
CodeModelJITDefault = 1,
402-
CodeModelSmall = 2,
403-
CodeModelKernel = 3,
404-
CodeModelMedium = 4,
405-
CodeModelLarge = 5,
415+
pub enum CodeModel {
416+
Other,
417+
Default,
418+
JITDefault,
419+
Small,
420+
Kernel,
421+
Medium,
422+
Large,
406423
}
407424

408425
#[repr(C)]
@@ -421,6 +438,7 @@ pub enum DiagnosticKind {
421438
#[repr(C)]
422439
#[derive(Copy, Clone)]
423440
pub enum ArchiveKind {
441+
Other,
424442
K_GNU,
425443
K_MIPS64,
426444
K_BSD,
@@ -444,10 +462,10 @@ impl FromStr for ArchiveKind {
444462
/// Represents the different LLVM passes Rust supports
445463
#[derive(Copy, Clone, PartialEq, Debug)]
446464
#[repr(C)]
447-
pub enum SupportedPassKind {
465+
pub enum PassKind {
466+
Other,
448467
Function,
449468
Module,
450-
Unsupported,
451469
}
452470

453471
// Opaque pointer types
@@ -2021,7 +2039,7 @@ extern {
20212039
pub fn LLVMIsAAllocaInst(value_ref: ValueRef) -> ValueRef;
20222040
pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
20232041

2024-
pub fn LLVMRustPassKind(Pass: PassRef) -> SupportedPassKind;
2042+
pub fn LLVMRustPassKind(Pass: PassRef) -> PassKind;
20252043
pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> PassRef;
20262044
pub fn LLVMRustAddPass(PM: PassManagerRef, Pass: PassRef);
20272045

@@ -2031,7 +2049,7 @@ extern {
20312049
pub fn LLVMRustCreateTargetMachine(Triple: *const c_char,
20322050
CPU: *const c_char,
20332051
Features: *const c_char,
2034-
Model: CodeGenModel,
2052+
Model: CodeModel,
20352053
Reloc: RelocMode,
20362054
Level: CodeGenOptLevel,
20372055
UseSoftFP: bool,
@@ -2057,7 +2075,8 @@ extern {
20572075
PM: PassManagerRef,
20582076
M: ModuleRef,
20592077
Output: *const c_char,
2060-
FileType: FileType) -> bool;
2078+
FileType: FileType)
2079+
-> LLVMRustResult;
20612080
pub fn LLVMRustPrintModule(PM: PassManagerRef,
20622081
M: ModuleRef,
20632082
Output: *const c_char);
@@ -2123,7 +2142,8 @@ extern {
21232142
NumMembers: size_t,
21242143
Members: *const RustArchiveMemberRef,
21252144
WriteSymbtab: bool,
2126-
Kind: ArchiveKind) -> c_int;
2145+
Kind: ArchiveKind) ->
2146+
LLVMRustResult;
21272147
pub fn LLVMRustArchiveMemberNew(Filename: *const c_char,
21282148
Name: *const c_char,
21292149
Child: ArchiveChildRef) -> RustArchiveMemberRef;

‎src/librustc_trans/back/archive.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ impl<'a> ArchiveBuilder<'a> {
293293
members.as_ptr(),
294294
self.should_update_symbols,
295295
kind);
296-
let ret = if r != 0 {
296+
let ret = if r.into_result().is_err() {
297297
let err = llvm::LLVMRustGetLastError();
298298
let msg = if err.is_null() {
299299
"failed to write archive".to_string()

‎src/librustc_trans/back/write.rs

+25-21
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ pub fn write_output_file(
5454
let output_c = path2cstr(output);
5555
let result = llvm::LLVMRustWriteOutputFile(
5656
target, pm, m, output_c.as_ptr(), file_type);
57-
if !result {
57+
if result.into_result().is_err() {
5858
llvm_err(handler, format!("could not write output to {}", output.display()));
5959
}
6060
}
@@ -138,11 +138,11 @@ fn target_feature(sess: &Session) -> String {
138138

139139
fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
140140
match optimize {
141-
config::OptLevel::No => llvm::CodeGenLevelNone,
142-
config::OptLevel::Less => llvm::CodeGenLevelLess,
143-
config::OptLevel::Default => llvm::CodeGenLevelDefault,
144-
config::OptLevel::Aggressive => llvm::CodeGenLevelAggressive,
145-
_ => llvm::CodeGenLevelDefault,
141+
config::OptLevel::No => llvm::CodeGenOptLevel::None,
142+
config::OptLevel::Less => llvm::CodeGenOptLevel::Less,
143+
config::OptLevel::Default => llvm::CodeGenOptLevel::Default,
144+
config::OptLevel::Aggressive => llvm::CodeGenOptLevel::Aggressive,
145+
_ => llvm::CodeGenOptLevel::Default,
146146
}
147147
}
148148

@@ -169,11 +169,11 @@ pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
169169
};
170170

171171
let code_model = match code_model_arg {
172-
"default" => llvm::CodeModelDefault,
173-
"small" => llvm::CodeModelSmall,
174-
"kernel" => llvm::CodeModelKernel,
175-
"medium" => llvm::CodeModelMedium,
176-
"large" => llvm::CodeModelLarge,
172+
"default" => llvm::CodeModel::Default,
173+
"small" => llvm::CodeModel::Small,
174+
"kernel" => llvm::CodeModel::Kernel,
175+
"medium" => llvm::CodeModel::Medium,
176+
"large" => llvm::CodeModel::Large,
177177
_ => {
178178
sess.err(&format!("{:?} is not a valid code model",
179179
sess.opts
@@ -449,9 +449,9 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
449449
return false;
450450
}
451451
let pass_manager = match llvm::LLVMRustPassKind(pass) {
452-
llvm::SupportedPassKind::Function => fpm,
453-
llvm::SupportedPassKind::Module => mpm,
454-
llvm::SupportedPassKind::Unsupported => {
452+
llvm::PassKind::Function => fpm,
453+
llvm::PassKind::Module => mpm,
454+
llvm::PassKind::Other => {
455455
cgcx.handler.err("Encountered LLVM pass kind we can't handle");
456456
return true
457457
},
@@ -579,7 +579,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
579579
};
580580
with_codegen(tm, llmod, config.no_builtins, |cpm| {
581581
write_output_file(cgcx.handler, tm, cpm, llmod, &path,
582-
llvm::AssemblyFileType);
582+
llvm::FileType::AssemblyFile);
583583
});
584584
if config.emit_obj {
585585
llvm::LLVMDisposeModule(llmod);
@@ -588,7 +588,8 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
588588

589589
if write_obj {
590590
with_codegen(tm, llmod, config.no_builtins, |cpm| {
591-
write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out, llvm::ObjectFileType);
591+
write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out,
592+
llvm::FileType::ObjectFile);
592593
});
593594
}
594595
});
@@ -1078,7 +1079,7 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
10781079
// reasonable defaults and prepare it to actually populate the pass
10791080
// manager.
10801081
let builder = llvm::LLVMPassManagerBuilderCreate();
1081-
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenLevelNone);
1082+
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
10821083
let opt_size = config.opt_size.unwrap_or(llvm::CodeGenOptSizeNone);
10831084
let inline_threshold = config.inline_threshold;
10841085

@@ -1102,7 +1103,7 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
11021103
(_, _, Some(t)) => {
11031104
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t as u32);
11041105
}
1105-
(llvm::CodeGenLevelAggressive, _, _) => {
1106+
(llvm::CodeGenOptLevel::Aggressive, _, _) => {
11061107
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);
11071108
}
11081109
(_, llvm::CodeGenOptSizeDefault, _) => {
@@ -1111,15 +1112,18 @@ pub unsafe fn with_llvm_pmb(llmod: ModuleRef,
11111112
(_, llvm::CodeGenOptSizeAggressive, _) => {
11121113
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 25);
11131114
}
1114-
(llvm::CodeGenLevelNone, _, _) => {
1115+
(llvm::CodeGenOptLevel::None, _, _) => {
11151116
llvm::LLVMRustAddAlwaysInlinePass(builder, false);
11161117
}
1117-
(llvm::CodeGenLevelLess, _, _) => {
1118+
(llvm::CodeGenOptLevel::Less, _, _) => {
11181119
llvm::LLVMRustAddAlwaysInlinePass(builder, true);
11191120
}
1120-
(llvm::CodeGenLevelDefault, _, _) => {
1121+
(llvm::CodeGenOptLevel::Default, _, _) => {
11211122
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225);
11221123
}
1124+
(llvm::CodeGenOptLevel::Other, _, _) => {
1125+
bug!("CodeGenOptLevel::Other selected")
1126+
}
11231127
}
11241128

11251129
f(builder);

‎src/librustc_trans/context.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -325,10 +325,10 @@ pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode {
325325
};
326326

327327
match reloc_model_arg {
328-
"pic" => llvm::RelocPIC,
329-
"static" => llvm::RelocStatic,
330-
"default" => llvm::RelocDefault,
331-
"dynamic-no-pic" => llvm::RelocDynamicNoPic,
328+
"pic" => llvm::RelocMode::PIC,
329+
"static" => llvm::RelocMode::Static,
330+
"default" => llvm::RelocMode::Default,
331+
"dynamic-no-pic" => llvm::RelocMode::DynamicNoPic,
332332
_ => {
333333
sess.err(&format!("{:?} is not a valid relocation mode",
334334
sess.opts
@@ -347,7 +347,7 @@ fn is_any_library(sess: &Session) -> bool {
347347
}
348348

349349
pub fn is_pie_binary(sess: &Session) -> bool {
350-
!is_any_library(sess) && get_reloc_model(sess) == llvm::RelocPIC
350+
!is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC
351351
}
352352

353353
unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {

‎src/rustllvm/ArchiveWrapper.cpp

+65-33
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,62 @@
1616
using namespace llvm;
1717
using namespace llvm::object;
1818

19-
struct LLVMRustArchiveMember {
19+
struct RustArchiveMember {
2020
const char *filename;
2121
const char *name;
2222
Archive::Child child;
2323

24-
LLVMRustArchiveMember(): filename(NULL), name(NULL),
24+
RustArchiveMember(): filename(NULL), name(NULL),
2525
#if LLVM_VERSION_MINOR >= 8
2626
child(NULL, NULL, NULL)
2727
#else
2828
child(NULL, NULL)
2929
#endif
3030
{}
31-
~LLVMRustArchiveMember() {}
31+
~RustArchiveMember() {}
3232
};
3333

34-
typedef OwningBinary<Archive> RustArchive;
3534

36-
extern "C" void*
35+
struct RustArchiveIterator {
36+
Archive::child_iterator cur;
37+
Archive::child_iterator end;
38+
#if LLVM_VERSION_MINOR >= 9
39+
Error err;
40+
#endif
41+
};
42+
43+
enum class LLVMRustArchiveKind {
44+
Other,
45+
GNU,
46+
MIPS64,
47+
BSD,
48+
COFF,
49+
};
50+
51+
static Archive::Kind
52+
from_rust(LLVMRustArchiveKind kind)
53+
{
54+
switch (kind) {
55+
case LLVMRustArchiveKind::GNU:
56+
return Archive::K_GNU;
57+
case LLVMRustArchiveKind::MIPS64:
58+
return Archive::K_MIPS64;
59+
case LLVMRustArchiveKind::BSD:
60+
return Archive::K_BSD;
61+
case LLVMRustArchiveKind::COFF:
62+
return Archive::K_COFF;
63+
default:
64+
abort();
65+
}
66+
}
67+
68+
typedef OwningBinary<Archive> *LLVMRustArchiveRef;
69+
typedef RustArchiveMember *LLVMRustArchiveMemberRef;
70+
typedef Archive::Child *LLVMRustArchiveChildRef;
71+
typedef Archive::Child const *LLVMRustArchiveChildConstRef;
72+
typedef RustArchiveIterator *LLVMRustArchiveIteratorRef;
73+
74+
extern "C" LLVMRustArchiveRef
3775
LLVMRustOpenArchive(char *path) {
3876
ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
3977
-1,
@@ -66,20 +104,12 @@ LLVMRustOpenArchive(char *path) {
66104
}
67105

68106
extern "C" void
69-
LLVMRustDestroyArchive(RustArchive *ar) {
107+
LLVMRustDestroyArchive(LLVMRustArchiveRef ar) {
70108
delete ar;
71109
}
72110

73-
struct RustArchiveIterator {
74-
Archive::child_iterator cur;
75-
Archive::child_iterator end;
76-
#if LLVM_VERSION_MINOR >= 9
77-
Error err;
78-
#endif
79-
};
80-
81-
extern "C" RustArchiveIterator*
82-
LLVMRustArchiveIteratorNew(RustArchive *ra) {
111+
extern "C" LLVMRustArchiveIteratorRef
112+
LLVMRustArchiveIteratorNew(LLVMRustArchiveRef ra) {
83113
Archive *ar = ra->getBinary();
84114
RustArchiveIterator *rai = new RustArchiveIterator();
85115
#if LLVM_VERSION_MINOR <= 8
@@ -95,8 +125,8 @@ LLVMRustArchiveIteratorNew(RustArchive *ra) {
95125
return rai;
96126
}
97127

98-
extern "C" const Archive::Child*
99-
LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
128+
extern "C" LLVMRustArchiveChildConstRef
129+
LLVMRustArchiveIteratorNext(LLVMRustArchiveIteratorRef rai) {
100130
#if LLVM_VERSION_MINOR >= 9
101131
if (rai->err) {
102132
LLVMRustSetLastError(toString(std::move(rai->err)).c_str());
@@ -122,17 +152,17 @@ LLVMRustArchiveIteratorNext(RustArchiveIterator *rai) {
122152
}
123153

124154
extern "C" void
125-
LLVMRustArchiveChildFree(Archive::Child *child) {
155+
LLVMRustArchiveChildFree(LLVMRustArchiveChildRef child) {
126156
delete child;
127157
}
128158

129159
extern "C" void
130-
LLVMRustArchiveIteratorFree(RustArchiveIterator *rai) {
160+
LLVMRustArchiveIteratorFree(LLVMRustArchiveIteratorRef rai) {
131161
delete rai;
132162
}
133163

134164
extern "C" const char*
135-
LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
165+
LLVMRustArchiveChildName(LLVMRustArchiveChildConstRef child, size_t *size) {
136166
ErrorOr<StringRef> name_or_err = child->getName();
137167
if (name_or_err.getError())
138168
return NULL;
@@ -142,7 +172,7 @@ LLVMRustArchiveChildName(const Archive::Child *child, size_t *size) {
142172
}
143173

144174
extern "C" const char*
145-
LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
175+
LLVMRustArchiveChildData(LLVMRustArchiveChildRef child, size_t *size) {
146176
StringRef buf;
147177
ErrorOr<StringRef> buf_or_err = child->getBuffer();
148178
if (buf_or_err.getError()) {
@@ -154,9 +184,10 @@ LLVMRustArchiveChildData(Archive::Child *child, size_t *size) {
154184
return buf.data();
155185
}
156186

157-
extern "C" LLVMRustArchiveMember*
158-
LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) {
159-
LLVMRustArchiveMember *Member = new LLVMRustArchiveMember;
187+
extern "C" LLVMRustArchiveMemberRef
188+
LLVMRustArchiveMemberNew(char *Filename, char *Name,
189+
LLVMRustArchiveChildRef child) {
190+
RustArchiveMember *Member = new RustArchiveMember;
160191
Member->filename = Filename;
161192
Member->name = Name;
162193
if (child)
@@ -165,22 +196,23 @@ LLVMRustArchiveMemberNew(char *Filename, char *Name, Archive::Child *child) {
165196
}
166197

167198
extern "C" void
168-
LLVMRustArchiveMemberFree(LLVMRustArchiveMember *Member) {
199+
LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) {
169200
delete Member;
170201
}
171202

172-
extern "C" int
203+
extern "C" LLVMRustResult
173204
LLVMRustWriteArchive(char *Dst,
174205
size_t NumMembers,
175-
const LLVMRustArchiveMember **NewMembers,
206+
const LLVMRustArchiveMemberRef *NewMembers,
176207
bool WriteSymbtab,
177-
Archive::Kind Kind) {
208+
LLVMRustArchiveKind rust_kind) {
178209

179210
#if LLVM_VERSION_MINOR <= 8
180211
std::vector<NewArchiveIterator> Members;
181212
#else
182213
std::vector<NewArchiveMember> Members;
183214
#endif
215+
auto Kind = from_rust(rust_kind);
184216

185217
for (size_t i = 0; i < NumMembers; i++) {
186218
auto Member = NewMembers[i];
@@ -190,7 +222,7 @@ LLVMRustWriteArchive(char *Dst,
190222
Expected<NewArchiveMember> MOrErr = NewArchiveMember::getFile(Member->filename, true);
191223
if (!MOrErr) {
192224
LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
193-
return -1;
225+
return LLVMRustResult::Failure;
194226
}
195227
Members.push_back(std::move(*MOrErr));
196228
#elif LLVM_VERSION_MINOR == 8
@@ -205,7 +237,7 @@ LLVMRustWriteArchive(char *Dst,
205237
Expected<NewArchiveMember> MOrErr = NewArchiveMember::getOldMember(Member->child, true);
206238
if (!MOrErr) {
207239
LLVMRustSetLastError(toString(MOrErr.takeError()).c_str());
208-
return -1;
240+
return LLVMRustResult::Failure;
209241
}
210242
Members.push_back(std::move(*MOrErr));
211243
#endif
@@ -217,7 +249,7 @@ LLVMRustWriteArchive(char *Dst,
217249
auto pair = writeArchive(Dst, Members, WriteSymbtab, Kind, true);
218250
#endif
219251
if (!pair.second)
220-
return 0;
252+
return LLVMRustResult::Success;
221253
LLVMRustSetLastError(pair.second.message().c_str());
222-
return -1;
254+
return LLVMRustResult::Failure;
223255
}

‎src/rustllvm/PassWrapper.cpp

+112-26
Original file line numberDiff line numberDiff line change
@@ -54,41 +54,48 @@ LLVMInitializePasses() {
5454
initializeTarget(Registry);
5555
}
5656

57-
58-
enum class SupportedPassKind {
57+
enum class LLVMRustPassKind {
58+
Other,
5959
Function,
6060
Module,
61-
Unsupported
6261
};
6362

64-
extern "C" Pass*
63+
static LLVMRustPassKind
64+
to_rust(PassKind kind)
65+
{
66+
switch (kind) {
67+
case PT_Function:
68+
return LLVMRustPassKind::Function;
69+
case PT_Module:
70+
return LLVMRustPassKind::Module;
71+
default:
72+
return LLVMRustPassKind::Other;
73+
}
74+
}
75+
76+
extern "C" LLVMPassRef
6577
LLVMRustFindAndCreatePass(const char *PassName) {
6678
StringRef SR(PassName);
6779
PassRegistry *PR = PassRegistry::getPassRegistry();
6880

6981
const PassInfo *PI = PR->getPassInfo(SR);
7082
if (PI) {
71-
return PI->createPass();
83+
return wrap(PI->createPass());
7284
}
7385
return NULL;
7486
}
7587

76-
extern "C" SupportedPassKind
77-
LLVMRustPassKind(Pass *pass) {
78-
assert(pass);
79-
PassKind passKind = pass->getPassKind();
80-
if (passKind == PT_Module) {
81-
return SupportedPassKind::Module;
82-
} else if (passKind == PT_Function) {
83-
return SupportedPassKind::Function;
84-
} else {
85-
return SupportedPassKind::Unsupported;
86-
}
88+
extern "C" LLVMRustPassKind
89+
LLVMRustPassKind(LLVMPassRef rust_pass) {
90+
assert(rust_pass);
91+
Pass *pass = unwrap(rust_pass);
92+
return to_rust(pass->getPassKind());
8793
}
8894

8995
extern "C" void
90-
LLVMRustAddPass(LLVMPassManagerRef PM, Pass *pass) {
91-
assert(pass);
96+
LLVMRustAddPass(LLVMPassManagerRef PM, LLVMPassRef rust_pass) {
97+
assert(rust_pass);
98+
Pass *pass = unwrap(rust_pass);
9299
PassManagerBase *pm = unwrap(PM);
93100
pm->add(pass);
94101
}
@@ -162,13 +169,69 @@ LLVMRustHasFeature(LLVMTargetMachineRef TM,
162169
return (Bits & FeatureEntry->Value) == FeatureEntry->Value;
163170
}
164171

172+
enum class LLVMRustCodeModel {
173+
Other,
174+
Default,
175+
JITDefault,
176+
Small,
177+
Kernel,
178+
Medium,
179+
Large,
180+
};
181+
182+
static CodeModel::Model
183+
from_rust(LLVMRustCodeModel model)
184+
{
185+
switch (model) {
186+
case LLVMRustCodeModel::Default:
187+
return CodeModel::Default;
188+
case LLVMRustCodeModel::JITDefault:
189+
return CodeModel::JITDefault;
190+
case LLVMRustCodeModel::Small:
191+
return CodeModel::Small;
192+
case LLVMRustCodeModel::Kernel:
193+
return CodeModel::Kernel;
194+
case LLVMRustCodeModel::Medium:
195+
return CodeModel::Medium;
196+
case LLVMRustCodeModel::Large:
197+
return CodeModel::Large;
198+
default:
199+
abort();
200+
}
201+
}
202+
203+
enum class LLVMRustCodeGenOptLevel {
204+
Other,
205+
None,
206+
Less,
207+
Default,
208+
Aggressive,
209+
};
210+
211+
static CodeGenOpt::Level
212+
from_rust(LLVMRustCodeGenOptLevel level)
213+
{
214+
switch (level) {
215+
case LLVMRustCodeGenOptLevel::None:
216+
return CodeGenOpt::None;
217+
case LLVMRustCodeGenOptLevel::Less:
218+
return CodeGenOpt::Less;
219+
case LLVMRustCodeGenOptLevel::Default:
220+
return CodeGenOpt::Default;
221+
case LLVMRustCodeGenOptLevel::Aggressive:
222+
return CodeGenOpt::Aggressive;
223+
default:
224+
abort();
225+
}
226+
}
227+
165228
extern "C" LLVMTargetMachineRef
166229
LLVMRustCreateTargetMachine(const char *triple,
167230
const char *cpu,
168231
const char *feature,
169-
CodeModel::Model CM,
232+
LLVMRustCodeModel rust_CM,
170233
LLVMRelocMode Reloc,
171-
CodeGenOpt::Level OptLevel,
234+
LLVMRustCodeGenOptLevel rust_OptLevel,
172235
bool UseSoftFloat,
173236
bool PositionIndependentExecutable,
174237
bool FunctionSections,
@@ -179,6 +242,9 @@ LLVMRustCreateTargetMachine(const char *triple,
179242
#else
180243
Optional<Reloc::Model> RM;
181244
#endif
245+
auto CM = from_rust(rust_CM);
246+
auto OptLevel = from_rust(rust_OptLevel);
247+
182248
switch (Reloc){
183249
case LLVMRelocStatic:
184250
RM = Reloc::Static;
@@ -251,14 +317,14 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
251317

252318
extern "C" void
253319
LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB,
254-
CodeGenOpt::Level OptLevel,
320+
LLVMRustCodeGenOptLevel OptLevel,
255321
bool MergeFunctions,
256322
bool SLPVectorize,
257323
bool LoopVectorize) {
258324
// Ignore mergefunc for now as enabling it causes crashes.
259325
//unwrap(PMB)->MergeFunctions = MergeFunctions;
260326
unwrap(PMB)->SLPVectorize = SLPVectorize;
261-
unwrap(PMB)->OptLevel = OptLevel;
327+
unwrap(PMB)->OptLevel = from_rust(OptLevel);
262328
unwrap(PMB)->LoopVectorize = LoopVectorize;
263329
}
264330

@@ -314,13 +380,33 @@ LLVMRustSetLLVMOptions(int Argc, char **Argv) {
314380
cl::ParseCommandLineOptions(Argc, Argv);
315381
}
316382

317-
extern "C" bool
383+
enum class LLVMRustFileType {
384+
Other,
385+
AssemblyFile,
386+
ObjectFile,
387+
};
388+
389+
static TargetMachine::CodeGenFileType
390+
from_rust(LLVMRustFileType type)
391+
{
392+
switch (type) {
393+
case LLVMRustFileType::AssemblyFile:
394+
return TargetMachine::CGFT_AssemblyFile;
395+
case LLVMRustFileType::ObjectFile:
396+
return TargetMachine::CGFT_ObjectFile;
397+
default:
398+
abort();
399+
}
400+
}
401+
402+
extern "C" LLVMRustResult
318403
LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
319404
LLVMPassManagerRef PMR,
320405
LLVMModuleRef M,
321406
const char *path,
322-
TargetMachine::CodeGenFileType FileType) {
407+
LLVMRustFileType rust_FileType) {
323408
llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
409+
auto FileType = from_rust(rust_FileType);
324410

325411
std::string ErrorInfo;
326412
std::error_code EC;
@@ -329,7 +415,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
329415
ErrorInfo = EC.message();
330416
if (ErrorInfo != "") {
331417
LLVMRustSetLastError(ErrorInfo.c_str());
332-
return false;
418+
return LLVMRustResult::Failure;
333419
}
334420

335421
unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
@@ -339,7 +425,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
339425
// stream (OS), so the only real safe place to delete this is here? Don't we
340426
// wish this was written in Rust?
341427
delete PM;
342-
return true;
428+
return LLVMRustResult::Success;
343429
}
344430

345431
extern "C" void

‎src/rustllvm/README

+14
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,16 @@
11
This directory currently contains some LLVM support code. This will generally
22
be sent upstream to LLVM in time; for now it lives here.
3+
4+
NOTE: the LLVM C++ ABI is subject to between-version breakage and must *never*
5+
be exposed to Rust. To allow for easy auditing of that, all Rust-exposed types
6+
must be typedef-ed as "LLVMXyz", or "LLVMRustXyz" if they were defined here.
7+
8+
Functions that return a failure status and leave the error in
9+
the LLVM last error should return an LLVMRustResult rather than an
10+
int or anything to avoid confusion.
11+
12+
When translating enums, add a single `Other` variant as the first
13+
one to allow for new variants to be added. It should abort when used
14+
as an input.
15+
16+
All other types must not be typedef-ed as such.

‎src/rustllvm/rustllvm.h

+5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@
5858

5959
void LLVMRustSetLastError(const char*);
6060

61+
enum class LLVMRustResult {
62+
Success,
63+
Failure
64+
};
65+
6166
typedef struct OpaqueRustString *RustStringRef;
6267
typedef struct LLVMOpaqueTwine *LLVMTwineRef;
6368
typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef;

0 commit comments

Comments
 (0)
Please sign in to comment.