diff options
43 files changed, 370 insertions, 192 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html index 83ea026c6b..0985cbd61e 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -545,11 +545,26 @@ All Global Variables and Functions have one of the following types of linkage: </dd> <dt><tt><b><a name="linkage_externweak">extern_weak</a></b></tt>: </dt> + <dd>The semantics of this linkage follow the ELF object file model: the symbol is weak until linked, if not linked, the symbol becomes null instead of being an undefined reference. </dd> + <dt><tt><b><a name="linkage_linkonce">linkonce_odr</a></b></tt>: </dt> + <dt><tt><b><a name="linkage_common">common_odr</a></b></tt>: </dt> + <dt><tt><b><a name="linkage_weak">weak_odr</a></b></tt>: </dt> + <dt><tt><b><a name="linkage_externweak">extern_weak_odr</a></b></tt>: </dt> + <dd>Some languages allow inequivalent globals to be merged, such as two + functions with different semantics. Other languages, such as <tt>C++</tt>, + ensure that only equivalent globals are ever merged (the "one definition + rule" - <tt>odr</tt>). Such languages can use the <tt>linkonce_odr</tt>, + <tt>common_odr</tt>, <tt>weak_odr</tt> and <tt>extern_weak_odr</tt> linkage + types to indicate that the global will only be merged with equivalent + globals. These linkage types are otherwise the same as their + non-<tt>odr</tt> versions. + </dd> + <dt><tt><b><a name="linkage_external">externally visible</a></b></tt>:</dt> <dd>If none of the above identifiers are used, the global is externally @@ -592,9 +607,9 @@ external (i.e., lacking any linkage declarations), they are accessible outside of the current module.</p> <p>It is illegal for a function <i>declaration</i> to have any linkage type other than "externally visible", <tt>dllimport</tt>, -or <tt>extern_weak</tt>.</p> -<p>Aliases can have only <tt>external</tt>, <tt>internal</tt> and <tt>weak</tt> -linkages.</p> +<tt>extern_weak</tt> or <tt>extern_weak_odr</tt>.</p> +<p>Aliases can have only <tt>external</tt>, <tt>internal</tt>, <tt>weak</tt> +or <tt>weak_odr</tt> linkages.</p> </div> <!-- ======================================================================= --> diff --git a/docs/ProgrammersManual.html b/docs/ProgrammersManual.html index 289a569024..cf46a97e68 100644 --- a/docs/ProgrammersManual.html +++ b/docs/ProgrammersManual.html @@ -3322,11 +3322,12 @@ never change at runtime).</p> <p>Create a new global variable of the specified type. If <tt>isConstant</tt> is true then the global variable will be marked as unchanging for the program. The Linkage parameter specifies the type of - linkage (internal, external, weak, linkonce, appending) for the variable. If - the linkage is InternalLinkage, WeakLinkage, or LinkOnceLinkage, then - the resultant global variable will have internal linkage. AppendingLinkage - concatenates together all instances (in different translation units) of the - variable into a single variable but is only applicable to arrays. See + linkage (internal, external, weak, linkonce, appending) for the variable. + If the linkage is InternalLinkage, WeakAnyLinkage, WeakODRLinkage, + LinkOnceAnyLinkage or LinkOnceODRLinkage, then the resultant + global variable will have internal linkage. AppendingLinkage concatenates + together all instances (in different translation units) of the variable + into a single variable but is only applicable to arrays. See the <a href="LangRef.html#modulestructure">LLVM Language Reference</a> for further details on linkage types. Optionally an initializer, a name, and the module to put the variable into may be specified for the global variable as diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index 6016ac61b5..5d8cff414f 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -115,16 +115,26 @@ typedef enum { typedef enum { LLVMExternalLinkage, /**< Externally visible function */ - LLVMLinkOnceLinkage, /**< Keep one copy of function when linking (inline)*/ - LLVMWeakLinkage, /**< Keep one copy of function when linking (weak) */ + LLVMLinkOnceAnyLinkage, /**< Keep one copy of function when linking (inline)*/ + LLVMLinkOnceODRLinkage, /**< Same, but only replaced by something + equivalent. */ + LLVMWeakAnyLinkage, /**< Keep one copy of function when linking (weak) */ + LLVMWeakODRLinkage, /**< Same, but only replaced by something + equivalent. */ LLVMAppendingLinkage, /**< Special purpose, only applies to global arrays */ LLVMInternalLinkage, /**< Rename collisions when linking (static functions) */ + LLVMPrivateLinkage, /**< Like Internal, but omit from symbol table */ LLVMDLLImportLinkage, /**< Function to be imported from DLL */ LLVMDLLExportLinkage, /**< Function to be accessible from DLL */ - LLVMExternalWeakLinkage,/**< ExternalWeak linkage description */ - LLVMGhostLinkage /**< Stand-in functions for streaming fns from + LLVMExternalWeakAnyLinkage,/**< ExternalWeak linkage description */ + LLVMExternalWeakODRLinkage,/**< Same, but only replaced by something + equivalent. */ + LLVMGhostLinkage, /**< Stand-in functions for streaming fns from bitcode */ + LLVMCommonAnyLinkage, /**< Tentative definitions */ + LLVMCommonODRLinkage /**< Same, but only replaced by something + equivalent. */ } LLVMLinkage; typedef enum { diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index 8fb5580d0d..33f50c907b 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -31,16 +31,20 @@ public: /// @brief An enumeration for the kinds of linkage for global values. enum LinkageTypes { ExternalLinkage = 0,///< Externally visible function - LinkOnceLinkage, ///< Keep one copy of function when linking (inline) - WeakLinkage, ///< Keep one copy of named function when linking (weak) + LinkOnceAnyLinkage, ///< Keep one copy of function when linking (inline) + LinkOnceODRLinkage, ///< Same, but only replaced by something equivalent. + WeakAnyLinkage, ///< Keep one copy of named function when linking (weak) + WeakODRLinkage, ///< Same, but only replaced by something equivalent. AppendingLinkage, ///< Special purpose, only applies to global arrays InternalLinkage, ///< Rename collisions when linking (static functions) PrivateLinkage, ///< Like Internal, but omit from symbol table DLLImportLinkage, ///< Function to be imported from DLL DLLExportLinkage, ///< Function to be accessible from DLL - ExternalWeakLinkage,///< ExternalWeak linkage description + ExternalWeakAnyLinkage,///< ExternalWeak linkage description + ExternalWeakODRLinkage,///< Same, but only replaced by something equivalent. GhostLinkage, ///< Stand-in functions for streaming fns from BC files - CommonLinkage ///< Tentative definitions + CommonAnyLinkage, ///< Tentative definitions + CommonODRLinkage ///< Same, but only replaced by something equivalent. }; /// @brief An enumeration for the kinds of visibility of global values. @@ -99,31 +103,67 @@ public: return reinterpret_cast<const PointerType*>(User::getType()); } - bool hasExternalLinkage() const { return Linkage == ExternalLinkage; } - bool hasLinkOnceLinkage() const { return Linkage == LinkOnceLinkage; } - bool hasWeakLinkage() const { return Linkage == WeakLinkage; } - bool hasCommonLinkage() const { return Linkage == CommonLinkage; } - bool hasAppendingLinkage() const { return Linkage == AppendingLinkage; } - bool hasInternalLinkage() const { return Linkage == InternalLinkage; } - bool hasPrivateLinkage() const { return Linkage == PrivateLinkage; } - bool hasLocalLinkage() const { + static LinkageTypes getLinkOnceLinkage(bool ODR) { + return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage; + } + static LinkageTypes getWeakLinkage(bool ODR) { + return ODR ? WeakODRLinkage : WeakAnyLinkage; + } + static LinkageTypes getCommonLinkage(bool ODR) { + return ODR ? CommonODRLinkage : CommonAnyLinkage; + } + static LinkageTypes getExternalWeakLinkage(bool ODR) { + return ODR ? ExternalWeakODRLinkage : ExternalWeakAnyLinkage; + } + + bool hasExternalLinkage() const { return Linkage == ExternalLinkage; } + bool hasLinkOnceLinkage() const { + return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage; + } + bool hasWeakLinkage() const { + return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage; + } + bool hasAppendingLinkage() const { return Linkage == AppendingLinkage; } + bool hasInternalLinkage() const { return Linkage == InternalLinkage; } + bool hasPrivateLinkage() const { return Linkage == PrivateLinkage; } + bool hasLocalLinkage() const { return Linkage == InternalLinkage || Linkage == PrivateLinkage; } - bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; } - bool hasDLLExportLinkage() const { return Linkage == DLLExportLinkage; } - bool hasExternalWeakLinkage() const { return Linkage == ExternalWeakLinkage; } - bool hasGhostLinkage() const { return Linkage == GhostLinkage; } + bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; } + bool hasDLLExportLinkage() const { return Linkage == DLLExportLinkage; } + bool hasExternalWeakLinkage() const { + return Linkage == ExternalWeakAnyLinkage || + Linkage == ExternalWeakODRLinkage; + } + bool hasGhostLinkage() const { return Linkage == GhostLinkage; } + bool hasCommonLinkage() const { + return Linkage == CommonAnyLinkage || Linkage == CommonODRLinkage; + } + void setLinkage(LinkageTypes LT) { Linkage = LT; } LinkageTypes getLinkage() const { return Linkage; } /// mayBeOverridden - Whether the definition of this global may be replaced - /// at link time. For example, if a function has weak linkage then the code - /// defining it may be replaced by different code. + /// 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. bool mayBeOverridden() const { - return (Linkage == WeakLinkage || - Linkage == LinkOnceLinkage || - Linkage == CommonLinkage || - Linkage == ExternalWeakLinkage); + return (Linkage == WeakAnyLinkage || + Linkage == LinkOnceAnyLinkage || + Linkage == CommonAnyLinkage || + Linkage == ExternalWeakAnyLinkage); + } + + /// isWeakForLinker - Whether the definition of this global may be replaced at + /// link time, whether the replacement is equivalent to the original or not. + bool isWeakForLinker() const { + return (Linkage == WeakAnyLinkage || + Linkage == WeakODRLinkage || + Linkage == LinkOnceAnyLinkage || + Linkage == LinkOnceODRLinkage || + Linkage == CommonAnyLinkage || + Linkage == CommonODRLinkage || + Linkage == ExternalWeakAnyLinkage || + Linkage == ExternalWeakODRLinkage); } /// copyAttributesFrom - copy all additional attributes (those not needed to diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index deb5c9bbfb..a063aa53ba 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -344,7 +344,7 @@ DIAnchor DIFactory::GetOrCreateAnchor(unsigned TAG, const char *Name) { if (GV->hasInitializer()) return SubProgramAnchor = DIAnchor(GV); - GV->setLinkage(GlobalValue::LinkOnceLinkage); + GV->setLinkage(GlobalValue::LinkOnceAnyLinkage); GV->setSection("llvm.metadata"); GV->setConstant(true); M.addTypeName("llvm.dbg.anchor.type", EltTy); diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index fb491d3278..6f1d5eefe8 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -456,15 +456,19 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(private); KEYWORD(internal); KEYWORD(linkonce); + KEYWORD(linkonce_odr); KEYWORD(weak); + KEYWORD(weak_odr); KEYWORD(appending); KEYWORD(dllimport); KEYWORD(dllexport); KEYWORD(common); + KEYWORD(common_odr); KEYWORD(default); KEYWORD(hidden); KEYWORD(protected); KEYWORD(extern_weak); + KEYWORD(extern_weak_odr); KEYWORD(external); KEYWORD(thread_local); KEYWORD(zeroinitializer); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 19f8415bba..90dd50743a 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -116,12 +116,16 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_private: // OptionalLinkage case lltok::kw_internal: // OptionalLinkage case lltok::kw_weak: // OptionalLinkage + case lltok::kw_weak_odr: // OptionalLinkage case lltok::kw_linkonce: // OptionalLinkage + case lltok::kw_linkonce_odr: // OptionalLinkage case lltok::kw_appending: // OptionalLinkage case lltok::kw_dllexport: // OptionalLinkage case lltok::kw_common: // OptionalLinkage + case lltok::kw_common_odr: // OptionalLinkage case lltok::kw_dllimport: // OptionalLinkage case lltok::kw_extern_weak: // OptionalLinkage + case lltok::kw_extern_weak_odr: // OptionalLinkage case lltok::kw_external: { // OptionalLinkage unsigned Linkage, Visibility; if (ParseOptionalLinkage(Linkage) || @@ -377,7 +381,8 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, return true; if (Linkage != GlobalValue::ExternalLinkage && - Linkage != GlobalValue::WeakLinkage && + Linkage != GlobalValue::WeakAnyLinkage && + Linkage != GlobalValue::WeakODRLinkage && Linkage != GlobalValue::InternalLinkage && Linkage != GlobalValue::PrivateLinkage) return Error(LinkageLoc, "invalid linkage type for alias"); @@ -461,7 +466,8 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, // present. Constant *Init = 0; if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage && - Linkage != GlobalValue::ExternalWeakLinkage && + Linkage != GlobalValue::ExternalWeakAnyLinkage && + Linkage != GlobalValue::ExternalWeakODRLinkage && Linkage != GlobalValue::ExternalLinkage)) { if (ParseGlobalValue(Ty, Init)) return true; @@ -576,10 +582,10 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, return 0; } - FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); + FwdVal = Function::Create(FT, GlobalValue::ExternalWeakAnyLinkage, Name, M); } else { FwdVal = new GlobalVariable(PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, Name, M); + GlobalValue::ExternalWeakAnyLinkage, 0, Name, M); } ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); @@ -620,10 +626,10 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) { Error(Loc, "function may not return opaque type"); return 0; } - FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M); + FwdVal = Function::Create(FT, GlobalValue::ExternalWeakAnyLinkage, "", M); } else { FwdVal = new GlobalVariable(PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, "", M); + GlobalValue::ExternalWeakAnyLinkage, 0, "", M); } ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); @@ -746,27 +752,36 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { /// ::= 'private' /// ::= 'internal' /// ::= 'weak' +/// ::= 'weak_odr' /// ::= 'linkonce' +/// ::= 'linkonce_odr' /// ::= 'appending' /// ::= 'dllexport' /// ::= 'common' +/// ::= 'common_odr' /// ::= 'dllimport' /// ::= 'extern_weak' +/// ::= 'extern_weak_odr' /// ::= 'external' bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { HasLinkage = false; switch (Lex.getKind()) { - default: Res = GlobalValue::ExternalLinkage; return false; - case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break; - case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break; - case lltok::kw_weak: Res = GlobalValue::WeakLinkage; break; - case lltok::kw_linkonce: Res = GlobalValue::LinkOnceLinkage; 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; - case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break; - case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break; - case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break; + default: Res = GlobalValue::ExternalLinkage; return false; + case lltok::kw_private: Res = GlobalValue::PrivateLinkage; 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; + case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break; + case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break; + case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break; + case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break; + case lltok::kw_common: Res = GlobalValue::CommonAnyLinkage; break; + case lltok::kw_common_odr: Res = GlobalValue::CommonODRLinkage; break; + case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break; + case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakAnyLinkage; break; + case lltok::kw_extern_weak_odr: + Res = GlobalValue::ExternalWeakODRLinkage; break; + case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break; } Lex.Lex(); HasLinkage = true; @@ -2074,21 +2089,25 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { case GlobalValue::ExternalLinkage: break; // always ok. case GlobalValue::DLLImportLinkage: - case GlobalValue::ExternalWeakLinkage: + case GlobalValue::ExternalWeakAnyLinkage: + case GlobalValue::ExternalWeakODRLinkage: if (isDefine) return Error(LinkageLoc, "invalid linkage for function definition"); break; case GlobalValue::PrivateLinkage: case GlobalValue::InternalLinkage: - case GlobalValue::LinkOnceLinkage: - case GlobalValue::WeakLinkage: + case GlobalValue::LinkOnceAnyLinkage: + case GlobalValue::LinkOnceODRLinkage: + case GlobalValue::WeakAnyLinkage: + case GlobalValue::WeakODRLinkage: case GlobalValue::DLLExportLinkage: if (!isDefine) return Error(LinkageLoc, "invalid linkage for function declaration"); break; case GlobalValue::AppendingLinkage: case GlobalValue::GhostLinkage: - case GlobalValue::CommonLinkage: + case GlobalValue::CommonAnyLinkage: + case GlobalValue::CommonODRLinkage: return Error(LinkageLoc, "invalid function linkage type"); } diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index e3bc908b6e..efdc77af81 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -36,9 +36,10 @@ namespace lltok { kw_declare, kw_define, kw_global, kw_constant, - kw_private, kw_internal, kw_linkonce, kw_weak, kw_appending, kw_dllimport, - kw_dllexport, kw_common, kw_default, kw_hidden, kw_protected, - kw_extern_weak, + kw_private, kw_internal, kw_linkonce, kw_linkonce_odr, kw_weak, kw_weak_odr, + kw_appending, kw_dllimport, kw_dllexport, kw_common, kw_common_odr, + kw_default, kw_hidden, kw_protected, + kw_extern_weak, kw_extern_weak_odr, kw_external, kw_thread_local, kw_zeroinitializer, kw_undef, kw_null, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 2ddfbe3a13..0fe6fc682c 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -59,15 +59,19 @@ static GlobalValue::LinkageTypes GetDecodedLinkage(unsigned Val) { switch (Val) { default: // Map unknown/new linkages to external case 0: return GlobalValue::ExternalLinkage; - case 1: return GlobalValue::WeakLinkage; + case 1: return GlobalValue::WeakAnyLinkage; case 2: return GlobalValue::AppendingLinkage; case 3: return GlobalValue::InternalLinkage; - case 4: return GlobalValue::LinkOnceLinkage; + case 4: return GlobalValue::LinkOnceAnyLinkage; case 5: return GlobalValue::DLLImportLinkage; case 6: return GlobalValue::DLLExportLinkage; - case 7: return GlobalValue::ExternalWeakLinkage; - case 8: return GlobalValue::CommonLinkage; + case 7: return GlobalValue::ExternalWeakAnyLinkage; + case 8: return GlobalValue::CommonAnyLinkage; case 9: return GlobalValue::PrivateLinkage; + case 10: return GlobalValue::WeakODRLinkage; + case 11: return GlobalValue::LinkOnceODRLinkage; + case 12: return GlobalValue::ExternalWeakODRLinkage; + case 13: return GlobalValue::CommonODRLinkage; } } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 5633f0ffad..fefffbedb6 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -276,15 +276,19 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) { default: assert(0 && "Invalid linkage!"); case GlobalValue::GhostLinkage: // Map ghost linkage onto external. case GlobalValue::ExternalLinkage: return 0; - case GlobalValue::WeakLinkage: return 1; + case GlobalValue::WeakAnyLinkage: return 1; case GlobalValue::AppendingLinkage: return 2; case GlobalValue::InternalLinkage: return 3; - case GlobalValue::LinkOnceLinkage: return 4; + 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::ExternalWeakAnyLinkage: return 7; + case GlobalValue::CommonAnyLinkage: return 8; case GlobalValue::PrivateLinkage: return 9; + case GlobalValue::WeakODRLinkage: return 10; + case GlobalValue::LinkOnceODRLinkage: return 11; + case GlobalValue::ExternalWeakODRLinkage: return 12; + case GlobalValue::CommonODRLinkage: return 13; } } diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 5c4957aba1..9181216b5a 100644 --- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -3135,9 +3135,8 @@ public: GlobalVariable *GV = getGlobalVariable(V); if (!GV) return false; - - if (GV->getLinkage() != GlobalValue::InternalLinkage - && GV->getLinkage() != GlobalValue::LinkOnceLinkage) + + if (!GV->hasInternalLinkage () && !GV->hasLinkOnceLinkage()) return false; DIDescriptor DI(GV); @@ -3449,8 +3448,10 @@ class DwarfException : public Dwarf { } // If corresponding function is weak definition, this should be too. - if ((linkage == Function::WeakLinkage || - linkage == Function::LinkOnceLinkage) && + if ((linkage == Function::WeakAnyLinkage || + linkage == Function::WeakODRLinkage || + linkage == Function::LinkOnceAnyLinkage || + linkage == Function::LinkOnceODRLinkage) && TAI->getWeakDefDirective()) O << TAI->getWeakDefDirective() << EHFrameInfo.FnName << "\n"; @@ -3461,8 +3462,10 @@ class DwarfException : public Dwarf { // unwind info is to be available for non-EH uses. if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory && - ((linkage != Function::WeakLinkage && - linkage != Function::LinkOnceLinkage) || + ((linkage != Function::WeakAnyLinkage && + linkage != Function::WeakODRLinkage && + linkage != Function::LinkOnceAnyLinkage && + linkage != Function::LinkOnceODRLinkage) || !TAI->getWeakDefDirective() || TAI->getSupportsWeakOmittedEHFrame())) { diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index 7cca74b1fb..ddc4e3588b 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -174,8 +174,10 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &F) { case GlobalValue::ExternalLinkage: FnSym.SetBind(ELFWriter::ELFSym::STB_GLOBAL); break; - case GlobalValue::LinkOnceLinkage: - case GlobalValue::WeakLinkage: + case GlobalValue::LinkOnceAnyLinkage: + case GlobalValue::LinkOnceODRLinkage: + case GlobalValue::WeakAnyLinkage: + case GlobalValue::WeakODRLinkage: FnSym.SetBind(ELFWriter::ELFSym::STB_WEAK); break; case GlobalValue::PrivateLinkage: diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp index 5b4de27b8a..56b1736b41 100644 --- a/lib/CodeGen/IntrinsicLowering.cpp +++ b/lib/CodeGen/IntrinsicLowering.cpp @@ -316,7 +316,7 @@ static Instruction *LowerPartSelect(CallInst *CI) { |