bridge: support implicit_variable_reference

implicit_variable_reference is just a reference of an external
global variable.

Relax some assertions in creating global variable. When we see a
definition and a declaration of the same global variable in the
same package, the definition wins. Here we don't require some
attributes (e.g. isConstant) match, just overwrite them. This is
because some attributes may be not known when we create a
declaration, e.g. implicit_variable_reference. And these
attributes don't really matter for an external declaration.

Change-Id: I981061880326dad10e7b011074c330a36c461ecb
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/179640
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/bridge/go-llvm.cpp b/bridge/go-llvm.cpp
index 75c3998..a8d1662 100644
--- a/bridge/go-llvm.cpp
+++ b/bridge/go-llvm.cpp
@@ -2089,13 +2089,14 @@
   if (glob && glob->getLinkage() == linkage) {
     // A global variable with same name already exists.
     if (glob->getType()->getElementType() == btype->type()) {
-      assert(glob->isConstant() == (isConstant == MV_Constant));
-      assert(glob->hasComdat() == (inComdat == MV_InComdat));
-      assert(glob->getLinkage() == linkage);
-
       if (isExtInit == MV_NotExternallyInitialized) {
         // A definition overrides a declaration for external var.
         glob->setExternallyInitialized(false);
+        glob->setConstant(isConstant == MV_Constant);
+        if (inComdat == MV_InComdat) {
+          assert(! gname.empty());
+          glob->setComdat(module().getOrInsertComdat(gname));
+        }
         if (alignment)
           glob->setAlignment(alignment);
         if (initializer)
@@ -2367,8 +2368,10 @@
                                                      const std::string &asmname,
                                                      Btype *btype)
 {
-  assert(false && "Llvm_backend::implicit_variable_reference not yet impl");
-  return nullptr;
+  bool is_external = true, is_hidden = false, in_unique_section = false;
+  Location location; // dummy
+  return global_variable(name, asmname, btype, is_external, is_hidden,
+                         in_unique_section, location);
 }
 
 // Create a named immutable initialized data structure.