@@ -1139,7 +1139,9 @@ pub fn trans_stmt(cx: block, s: ast::stmt) -> block {
1139
1139
}
1140
1140
}
1141
1141
}
1142
- ast:: decl_item( i) => trans_item ( cx. fcx . ccx , * i)
1142
+ ast:: decl_item( i) => {
1143
+ trans_item ( cx. fcx . ccx , * i, DontForceInternal )
1144
+ }
1143
1145
}
1144
1146
}
1145
1147
ast:: stmt_mac( * ) => cx. tcx ( ) . sess . bug ( ~"unexpanded macro")
@@ -1972,26 +1974,36 @@ pub fn trans_struct_dtor(ccx: @crate_ctxt,
1972
1974
lldecl
1973
1975
}
1974
1976
1975
- pub fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def,
1976
- id: ast::node_id, degen: bool,
1977
- path: @ast_map::path, vi: @~[ty::VariantInfo],
1978
- i: &mut uint) {
1977
+ pub fn trans_enum_def(ccx: @crate_ctxt,
1978
+ enum_definition: ast::enum_def,
1979
+ id: ast::node_id,
1980
+ degen: bool,
1981
+ path: @ast_map::path,
1982
+ vi: @~[ty::VariantInfo],
1983
+ i: &mut uint,
1984
+ force_internal: ForceInternalFlag) {
1979
1985
for vec::each(enum_definition.variants) |variant| {
1980
1986
let disr_val = vi[*i].disr_val;
1981
1987
*i += 1;
1982
1988
1983
1989
match variant.node.kind {
1984
1990
ast::tuple_variant_kind(ref args) if args.len() > 0 => {
1985
1991
let llfn = get_item_val(ccx, variant.node.id);
1992
+ if force_internal == ForceInternal {
1993
+ internalize_item(llfn);
1994
+ }
1986
1995
trans_enum_variant(ccx, id, *variant, /*bad*/copy *args,
1987
1996
disr_val, degen, None, llfn);
1988
1997
}
1989
1998
ast::tuple_variant_kind(_) => {
1990
1999
// Nothing to do.
1991
2000
}
1992
2001
ast::struct_variant_kind(struct_def) => {
1993
- trans_struct_def(ccx, struct_def, path,
1994
- variant.node.id);
2002
+ trans_struct_def(ccx,
2003
+ struct_def,
2004
+ path,
2005
+ variant.node.id,
2006
+ force_internal);
1995
2007
}
1996
2008
ast::enum_variant_kind(ref enum_definition) => {
1997
2009
trans_enum_def(ccx,
@@ -2000,13 +2012,28 @@ pub fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def,
2000
2012
degen,
2001
2013
path,
2002
2014
vi,
2003
- &mut *i);
2015
+ &mut *i,
2016
+ force_internal);
2004
2017
}
2005
2018
}
2006
2019
}
2007
2020
}
2008
2021
2009
- pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
2022
+ #[deriving_eq]
2023
+ pub enum ForceInternalFlag {
2024
+ DontForceInternal,
2025
+ ForceInternal,
2026
+ }
2027
+
2028
+ // Marks the LLVM ValueRef corresponding to the given item as internal, so
2029
+ // that if it gets inlined away LLVM won't bother translating it.
2030
+ pub fn internalize_item(llval: ValueRef) {
2031
+ lib::llvm::SetLinkage(llval, lib::llvm::InternalLinkage);
2032
+ }
2033
+
2034
+ pub fn trans_item(ccx: @crate_ctxt,
2035
+ item: ast::item,
2036
+ force_internal: ForceInternalFlag) {
2010
2037
let _icx = ccx.insn_ctxt(" trans_item");
2011
2038
let path = match ccx.tcx.items.get(&item.id) {
2012
2039
ast_map::node_item(_, p) => p,
@@ -2017,13 +2044,19 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
2017
2044
ast::item_fn(ref decl, purity, ref tps, ref body) => {
2018
2045
if purity == ast::extern_fn {
2019
2046
let llfndecl = get_item_val(ccx, item.id);
2047
+ if force_internal == ForceInternal {
2048
+ internalize_item(llfndecl);
2049
+ }
2020
2050
foreign::trans_foreign_fn(ccx,
2021
2051
vec::append(
2022
2052
/*bad*/copy *path,
2023
2053
~[path_name(item.ident)]),
2024
2054
decl, body, llfndecl, item.id);
2025
2055
} else if tps.is_empty() {
2026
2056
let llfndecl = get_item_val(ccx, item.id);
2057
+ if force_internal == ForceInternal {
2058
+ internalize_item(llfndecl);
2059
+ }
2027
2060
trans_fn(ccx,
2028
2061
vec::append(/*bad*/copy *path, ~[path_name(item.ident)]),
2029
2062
decl, body, llfndecl, no_self, None, item.id, None);
@@ -2032,16 +2065,22 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
2032
2065
match stmt.node {
2033
2066
ast::stmt_decl(@codemap::spanned { node: ast::decl_item(i),
2034
2067
_ }, _) => {
2035
- trans_item(ccx, *i);
2068
+ trans_item(ccx, *i, DontForceInternal );
2036
2069
}
2037
2070
_ => ()
2038
2071
}
2039
2072
}
2040
2073
}
2041
2074
}
2042
2075
ast::item_impl(tps, _, _, ms) => {
2043
- meth::trans_impl(ccx, /*bad*/copy *path, item.ident, ms, tps, None,
2044
- item.id);
2076
+ meth::trans_impl(ccx,
2077
+ /*bad*/copy *path,
2078
+ item.ident,
2079
+ ms,
2080
+ tps,
2081
+ None,
2082
+ item.id,
2083
+ force_internal);
2045
2084
}
2046
2085
ast::item_mod(m) => {
2047
2086
trans_mod(ccx, m);
@@ -2051,8 +2090,14 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
2051
2090
let degen = (*enum_definition).variants.len() == 1u;
2052
2091
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
2053
2092
let mut i = 0;
2054
- trans_enum_def(ccx, (*enum_definition), item.id,
2055
- degen, path, vi, &mut i);
2093
+ trans_enum_def(ccx,
2094
+ *enum_definition,
2095
+ item.id,
2096
+ degen,
2097
+ path,
2098
+ vi,
2099
+ &mut i,
2100
+ force_internal);
2056
2101
}
2057
2102
}
2058
2103
ast::item_const(_, expr) => consts::trans_const(ccx, expr, item.id),
@@ -2066,16 +2111,22 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
2066
2111
}
2067
2112
ast::item_struct(struct_def, tps) => {
2068
2113
if tps.is_empty() {
2069
- trans_struct_def(ccx, struct_def, path, item.id);
2114
+ trans_struct_def(ccx,
2115
+ struct_def,
2116
+ path,
2117
+ item.id,
2118
+ DontForceInternal);
2070
2119
}
2071
2120
}
2072
2121
_ => {/* fall through */ }
2073
2122
}
2074
2123
}
2075
2124
2076
- pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
2125
+ pub fn trans_struct_def(ccx: @crate_ctxt,
2126
+ struct_def: @ast::struct_def,
2077
2127
path: @ast_map::path,
2078
- id: ast::node_id) {
2128
+ id: ast::node_id,
2129
+ force_internal: ForceInternalFlag) {
2079
2130
// Translate the destructor.
2080
2131
do option::iter(&struct_def.dtor) |dtor| {
2081
2132
trans_struct_dtor(ccx, /*bad*/copy *path, &dtor.node.body,
@@ -2088,6 +2139,9 @@ pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
2088
2139
// otherwise this is a unit-like struct.
2089
2140
Some(ctor_id) if struct_def.fields.len() > 0 => {
2090
2141
let llfndecl = get_item_val(ccx, ctor_id);
2142
+ if force_internal == ForceInternal {
2143
+ internalize_item(llfndecl);
2144
+ }
2091
2145
trans_tuple_struct(ccx, /*bad*/copy struct_def.fields,
2092
2146
ctor_id, None, llfndecl);
2093
2147
}
@@ -2103,7 +2157,7 @@ pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
2103
2157
pub fn trans_mod(ccx: @crate_ctxt, m: ast::_mod) {
2104
2158
let _icx = ccx.insn_ctxt(" trans_mod");
2105
2159
for vec::each(m.items) |item| {
2106
- trans_item(ccx, **item);
2160
+ trans_item(ccx, **item, DontForceInternal );
2107
2161
}
2108
2162
}
2109
2163
@@ -2477,8 +2531,9 @@ pub fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
2477
2531
ccx.sess.bug(~" get_item_val( ) : unexpected variant")
2478
2532
}
2479
2533
};
2480
- if !(exprt || ccx.reachable.contains_key(&id)) {
2481
- lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage);
2534
+ if !*ccx.sess.building_library ||
2535
+ (!exprt && !ccx.reachable.contains_key(&id)) {
2536
+ internalize_item(val);
2482
2537
}
2483
2538
ccx.item_vals.insert(id, val);
2484
2539
val
0 commit comments