@@ -72,95 +72,74 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
7272
7373 attributes:: from_fn_attrs ( cx, func, instance) ;
7474
75- let instance_def_id = instance. def_id ( ) ;
76-
77- // TODO(antoyo): set linkage and attributes.
78-
79- // Apply an appropriate linkage/visibility value to our item that we
80- // just declared.
81- //
82- // This is sort of subtle. Inside our codegen unit we started off
83- // compilation by predefining all our own `MonoItem` instances. That
84- // is, everything we're codegenning ourselves is already defined. That
85- // means that anything we're actually codegenning in this codegen unit
86- // will have hit the above branch in `get_declared_value`. As a result,
87- // we're guaranteed here that we're declaring a symbol that won't get
88- // defined, or in other words we're referencing a value from another
89- // codegen unit or even another crate.
90- //
91- // So because this is a foreign value we blanket apply an external
92- // linkage directive because it's coming from a different object file.
93- // The visibility here is where it gets tricky. This symbol could be
94- // referencing some foreign crate or foreign library (an `extern`
95- // block) in which case we want to leave the default visibility. We may
96- // also, though, have multiple codegen units. It could be a
97- // monomorphization, in which case its expected visibility depends on
98- // whether we are sharing generics or not. The important thing here is
99- // that the visibility we apply to the declaration is the same one that
100- // has been applied to the definition (wherever that definition may be).
101- let is_generic = instance. args . non_erasable_generics ( ) . next ( ) . is_some ( ) ;
102-
103- if is_generic {
104- // This is a monomorphization. Its expected visibility depends
105- // on whether we are in share-generics mode.
106-
107- if cx. tcx . sess . opts . share_generics ( ) {
108- // We are in share_generics mode.
109-
110- if let Some ( instance_def_id) = instance_def_id. as_local ( ) {
111- // This is a definition from the current crate. If the
112- // definition is unreachable for downstream crates or
113- // the current crate does not re-export generics, the
114- // definition of the instance will have been declared
115- // as `hidden`.
116- if cx. tcx . is_unreachable_local_definition ( instance_def_id)
75+ #[ cfg( feature = "master" ) ]
76+ {
77+ let instance_def_id = instance. def_id ( ) ;
78+
79+ // TODO(antoyo): set linkage and attributes.
80+
81+ // Apply an appropriate linkage/visibility value to our item that we
82+ // just declared.
83+ //
84+ // This is sort of subtle. Inside our codegen unit we started off
85+ // compilation by predefining all our own `MonoItem` instances. That
86+ // is, everything we're codegenning ourselves is already defined. That
87+ // means that anything we're actually codegenning in this codegen unit
88+ // will have hit the above branch in `get_declared_value`. As a result,
89+ // we're guaranteed here that we're declaring a symbol that won't get
90+ // defined, or in other words we're referencing a value from another
91+ // codegen unit or even another crate.
92+ //
93+ // So because this is a foreign value we blanket apply an external
94+ // linkage directive because it's coming from a different object file.
95+ // The visibility here is where it gets tricky. This symbol could be
96+ // referencing some foreign crate or foreign library (an `extern`
97+ // block) in which case we want to leave the default visibility. We may
98+ // also, though, have multiple codegen units. It could be a
99+ // monomorphization, in which case its expected visibility depends on
100+ // whether we are sharing generics or not. The important thing here is
101+ // that the visibility we apply to the declaration is the same one that
102+ // has been applied to the definition (wherever that definition may be).
103+ let is_generic = instance. args . non_erasable_generics ( ) . next ( ) . is_some ( ) ;
104+
105+ let is_hidden = if is_generic {
106+ // This is a monomorphization of a generic function.
107+ if !( cx. tcx . sess . opts . share_generics ( )
108+ || tcx. codegen_fn_attrs ( instance_def_id) . inline
109+ == rustc_attr:: InlineAttr :: Never )
110+ {
111+ // When not sharing generics, all instances are in the same
112+ // crate and have hidden visibility.
113+ true
114+ } else if let Some ( instance_def_id) = instance_def_id. as_local ( ) {
115+ // This is a monomorphization of a generic function
116+ // defined in the current crate. It is hidden if:
117+ // - the definition is unreachable for downstream
118+ // crates, or
119+ // - the current crate does not re-export generics
120+ // (because the crate is a C library or executable)
121+ cx. tcx . is_unreachable_local_definition ( instance_def_id)
117122 || !cx. tcx . local_crate_exports_generics ( )
118- {
119- #[ cfg( feature = "master" ) ]
120- func. add_attribute ( FnAttribute :: Visibility ( Visibility :: Hidden ) ) ;
121- }
122123 } else {
123124 // This is a monomorphization of a generic function
124- // defined in an upstream crate.
125- if instance. upstream_monomorphization ( tcx) . is_some ( ) {
126- // This is instantiated in another crate. It cannot
127- // be `hidden`.
128- } else {
129- // This is a local instantiation of an upstream definition.
130- // If the current crate does not re-export it
131- // (because it is a C library or an executable), it
132- // will have been declared `hidden`.
133- if !cx. tcx . local_crate_exports_generics ( ) {
134- #[ cfg( feature = "master" ) ]
135- func. add_attribute ( FnAttribute :: Visibility ( Visibility :: Hidden ) ) ;
136- }
137- }
125+ // defined in an upstream crate. It is hidden if:
126+ // - it is instantiated in this crate, and
127+ // - the current crate does not re-export generics
128+ instance. upstream_monomorphization ( tcx) . is_none ( )
129+ && !cx. tcx . local_crate_exports_generics ( )
138130 }
139131 } else {
140- // When not sharing generics, all instances are in the same
141- // crate and have hidden visibility
142- #[ cfg( feature = "master" ) ]
132+ // This is a non-generic function. It is hidden if:
133+ // - it is instantiated in the local crate, and
134+ // - it is defined an upstream crate (non-local), or
135+ // - it is not reachable
136+ cx. tcx . is_codegened_item ( instance_def_id)
137+ && ( !instance_def_id. is_local ( )
138+ || !cx. tcx . is_reachable_non_generic ( instance_def_id) )
139+ } ;
140+ if is_hidden {
143141 func. add_attribute ( FnAttribute :: Visibility ( Visibility :: Hidden ) ) ;
144142 }
145- } else {
146- // This is a non-generic function
147- if cx. tcx . is_codegened_item ( instance_def_id) {
148- // This is a function that is instantiated in the local crate
149-
150- if instance_def_id. is_local ( ) {
151- // This is function that is defined in the local crate.
152- // If it is not reachable, it is hidden.
153- if !cx. tcx . is_reachable_non_generic ( instance_def_id) {
154- #[ cfg( feature = "master" ) ]
155- func. add_attribute ( FnAttribute :: Visibility ( Visibility :: Hidden ) ) ;
156- }
157- } else {
158- // This is a function from an upstream crate that has
159- // been instantiated here. These are always hidden.
160- #[ cfg( feature = "master" ) ]
161- func. add_attribute ( FnAttribute :: Visibility ( Visibility :: Hidden ) ) ;
162- }
163- }
164143 }
165144
166145 func
0 commit comments