Skip to content

Commit b9a8c1a

Browse files
committed
Fix incorrect LLVM Linkage enum
The `Linkage` enum in librustc_llvm got out of sync with the version in LLVM and it caused two variants of the #[linkage=""] attribute to break. This adds the functions `LLVMRustGetLinkage` and `LLVMRustSetLinkage` which convert between the Rust Linkage enum and the LLVM one, which should stop this from breaking every time LLVM changes it. Fixes rust-lang#33992
1 parent e77d86c commit b9a8c1a

File tree

11 files changed

+180
-66
lines changed

11 files changed

+180
-66
lines changed

src/librustc_llvm/ffi.rs

+11-17
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,21 @@ pub enum CallConv {
4747
X86_VectorCall = 80
4848
}
4949

50-
/// LLVMLinkage
51-
///
52-
/// This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
53-
/// DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
54-
/// LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
55-
/// they've been removed in upstream LLVM commit r203866.
50+
/// LLVMRustLinkage
5651
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
5752
#[repr(C)]
5853
pub enum Linkage {
5954
ExternalLinkage = 0,
6055
AvailableExternallyLinkage = 1,
6156
LinkOnceAnyLinkage = 2,
6257
LinkOnceODRLinkage = 3,
63-
WeakAnyLinkage = 5,
64-
WeakODRLinkage = 6,
65-
AppendingLinkage = 7,
66-
InternalLinkage = 8,
67-
PrivateLinkage = 9,
68-
ExternalWeakLinkage = 12,
69-
CommonLinkage = 14,
58+
WeakAnyLinkage = 4,
59+
WeakODRLinkage = 5,
60+
AppendingLinkage = 6,
61+
InternalLinkage = 7,
62+
PrivateLinkage = 8,
63+
ExternalWeakLinkage = 9,
64+
CommonLinkage = 10,
7065
}
7166

7267
/// LLVMDiagnosticSeverity
@@ -253,8 +248,7 @@ pub enum FileType {
253248
ObjectFile,
254249
}
255250

256-
/// Enum pinned in LLVMContext, used in
257-
/// LLVMSetMetadata so ABI-stable.
251+
/// LLVMMetadataType
258252
#[derive(Copy, Clone)]
259253
#[repr(C)]
260254
pub enum MetadataType {
@@ -821,8 +815,8 @@ extern {
821815
/* Operations on global variables, functions, and aliases (globals) */
822816
pub fn LLVMGetGlobalParent(Global: ValueRef) -> ModuleRef;
823817
pub fn LLVMIsDeclaration(Global: ValueRef) -> Bool;
824-
pub fn LLVMGetLinkage(Global: ValueRef) -> c_uint;
825-
pub fn LLVMSetLinkage(Global: ValueRef, Link: Linkage);
818+
pub fn LLVMRustGetLinkage(Global: ValueRef) -> Linkage;
819+
pub fn LLVMRustSetLinkage(Global: ValueRef, RustLinkage: Linkage);
826820
pub fn LLVMGetSection(Global: ValueRef) -> *const c_char;
827821
pub fn LLVMSetSection(Global: ValueRef, Section: *const c_char);
828822
pub fn LLVMGetVisibility(Global: ValueRef) -> c_uint;

src/librustc_trans/base.rs

+32-32
Original file line numberDiff line numberDiff line change
@@ -1198,17 +1198,17 @@ pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
11981198
// ghost, dllimport, dllexport and linkonce_odr_autohide are not supported
11991199
// and don't have to be, LLVM treats them as no-ops.
12001200
match name {
1201-
"appending" => Some(llvm::AppendingLinkage),
1202-
"available_externally" => Some(llvm::AvailableExternallyLinkage),
1203-
"common" => Some(llvm::CommonLinkage),
1204-
"extern_weak" => Some(llvm::ExternalWeakLinkage),
1205-
"external" => Some(llvm::ExternalLinkage),
1206-
"internal" => Some(llvm::InternalLinkage),
1207-
"linkonce" => Some(llvm::LinkOnceAnyLinkage),
1208-
"linkonce_odr" => Some(llvm::LinkOnceODRLinkage),
1209-
"private" => Some(llvm::PrivateLinkage),
1210-
"weak" => Some(llvm::WeakAnyLinkage),
1211-
"weak_odr" => Some(llvm::WeakODRLinkage),
1201+
"appending" => Some(llvm::Linkage::AppendingLinkage),
1202+
"available_externally" => Some(llvm::Linkage::AvailableExternallyLinkage),
1203+
"common" => Some(llvm::Linkage::CommonLinkage),
1204+
"extern_weak" => Some(llvm::Linkage::ExternalWeakLinkage),
1205+
"external" => Some(llvm::Linkage::ExternalLinkage),
1206+
"internal" => Some(llvm::Linkage::InternalLinkage),
1207+
"linkonce" => Some(llvm::Linkage::LinkOnceAnyLinkage),
1208+
"linkonce_odr" => Some(llvm::Linkage::LinkOnceODRLinkage),
1209+
"private" => Some(llvm::Linkage::PrivateLinkage),
1210+
"weak" => Some(llvm::Linkage::WeakAnyLinkage),
1211+
"weak_odr" => Some(llvm::Linkage::WeakODRLinkage),
12121212
_ => None,
12131213
}
12141214
}
@@ -1401,10 +1401,10 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
14011401
// are referenced via a declaration in some other codegen unit.
14021402
for ccx in ccxs.iter_need_trans() {
14031403
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
1404-
let linkage = llvm::LLVMGetLinkage(val);
1404+
let linkage = llvm::LLVMRustGetLinkage(val);
14051405
// We only care about external declarations (not definitions)
14061406
// and available_externally definitions.
1407-
let is_available_externally = linkage == llvm::AvailableExternallyLinkage as c_uint;
1407+
let is_available_externally = linkage == llvm::Linkage::AvailableExternallyLinkage;
14081408
let is_decl = llvm::LLVMIsDeclaration(val) != 0;
14091409

14101410
if is_decl || is_available_externally {
@@ -1446,11 +1446,11 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
14461446
// then give it internal linkage.
14471447
for ccx in ccxs.iter_need_trans() {
14481448
for val in iter_globals(ccx.llmod()).chain(iter_functions(ccx.llmod())) {
1449-
let linkage = llvm::LLVMGetLinkage(val);
1449+
let linkage = llvm::LLVMRustGetLinkage(val);
14501450

1451-
let is_externally_visible = (linkage == llvm::ExternalLinkage as c_uint) ||
1452-
(linkage == llvm::LinkOnceODRLinkage as c_uint) ||
1453-
(linkage == llvm::WeakODRLinkage as c_uint);
1451+
let is_externally_visible = (linkage == llvm::Linkage::ExternalLinkage) ||
1452+
(linkage == llvm::Linkage::LinkOnceODRLinkage) ||
1453+
(linkage == llvm::Linkage::WeakODRLinkage);
14541454
let is_definition = llvm::LLVMIsDeclaration(val) == 0;
14551455

14561456
// If this is a definition (as opposed to just a declaration)
@@ -1465,7 +1465,7 @@ fn internalize_symbols<'a, 'tcx>(sess: &Session,
14651465
let has_fixed_linkage = linkage_fixed_explicitly.contains(&name_cow);
14661466

14671467
if !is_referenced_somewhere && !is_reachable && !has_fixed_linkage {
1468-
llvm::LLVMSetLinkage(val, llvm::InternalLinkage);
1468+
llvm::LLVMRustSetLinkage(val, llvm::Linkage::InternalLinkage);
14691469
llvm::LLVMSetDLLStorageClass(val,
14701470
llvm::DLLStorageClass::Default);
14711471
llvm::UnsetComdat(val);
@@ -1495,8 +1495,8 @@ fn create_imps(cx: &CrateContextList) {
14951495
for ccx in cx.iter_need_trans() {
14961496
let exported: Vec<_> = iter_globals(ccx.llmod())
14971497
.filter(|&val| {
1498-
llvm::LLVMGetLinkage(val) ==
1499-
llvm::ExternalLinkage as c_uint &&
1498+
llvm::LLVMRustGetLinkage(val) ==
1499+
llvm::Linkage::ExternalLinkage &&
15001500
llvm::LLVMIsDeclaration(val) == 0
15011501
})
15021502
.collect();
@@ -1512,7 +1512,7 @@ fn create_imps(cx: &CrateContextList) {
15121512
imp_name.as_ptr() as *const _);
15131513
let init = llvm::LLVMConstBitCast(val, i8p_ty.to_ref());
15141514
llvm::LLVMSetInitializer(imp, init);
1515-
llvm::LLVMSetLinkage(imp, llvm::ExternalLinkage);
1515+
llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);
15161516
}
15171517
}
15181518
}
@@ -1937,17 +1937,17 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
19371937
output.push_str(&cgu_name[..]);
19381938

19391939
let linkage_abbrev = match linkage {
1940-
llvm::ExternalLinkage => "External",
1941-
llvm::AvailableExternallyLinkage => "Available",
1942-
llvm::LinkOnceAnyLinkage => "OnceAny",
1943-
llvm::LinkOnceODRLinkage => "OnceODR",
1944-
llvm::WeakAnyLinkage => "WeakAny",
1945-
llvm::WeakODRLinkage => "WeakODR",
1946-
llvm::AppendingLinkage => "Appending",
1947-
llvm::InternalLinkage => "Internal",
1948-
llvm::PrivateLinkage => "Private",
1949-
llvm::ExternalWeakLinkage => "ExternalWeak",
1950-
llvm::CommonLinkage => "Common",
1940+
llvm::Linkage::ExternalLinkage => "External",
1941+
llvm::Linkage::AvailableExternallyLinkage => "Available",
1942+
llvm::Linkage::LinkOnceAnyLinkage => "OnceAny",
1943+
llvm::Linkage::LinkOnceODRLinkage => "OnceODR",
1944+
llvm::Linkage::WeakAnyLinkage => "WeakAny",
1945+
llvm::Linkage::WeakODRLinkage => "WeakODR",
1946+
llvm::Linkage::AppendingLinkage => "Appending",
1947+
llvm::Linkage::InternalLinkage => "Internal",
1948+
llvm::Linkage::PrivateLinkage => "Private",
1949+
llvm::Linkage::ExternalWeakLinkage => "ExternalWeak",
1950+
llvm::Linkage::CommonLinkage => "Common",
19511951
};
19521952

19531953
output.push_str("[");

src/librustc_trans/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
472472
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
473473
attributes::unwind(llfn, true);
474474
unsafe {
475-
llvm::LLVMSetLinkage(llfn, llvm::ExternalLinkage);
475+
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
476476
}
477477
}
478478

src/librustc_trans/closure.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,10 @@ pub fn trans_closure_body_via_mir<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
110110

111111
unsafe {
112112
if ccx.sess().target.target.options.allows_weak_linkage {
113-
llvm::LLVMSetLinkage(llfn, llvm::WeakODRLinkage);
113+
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::WeakODRLinkage);
114114
llvm::SetUniqueComdat(ccx.llmod(), llfn);
115115
} else {
116-
llvm::LLVMSetLinkage(llfn, llvm::InternalLinkage);
116+
llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage);
117117
}
118118
}
119119

src/librustc_trans/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
817817
});
818818
llvm::LLVMSetInitializer(g, sc);
819819
llvm::LLVMSetGlobalConstant(g, True);
820-
llvm::LLVMSetLinkage(g, llvm::InternalLinkage);
820+
llvm::LLVMRustSetLinkage(g, llvm::Linkage::InternalLinkage);
821821

822822
cx.const_cstr_cache().borrow_mut().insert(s, g);
823823
g

src/librustc_trans/consts.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
use llvm;
1313
use llvm::{SetUnnamedAddr};
14-
use llvm::{InternalLinkage, ValueRef, True};
14+
use llvm::{ValueRef, True};
1515
use rustc_const_eval::ConstEvalErr;
1616
use rustc::hir::def_id::DefId;
1717
use rustc::hir::map as hir_map;
@@ -53,7 +53,7 @@ pub fn addr_of_mut(ccx: &CrateContext,
5353
});
5454
llvm::LLVMSetInitializer(gv, cv);
5555
llvm::LLVMSetAlignment(gv, align);
56-
llvm::LLVMSetLinkage(gv, InternalLinkage);
56+
llvm::LLVMRustSetLinkage(gv, llvm::Linkage::InternalLinkage);
5757
SetUnnamedAddr(gv, true);
5858
gv
5959
}
@@ -142,7 +142,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
142142
unsafe {
143143
// Declare a symbol `foo` with the desired linkage.
144144
let g1 = declare::declare_global(ccx, &sym, llty2);
145-
llvm::LLVMSetLinkage(g1, linkage);
145+
llvm::LLVMRustSetLinkage(g1, linkage);
146146

147147
// Declare an internal global `extern_with_linkage_foo` which
148148
// is initialized with the address of `foo`. If `foo` is
@@ -156,7 +156,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef {
156156
ccx.sess().span_fatal(span,
157157
&format!("symbol `{}` is already defined", &sym))
158158
});
159-
llvm::LLVMSetLinkage(g2, llvm::InternalLinkage);
159+
llvm::LLVMRustSetLinkage(g2, llvm::Linkage::InternalLinkage);
160160
llvm::LLVMSetInitializer(g2, g1);
161161
g2
162162
}

src/librustc_trans/debuginfo/gdb.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext)
7777
llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents));
7878
llvm::LLVMSetGlobalConstant(section_var, llvm::True);
7979
llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
80-
llvm::LLVMSetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
80+
llvm::LLVMRustSetLinkage(section_var, llvm::Linkage::LinkOnceODRLinkage);
8181
// This should make sure that the whole section is not larger than
8282
// the string it contains. Otherwise we get a warning from GDB.
8383
llvm::LLVMSetAlignment(section_var, 1);

src/librustc_trans/declare.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ pub fn define_internal_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
164164
name: &str,
165165
fn_type: ty::Ty<'tcx>) -> ValueRef {
166166
let llfn = define_fn(ccx, name, fn_type);
167-
unsafe { llvm::LLVMSetLinkage(llfn, llvm::InternalLinkage) };
167+
unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) };
168168
llfn
169169
}
170170

src/librustc_trans/trans_item.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl<'a, 'tcx> TransItem<'tcx> {
160160
&format!("symbol `{}` is already defined", symbol_name))
161161
});
162162

163-
unsafe { llvm::LLVMSetLinkage(g, linkage) };
163+
unsafe { llvm::LLVMRustSetLinkage(g, linkage) };
164164

165165
let instance = Instance::mono(ccx.shared(), def_id);
166166
ccx.instances().borrow_mut().insert(instance, g);
@@ -180,10 +180,10 @@ impl<'a, 'tcx> TransItem<'tcx> {
180180

181181
let attrs = ccx.tcx().get_attrs(instance.def);
182182
let lldecl = declare::declare_fn(ccx, symbol_name, mono_ty);
183-
unsafe { llvm::LLVMSetLinkage(lldecl, linkage) };
183+
unsafe { llvm::LLVMRustSetLinkage(lldecl, linkage) };
184184
base::set_link_section(ccx, lldecl, &attrs);
185-
if linkage == llvm::LinkOnceODRLinkage ||
186-
linkage == llvm::WeakODRLinkage {
185+
if linkage == llvm::Linkage::LinkOnceODRLinkage ||
186+
linkage == llvm::Linkage::WeakODRLinkage {
187187
llvm::SetUniqueComdat(ccx.llmod(), lldecl);
188188
}
189189

@@ -214,9 +214,9 @@ impl<'a, 'tcx> TransItem<'tcx> {
214214

215215
assert!(declare::get_defined_value(ccx, symbol_name).is_none());
216216
let llfn = declare::declare_cfn(ccx, symbol_name, llfnty);
217-
unsafe { llvm::LLVMSetLinkage(llfn, linkage) };
218-
if linkage == llvm::LinkOnceODRLinkage ||
219-
linkage == llvm::WeakODRLinkage {
217+
unsafe { llvm::LLVMRustSetLinkage(llfn, linkage) };
218+
if linkage == llvm::Linkage::LinkOnceODRLinkage ||
219+
linkage == llvm::Linkage::WeakODRLinkage {
220220
llvm::SetUniqueComdat(ccx.llmod(), llfn);
221221
}
222222
attributes::set_frame_pointer_elimination(ccx, llfn);

src/rustllvm/RustWrapper.cpp

+80
Original file line numberDiff line numberDiff line change
@@ -1232,3 +1232,83 @@ extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
12321232
GlobalObject *GV = unwrap<GlobalObject>(V);
12331233
GV->setComdat(nullptr);
12341234
}
1235+
1236+
enum class LLVMRustLinkage {
1237+
ExternalLinkage = 0,
1238+
AvailableExternallyLinkage = 1,
1239+
LinkOnceAnyLinkage = 2,
1240+
LinkOnceODRLinkage = 3,
1241+
WeakAnyLinkage = 4,
1242+
WeakODRLinkage = 5,
1243+
AppendingLinkage = 6,
1244+
InternalLinkage = 7,
1245+
PrivateLinkage = 8,
1246+
ExternalWeakLinkage = 9,
1247+
CommonLinkage = 10,
1248+
};
1249+
1250+
static LLVMRustLinkage to_rust(LLVMLinkage linkage) {
1251+
switch (linkage) {
1252+
case LLVMExternalLinkage:
1253+
return LLVMRustLinkage::ExternalLinkage;
1254+
case LLVMAvailableExternallyLinkage:
1255+
return LLVMRustLinkage::AvailableExternallyLinkage;
1256+
case LLVMLinkOnceAnyLinkage:
1257+
return LLVMRustLinkage::LinkOnceAnyLinkage;
1258+
case LLVMLinkOnceODRLinkage:
1259+
return LLVMRustLinkage::LinkOnceODRLinkage;
1260+
case LLVMWeakAnyLinkage:
1261+
return LLVMRustLinkage::WeakAnyLinkage;
1262+
case LLVMWeakODRLinkage:
1263+
return LLVMRustLinkage::WeakODRLinkage;
1264+
case LLVMAppendingLinkage:
1265+
return LLVMRustLinkage::AppendingLinkage;
1266+
case LLVMInternalLinkage:
1267+
return LLVMRustLinkage::InternalLinkage;
1268+
case LLVMPrivateLinkage:
1269+
return LLVMRustLinkage::PrivateLinkage;
1270+
case LLVMExternalWeakLinkage:
1271+
return LLVMRustLinkage::ExternalWeakLinkage;
1272+
case LLVMCommonLinkage:
1273+
return LLVMRustLinkage::CommonLinkage;
1274+
default:
1275+
llvm_unreachable("Invalid LLVMRustLinkage value!");
1276+
}
1277+
}
1278+
1279+
static LLVMLinkage from_rust(LLVMRustLinkage linkage) {
1280+
switch (linkage) {
1281+
case LLVMRustLinkage::ExternalLinkage:
1282+
return LLVMExternalLinkage;
1283+
case LLVMRustLinkage::AvailableExternallyLinkage:
1284+
return LLVMAvailableExternallyLinkage;
1285+
case LLVMRustLinkage::LinkOnceAnyLinkage:
1286+
return LLVMLinkOnceAnyLinkage;
1287+
case LLVMRustLinkage::LinkOnceODRLinkage:
1288+
return LLVMLinkOnceODRLinkage;
1289+
case LLVMRustLinkage::WeakAnyLinkage:
1290+
return LLVMWeakAnyLinkage;
1291+
case LLVMRustLinkage::WeakODRLinkage:
1292+
return LLVMWeakODRLinkage;
1293+
case LLVMRustLinkage::AppendingLinkage:
1294+
return LLVMAppendingLinkage;
1295+
case LLVMRustLinkage::InternalLinkage:
1296+
return LLVMInternalLinkage;
1297+
case LLVMRustLinkage::PrivateLinkage:
1298+
return LLVMPrivateLinkage;
1299+
case LLVMRustLinkage::ExternalWeakLinkage:
1300+
return LLVMExternalWeakLinkage;
1301+
case LLVMRustLinkage::CommonLinkage:
1302+
return LLVMCommonLinkage;
1303+
default:
1304+
llvm_unreachable("Invalid LLVMRustLinkage value!");
1305+
}
1306+
}
1307+
1308+
extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1309+
return to_rust(LLVMGetLinkage(V));
1310+
}
1311+
1312+
extern "C" void LLVMRustSetLinkage(LLVMValueRef V, LLVMRustLinkage RustLinkage) {
1313+
LLVMSetLinkage(V, from_rust(RustLinkage));
1314+
}

0 commit comments

Comments
 (0)