From 4d6bcd5b3263a86818db792ec700d8fb6333c8ea Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Mon, 17 Dec 2018 23:10:43 +0000 Subject: [PATCH] Update Microsoft name mangling scheme for exception specifiers in the type system Summary: The msvc exception specifier for noexcept function types has changed from the prior default of "Z" to "_E" if the function cannot throw when compiling with /std:C++17. Patch by Zachary Henkel! Reviewers: zturner, rnk Reviewed By: rnk Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D55685 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349414 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/LangOptions.h | 13 ++++++++----- lib/AST/MicrosoftMangle.cpp | 29 ++++++++++++++++++----------- lib/Driver/ToolChains/MSVC.cpp | 2 +- lib/Sema/SemaDeclAttr.cpp | 5 +++++ 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 34f510f5ca..b4f7fd867a 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -98,11 +98,14 @@ public: enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; + // Corresponds to _MSC_VER enum MSVCMajorVersion { - MSVC2010 = 16, - MSVC2012 = 17, - MSVC2013 = 18, - MSVC2015 = 19 + MSVC2010 = 1600, + MSVC2012 = 1700, + MSVC2013 = 1800, + MSVC2015 = 1900, + MSVC2017 = 1910, + MSVC2017_5 = 1912 }; /// Clang versions with different platform ABI conformance. @@ -271,7 +274,7 @@ public: } bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { - return MSCompatibilityVersion >= MajorVersion * 10000000U; + return MSCompatibilityVersion >= MajorVersion * 100000U; } /// Reset all of the options that are not considered when building a diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index db0d770d9a..caa3af598d 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -316,7 +316,8 @@ public: QualifierMangleMode QMM = QMM_Mangle); void mangleFunctionType(const FunctionType *T, const FunctionDecl *D = nullptr, - bool ForceThisQuals = false); + bool ForceThisQuals = false, + bool MangleExceptionSpec = true); void mangleNestedName(const NamedDecl *ND); private: @@ -513,7 +514,7 @@ void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD, mangleFunctionClass(FD); - mangleFunctionType(FT, FD); + mangleFunctionType(FT, FD, false, false); } else { Out << '9'; } @@ -2127,7 +2128,8 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T, void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, const FunctionDecl *D, - bool ForceThisQuals) { + bool ForceThisQuals, + bool MangleExceptionSpec) { // ::= // const FunctionProtoType *Proto = dyn_cast(T); @@ -2260,7 +2262,12 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, Out << '@'; } - mangleThrowSpecification(Proto); + if (MangleExceptionSpec && getASTContext().getLangOpts().CPlusPlus17 && + getASTContext().getLangOpts().isCompatibleWithMSVC( + LangOptions::MSVC2017_5)) + mangleThrowSpecification(Proto); + else + Out << 'Z'; } void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) { @@ -2365,15 +2372,15 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) { void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) { mangleCallingConvention(T->getCallConv()); } + void MicrosoftCXXNameMangler::mangleThrowSpecification( const FunctionProtoType *FT) { - // ::= Z # throw(...) (default) - // ::= @ # throw() or __declspec/__attribute__((nothrow)) - // ::= + - // NOTE: Since the Microsoft compiler ignores throw specifications, they are - // all actually mangled as 'Z'. (They're ignored because their associated - // functionality isn't implemented, and probably never will be.) - Out << 'Z'; + // ::= Z # (default) + // ::= _E # noexcept + if (FT->canThrow()) + Out << 'Z'; + else + Out << "_E"; } void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T, diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp index 839f313623..7e34b0df5c 100644 --- a/lib/Driver/ToolChains/MSVC.cpp +++ b/lib/Driver/ToolChains/MSVC.cpp @@ -1286,7 +1286,7 @@ VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D, if (MSVT.empty() && Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, IsWindowsMSVC)) { - // -fms-compatibility-version=19.11 is default, aka 2017 + // -fms-compatibility-version=19.11 is default, aka 2017, 15.3 MSVT = VersionTuple(19, 11); } return MSVT; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index ba041a8786..3e0fa53041 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -5694,6 +5694,11 @@ static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) { if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Version)) return; + // The attribute expects a "major" version number like 19, but new versions of + // MSVC have moved to updating the "minor", or less significant numbers, so we + // have to multiply by 100 now. + Version *= 100; + // TODO: Investigate what happens with the next major version of MSVC. if (Version != LangOptions::MSVC2015) { S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) -- 2.40.0