Index: clang/lib/AST/ItaniumMangle.cpp =================================================================== --- clang/lib/AST/ItaniumMangle.cpp +++ clang/lib/AST/ItaniumMangle.cpp @@ -516,7 +516,9 @@ void mangleType(const TagType*); void mangleType(TemplateName); - static StringRef getCallingConvQualifierName(CallingConv CC); + StringRef getCallingConvQualifierName(CallingConv CC); + StringRef maybeQualifyCallingConv(StringRef CCQual, + LangOptions::ClangABI PrevVer); void mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo info); void mangleExtFunctionInfo(const FunctionType *T); void mangleBareFunctionType(const FunctionProtoType *T, bool MangleReturnType, @@ -2643,6 +2645,15 @@ } } +/// Use a vendor extension qualifier for this calling convention if the current +/// version is after the version before this mangling was introduced in clang. +StringRef +CXXNameMangler::maybeQualifyCallingConv(StringRef CCQual, + LangOptions::ClangABI PrevVer) { + auto CurrentABIVersion = getASTContext().getLangOpts().getClangABICompat(); + return (CurrentABIVersion > PrevVer) ? CCQual : ""; +} + StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) { switch (CC) { case CC_C: @@ -2663,15 +2674,16 @@ return ""; case CC_X86StdCall: - return "stdcall"; + return maybeQualifyCallingConv("stdcall", LangOptions::ClangABI::Ver7); case CC_X86FastCall: - return "fastcall"; + return maybeQualifyCallingConv("fastcall", LangOptions::ClangABI::Ver7); case CC_X86ThisCall: - return "thiscall"; + return maybeQualifyCallingConv("thiscall", LangOptions::ClangABI::Ver7); case CC_X86_64SysV: - return "sysv_abi"; + return maybeQualifyCallingConv("sysv_abi", LangOptions::ClangABI::Ver7); case CC_Win64: - return "ms_abi"; + return maybeQualifyCallingConv("ms_abi", LangOptions::ClangABI::Ver7); + case CC_Swift: return "swiftcall"; } Index: clang/test/CodeGenCXX/mangle-win-ccs-old.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/mangle-win-ccs-old.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-gnu -o - | FileCheck %s --check-prefix=MINGW32 +// RUN: %clang_cc1 %s -emit-llvm -triple i686-windows-gnu -o - -fclang-abi-compat=7 | FileCheck %s --check-prefix=MINGW32-OLD +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-windows-gnu -o - | FileCheck %s --check-prefix=MINGW64 +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-windows-gnu -o - -fclang-abi-compat=7 | FileCheck %s --check-prefix=MINGW64-OLD +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=LINUX +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-linux-gnu -o - -fclang-abi-compat=7 | FileCheck %s --check-prefix=LINUX-OLD + +#if defined(__i386__) && defined(__MINGW32__) +void cb_cdecl (void ( *cb)(int)) { cb(42); } +void cb_stdcall (void (__attribute__((stdcall )) *cb)(int)) { cb(42); } +void cb_fastcall(void (__attribute__((fastcall)) *cb)(int)) { cb(42); } +void cb_thiscall(void (__attribute__((thiscall)) *cb)(int)) { cb(42); } + +// MINGW32: define dso_local void @_Z8cb_cdeclPFviE(void (i32)* %cb) +// MINGW32: define dso_local void @_Z10cb_stdcallPU7stdcallFviE(void (i32)* %cb) +// MINGW32: define dso_local void @_Z11cb_fastcallPU8fastcallFviE(void (i32)* %cb) +// MINGW32: define dso_local void @_Z11cb_thiscallPU8thiscallFviE(void (i32)* %cb) + +// MINGW32-OLD: define dso_local void @_Z8cb_cdeclPFviE(void (i32)* %cb) +// MINGW32-OLD: define dso_local void @_Z10cb_stdcallPFviE(void (i32)* %cb) +// MINGW32-OLD: define dso_local void @_Z11cb_fastcallPFviE(void (i32)* %cb) +// MINGW32-OLD: define dso_local void @_Z11cb_thiscallPFviE(void (i32)* %cb) +#endif + +#if defined(__x86_64__) && defined(__MINGW32__) +void cb_sysvabi(void (__attribute__((sysv_abi)) *cb)(int)) { cb(42); } +void cb_msabi (void (__attribute__((ms_abi )) *cb)(int)) { cb(42); } + +// MINGW64: define dso_local void @_Z10cb_sysvabiPU8sysv_abiFviE(void (i32)* %cb) +// MINGW64: define dso_local void @_Z8cb_msabiPFviE(void (i32)* %cb) + +// MINGW64-OLD: define dso_local void @_Z10cb_sysvabiPFviE(void (i32)* %cb) +// MINGW64-OLD: define dso_local void @_Z8cb_msabiPFviE(void (i32)* %cb) +#endif + +#if defined(__x86_64__) && defined(__linux__) +void cb_sysvabi(void (__attribute__((sysv_abi)) *cb)(int)) { cb(42); } +void cb_msabi (void (__attribute__((ms_abi )) *cb)(int)) { cb(42); } + +// LINUX: define void @_Z10cb_sysvabiPFviE(void (i32)* %cb) +// LINUX: define void @_Z8cb_msabiPU6ms_abiFviE(void (i32)* %cb) + +// LINUX-OLD: define void @_Z10cb_sysvabiPFviE(void (i32)* %cb) +// LINUX-OLD: define void @_Z8cb_msabiPFviE(void (i32)* %cb) +#endif