diff options
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 23 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/Windows/dllexport.ll | 75 |
2 files changed, 98 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 6d0608f9baa..8e064714108 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -548,6 +548,29 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); } + if (TT.isOSBinFormatCOFF()) { + const auto &TLOF = + static_cast<const TargetLoweringObjectFileCOFF &>(getObjFileLowering()); + + std::string Flags; + raw_string_ostream OS(Flags); + + for (const auto &Function : M) + TLOF.emitLinkerFlagsForGlobal(OS, &Function, *Mang); + for (const auto &Global : M.globals()) + TLOF.emitLinkerFlagsForGlobal(OS, &Global, *Mang); + for (const auto &Alias : M.aliases()) + TLOF.emitLinkerFlagsForGlobal(OS, &Alias, *Mang); + + OS.flush(); + + // Output collected flags + if (!Flags.empty()) { + OutStreamer->SwitchSection(TLOF.getDrectveSection()); + OutStreamer->EmitBytes(Flags); + } + } + // The last attribute to be emitted is ABI_optimization_goals MCTargetStreamer &TS = *OutStreamer->getTargetStreamer(); ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); diff --git a/llvm/test/CodeGen/ARM/Windows/dllexport.ll b/llvm/test/CodeGen/ARM/Windows/dllexport.ll new file mode 100644 index 00000000000..27496208862 --- /dev/null +++ b/llvm/test/CodeGen/ARM/Windows/dllexport.ll @@ -0,0 +1,75 @@ +; RUN: llc -mtriple thumbv7--windows-itanium -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-GNU +; RUN: llc -mtriple thumbv7--windows-gnu -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-GNU +; RUN: llc -mtriple thumbv7--windows-msvc -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-MSVC + +define void @f() { + ret void +} + +define dllexport void @g() { + ret void +} + +define dllexport void @h() unnamed_addr { + ret void +} + +declare dllexport void @i() + +define linkonce_odr dllexport void @j() { + ret void +} + +define linkonce_odr dllexport void @k() alwaysinline { + ret void +} + +define weak_odr dllexport void @l() { + ret void +} + +@m = dllexport global i32 0, align 4 +@n = dllexport unnamed_addr constant i32 0 +@o = common dllexport global i32 0, align 4 +@p = weak_odr dllexport global i32 0, align 4 +@q = weak_odr dllexport unnamed_addr constant i32 0 + +@r = dllexport alias void (), void () * @f +@s = dllexport alias void (), void () * @g +@t = dllexport alias void (), void () * @f +@u = weak_odr dllexport alias void (), void () * @g + +; CHECK: .section .drectve +; CHECK-GNU-NOT: -export:f +; CHECK-GNU: -export:g +; CHECK-GNU-SAME: -export:h +; CHECK-GNU-NOT: -export:i +; CHECK-GNU-SAME: -export:j +; CHECK-GNU-SAME: -export:k +; CHECK-GNU-SAME: -export:l +; CHECK-GNU-SAME: -export:m,data +; CHECK-GNU-SAME: -export:n,data +; CHECK-GNU-SAME: -export:o,data +; CHECK-GNU-SAME: -export:p,data +; CHECK-GNU-SAME: -export:q,data +; CHECK-GNU-SAME: -export:r +; CHECK-GNU-SAME: -export:s +; CHECK-GNU-SAME: -export:t +; CHECK-GNU-SAME: -export:u +; CHECK-MSVC-NOT: /EXPORT:f +; CHECK-MSVC: /EXPORT:g +; CHECK-MSVC-SAME: /EXPORT:h +; CHECK-MSVC-NOT: /EXPORT:i +; CHECK-MSVC-SAME: /EXPORT:j +; CHECK-MSVC-SAME: /EXPORT:k +; CHECK-MSVC-SAME: /EXPORT:l +; CHECK-MSVC-SAME: /EXPORT:m,DATA +; CHECK-MSVC-SAME: /EXPORT:n,DATA +; CHECK-MSVC-SAME: /EXPORT:o,DATA +; CHECK-MSVC-SAME: /EXPORT:p,DATA +; CHECK-MSVC-SAME: /EXPORT:q,DATA +; CHECK-MSVC-SAME: /EXPORT:r +; CHECK-MSVC-SAME: /EXPORT:s +; CHECK-MSVC-SAME: /EXPORT:t +; CHECK-MSVC-SAME: /EXPORT:u + |