Result = ConstantStruct::get(cast<StructType>(CPS->getType()), Operands);
} else if (isa<ConstantPointerNull>(CPV) || isa<UndefValue>(CPV)) {
Result = const_cast<Constant*>(CPV);
- } else if (const ConstantPacked *CP = dyn_cast<ConstantPacked>(CPV)) {
+ } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CPV)) {
std::vector<Constant*> Operands(CP->getNumOperands());
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
Operands[i] = cast<Constant>(RemapOperand(CP->getOperand(i), ValueMap));
- Result = ConstantPacked::get(Operands);
+ Result = ConstantVector::get(Operands);
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
std::vector<Constant*> Ops;
for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
ValueSymbolTable &ST = GV->getParent()->getValueSymbolTable();
// If there is a conflict, rename the conflict.
- GlobalValue *ConflictGV = cast_or_null<GlobalValue>(ST.lookup(Name));
- if (ConflictGV) {
+ if (GlobalValue *ConflictGV = cast_or_null<GlobalValue>(ST.lookup(Name))) {
assert(ConflictGV->hasInternalLinkage() &&
"Not conflicting with a static global, should link instead!");
- ConflictGV->setName(""); // Eliminate the conflict
- }
- GV->setName(Name); // Force the name back
- if (ConflictGV) {
- ConflictGV->setName(Name); // This will cause ConflictGV to get renamed
+ GV->takeName(ConflictGV);
+ ConflictGV->setName(Name); // This will cause ConflictGV to get renamed
assert(ConflictGV->getName() != Name && "ForceRenaming didn't work");
+ } else {
+ GV->setName(Name); // Force the name back
}
- assert(GV->getName() == Name && "ForceRenaming didn't work");
}
/// CopyGVAttributes - copy additional attributes (those not needed to construct
/// 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.
+/// 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, GlobalValue *Src,
GlobalValue::LinkageTypes <, bool &LinkFromSrc,
std::string *Err) {
return Error(Err, "Linking globals named '" + Src->getName() +
"': symbol multiply defined!");
}
+
+ // Check visibility
+ if (Dest && Src->getVisibility() != Dest->getVisibility())
+ return Error(Err, "Linking globals named '" + Src->getName() +
+ "': symbols have different visibilities!");
return false;
}
GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(),
SGV->isConstant(), SGV->getLinkage(), /*init*/0,
- SGV->getName(), Dest);
+ SGV->getName(), Dest, SGV->isThreadLocal());
// Propagate alignment, visibility and section info.
CopyGVAttributes(NewDGV, SGV);
GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(),
SGV->isConstant(), SGV->getLinkage(), /*init*/0,
- "", Dest);
+ "", Dest, SGV->isThreadLocal());
// Propagate alignment, section and visibility info.
NewDGV->setAlignment(DGV->getAlignment());
GlobalVariable *NewDGV =
new GlobalVariable(SGV->getType()->getElementType(),
DGV->isConstant(), DGV->getLinkage());
+ NewDGV->setThreadLocal(DGV->isThreadLocal());
CopyGVAttributes(NewDGV, DGV);
Dest->getGlobalList().insert(DGV, NewDGV);
DGV->replaceAllUsesWith(
return false;
}
+// LinkAlias - Loop through the alias in the src module and link them into the
+// dest module.
+static bool LinkAlias(Module *Dest, const Module *Src, std::string *Err) {
+ // Loop over all alias in the src module
+ for (Module::const_alias_iterator I = Src->alias_begin(),
+ E = Src->alias_end(); I != E; ++I) {
+ const GlobalAlias *GA = I;
+
+ GlobalValue *NewAliased = NULL;
+ const GlobalValue *Aliased = GA->getAliasedGlobal();
+ if (isa<GlobalVariable>(*Aliased))
+ NewAliased = Dest->getGlobalVariable(Aliased->getName());
+ else if (isa<Function>(*Aliased))
+ NewAliased = Dest->getFunction(Aliased->getName());
+ // FIXME: we should handle the bitcast alias.
+ assert(NewAliased && "Can't find the aliased GV.");
+
+ GlobalAlias *NewGA = new GlobalAlias(GA->getType(), GA->getLinkage(),
+ GA->getName(), NewAliased, Dest);
+ CopyGVAttributes(NewGA, GA);
+ }
+ return false;
+}
+
// LinkGlobalInits - Update the initializers in the Dest module now that all
// globals that may be referenced are in Dest.
RecursiveResolveTypes(SF->getType(), DF->getType(),
&Dest->getTypeSymbolTable(), "");
}
+
+ // Check visibility
+ if (DF && !DF->hasInternalLinkage() &&
+ SF->getVisibility() != DF->getVisibility())
+ return Error(Err, "Linking functions named '" + SF->getName() +
+ "': symbols have different visibilities!");
if (DF && DF->getType() != SF->getType()) {
if (DF->isDeclaration() && !SF->isDeclaration()) {
return Error(ErrorMsg,
"Appending variables linked with different const'ness!");
+ if (G1->getAlignment() != G2->getAlignment())
+ return Error(ErrorMsg,
+ "Appending variables with different alignment need to be linked!");
+
+ if (G1->getVisibility() != G2->getVisibility())
+ return Error(ErrorMsg,
+ "Appending variables with different visibility need to be linked!");
+
+ if (G1->getSection() != G2->getSection())
+ return Error(ErrorMsg,
+ "Appending variables with different section name need to be linked!");
+
unsigned NewSize = T1->getNumElements() + T2->getNumElements();
ArrayType *NewType = ArrayType::get(T1->getElementType(), NewSize);
// Create the new global variable...
GlobalVariable *NG =
new GlobalVariable(NewType, G1->isConstant(), G1->getLinkage(),
- /*init*/0, First->first, M);
+ /*init*/0, First->first, M, G1->isThreadLocal());
+
+ // Propagate alignment, visibility and section info.
+ CopyGVAttributes(NG, G1);
// Merge the initializer...
Inits.reserve(NewSize);
// If there were any appending global variables, link them together now.
if (LinkAppendingVars(Dest, AppendingVars, ErrorMsg)) return true;
+ // If there were any alias, link them now.
+ if (LinkAlias(Dest, Src, ErrorMsg)) return true;
+
// If the source library's module id is in the dependent library list of the
// destination library, remove it since that module is now linked in.
sys::Path modId;