+/// CopyGVAttributes - copy additional attributes (those not needed to construct
+/// a GlobalValue) from the SrcGV to the DestGV.
+static void CopyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) {
+ // Use the maximum alignment, rather than just copying the alignment of SrcGV.
+ unsigned Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment());
+ DestGV->copyAttributesFrom(SrcGV);
+ DestGV->setAlignment(Alignment);
+}
+
+/// GetLinkageResult - 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, 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. It also performs
+/// visibility checks: we cannot link together two symbols with different
+/// visibilities.
+static bool GetLinkageResult(GlobalValue *Dest, const GlobalValue *Src,
+ GlobalValue::LinkageTypes <, bool &LinkFromSrc,
+ std::string *Err) {
+ assert((!Dest || !Src->hasInternalLinkage()) &&
+ "If Src has internal linkage, Dest shouldn't be set!");
+ if (!Dest) {
+ // Linking something to nothing.
+ LinkFromSrc = true;
+ LT = Src->getLinkage();
+ } else if (Src->isDeclaration()) {
+ // If Src is external or if both Src & Dest are external.. Just link the
+ // external globals, we aren't adding anything.
+ if (Src->hasDLLImportLinkage()) {
+ // If one of GVs has DLLImport linkage, result should be dllimport'ed.
+ if (Dest->isDeclaration()) {
+ LinkFromSrc = true;
+ LT = Src->getLinkage();
+ }
+ } else if (Dest->hasExternalWeakLinkage()) {
+ //If the Dest is weak, use the source linkage
+ LinkFromSrc = true;
+ LT = Src->getLinkage();
+ } else {
+ LinkFromSrc = false;
+ LT = Dest->getLinkage();
+ }
+ } else if (Dest->isDeclaration() && !Dest->hasDLLImportLinkage()) {
+ // If Dest is external but Src is not:
+ LinkFromSrc = true;
+ LT = Src->getLinkage();
+ } else if (Src->hasAppendingLinkage() || Dest->hasAppendingLinkage()) {
+ if (Src->getLinkage() != Dest->getLinkage())
+ return Error(Err, "Linking globals named '" + Src->getName() +
+ "': can only link appending global with another appending global!");
+ LinkFromSrc = true; // Special cased.
+ LT = Src->getLinkage();
+ } else if (Src->hasWeakLinkage() || Src->hasLinkOnceLinkage() ||
+ Src->hasCommonLinkage()) {
+ // At this point we know that Dest has LinkOnce, External*, Weak, Common,
+ // or DLL* linkage.
+ if ((Dest->hasLinkOnceLinkage() &&
+ (Src->hasWeakLinkage() || Src->hasCommonLinkage())) ||
+ Dest->hasExternalWeakLinkage()) {
+ LinkFromSrc = true;
+ LT = Src->getLinkage();
+ } else {
+ LinkFromSrc = false;
+ LT = Dest->getLinkage();
+ }
+ } else if (Dest->hasWeakLinkage() || Dest->hasLinkOnceLinkage() ||
+ Dest->hasCommonLinkage()) {
+ // At this point we know that Src has External* or DLL* linkage.
+ if (Src->hasExternalWeakLinkage()) {
+ LinkFromSrc = false;
+ LT = Dest->getLinkage();
+ } else {
+ LinkFromSrc = true;
+ LT = GlobalValue::ExternalLinkage;
+ }
+ } else {
+ assert((Dest->hasExternalLinkage() ||
+ Dest->hasDLLImportLinkage() ||
+ Dest->hasDLLExportLinkage() ||
+ Dest->hasExternalWeakLinkage()) &&
+ (Src->hasExternalLinkage() ||
+ Src->hasDLLImportLinkage() ||
+ Src->hasDLLExportLinkage() ||
+ Src->hasExternalWeakLinkage()) &&
+ "Unexpected linkage type!");
+ return Error(Err, "Linking globals named '" + Src->getName() +
+ "': symbol multiply defined!");
+ }
+
+ // Check visibility
+ if (Dest && Src->getVisibility() != Dest->getVisibility())
+ if (!Src->isDeclaration() && !Dest->isDeclaration())
+ return Error(Err, "Linking globals named '" + Src->getName() +
+ "': symbols have different visibilities!");
+ return false;
+}