Add a new "available_externally" linkage type.  This is intended
to support C99 inline, GNU extern inline, etc.  Related bugzilla's
include PR3517, PR3100, & PR2933.  Nothing uses this yet, but it
appears to work.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68940 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index d4815d8..b227af2 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -487,6 +487,7 @@
 
   KEYWORD(private);
   KEYWORD(internal);
+  KEYWORD(available_externally);
   KEYWORD(linkonce);
   KEYWORD(linkonce_odr);
   KEYWORD(weak);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 177161e..d92957a 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -764,6 +764,9 @@
   case lltok::kw_weak_odr:     Res = GlobalValue::WeakODRLinkage; break;
   case lltok::kw_linkonce:     Res = GlobalValue::LinkOnceAnyLinkage; break;
   case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break;
+  case lltok::kw_available_externally:
+    Res = GlobalValue::AvailableExternallyLinkage;
+    break;
   case lltok::kw_appending:    Res = GlobalValue::AppendingLinkage; break;
   case lltok::kw_dllexport:    Res = GlobalValue::DLLExportLinkage; break;
   case lltok::kw_common:       Res = GlobalValue::CommonLinkage; break;
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 35cb4db..d8bd38a 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -37,7 +37,7 @@
     kw_global,  kw_constant,
 
     kw_private, kw_internal, kw_linkonce, kw_linkonce_odr, kw_weak, kw_weak_odr,
-    kw_appending, kw_dllimport, kw_dllexport, kw_common,
+    kw_appending, kw_dllimport, kw_dllexport, kw_common,kw_available_externally,
     kw_default, kw_hidden, kw_protected,
     kw_extern_weak,
     kw_external, kw_thread_local,
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 6f91dda..8079acd 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -70,6 +70,7 @@
   case 9: return GlobalValue::PrivateLinkage;
   case 10: return GlobalValue::WeakODRLinkage;
   case 11: return GlobalValue::LinkOnceODRLinkage;
+  case 12: return GlobalValue::AvailableExternallyLinkage;
   }
 }
 
diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp
index c836d39..1937c7e 100644
--- a/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -287,6 +287,7 @@
   case GlobalValue::PrivateLinkage:      return 9;
   case GlobalValue::WeakODRLinkage:      return 10;
   case GlobalValue::LinkOnceODRLinkage:  return 11;
+  case GlobalValue::AvailableExternallyLinkage:  return 12;
   }
 }
 
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d19e9af..0979ced 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -443,7 +443,9 @@
   }
 
   // Ignore debug and non-emitted data.
-  if (GV->getSection() == "llvm.metadata") return true;
+  if (GV->getSection() == "llvm.metadata" ||
+      GV->hasAvailableExternallyLinkage())
+    return true;
   
   if (!GV->hasAppendingLinkage()) return false;
 
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index d59609b..4582f4a 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -3519,6 +3519,9 @@
   ///
   void EmitEHFrame(const FunctionEHFrameInfo &EHFrameInfo) {
     Function::LinkageTypes linkage = EHFrameInfo.function->getLinkage();
+    
+    assert(!EHFrameInfo.function->hasAvailableExternallyLinkage() && 
+           "Should not emit 'available externally' functions at all");
 
     Asm->SwitchToTextSection(TAI->getDwarfEHFrameSection());
 
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index bd7105f..18a040e 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -38,8 +38,14 @@
 static AnnotationID MF_AID(
   AnnotationManager::getID("CodeGen::MachineCodeForFunction"));
 
-// Out of line virtual function to home classes.
-void MachineFunctionPass::virtfn() {}
+bool MachineFunctionPass::runOnFunction(Function &F) {
+  // Do not codegen any 'available_externally' functions at all, they have
+  // definitions outside the translation unit.
+  if (F.hasAvailableExternallyLinkage())
+    return false;
+  
+  return runOnMachineFunction(MachineFunction::get(&F));
+}
 
 namespace {
   struct VISIBILITY_HIDDEN Printer : public MachineFunctionPass {
diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp
index 0ca4e10..4a15d88 100644
--- a/lib/Linker/LinkModules.cpp
+++ b/lib/Linker/LinkModules.cpp
@@ -480,9 +480,10 @@
   } else if (Src->isWeakForLinker()) {
     // At this point we know that Dest has LinkOnce, External*, Weak, Common,
     // or DLL* linkage.
-    if ((Dest->hasLinkOnceLinkage() &&
-          (Src->hasWeakLinkage() || Src->hasCommonLinkage())) ||
-        Dest->hasExternalWeakLinkage()) {
+    if (Dest->hasExternalWeakLinkage() ||
+        Dest->hasAvailableExternallyLinkage() ||
+        (Dest->hasLinkOnceLinkage() &&
+         (Src->hasWeakLinkage() || Src->hasCommonLinkage()))) {
       LinkFromSrc = true;
       LT = Src->getLinkage();
     } else {
diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp
index 8262408..e89d5f9 100644
--- a/lib/Target/CppBackend/CPPBackend.cpp
+++ b/lib/Target/CppBackend/CPPBackend.cpp
@@ -294,6 +294,8 @@
       Out << "GlobalValue::InternalLinkage"; break;
     case GlobalValue::PrivateLinkage:
       Out << "GlobalValue::PrivateLinkage"; break;
+    case GlobalValue::AvailableExternallyLinkage:
+      Out << "GlobalValue::AvailableExternallyLinkage "; break;
     case GlobalValue::LinkOnceAnyLinkage:
       Out << "GlobalValue::LinkOnceAnyLinkage "; break;
     case GlobalValue::LinkOnceODRLinkage:
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp
index b1bf42e..e4dd9d6 100644
--- a/lib/VMCore/AsmWriter.cpp
+++ b/lib/VMCore/AsmWriter.cpp
@@ -1225,6 +1225,9 @@
   switch (LT) {
   case GlobalValue::PrivateLinkage:     Out << "private "; break;
   case GlobalValue::InternalLinkage:    Out << "internal "; break;
+  case GlobalValue::AvailableExternallyLinkage:
+    Out << "available_externally ";
+    break;
   case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break;
   case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break;
   case GlobalValue::WeakAnyLinkage:     Out << "weak "; break;