Index: llvm/trunk/lib/Object/RecordStreamer.cpp =================================================================== --- llvm/trunk/lib/Object/RecordStreamer.cpp +++ llvm/trunk/lib/Object/RecordStreamer.cpp @@ -149,6 +149,7 @@ for (auto &Symver : SymverAliasMap) { const MCSymbol *Aliasee = Symver.first; MCSymbolAttr Attr = MCSA_Invalid; + bool IsDefined = false; // First check if the aliasee binding was recorded in the asm. RecordStreamer::State state = getSymbolState(Aliasee); @@ -165,26 +166,52 @@ break; } - // If we don't have a symbol attribute from assembly, then check if - // the aliasee was defined in the IR. - if (Attr == MCSA_Invalid) { - const auto *GV = M.getNamedValue(Aliasee->getName()); + switch (state) { + case RecordStreamer::Defined: + case RecordStreamer::DefinedGlobal: + case RecordStreamer::DefinedWeak: + IsDefined = true; + break; + case RecordStreamer::NeverSeen: + case RecordStreamer::Global: + case RecordStreamer::Used: + case RecordStreamer::UndefinedWeak: + break; + } + + if (Attr == MCSA_Invalid || !IsDefined) { + const GlobalValue *GV = M.getNamedValue(Aliasee->getName()); if (!GV) { auto MI = MangledNameMap.find(Aliasee->getName()); if (MI != MangledNameMap.end()) GV = MI->second; } if (GV) { - if (GV->hasExternalLinkage()) - Attr = MCSA_Global; - else if (GV->hasLocalLinkage()) - Attr = MCSA_Local; - else if (GV->isWeakForLinker()) - Attr = MCSA_Weak; + // If we don't have a symbol attribute from assembly, then check if + // the aliasee was defined in the IR. + if (Attr == MCSA_Invalid) { + if (GV->hasExternalLinkage()) + Attr = MCSA_Global; + else if (GV->hasLocalLinkage()) + Attr = MCSA_Local; + else if (GV->isWeakForLinker()) + Attr = MCSA_Weak; + } + IsDefined = IsDefined || !GV->isDeclarationForLinker(); } } + // Set the detected binding on each alias with this aliasee. for (auto AliasName : Symver.second) { + std::pair Split = AliasName.split("@@@"); + SmallString<128> NewName; + if (!Split.second.empty() && !Split.second.startswith("@")) { + // Special processing for "@@@" according + // https://sourceware.org/binutils/docs/as/Symver.html + const char *Separator = IsDefined ? "@@" : "@"; + AliasName = + (Split.first + Separator + Split.second).toStringRef(NewName); + } MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName); // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be // converted into @ or @@. Index: llvm/trunk/test/LTO/X86/symver-asm3.ll =================================================================== --- llvm/trunk/test/LTO/X86/symver-asm3.ll +++ llvm/trunk/test/LTO/X86/symver-asm3.ll @@ -0,0 +1,40 @@ +; Test special handling of @@@. + +; RUN: llvm-as < %s >%t1 +; RUN: llvm-nm %t1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +module asm "foo1:" +; CHECK-DAG: t foo1 + +module asm ".symver foo1, foo@@@VER1" +; CHECK-DAG: t foo@@VER1 + +module asm ".symver foo2, foo@@@VER2" +; CHECK-DAG: U foo2 +; CHECK-DAG: t foo@VER2 + +module asm ".symver foo3, foo@@@VER3" +; CHECK-DAG: t foo@@VER3 + +module asm ".symver foo4, foo@@@VER4" +; CHECK-DAG: T foo@@VER4 + +module asm ".symver foo5, foo@@@VER5" +; CHECK-DAG: T foo@VER5 + +module asm "foo3:" +; CHECK-DAG: t foo3 + +module asm ".local foo1" +module asm ".local foo3" + +define void @foo4() { +; CHECK-DAG: T foo4 + ret void +} + +declare void @foo5() +; CHECK-DAG: U foo5