[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-17 Thread Reid Kleckner via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL349414: Update Microsoft name mangling scheme for exception 
specifiers in the type… (authored by rnk, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D55685?vs=178490=178542#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685

Files:
  cfe/trunk/include/clang/Basic/LangOptions.h
  cfe/trunk/lib/AST/MicrosoftMangle.cpp
  cfe/trunk/lib/Driver/ToolChains/MSVC.cpp
  cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Index: cfe/trunk/include/clang/Basic/LangOptions.h
===
--- cfe/trunk/include/clang/Basic/LangOptions.h
+++ cfe/trunk/include/clang/Basic/LangOptions.h
@@ -98,11 +98,14 @@
 
   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 @@
   }
 
   bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
-return MSCompatibilityVersion >= MajorVersion * 1000U;
+return MSCompatibilityVersion >= MajorVersion * 10U;
   }
 
   /// Reset all of the options that are not considered when building a
Index: cfe/trunk/lib/Driver/ToolChains/MSVC.cpp
===
--- cfe/trunk/lib/Driver/ToolChains/MSVC.cpp
+++ cfe/trunk/lib/Driver/ToolChains/MSVC.cpp
@@ -1286,7 +1286,7 @@
   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;
Index: cfe/trunk/lib/AST/MicrosoftMangle.cpp
===
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp
@@ -316,7 +316,8 @@
   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 @@
 
 mangleFunctionClass(FD);
 
-mangleFunctionType(FT, FD);
+mangleFunctionType(FT, FD, false, false);
   } else {
 Out << '9';
   }
@@ -2127,7 +2128,8 @@
 
 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 @@
   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(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,
Index: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
===
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp
@@ -5694,6 +5694,11 @@
   if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Version))
 return;
 
+  // The attribute expects a 

[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-17 Thread Zachary Henkel via Phabricator via cfe-commits
zahen added a comment.

I don't have check-in permission, so I'd appreciate if someone could handle the 
actual commit.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-17 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

lgtm, thanks!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-17 Thread Zachary Henkel via Phabricator via cfe-commits
zahen updated this revision to Diff 178490.
zahen added a comment.

Added support for msvc minor version as requested.  Tied the updated mangling 
scheme to C++17 & compatibility mode > 1912 (15.5).  Added additional tests.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685

Files:
  include/clang/Basic/LangOptions.h
  lib/AST/MicrosoftMangle.cpp
  lib/Driver/ToolChains/MSVC.cpp
  test/CodeGenCXX/mangle-ms-exception-spec.cpp

Index: test/CodeGenCXX/mangle-ms-exception-spec.cpp
===
--- test/CodeGenCXX/mangle-ms-exception-spec.cpp
+++ test/CodeGenCXX/mangle-ms-exception-spec.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -Wno-noexcept-type -fms-compatibility-version=19.12 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=NOCOMPAT
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-compatibility-version=19.12 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+// Prove that mangling only changed for noexcept types under /std:C++17, not all noexcept functions
+// CHECK-DAG: @"?nochange@@YAXXZ"
+void nochange() noexcept {}
+
+// CXX11-DAG: @"?a@@YAXP6AHXZ@Z"
+// NOCOMPAT-DAG: @"?a@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?a@@YAXP6AHX_E@Z"
+void a(int() noexcept) {}
+// CHECK-DAG: @"?b@@YAXP6AHXZ@Z"
+void b(int() noexcept(false)) {}
+// CXX11-DAG: @"?c@@YAXP6AHXZ@Z"
+// NOCOMPAT-DAG: @"?c@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?c@@YAXP6AHX_E@Z"
+void c(int() noexcept(true)) {}
+// CHECK-DAG: @"?d@@YAXP6AHXZ@Z"
+void d(int()) {}
+
+template 
+class e;
+template 
+class e {
+  // CXX11-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+  // NOCOMPAT-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+  // CXX17-DAG: @"?ee@?$e@$$A6AXX_E@@EEAAXXZ"
+  virtual T ee(U &&...) noexcept {};
+};
+
+e e1;
+
+template 
+class f;
+template 
+class f {
+  // CHECK-DAG: @"?ff@?$f@$$A6AXXZ@@EEAAXXZ"
+  virtual T ff(U &&...) noexcept {};
+};
+
+f f1;
Index: lib/Driver/ToolChains/MSVC.cpp
===
--- lib/Driver/ToolChains/MSVC.cpp
+++ lib/Driver/ToolChains/MSVC.cpp
@@ -1286,7 +1286,7 @@
   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;
Index: lib/AST/MicrosoftMangle.cpp
===
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -315,7 +315,8 @@
   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:
@@ -512,7 +513,7 @@
 
 mangleFunctionClass(FD);
 
-mangleFunctionType(FT, FD);
+mangleFunctionType(FT, FD, false, false);
   } else {
 Out << '9';
   }
@@ -2061,7 +2062,8 @@
 
 void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
  const FunctionDecl *D,
- bool ForceThisQuals) {
+ bool ForceThisQuals,
+ bool MangleExceptionSpec) {
   //  ::=  
   //   
   const FunctionProtoType *Proto = dyn_cast(T);
@@ -2194,7 +2196,12 @@
   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) {
@@ -2299,15 +2306,15 @@
 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 

[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-14 Thread Zachary Henkel via Phabricator via cfe-commits
zahen added a comment.

In D55685#1331810 , @zturner wrote:

> BTW, as far as updating the demangler, as long as it doesn't crash or 
> generate an error on a valid `_E` mangling, that should be sufficient (with a 
> test).  If you want bonus points you can make it print out `noexcept` when 
> you see the `_E`, but I won't require it as it's a bit of extra work.  If you 
> decide not to do that, I'll just file a bug for it so that we don't forget.


I have the full set of demangler updates ready to go and will upload shortly 
(Monday at the latest due to travel)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-14 Thread Zachary Turner via Phabricator via cfe-commits
zturner added a comment.

BTW, as far as updating the demangler, as long as it doesn't crash or generate 
an error on a valid `_E` mangling, that should be sufficient (with a test).  If 
you want bonus points you can make it print out `noexcept` when you see the 
`_E`, but I won't require it as it's a bit of extra work.  If you decide not to 
do that, I'll just file a bug for it so that we don't forget.




Comment at: lib/AST/MicrosoftMangle.cpp:2311-2314
+  if (FT->canThrow())
+Out << 'Z';
+  else
+Out << "_E";

rnk wrote:
> zahen wrote:
> > zturner wrote:
> > > I knew that the mangling changed whenever a pointer to a `noexcept` 
> > > function is passed as an argument, and we don't yet handle that, but I'm 
> > > surprised to hear that they changed an existing mangling, since it's a 
> > > hard ABI break.
> > > 
> > > Do you know the major and minor version numbers that this changed in?  
> > > I'd like to test it out for starters, but also since this is an ABI break 
> > > we would need to put it behind `-fms-compatibility-version` and only 
> > > mangle using the new scheme when the compatibility version is 
> > > sufficiently high.
> > It's only when a function is used as a type.  My original rathole was 
> > trying to enumerate all of the places where that could be, but instead I 
> > settled on "everywhere but the initial definition".  It's why false is 
> > passed in the 4th parameter on line 516.
> > 
> > I've confirmed this changed in 15.5 so I'll use that as the compat version.
> I see existing code that uses this pattern: 
> `getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015)`
> 
> The MSVCMajorVersion enum is symbolic, so I think you might have to multiply 
> it by a hundred and modify LangOptions::isCompatibleWithMSVC to multiply by 
> two fewer places.
> 
> I guess to fit with the existing enums we'd say MSVC2017_5, even though that 
> conflates VS and VC version numbers.
Ok, I see it now.  That should be fine.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-14 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: lib/AST/MicrosoftMangle.cpp:2311-2314
+  if (FT->canThrow())
+Out << 'Z';
+  else
+Out << "_E";

zahen wrote:
> zturner wrote:
> > I knew that the mangling changed whenever a pointer to a `noexcept` 
> > function is passed as an argument, and we don't yet handle that, but I'm 
> > surprised to hear that they changed an existing mangling, since it's a hard 
> > ABI break.
> > 
> > Do you know the major and minor version numbers that this changed in?  I'd 
> > like to test it out for starters, but also since this is an ABI break we 
> > would need to put it behind `-fms-compatibility-version` and only mangle 
> > using the new scheme when the compatibility version is sufficiently high.
> It's only when a function is used as a type.  My original rathole was trying 
> to enumerate all of the places where that could be, but instead I settled on 
> "everywhere but the initial definition".  It's why false is passed in the 4th 
> parameter on line 516.
> 
> I've confirmed this changed in 15.5 so I'll use that as the compat version.
I see existing code that uses this pattern: 
`getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015)`

The MSVCMajorVersion enum is symbolic, so I think you might have to multiply it 
by a hundred and modify LangOptions::isCompatibleWithMSVC to multiply by two 
fewer places.

I guess to fit with the existing enums we'd say MSVC2017_5, even though that 
conflates VS and VC version numbers.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-14 Thread Zachary Henkel via Phabricator via cfe-commits
zahen added a comment.

In D55685#1330717 , @zturner wrote:

> Also we still need to put this behind `-fms-compatibility-version`.  Finally, 
> it would be nice if you could also update the demangler 
> (`llvm/lib/Demangle/MicrosoftDemangle.cpp`)


This was introduced in 15.5 (1912).  What's the preferred way to represent that 
in clang code?




Comment at: lib/AST/MicrosoftMangle.cpp:2311-2314
+  if (FT->canThrow())
+Out << 'Z';
+  else
+Out << "_E";

zturner wrote:
> I knew that the mangling changed whenever a pointer to a `noexcept` function 
> is passed as an argument, and we don't yet handle that, but I'm surprised to 
> hear that they changed an existing mangling, since it's a hard ABI break.
> 
> Do you know the major and minor version numbers that this changed in?  I'd 
> like to test it out for starters, but also since this is an ABI break we 
> would need to put it behind `-fms-compatibility-version` and only mangle 
> using the new scheme when the compatibility version is sufficiently high.
It's only when a function is used as a type.  My original rathole was trying to 
enumerate all of the places where that could be, but instead I settled on 
"everywhere but the initial definition".  It's why false is passed in the 4th 
parameter on line 516.

I've confirmed this changed in 15.5 so I'll use that as the compat version.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-13 Thread Zachary Turner via Phabricator via cfe-commits
zturner added a comment.

Also we still need to put this behind `-fms-compatibility-version`.  Finally, 
it would be nice if you could also update the demangler 
(`llvm/lib/Demangle/MicrosoftDemangle.cpp`)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-13 Thread Zachary Turner via Phabricator via cfe-commits
zturner added a comment.

Ahh I read the new test cases, and all of the test cases are about the case 
where `noexcept` function is a parameter, so maybe this is actually the case I 
was referring to.  Can you add a test case for something like this:

  void f() noexcept { }

I get this:

  00A  SECT4  notype ()External | ?foo@@YAXXZ (void __cdecl 
foo(void))
  00B 0010 SECT4  notype ()External | ?bar@@YAXP6AXX_E@Z (void 
__cdecl bar(void (__cdecl*)(void) noexcept))

Showing that it is in fact only for function parameters.  So we should have a 
test to confirm that the behavior when the `noexcept` function is not a 
parameter remains `Z` (from the code it looks like this might be broken under 
this patch).


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-13 Thread Zachary Turner via Phabricator via cfe-commits
zturner added inline comments.



Comment at: lib/AST/MicrosoftMangle.cpp:2311-2314
+  if (FT->canThrow())
+Out << 'Z';
+  else
+Out << "_E";

I knew that the mangling changed whenever a pointer to a `noexcept` function is 
passed as an argument, and we don't yet handle that, but I'm surprised to hear 
that they changed an existing mangling, since it's a hard ABI break.

Do you know the major and minor version numbers that this changed in?  I'd like 
to test it out for starters, but also since this is an ABI break we would need 
to put it behind `-fms-compatibility-version` and only mangle using the new 
scheme when the compatibility version is sufficiently high.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55685/new/

https://reviews.llvm.org/D55685



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55685: Update Microsoft name mangling scheme for exception specifiers in the type system

2018-12-13 Thread Zachary Henkel via Phabricator via cfe-commits
zahen created this revision.
zahen added reviewers: zturner, rnk.
Herald added a subscriber: cfe-commits.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D55685

Files:
  lib/AST/MicrosoftMangle.cpp
  test/CodeGenCXX/mangle-ms-exception-spec.cpp

Index: test/CodeGenCXX/mangle-ms-exception-spec.cpp
===
--- test/CodeGenCXX/mangle-ms-exception-spec.cpp
+++ test/CodeGenCXX/mangle-ms-exception-spec.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 -Wno-noexcept-type | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
+// RUN: %clang_cc1 -std=c++17 -fms-extensions -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+
+// CXX11-DAG: @"?a@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?a@@YAXP6AHX_E@Z"
+void a(int() noexcept) {}
+// CHECK-DAG: @"?b@@YAXP6AHXZ@Z"
+void b(int() noexcept(false)) {}
+// CXX11-DAG: @"?c@@YAXP6AHXZ@Z"
+// CXX17-DAG: @"?c@@YAXP6AHX_E@Z"
+void c(int() noexcept(true)) {}
+// CHECK-DAG: @"?d@@YAXP6AHXZ@Z"
+void d(int()) {}
+
+template 
+class e;
+template 
+class e {
+  // CXX11-DAG: @"?ee@?$e@$$A6AXXZ@@EEAAXXZ"
+  // CXX17-DAG: @"?ee@?$e@$$A6AXX_E@@EEAAXXZ"
+  virtual T ee(U &&...) noexcept {};
+};
+
+e e1;
+
+template 
+class f;
+template 
+class f {
+  // CHECK-DAG: @"?ff@?$f@$$A6AXXZ@@EEAAXXZ"
+  virtual T ff(U &&...) noexcept {};
+};
+
+f f1;
Index: lib/AST/MicrosoftMangle.cpp
===
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -315,7 +315,8 @@
   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:
@@ -512,7 +513,7 @@
 
 mangleFunctionClass(FD);
 
-mangleFunctionType(FT, FD);
+mangleFunctionType(FT, FD, false, false);
   } else {
 Out << '9';
   }
@@ -2061,7 +2062,8 @@
 
 void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
  const FunctionDecl *D,
- bool ForceThisQuals) {
+ bool ForceThisQuals,
+ bool MangleExceptionSpec) {
   //  ::=  
   //   
   const FunctionProtoType *Proto = dyn_cast(T);
@@ -2194,7 +2196,10 @@
   Out << '@';
   }
 
-  mangleThrowSpecification(Proto);
+if (getASTContext().getLangOpts().CPlusPlus17 && MangleExceptionSpec)
+  mangleThrowSpecification(Proto);
+else
+  Out << 'Z';
 }
 
 void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
@@ -2301,13 +2306,12 @@
 }
 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,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits