gollvm: adjust symbol linkage recipe for 'only_inline' functions

Change the recipe used to compute symbol linkage for functions that
the front end has marked "only_inline".  Up to this point all inline
functions emitted by the front end were marked as non-visible; now
(at the moment) all functions are marked as visible. The new recipe
is roughly:

  (!visible ? InternalLinkage :
    (only_inline ? AvailableExternallyLinkage :
                   ExternalLinkage)

Includes an update to the unit test for this attribute as well.

Change-Id: I5ebc5051ded4a9ce1bf96dcbf8ca6d074f8769ca
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/180478
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/bridge/go-llvm.cpp b/bridge/go-llvm.cpp
index 3e77a4f..93a5318 100644
--- a/bridge/go-llvm.cpp
+++ b/bridge/go-llvm.cpp
@@ -2580,12 +2580,20 @@
     }
   }
 
+  // At the moment don't allow the combination of only_inline and non-visible.
+  // The assumption is that if the FE exports an inlinable function, that
+  // function will be visible (in the ELF object file sense) in the host pkg.
+  assert(((flags & Backend::function_only_inline) == 0) ||
+         ((flags & Backend::function_is_visible) != 0));
+
   llvm::GlobalValue::LinkageTypes linkage =
       llvm::GlobalValue::InternalLinkage;
-  if ((flags & Backend::function_is_visible) != 0)
-    linkage = llvm::GlobalValue::ExternalLinkage;
-  else if ((flags & Backend::function_only_inline) != 0)
-    linkage = llvm::GlobalValue::AvailableExternallyLinkage;
+  if ((flags & Backend::function_is_visible) != 0) {
+    if ((flags & Backend::function_only_inline) != 0)
+      linkage = llvm::GlobalValue::AvailableExternallyLinkage;
+    else
+      linkage = llvm::GlobalValue::ExternalLinkage;
+  }
   llvm::StringRef fn(fns);
   llvm::Constant *fcnValue = nullptr;
   llvm::Value *declVal = module_->getNamedValue(fn);
diff --git a/unittests/BackendCore/BackendFcnTests.cpp b/unittests/BackendCore/BackendFcnTests.cpp
index 659b0d5..8e94c3c 100644
--- a/unittests/BackendCore/BackendFcnTests.cpp
+++ b/unittests/BackendCore/BackendFcnTests.cpp
@@ -88,8 +88,8 @@
   for (auto vis : is_visible) {
     for (auto inl : is_inlinable) {
       for (auto only_inl : only_inline) {
-        // Functions imported only for inlining cannot be exported.
-        if (only_inl && vis)
+        // Assume all inlinable functions are visible.
+        if (only_inl && !vis)
           continue;
         for (auto nosplit : split_stack) {
           for (auto noret : is_noret) {
@@ -111,9 +111,9 @@
             EXPECT_FALSE(llfunc->isVarArg());
             EXPECT_EQ(llfunc->hasFnAttribute(Attribute::NoInline), !inl);
             EXPECT_EQ(llfunc->hasFnAttribute(Attribute::NoReturn), noret);
-            EXPECT_EQ(llfunc->hasExternalLinkage(), vis);
-            EXPECT_EQ(llfunc->hasInternalLinkage(), !vis && !only_inl);
-            EXPECT_EQ(llfunc->hasAvailableExternallyLinkage(), only_inl);
+            EXPECT_EQ(llfunc->hasInternalLinkage(), !vis);
+            EXPECT_EQ(llfunc->hasExternalLinkage(), vis && !only_inl);
+            EXPECT_EQ(llfunc->hasAvailableExternallyLinkage(), vis && only_inl);
             EXPECT_EQ(befcn->splitStack() == Bfunction::YesSplit, !nosplit);
           }
         }