about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc/src/callee.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/callee.rs')
-rw-r--r--compiler/rustc_codegen_gcc/src/callee.rs143
1 files changed, 61 insertions, 82 deletions
diff --git a/compiler/rustc_codegen_gcc/src/callee.rs b/compiler/rustc_codegen_gcc/src/callee.rs
index 65972a03e83..c133ae4fcdd 100644
--- a/compiler/rustc_codegen_gcc/src/callee.rs
+++ b/compiler/rustc_codegen_gcc/src/callee.rs
@@ -72,95 +72,74 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
 
         attributes::from_fn_attrs(cx, func, instance);
 
-        let instance_def_id = instance.def_id();
-
-        // TODO(antoyo): set linkage and attributes.
-
-        // Apply an appropriate linkage/visibility value to our item that we
-        // just declared.
-        //
-        // This is sort of subtle. Inside our codegen unit we started off
-        // compilation by predefining all our own `MonoItem` instances. That
-        // is, everything we're codegenning ourselves is already defined. That
-        // means that anything we're actually codegenning in this codegen unit
-        // will have hit the above branch in `get_declared_value`. As a result,
-        // we're guaranteed here that we're declaring a symbol that won't get
-        // defined, or in other words we're referencing a value from another
-        // codegen unit or even another crate.
-        //
-        // So because this is a foreign value we blanket apply an external
-        // linkage directive because it's coming from a different object file.
-        // The visibility here is where it gets tricky. This symbol could be
-        // referencing some foreign crate or foreign library (an `extern`
-        // block) in which case we want to leave the default visibility. We may
-        // also, though, have multiple codegen units. It could be a
-        // monomorphization, in which case its expected visibility depends on
-        // whether we are sharing generics or not. The important thing here is
-        // that the visibility we apply to the declaration is the same one that
-        // has been applied to the definition (wherever that definition may be).
-        let is_generic = instance.args.non_erasable_generics().next().is_some();
-
-        if is_generic {
-            // This is a monomorphization. Its expected visibility depends
-            // on whether we are in share-generics mode.
-
-            if cx.tcx.sess.opts.share_generics() {
-                // We are in share_generics mode.
-
-                if let Some(instance_def_id) = instance_def_id.as_local() {
-                    // This is a definition from the current crate. If the
-                    // definition is unreachable for downstream crates or
-                    // the current crate does not re-export generics, the
-                    // definition of the instance will have been declared
-                    // as `hidden`.
-                    if cx.tcx.is_unreachable_local_definition(instance_def_id)
+        #[cfg(feature = "master")]
+        {
+            let instance_def_id = instance.def_id();
+
+            // TODO(antoyo): set linkage and attributes.
+
+            // Apply an appropriate linkage/visibility value to our item that we
+            // just declared.
+            //
+            // This is sort of subtle. Inside our codegen unit we started off
+            // compilation by predefining all our own `MonoItem` instances. That
+            // is, everything we're codegenning ourselves is already defined. That
+            // means that anything we're actually codegenning in this codegen unit
+            // will have hit the above branch in `get_declared_value`. As a result,
+            // we're guaranteed here that we're declaring a symbol that won't get
+            // defined, or in other words we're referencing a value from another
+            // codegen unit or even another crate.
+            //
+            // So because this is a foreign value we blanket apply an external
+            // linkage directive because it's coming from a different object file.
+            // The visibility here is where it gets tricky. This symbol could be
+            // referencing some foreign crate or foreign library (an `extern`
+            // block) in which case we want to leave the default visibility. We may
+            // also, though, have multiple codegen units. It could be a
+            // monomorphization, in which case its expected visibility depends on
+            // whether we are sharing generics or not. The important thing here is
+            // that the visibility we apply to the declaration is the same one that
+            // has been applied to the definition (wherever that definition may be).
+            let is_generic = instance.args.non_erasable_generics().next().is_some();
+
+            let is_hidden = if is_generic {
+                // This is a monomorphization of a generic function.
+                if !(cx.tcx.sess.opts.share_generics()
+                    || tcx.codegen_fn_attrs(instance_def_id).inline
+                        == rustc_attr_parsing::InlineAttr::Never)
+                {
+                    // When not sharing generics, all instances are in the same
+                    // crate and have hidden visibility.
+                    true
+                } else if let Some(instance_def_id) = instance_def_id.as_local() {
+                    // This is a monomorphization of a generic function
+                    // defined in the current crate. It is hidden if:
+                    // - the definition is unreachable for downstream
+                    //   crates, or
+                    // - the current crate does not re-export generics
+                    //   (because the crate is a C library or executable)
+                    cx.tcx.is_unreachable_local_definition(instance_def_id)
                         || !cx.tcx.local_crate_exports_generics()
-                    {
-                        #[cfg(feature = "master")]
-                        func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
-                    }
                 } else {
                     // This is a monomorphization of a generic function
-                    // defined in an upstream crate.
-                    if instance.upstream_monomorphization(tcx).is_some() {
-                        // This is instantiated in another crate. It cannot
-                        // be `hidden`.
-                    } else {
-                        // This is a local instantiation of an upstream definition.
-                        // If the current crate does not re-export it
-                        // (because it is a C library or an executable), it
-                        // will have been declared `hidden`.
-                        if !cx.tcx.local_crate_exports_generics() {
-                            #[cfg(feature = "master")]
-                            func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
-                        }
-                    }
+                    // defined in an upstream crate. It is hidden if:
+                    // - it is instantiated in this crate, and
+                    // - the current crate does not re-export generics
+                    instance.upstream_monomorphization(tcx).is_none()
+                        && !cx.tcx.local_crate_exports_generics()
                 }
             } else {
-                // When not sharing generics, all instances are in the same
-                // crate and have hidden visibility
-                #[cfg(feature = "master")]
+                // This is a non-generic function. It is hidden if:
+                // - it is instantiated in the local crate, and
+                //   - it is defined an upstream crate (non-local), or
+                //   - it is not reachable
+                cx.tcx.is_codegened_item(instance_def_id)
+                    && (!instance_def_id.is_local()
+                        || !cx.tcx.is_reachable_non_generic(instance_def_id))
+            };
+            if is_hidden {
                 func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
             }
-        } else {
-            // This is a non-generic function
-            if cx.tcx.is_codegened_item(instance_def_id) {
-                // This is a function that is instantiated in the local crate
-
-                if instance_def_id.is_local() {
-                    // This is function that is defined in the local crate.
-                    // If it is not reachable, it is hidden.
-                    if !cx.tcx.is_reachable_non_generic(instance_def_id) {
-                        #[cfg(feature = "master")]
-                        func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
-                    }
-                } else {
-                    // This is a function from an upstream crate that has
-                    // been instantiated here. These are always hidden.
-                    #[cfg(feature = "master")]
-                    func.add_attribute(FnAttribute::Visibility(Visibility::Hidden));
-                }
-            }
         }
 
         func