mstorsjo created this revision. mstorsjo added reviewers: rnk, smeenai. This assumes that the library is an import library for a system dll (named e.g. libkernel32.a) or a static library; it won't work for import libraries for normal user dlls named e.g. libfoo.dll.a). Since ld.bfd doesn't support embedded defaultlibrary directives, this feature probably shouldn't see much use in the wider mingw ecosystem anyway.
This is an alternative to the MinGW specific logic in https://reviews.llvm.org/D53012. This supersedes everything of https://reviews.llvm.org/D52990. If this logic is placed elsewhere, half of https://reviews.llvm.org/D52990 still is required. Repository: rC Clang https://reviews.llvm.org/D53013 Files: lib/CodeGen/TargetInfo.cpp test/CodeGen/dependent-lib.c test/Driver/fsanitize.c
Index: test/Driver/fsanitize.c =================================================================== --- test/Driver/fsanitize.c +++ test/Driver/fsanitize.c @@ -17,9 +17,11 @@ // RUN: %clang -target i386-pc-win32 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32 // RUN: %clang -target i386-pc-win32 -fsanitize=undefined -x c++ %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32 --check-prefix=CHECK-UNDEFINED-WIN-CXX // RUN: %clang -target x86_64-pc-win32 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN64 +// RUN: %clang -target x86_64-w64-mingw32 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN64-MINGW // RUN: %clang -target x86_64-pc-win32 -fsanitize=undefined -x c++ %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN64 --check-prefix=CHECK-UNDEFINED-WIN-CXX // CHECK-UNDEFINED-WIN32: "--dependent-lib={{[^"]*}}ubsan_standalone-i386.lib" // CHECK-UNDEFINED-WIN64: "--dependent-lib={{[^"]*}}ubsan_standalone-x86_64.lib" +// CHECK-UNDEFINED-WIN64-MINGW: "--dependent-lib={{[^"]*}}libclang_rt.ubsan_standalone-x86_64.a" // CHECK-UNDEFINED-WIN-CXX: "--dependent-lib={{[^"]*}}ubsan_standalone_cxx{{[^"]*}}.lib" // CHECK-UNDEFINED-WIN-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}} Index: test/CodeGen/dependent-lib.c =================================================================== --- test/CodeGen/dependent-lib.c +++ test/CodeGen/dependent-lib.c @@ -1,11 +1,15 @@ // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple thumbv7-windows -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-pc-win32 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple x86_64-w64-mingw32 -emit-llvm -o - | FileCheck -check-prefix MINGW %s // RUN: %clang_cc1 %s --dependent-lib=msvcrt -triple i686-pc-linux -emit-llvm -o - | FileCheck -check-prefix LINUX %s // CHECK: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} // CHECK: ![[msvcrt]] = !{!"/DEFAULTLIB:msvcrt.lib"} +// MINGW: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} +// MINGW: ![[msvcrt]] = !{!"/DEFAULTLIB:libmsvcrt.a"} + // LINUX: !llvm.linker.options = !{![[msvcrt:[0-9]+]]} // LINUX: ![[msvcrt]] = !{!"-lmsvcrt"} Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -2330,41 +2330,56 @@ } }; -static std::string qualifyWindowsLibrary(llvm::StringRef Lib) { +static std::string qualifyWindowsLibrary(llvm::StringRef Lib, + bool MinGWLibraryNames) { // If the argument does not end in .lib, automatically add the suffix. // If the argument contains a space, enclose it in quotes. // This matches the behavior of MSVC. bool Quote = (Lib.find(" ") != StringRef::npos); std::string ArgStr = Quote ? "\"" : ""; - ArgStr += Lib; - if (!Lib.endswith_lower(".lib")) - ArgStr += ".lib"; + if (MinGWLibraryNames) { + if (!Lib.endswith_lower(".a") && !Lib.startswith_lower("lib") && + !Lib.contains('/') && !Lib.contains('\\')) { + ArgStr += "lib"; + ArgStr += Lib; + ArgStr += ".a"; + } else { + ArgStr += Lib; + } + } else { + ArgStr += Lib; + if (!Lib.endswith_lower(".lib")) + ArgStr += ".lib"; + } ArgStr += Quote ? "\"" : ""; return ArgStr; } class WinX86_32TargetCodeGenInfo : public X86_32TargetCodeGenInfo { public: WinX86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI, bool RetSmallStructInRegABI, bool Win32StructABI, - unsigned NumRegisterParameters) + unsigned NumRegisterParameters, bool MinGWLibraryNames) : X86_32TargetCodeGenInfo(CGT, DarwinVectorABI, RetSmallStructInRegABI, - Win32StructABI, NumRegisterParameters, false) {} + Win32StructABI, NumRegisterParameters, false), + MinGWLibraryNames(MinGWLibraryNames) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override; void getDependentLibraryOption(llvm::StringRef Lib, llvm::SmallString<24> &Opt) const override { Opt = "/DEFAULTLIB:"; - Opt += qualifyWindowsLibrary(Lib); + Opt += qualifyWindowsLibrary(Lib, MinGWLibraryNames); } void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value, llvm::SmallString<32> &Opt) const override { Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; } + + bool MinGWLibraryNames; }; static void addStackProbeTargetAttributes(const Decl *D, llvm::GlobalValue *GV, @@ -2390,8 +2405,9 @@ class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo { public: WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, - X86AVXABILevel AVXLevel) - : TargetCodeGenInfo(new WinX86_64ABIInfo(CGT)) {} + X86AVXABILevel AVXLevel, bool MinGWLibraryNames) + : TargetCodeGenInfo(new WinX86_64ABIInfo(CGT)), + MinGWLibraryNames(MinGWLibraryNames) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override; @@ -2413,14 +2429,16 @@ void getDependentLibraryOption(llvm::StringRef Lib, llvm::SmallString<24> &Opt) const override { Opt = "/DEFAULTLIB:"; - Opt += qualifyWindowsLibrary(Lib); + Opt += qualifyWindowsLibrary(Lib, MinGWLibraryNames); } void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value, llvm::SmallString<32> &Opt) const override { Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; } + + bool MinGWLibraryNames; }; void WinX86_64TargetCodeGenInfo::setTargetAttributes( @@ -4990,18 +5008,22 @@ class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { public: - WindowsAArch64TargetCodeGenInfo(CodeGenTypes &CGT, AArch64ABIInfo::ABIKind K) - : AArch64TargetCodeGenInfo(CGT, K) {} + WindowsAArch64TargetCodeGenInfo(CodeGenTypes &CGT, AArch64ABIInfo::ABIKind K, + bool MinGWLibraryNames) + : AArch64TargetCodeGenInfo(CGT, K), MinGWLibraryNames(MinGWLibraryNames) { + } void getDependentLibraryOption(llvm::StringRef Lib, llvm::SmallString<24> &Opt) const override { - Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib); + Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib, MinGWLibraryNames); } void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value, llvm::SmallString<32> &Opt) const override { Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; } + + bool MinGWLibraryNames; }; } @@ -5650,21 +5672,24 @@ class WindowsARMTargetCodeGenInfo : public ARMTargetCodeGenInfo { public: - WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIInfo::ABIKind K) - : ARMTargetCodeGenInfo(CGT, K) {} + WindowsARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIInfo::ABIKind K, + bool MinGWLibraryNames) + : ARMTargetCodeGenInfo(CGT, K), MinGWLibraryNames(MinGWLibraryNames) {} void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override; void getDependentLibraryOption(llvm::StringRef Lib, llvm::SmallString<24> &Opt) const override { - Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib); + Opt = "/DEFAULTLIB:" + qualifyWindowsLibrary(Lib, MinGWLibraryNames); } void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value, llvm::SmallString<32> &Opt) const override { Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; } + + bool MinGWLibraryNames; }; void WindowsARMTargetCodeGenInfo::setTargetAttributes( @@ -9099,8 +9124,8 @@ if (getTarget().getABI() == "darwinpcs") Kind = AArch64ABIInfo::DarwinPCS; else if (Triple.isOSWindows()) - return SetCGInfo( - new WindowsAArch64TargetCodeGenInfo(Types, AArch64ABIInfo::Win64)); + return SetCGInfo(new WindowsAArch64TargetCodeGenInfo( + Types, AArch64ABIInfo::Win64, Triple.isOSCygMing())); return SetCGInfo(new AArch64TargetCodeGenInfo(Types, Kind)); } @@ -9114,8 +9139,8 @@ case llvm::Triple::thumb: case llvm::Triple::thumbeb: { if (Triple.getOS() == llvm::Triple::Win32) { - return SetCGInfo( - new WindowsARMTargetCodeGenInfo(Types, ARMABIInfo::AAPCS_VFP)); + return SetCGInfo(new WindowsARMTargetCodeGenInfo( + Types, ARMABIInfo::AAPCS_VFP, Triple.isOSCygMing())); } ARMABIInfo::ABIKind Kind = ARMABIInfo::AAPCS; @@ -9187,11 +9212,13 @@ bool RetSmallStructInRegABI = X86_32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts); bool IsWin32FloatStructABI = Triple.isOSWindows() && !Triple.isOSCygMing(); + bool MinGWLibraryNames = Triple.isOSCygMing(); if (Triple.getOS() == llvm::Triple::Win32) { return SetCGInfo(new WinX86_32TargetCodeGenInfo( Types, IsDarwinVectorABI, RetSmallStructInRegABI, - IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters)); + IsWin32FloatStructABI, CodeGenOpts.NumRegisterParameters, + MinGWLibraryNames)); } else { return SetCGInfo(new X86_32TargetCodeGenInfo( Types, IsDarwinVectorABI, RetSmallStructInRegABI, @@ -9209,7 +9236,8 @@ switch (Triple.getOS()) { case llvm::Triple::Win32: - return SetCGInfo(new WinX86_64TargetCodeGenInfo(Types, AVXLevel)); + return SetCGInfo(new WinX86_64TargetCodeGenInfo(Types, AVXLevel, + Triple.isOSCygMing())); case llvm::Triple::PS4: return SetCGInfo(new PS4TargetCodeGenInfo(Types, AVXLevel)); default:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits