diff options
-rw-r--r-- | docs/LangRef.html | 10 | ||||
-rw-r--r-- | include/llvm-c/Core.h | 4 | ||||
-rw-r--r-- | include/llvm/GlobalValue.h | 39 | ||||
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 9 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 3 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 1 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 31 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 10 | ||||
-rw-r--r-- | lib/Target/CppBackend/CPPBackend.cpp | 2 | ||||
-rw-r--r-- | lib/Target/Mangler.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 5 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 4 | ||||
-rw-r--r-- | test/Feature/linker_private_linkages.ll | 1 |
15 files changed, 91 insertions, 35 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html index 7422d72a59..b8897fd505 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -25,6 +25,7 @@ <li><a href="#linkage_private">'<tt>private</tt>' Linkage</a></li> <li><a href="#linkage_linker_private">'<tt>linker_private</tt>' Linkage</a></li> <li><a href="#linkage_linker_private_weak">'<tt>linker_private_weak</tt>' Linkage</a></li> + <li><a href="#linkage_linker_private_weak_def_auto">'<tt>linker_private_weak_def_auto</tt>' Linkage</a></li> <li><a href="#linkage_internal">'<tt>internal</tt>' Linkage</a></li> <li><a href="#linkage_available_externally">'<tt>available_externally</tt>' Linkage</a></li> <li><a href="#linkage_linkonce">'<tt>linkonce</tt>' Linkage</a></li> @@ -557,6 +558,15 @@ define i32 @main() { <i>; i32()* </i> linker. The symbols are removed by the linker from the final linked image (executable or dynamic library).</dd> + <dt><tt><b><a name="linkage_linker_private_weak_def_auto">linker_private_weak_def_auto</a></b></tt></dt> + <dd>Similar to "<tt>linker_private_weak</tt>", but it's known that the address + of the object is not taken. For instance, functions that had an inline + definition, but the compiler decided not to inline it. Note, + unlike <tt>linker_private</tt> and <tt>linker_private_weak</tt>, + <tt>linker_private_weak_def_auto</tt> may have only <tt>default</tt> + visibility. The symbols are removed by the linker from the final linked + image (executable or dynamic library).</dd> + <dt><tt><b><a name="linkage_internal">internal</a></b></tt></dt> <dd>Similar to private, but the value shows as a local symbol (<tt>STB_LOCAL</tt> in the case of ELF) in the object file. This diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 665dd0447c..20c6383211 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -227,7 +227,9 @@ typedef enum { LLVMGhostLinkage, /**< Obsolete */ LLVMCommonLinkage, /**< Tentative definitions */ LLVMLinkerPrivateLinkage, /**< Like Private, but linker removes. */ - LLVMLinkerPrivateWeakLinkage /**< Like LinkerPrivate, but is weak. */ + LLVMLinkerPrivateWeakLinkage, /**< Like LinkerPrivate, but is weak. */ + LLVMLinkerPrivateWeakDefAutoLinkage /**< Like LinkerPrivateWeak, but possibly + hidden. */ } LLVMLinkage; typedef enum { diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index f4bee85b45..62e84f8335 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -41,6 +41,8 @@ public: PrivateLinkage, ///< Like Internal, but omit from symbol table. LinkerPrivateLinkage, ///< Like Private, but linker removes. LinkerPrivateWeakLinkage, ///< Like LinkerPrivate, but weak. + LinkerPrivateWeakDefAutoLinkage, ///< Like LinkerPrivateWeak, but possibly + /// hidden. DLLImportLinkage, ///< Function to be imported from DLL DLLExportLinkage, ///< Function to be accessible from DLL. ExternalWeakLinkage,///< ExternalWeak linkage description. @@ -137,9 +139,13 @@ public: static bool isLinkerPrivateWeakLinkage(LinkageTypes Linkage) { return Linkage == LinkerPrivateWeakLinkage; } + static bool isLinkerPrivateWeakDefAutoLinkage(LinkageTypes Linkage) { + return Linkage == LinkerPrivateWeakDefAutoLinkage; + } static bool isLocalLinkage(LinkageTypes Linkage) { return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage) || - isLinkerPrivateLinkage(Linkage) || isLinkerPrivateWeakLinkage(Linkage); + isLinkerPrivateLinkage(Linkage) || isLinkerPrivateWeakLinkage(Linkage) || + isLinkerPrivateWeakDefAutoLinkage(Linkage); } static bool isDLLImportLinkage(LinkageTypes Linkage) { return Linkage == DLLImportLinkage; @@ -158,24 +164,26 @@ public: /// by something non-equivalent at link time. For example, if a function has /// weak linkage then the code defining it may be replaced by different code. static bool mayBeOverridden(LinkageTypes Linkage) { - return (Linkage == WeakAnyLinkage || - Linkage == LinkOnceAnyLinkage || - Linkage == CommonLinkage || - Linkage == ExternalWeakLinkage || - Linkage == LinkerPrivateWeakLinkage); + return Linkage == WeakAnyLinkage || + Linkage == LinkOnceAnyLinkage || + Linkage == CommonLinkage || + Linkage == ExternalWeakLinkage || + Linkage == LinkerPrivateWeakLinkage || + Linkage == LinkerPrivateWeakDefAutoLinkage; } /// isWeakForLinker - Whether the definition of this global may be replaced at /// link time. static bool isWeakForLinker(LinkageTypes Linkage) { - return (Linkage == AvailableExternallyLinkage || - Linkage == WeakAnyLinkage || - Linkage == WeakODRLinkage || - Linkage == LinkOnceAnyLinkage || - Linkage == LinkOnceODRLinkage || - Linkage == CommonLinkage || - Linkage == ExternalWeakLinkage || - Linkage == LinkerPrivateWeakLinkage); + return Linkage == AvailableExternallyLinkage || + Linkage == WeakAnyLinkage || + Linkage == WeakODRLinkage || + Linkage == LinkOnceAnyLinkage || + Linkage == LinkOnceODRLinkage || + Linkage == CommonLinkage || + Linkage == ExternalWeakLinkage || + Linkage == LinkerPrivateWeakLinkage || + Linkage == LinkerPrivateWeakDefAutoLinkage; } bool hasExternalLinkage() const { return isExternalLinkage(Linkage); } @@ -195,6 +203,9 @@ public: bool hasLinkerPrivateWeakLinkage() const { return isLinkerPrivateWeakLinkage(Linkage); } + bool hasLinkerPrivateWeakDefAutoLinkage() const { + return isLinkerPrivateWeakDefAutoLinkage(Linkage); + } bool hasLocalLinkage() const { return isLocalLinkage(Linkage); } bool hasDLLImportLinkage() const { return isDLLImportLinkage(Linkage); } bool hasDLLExportLinkage() const { return isDLLExportLinkage(Linkage); } diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index f4c0e50fd9..90696b950f 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -493,6 +493,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(private); KEYWORD(linker_private); KEYWORD(linker_private_weak); + KEYWORD(linker_private_weak_def_auto); KEYWORD(internal); KEYWORD(available_externally); KEYWORD(linkonce); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index dc545fff2d..0c5e04992f 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -199,6 +199,7 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_private: // OptionalLinkage case lltok::kw_linker_private: // OptionalLinkage case lltok::kw_linker_private_weak: // OptionalLinkage + case lltok::kw_linker_private_weak_def_auto: // OptionalLinkage case lltok::kw_internal: // OptionalLinkage case lltok::kw_weak: // OptionalLinkage case lltok::kw_weak_odr: // OptionalLinkage @@ -623,7 +624,8 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, Linkage != GlobalValue::InternalLinkage && Linkage != GlobalValue::PrivateLinkage && Linkage != GlobalValue::LinkerPrivateLinkage && - Linkage != GlobalValue::LinkerPrivateWeakLinkage) + Linkage != GlobalValue::LinkerPrivateWeakLinkage && + Linkage != GlobalValue::LinkerPrivateWeakDefAutoLinkage) return Error(LinkageLoc, "invalid linkage type for alias"); Constant *Aliasee; @@ -1008,6 +1010,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { /// ::= 'private' /// ::= 'linker_private' /// ::= 'linker_private_weak' +/// ::= 'linker_private_weak_def_auto' /// ::= 'internal' /// ::= 'weak' /// ::= 'weak_odr' @@ -1029,6 +1032,9 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { case lltok::kw_linker_private_weak: Res = GlobalValue::LinkerPrivateWeakLinkage; break; + case lltok::kw_linker_private_weak_def_auto: + Res = GlobalValue::LinkerPrivateWeakDefAutoLinkage; + break; case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break; case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break; case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break; @@ -2718,6 +2724,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { case GlobalValue::PrivateLinkage: case GlobalValue::LinkerPrivateLinkage: case GlobalValue::LinkerPrivateWeakLinkage: + case GlobalValue::LinkerPrivateWeakDefAutoLinkage: case GlobalValue::InternalLinkage: case GlobalValue::AvailableExternallyLinkage: case GlobalValue::LinkOnceAnyLinkage: diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 2703134ec1..e266db994e 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -37,7 +37,8 @@ namespace lltok { kw_declare, kw_define, kw_global, kw_constant, - kw_private, kw_linker_private, kw_linker_private_weak, kw_internal, + kw_private, kw_linker_private, kw_linker_private_weak, + kw_linker_private_weak_def_auto, kw_internal, kw_linkonce, kw_linkonce_odr, kw_weak, kw_weak_odr, kw_appending, kw_dllimport, kw_dllexport, kw_common, kw_available_externally, kw_default, kw_hidden, kw_protected, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 2010468824..2e86abfbc0 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -77,6 +77,7 @@ static GlobalValue::LinkageTypes GetDecodedLinkage(unsigned Val) { case 12: return GlobalValue::AvailableExternallyLinkage; case 13: return GlobalValue::LinkerPrivateLinkage; case 14: return GlobalValue::LinkerPrivateWeakLinkage; + case 15: return GlobalValue::LinkerPrivateWeakDefAutoLinkage; } } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 776c2d4495..390e4827fe 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -299,21 +299,22 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { static unsigned getEncodedLinkage(const GlobalValue *GV) { switch (GV->getLinkage()) { default: llvm_unreachable("Invalid linkage!"); - case GlobalValue::ExternalLinkage: return 0; - case GlobalValue::WeakAnyLinkage: return 1; - case GlobalValue::AppendingLinkage: return 2; - case GlobalValue::InternalLinkage: return 3; - case GlobalValue::LinkOnceAnyLinkage: return 4; - case GlobalValue::DLLImportLinkage: return 5; - case GlobalValue::DLLExportLinkage: return 6; - case GlobalValue::ExternalWeakLinkage: return 7; - case GlobalValue::CommonLinkage: return 8; - case GlobalValue::PrivateLinkage: return 9; - case GlobalValue::WeakODRLinkage: return 10; - case GlobalValue::LinkOnceODRLinkage: return 11; - case GlobalValue::AvailableExternallyLinkage: return 12; - case GlobalValue::LinkerPrivateLinkage: return 13; - case GlobalValue::LinkerPrivateWeakLinkage: return 14; + case GlobalValue::ExternalLinkage: return 0; + case GlobalValue::WeakAnyLinkage: return 1; + case GlobalValue::AppendingLinkage: return 2; + case GlobalValue::InternalLinkage: return 3; + case GlobalValue::LinkOnceAnyLinkage: return 4; + case GlobalValue::DLLImportLinkage: return 5; + case GlobalValue::DLLExportLinkage: return 6; + case GlobalValue::ExternalWeakLinkage: return 7; + case GlobalValue::CommonLinkage: return 8; + case GlobalValue::PrivateLinkage: return 9; + case GlobalValue::WeakODRLinkage: return 10; + case GlobalValue::LinkOnceODRLinkage: return 11; + case GlobalValue::AvailableExternallyLinkage: return 12; + case GlobalValue::LinkerPrivateLinkage: return 13; + case GlobalValue::LinkerPrivateWeakLinkage: return 14; + case GlobalValue::LinkerPrivateWeakDefAutoLinkage: return 15; } } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 25b8d99061..fa0b97fab6 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -200,11 +200,17 @@ void AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const { case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: case GlobalValue::LinkerPrivateWeakLinkage: + case GlobalValue::LinkerPrivateWeakDefAutoLinkage: if (MAI->getWeakDefDirective() != 0) { // .globl _foo OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); - // .weak_definition _foo - OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition); + + if ((GlobalValue::LinkageTypes)Linkage != + GlobalValue::LinkerPrivateWeakDefAutoLinkage) + // .weak_definition _foo + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition); + else + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate); } else if (MAI->getLinkOnceDirective() != 0) { // .globl _foo OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 3e21cd1de4..f08559f6e9 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -288,6 +288,8 @@ void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) { Out << "GlobalValue::LinkerPrivateLinkage"; break; case GlobalValue::LinkerPrivateWeakLinkage: Out << "GlobalValue::LinkerPrivateWeakLinkage"; break; + case GlobalValue::LinkerPrivateWeakDefAutoLinkage: + Out << "GlobalValue::LinkerPrivateWeakDefAutoLinkage"; break; case GlobalValue::AvailableExternallyLinkage: Out << "GlobalValue::AvailableExternallyLinkage "; break; case GlobalValue::LinkOnceAnyLinkage: diff --git a/lib/Target/Mangler.cpp b/lib/Target/Mangler.cpp index 2037a91145..49efe75d79 100644 --- a/lib/Target/Mangler.cpp +++ b/lib/Target/Mangler.cpp @@ -180,7 +180,8 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, ManglerPrefixTy PrefixTy = Mangler::Default; if (GV->hasPrivateLinkage() || isImplicitlyPrivate) PrefixTy = Mangler::Private; - else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage()) + else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage() || + GV->hasLinkerPrivateWeakDefAutoLinkage()) PrefixTy = Mangler::LinkerPrivate; // If this global has a name, handle it simply. diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index c925a7e339..c7f27c6263 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1435,6 +1435,9 @@ static void PrintLinkage(GlobalValue::LinkageTypes LT, case GlobalValue::LinkerPrivateWeakLinkage: Out << "linker_private_weak "; break; + case GlobalValue::LinkerPrivateWeakDefAutoLinkage: + Out << "linker_private_weak_def_auto "; + break; case GlobalValue::InternalLinkage: Out << "internal "; break; case GlobalValue::LinkOnceAnyLinkage: Out << "linkonce "; break; case GlobalValue::LinkOnceODRLinkage: Out << "linkonce_odr "; break; diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index f458051c31..e884404d8a 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -1069,6 +1069,8 @@ LLVMLinkage LLVMGetLinkage(LLVMValueRef Global) { return LLVMLinkerPrivateLinkage; case GlobalValue::LinkerPrivateWeakLinkage: return LLVMLinkerPrivateWeakLinkage; + case GlobalValue::LinkerPrivateWeakDefAutoLinkage: + return LLVMLinkerPrivateWeakDefAutoLinkage; case GlobalValue::DLLImportLinkage: return LLVMDLLImportLinkage; case GlobalValue::DLLExportLinkage: @@ -1122,6 +1124,9 @@ void LLVMSetLinkage(LLVMValueRef Global, LLVMLinkage Linkage) { case LLVMLinkerPrivateWeakLinkage: GV->setLinkage(GlobalValue::LinkerPrivateWeakLinkage); break; + case LLVMLinkerPrivateWeakDefAutoLinkage: + GV->setLinkage(GlobalValue::LinkerPrivateWeakDefAutoLinkage); + break; case LLVMDLLImportLinkage: GV->setLinkage(GlobalValue::DLLImportLinkage); break; diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 8ff1551424..a3f1510887 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -446,6 +446,10 @@ void Verifier::visitGlobalValue(GlobalValue &GV) { Assert1(GVar && GVar->getType()->getElementType()->isArrayTy(), "Only global arrays can have appending linkage!", GVar); } + + Assert1(!GV.hasLinkerPrivateWeakDefAutoLinkage() || GV.hasDefaultVisibility(), + "linker_private_weak_def_auto can only have default visibility!", + &GV); } void Verifier::visitGlobalVariable(GlobalVariable &GV) { diff --git a/test/Feature/linker_private_linkages.ll b/test/Feature/linker_private_linkages.ll index 19bcbb40aa..f9f2908756 100644 --- a/test/Feature/linker_private_linkages.ll +++ b/test/Feature/linker_private_linkages.ll @@ -4,3 +4,4 @@ @foo = linker_private hidden global i32 0 @bar = linker_private_weak hidden global i32 0 +@qux = linker_private_weak_def_auto global i32 0 |