aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-10-16 18:29:00 +0000
committerChris Lattner <sabre@nondot.org>2003-10-16 18:29:00 +0000
commit72ac148d4964fbff950fe11a0eeeda73973b849b (patch)
treefde7ca11baf974328570db3b0d678d98e576fb30
parent6b25242a4ba80e8c3a8a2664eefeba9c69814012 (diff)
Add support for 'weak' linkage.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9171 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AsmParser/llvmAsmParser.y2
-rw-r--r--lib/Linker/LinkModules.cpp37
-rw-r--r--lib/Target/CBackend/CBackend.cpp4
-rw-r--r--lib/Target/CBackend/Writer.cpp4
-rw-r--r--lib/Target/X86/Printer.cpp4
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp4
-rw-r--r--lib/Transforms/Utils/Linker.cpp37
-rw-r--r--lib/VMCore/AsmWriter.cpp10
-rw-r--r--lib/VMCore/Linker.cpp37
9 files changed, 117 insertions, 22 deletions
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 3347e8833a..725f254757 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -763,7 +763,7 @@ OptAssign : Name '=' {
OptLinkage : INTERNAL { $$ = GlobalValue::InternalLinkage; } |
LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } |
- WEAK { $$ = GlobalValue::LinkOnceLinkage; /* FIXME */ } |
+ WEAK { $$ = GlobalValue::WeakLinkage; } |
APPENDING { $$ = GlobalValue::AppendingLinkage; } |
/*empty*/ { $$ = GlobalValue::ExternalLinkage; };
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index aa9a8fcafd..a71572bd33 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -433,6 +433,24 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
} else if (DGV->isExternal()) { // If DGV is external but SGV is not...
ValueMap.insert(std::make_pair(SGV, DGV));
DGV->setLinkage(SGV->getLinkage()); // Inherit linkage!
+ } else if (SGV->hasWeakLinkage()) {
+ // At this point we know that DGV has LinkOnce, Appending, Weak, or
+ // External linkage. If DGV is Appending, this is an error.
+ if (DGV->hasAppendingLinkage())
+ return Error(Err, "Linking globals named '" + SGV->getName() +
+ " ' with 'weak' and 'appending' linkage is not allowed!");
+ // Otherwise, just perform the link.
+ ValueMap.insert(std::make_pair(SGV, DGV));
+ } else if (DGV->hasWeakLinkage()) {
+ // At this point we know that SGV has LinkOnce, Appending, or External
+ // linkage. If SGV is Appending, this is an error.
+ if (SGV->hasAppendingLinkage())
+ return Error(Err, "Linking globals named '" + SGV->getName() +
+ " ' with 'weak' and 'appending' linkage is not allowed!");
+ if (!SGV->hasLinkOnceLinkage())
+ DGV->setLinkage(SGV->getLinkage()); // Inherit linkage!
+ ValueMap.insert(std::make_pair(SGV, DGV));
+
} else if (SGV->getLinkage() != DGV->getLinkage()) {
return Error(Err, "Global variables named '" + SGV->getName() +
"' have different linkage specifiers!");
@@ -505,7 +523,7 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
return Error(Err, "Global Variable Collision on '" +
SGV->getType()->getDescription() +"':%"+SGV->getName()+
" - Global variables have different initializers");
- } else if (DGV->hasLinkOnceLinkage()) {
+ } else if (DGV->hasLinkOnceLinkage() || DGV->hasWeakLinkage()) {
// Nothing is required, mapped values will take the new global
// automatically.
} else if (DGV->hasAppendingLinkage()) {
@@ -574,6 +592,16 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src,
ValueMap.insert(std::make_pair(SF, DF));
DF->setLinkage(SF->getLinkage());
+ } else if (SF->hasWeakLinkage()) {
+ // At this point we know that DF has LinkOnce, Weak, or External linkage.
+ ValueMap.insert(std::make_pair(SF, DF));
+
+ } else if (DF->hasWeakLinkage()) {
+ // At this point we know that SF has LinkOnce or External linkage.
+ ValueMap.insert(std::make_pair(SF, DF));
+ if (!SF->hasLinkOnceLinkage()) // Don't inherit linkonce linkage
+ DF->setLinkage(SF->getLinkage());
+
} else if (SF->getLinkage() != DF->getLinkage()) {
return Error(Err, "Functions named '" + SF->getName() +
"' have different linkage specifiers!");
@@ -667,10 +695,9 @@ static bool LinkFunctionBodies(Module *Dest, const Module *Src,
// DF not external SF external?
if (!DF->isExternal()) {
if (DF->hasLinkOnceLinkage()) continue; // No relinkage for link-once!
- if (Err)
- *Err = "Function '" + (SF->hasName() ? SF->getName() :std::string(""))
- + "' body multiply defined!";
- return true;
+ if (SF->hasWeakLinkage()) continue;
+ return Error(Err, "Function '" + SF->getName() +
+ "' body multiply defined!");
}
if (LinkFunctionBody(DF, SF, ValueMap, Err)) return true;
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index af33e4b85f..a34f3f7712 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -684,6 +684,8 @@ void CWriter::printModule(Module *M) {
printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
if (I->hasLinkOnceLinkage())
Out << " __attribute__((common))";
+ else if (I->hasWeakLinkage())
+ Out << " __attribute__((weak))";
if (!I->getInitializer()->isNullValue()) {
Out << " = " ;
writeOperand(I->getInitializer());
@@ -893,6 +895,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
FunctionInnards << ")";
// Print out the return type and the entire signature for that matter
printType(Out, F->getReturnType(), FunctionInnards.str());
+
+ if (F->hasWeakLinkage()) Out << " __attribute((weak))";
}
void CWriter::printFunction(Function *F) {
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index af33e4b85f..a34f3f7712 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -684,6 +684,8 @@ void CWriter::printModule(Module *M) {
printType(Out, I->getType()->getElementType(), Mang->getValueName(I));
if (I->hasLinkOnceLinkage())
Out << " __attribute__((common))";
+ else if (I->hasWeakLinkage())
+ Out << " __attribute__((weak))";
if (!I->getInitializer()->isNullValue()) {
Out << " = " ;
writeOperand(I->getInitializer());
@@ -893,6 +895,8 @@ void CWriter::printFunctionSignature(const Function *F, bool Prototype) {
FunctionInnards << ")";
// Print out the return type and the entire signature for that matter
printType(Out, F->getReturnType(), FunctionInnards.str());
+
+ if (F->hasWeakLinkage()) Out << " __attribute((weak))";
}
void CWriter::printFunction(Function *F) {
diff --git a/lib/Target/X86/Printer.cpp b/lib/Target/X86/Printer.cpp
index fbc6b6e1af..f8c006cfd1 100644
--- a/lib/Target/X86/Printer.cpp
+++ b/lib/Target/X86/Printer.cpp
@@ -948,7 +948,8 @@ bool Printer::doFinalization(Module &M) {
unsigned Align = TD.getTypeAlignment(C->getType());
if (C->isNullValue() &&
- (I->hasLinkOnceLinkage() || I->hasInternalLinkage())) {
+ (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
+ I->hasWeakLinkage() /* FIXME: Verify correct */)) {
SwitchSection(O, CurSection, ".data");
if (I->hasInternalLinkage())
O << "\t.local " << name << "\n";
@@ -961,6 +962,7 @@ bool Printer::doFinalization(Module &M) {
} else {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
+ case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
// Nonnull linkonce -> weak
O << "\t.weak " << name << "\n";
SwitchSection(O, CurSection, "");
diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp
index fbc6b6e1af..f8c006cfd1 100644
--- a/lib/Target/X86/X86AsmPrinter.cpp
+++ b/lib/Target/X86/X86AsmPrinter.cpp
@@ -948,7 +948,8 @@ bool Printer::doFinalization(Module &M) {
unsigned Align = TD.getTypeAlignment(C->getType());
if (C->isNullValue() &&
- (I->hasLinkOnceLinkage() || I->hasInternalLinkage())) {
+ (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
+ I->hasWeakLinkage() /* FIXME: Verify correct */)) {
SwitchSection(O, CurSection, ".data");
if (I->hasInternalLinkage())
O << "\t.local " << name << "\n";
@@ -961,6 +962,7 @@ bool Printer::doFinalization(Module &M) {
} else {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
+ case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
// Nonnull linkonce -> weak
O << "\t.weak " << name << "\n";
SwitchSection(O, CurSection, "");
diff --git a/lib/Transforms/Utils/Linker.cpp b/lib/Transforms/Utils/Linker.cpp
index aa9a8fcafd..a71572bd33 100644
--- a/lib/Transforms/Utils/Linker.cpp
+++ b/lib/Transforms/Utils/Linker.cpp
@@ -433,6 +433,24 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
} else if (DGV->isExternal()) { // If DGV is external but SGV is not...
ValueMap.insert(std::make_pair(SGV, DGV));
DGV->setLinkage(SGV->getLinkage()); // Inherit linkage!
+ } else if (SGV->hasWeakLinkage()) {
+ // At this point we know that DGV has LinkOnce, Appending, Weak, or
+ // External linkage. If DGV is Appending, this is an error.
+ if (DGV->hasAppendingLinkage())
+ return Error(Err, "Linking globals named '" + SGV->getName() +
+ " ' with 'weak' and 'appending' linkage is not allowed!");
+ // Otherwise, just perform the link.
+ ValueMap.insert(std::make_pair(SGV, DGV));
+ } else if (DGV->hasWeakLinkage()) {
+ // At this point we know that SGV has LinkOnce, Appending, or External
+ // linkage. If SGV is Appending, this is an error.
+ if (SGV->hasAppendingLinkage())
+ return Error(Err, "Linking globals named '" + SGV->getName() +
+ " ' with 'weak' and 'appending' linkage is not allowed!");
+ if (!SGV->hasLinkOnceLinkage())
+ DGV->setLinkage(SGV->getLinkage()); // Inherit linkage!
+ ValueMap.insert(std::make_pair(SGV, DGV));
+
} else if (SGV->getLinkage() != DGV->getLinkage()) {
return Error(Err, "Global variables named '" + SGV->getName() +
"' have different linkage specifiers!");
@@ -505,7 +523,7 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
return Error(Err, "Global Variable Collision on '" +
SGV->getType()->getDescription() +"':%"+SGV->getName()+
" - Global variables have different initializers");
- } else if (DGV->hasLinkOnceLinkage()) {
+ } else if (DGV->hasLinkOnceLinkage() || DGV->hasWeakLinkage()) {
// Nothing is required, mapped values will take the new global
// automatically.
} else if (DGV->hasAppendingLinkage()) {
@@ -574,6 +592,16 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src,
ValueMap.insert(std::make_pair(SF, DF));
DF->setLinkage(SF->getLinkage());
+ } else if (SF->hasWeakLinkage()) {
+ // At this point we know that DF has LinkOnce, Weak, or External linkage.
+ ValueMap.insert(std::make_pair(SF, DF));
+
+ } else if (DF->hasWeakLinkage()) {
+ // At this point we know that SF has LinkOnce or External linkage.
+ ValueMap.insert(std::make_pair(SF, DF));
+ if (!SF->hasLinkOnceLinkage()) // Don't inherit linkonce linkage
+ DF->setLinkage(SF->getLinkage());
+
} else if (SF->getLinkage() != DF->getLinkage()) {
return Error(Err, "Functions named '" + SF->getName() +
"' have different linkage specifiers!");
@@ -667,10 +695,9 @@ static bool LinkFunctionBodies(Module *Dest, const Module *Src,
// DF not external SF external?
if (!DF->isExternal()) {
if (DF->hasLinkOnceLinkage()) continue; // No relinkage for link-once!
- if (Err)
- *Err = "Function '" + (SF->hasName() ? SF->getName() :std::string(""))
- + "' body multiply defined!";
- return true;
+ if (SF->hasWeakLinkage()) continue;
+ return Error(Err, "Function '" + SF->getName() +
+ "' body multiply defined!");
}
if (LinkFunctionBody(DF, SF, ValueMap, Err)) return true;
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index ea8f43c985..9437b59c53 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -584,8 +584,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
Out << "external ";
else
switch (GV->getLinkage()) {
- case GlobalValue::InternalLinkage: Out << "internal "; break;
- case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
+ case GlobalValue::InternalLinkage: Out << "internal "; break;
+ case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
+ case GlobalValue::WeakLinkage: Out << "weak "; break;
case GlobalValue::AppendingLinkage: Out << "appending "; break;
case GlobalValue::ExternalLinkage: break;
}
@@ -652,8 +653,9 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << "declare ";
else
switch (F->getLinkage()) {
- case GlobalValue::InternalLinkage: Out << "internal "; break;
- case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
+ case GlobalValue::InternalLinkage: Out << "internal "; break;
+ case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
+ case GlobalValue::WeakLinkage: Out << "weak "; break;
case GlobalValue::AppendingLinkage: Out << "appending "; break;
case GlobalValue::ExternalLinkage: break;
}
diff --git a/lib/VMCore/Linker.cpp b/lib/VMCore/Linker.cpp
index aa9a8fcafd..a71572bd33 100644
--- a/lib/VMCore/Linker.cpp
+++ b/lib/VMCore/Linker.cpp
@@ -433,6 +433,24 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
} else if (DGV->isExternal()) { // If DGV is external but SGV is not...
ValueMap.insert(std::make_pair(SGV, DGV));
DGV->setLinkage(SGV->getLinkage()); // Inherit linkage!
+ } else if (SGV->hasWeakLinkage()) {
+ // At this point we know that DGV has LinkOnce, Appending, Weak, or
+ // External linkage. If DGV is Appending, this is an error.
+ if (DGV->hasAppendingLinkage())
+ return Error(Err, "Linking globals named '" + SGV->getName() +
+ " ' with 'weak' and 'appending' linkage is not allowed!");
+ // Otherwise, just perform the link.
+ ValueMap.insert(std::make_pair(SGV, DGV));
+ } else if (DGV->hasWeakLinkage()) {
+ // At this point we know that SGV has LinkOnce, Appending, or External
+ // linkage. If SGV is Appending, this is an error.
+ if (SGV->hasAppendingLinkage())
+ return Error(Err, "Linking globals named '" + SGV->getName() +
+ " ' with 'weak' and 'appending' linkage is not allowed!");
+ if (!SGV->hasLinkOnceLinkage())
+ DGV->setLinkage(SGV->getLinkage()); // Inherit linkage!
+ ValueMap.insert(std::make_pair(SGV, DGV));
+
} else if (SGV->getLinkage() != DGV->getLinkage()) {
return Error(Err, "Global variables named '" + SGV->getName() +
"' have different linkage specifiers!");
@@ -505,7 +523,7 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
return Error(Err, "Global Variable Collision on '" +
SGV->getType()->getDescription() +"':%"+SGV->getName()+
" - Global variables have different initializers");
- } else if (DGV->hasLinkOnceLinkage()) {
+ } else if (DGV->hasLinkOnceLinkage() || DGV->hasWeakLinkage()) {
// Nothing is required, mapped values will take the new global
// automatically.
} else if (DGV->hasAppendingLinkage()) {
@@ -574,6 +592,16 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src,
ValueMap.insert(std::make_pair(SF, DF));
DF->setLinkage(SF->getLinkage());
+ } else if (SF->hasWeakLinkage()) {
+ // At this point we know that DF has LinkOnce, Weak, or External linkage.
+ ValueMap.insert(std::make_pair(SF, DF));
+
+ } else if (DF->hasWeakLinkage()) {
+ // At this point we know that SF has LinkOnce or External linkage.
+ ValueMap.insert(std::make_pair(SF, DF));
+ if (!SF->hasLinkOnceLinkage()) // Don't inherit linkonce linkage
+ DF->setLinkage(SF->getLinkage());
+
} else if (SF->getLinkage() != DF->getLinkage()) {
return Error(Err, "Functions named '" + SF->getName() +
"' have different linkage specifiers!");
@@ -667,10 +695,9 @@ static bool LinkFunctionBodies(Module *Dest, const Module *Src,
// DF not external SF external?
if (!DF->isExternal()) {
if (DF->hasLinkOnceLinkage()) continue; // No relinkage for link-once!
- if (Err)
- *Err = "Function '" + (SF->hasName() ? SF->getName() :std::string(""))
- + "' body multiply defined!";
- return true;
+ if (SF->hasWeakLinkage()) continue;
+ return Error(Err, "Function '" + SF->getName() +
+ "' body multiply defined!");
}
if (LinkFunctionBody(DF, SF, ValueMap, Err)) return true;