OSDN Git Service

Add support for 'weak' linkage.
authorChris Lattner <sabre@nondot.org>
Thu, 16 Oct 2003 18:29:00 +0000 (18:29 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 16 Oct 2003 18:29:00 +0000 (18:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9171 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/llvmAsmParser.y
lib/Linker/LinkModules.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/CBackend/Writer.cpp
lib/Target/X86/Printer.cpp
lib/Target/X86/X86AsmPrinter.cpp
lib/Transforms/Utils/Linker.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Linker.cpp

index 3347e88..725f254 100644 (file)
@@ -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; };
 
index aa9a8fc..a71572b 100644 (file)
@@ -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;
index af33e4b..a34f3f7 100644 (file)
@@ -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) {
index af33e4b..a34f3f7 100644 (file)
@@ -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) {
index fbc6b6e..f8c006c 100644 (file)
@@ -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, "");
index fbc6b6e..f8c006c 100644 (file)
@@ -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, "");
index aa9a8fc..a71572b 100644 (file)
@@ -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;
index ea8f43c..9437b59 100644 (file)
@@ -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;
     }
index aa9a8fc..a71572b 100644 (file)
@@ -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;