+// FIXME: Duplicated from the gold plugin. This should be refactored somewhere.
+static bool isDeclaration(const GlobalValue &V) {
+ if (V.hasAvailableExternallyLinkage())
+ return true;
+
+ if (V.isMaterializable())
+ return false;
+
+ return V.isDeclaration();
+}
+
+bool ModuleLinker::shouldLinkFromSource(const GlobalValue &Dest,
+ const GlobalValue &Src) {
+ bool SrcIsDeclaration = isDeclaration(Src);
+ bool DestIsDeclaration = isDeclaration(Dest);
+
+ // FIXME: Make datalayout mandatory and just use getDataLayout().
+ DataLayout DL(Dest.getParent());
+
+ if (SrcIsDeclaration) {
+ // If Src is external or if both Src & Dest are external.. Just link the
+ // external globals, we aren't adding anything.
+ if (Src.hasDLLImportStorageClass())
+ // If one of GVs is marked as DLLImport, result should be dllimport'ed.
+ return DestIsDeclaration;
+ // If the Dest is weak, use the source linkage.
+ return Dest.hasExternalWeakLinkage();
+ }
+
+ if (DestIsDeclaration)
+ // If Dest is external but Src is not:
+ return true;
+
+ if (Src.hasCommonLinkage()) {
+ if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage())
+ return true;
+
+ if (!Dest.hasCommonLinkage())
+ return false;
+
+ uint64_t DestSize = DL.getTypeAllocSize(Dest.getType()->getElementType());
+ uint64_t SrcSize = DL.getTypeAllocSize(Src.getType()->getElementType());
+ return SrcSize > DestSize;
+ }
+
+ if (Src.isWeakForLinker()) {
+ assert(!Dest.hasExternalWeakLinkage());
+ assert(!Dest.hasAvailableExternallyLinkage());
+
+ if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage())
+ return true;
+
+ return false;
+ }
+
+ if (Dest.isWeakForLinker()) {
+ assert(Src.hasExternalLinkage());
+ return true;
+ }
+
+ assert(!Src.hasExternalWeakLinkage());
+ assert(!Dest.hasExternalWeakLinkage());
+ assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() &&
+ "Unexpected linkage type!");
+ return emitError("Linking globals named '" + Src.getName() +
+ "': symbol multiply defined!");
+}
+
+/// This analyzes the two global values and determines what the result will look
+/// like in the destination module. In particular, it computes the resultant
+/// linkage type and visibility, computes whether the global in the source
+/// should be copied over to the destination (replacing the existing one), and
+/// computes whether this linkage is an error or not.