[clang] [MS ABI]: Support preserve_none in MS ABI (PR #96487)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 25 22:32:15 PDT 2024


https://github.com/antangelo updated https://github.com/llvm/llvm-project/pull/96487

>From 1e95098e324860268d55e72a14090f9524c7dde1 Mon Sep 17 00:00:00 2001
From: Antonio Abbatangelo <contact at antangelo.com>
Date: Mon, 24 Jun 2024 09:49:28 -0400
Subject: [PATCH 1/2] [MS ABI]: Support preserve_none in MS ABI

---
 clang/lib/AST/MicrosoftMangle.cpp             |  8 +++++-
 clang/lib/Basic/Targets/AArch64.cpp           |  1 +
 .../CodeGenCXX/msabi-preserve-none-cc.cpp     | 28 +++++++++++++++++++
 clang/test/Sema/preserve-none-call-conv.c     |  1 +
 4 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGenCXX/msabi-preserve-none-cc.cpp

diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 3923d34274703..b49a96f105cfb 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -2962,7 +2962,10 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
   //                      ::= J # __export __fastcall
   //                      ::= Q # __vectorcall
   //                      ::= S # __attribute__((__swiftcall__)) // Clang-only
-  //                      ::= T # __attribute__((__swiftasynccall__))
+  //                      ::= W # __attribute__((__swiftasynccall__))
+  //                      ::= U # __attribute__((__preserve_most__))
+  //                      ::= V # __attribute__((__preserve_none__)) //
+  //                      Clang-only
   //                            // Clang-only
   //                      ::= w # __regcall
   //                      ::= x # __regcall4
@@ -2986,6 +2989,9 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
     case CC_Swift: Out << 'S'; break;
     case CC_SwiftAsync: Out << 'W'; break;
     case CC_PreserveMost: Out << 'U'; break;
+    case CC_PreserveNone:
+      Out << 'V';
+      break;
     case CC_X86RegCall:
       if (getASTContext().getLangOpts().RegCall4)
         Out << "x";
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 31d8121b91d10..2692ddec26ff4 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1536,6 +1536,7 @@ WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
   case CC_OpenCLKernel:
   case CC_PreserveMost:
   case CC_PreserveAll:
+  case CC_PreserveNone:
   case CC_Swift:
   case CC_SwiftAsync:
   case CC_Win64:
diff --git a/clang/test/CodeGenCXX/msabi-preserve-none-cc.cpp b/clang/test/CodeGenCXX/msabi-preserve-none-cc.cpp
new file mode 100644
index 0000000000000..29df5e4d84a70
--- /dev/null
+++ b/clang/test/CodeGenCXX/msabi-preserve-none-cc.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s
+
+void __attribute__((__preserve_none__)) f() {}
+// CHECK-DAG: @"?f@@YVXXZ"
+
+void (__attribute__((__preserve_none__)) *p)();
+// CHECK-DAG: @"?p@@3P6VXXZEA
+
+namespace {
+void __attribute__((__preserve_none__)) __attribute__((__used__)) f() { }
+}
+// CHECK-DAG: @"?f@?A0x{{[^@]*}}@@YVXXZ"
+
+namespace n {
+void __attribute__((__preserve_none__)) f() {}
+}
+// CHECK-DAG: @"?f at n@@YVXXZ"
+
+struct __declspec(dllexport) S {
+  S(const S &) = delete;
+  S & operator=(const S &) = delete;
+  void __attribute__((__preserve_none__)) m() { }
+};
+// CHECK-DAG: @"?m at S@@QEAVXXZ"
+
+void f(void (__attribute__((__preserve_none__))())) {}
+// CHECK-DAG: @"?f@@YAXP6VXXZ at Z"
diff --git a/clang/test/Sema/preserve-none-call-conv.c b/clang/test/Sema/preserve-none-call-conv.c
index 4508095863de5..678fa7d5317e5 100644
--- a/clang/test/Sema/preserve-none-call-conv.c
+++ b/clang/test/Sema/preserve-none-call-conv.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify
+// RUN: %clang_cc1 %s -fsyntax-only -triple aarch64-unknown-unknown -verify
 
 typedef void typedef_fun_t(int);
 

>From 2f08dfbab5a2b92759a5a1d05a306dddbe5bdcf0 Mon Sep 17 00:00:00 2001
From: Antonio Abbatangelo <contact at antangelo.com>
Date: Wed, 26 Jun 2024 01:30:09 -0400
Subject: [PATCH 2/2] Emit error instead of abort on unsupported calling
 convention in MicrosoftMangle

---
 clang/lib/AST/MicrosoftMangle.cpp | 64 ++++++++++++++++++++++---------
 1 file changed, 45 insertions(+), 19 deletions(-)

diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index b49a96f105cfb..8cbaad62bf9d7 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -447,8 +447,8 @@ class MicrosoftCXXNameMangler {
   void mangleDecayedArrayType(const ArrayType *T);
   void mangleArrayType(const ArrayType *T);
   void mangleFunctionClass(const FunctionDecl *FD);
-  void mangleCallingConvention(CallingConv CC);
-  void mangleCallingConvention(const FunctionType *T);
+  void mangleCallingConvention(CallingConv CC, SourceRange Range);
+  void mangleCallingConvention(const FunctionType *T, SourceRange Range);
   void mangleIntegerLiteral(const llvm::APSInt &Number,
                             const NonTypeTemplateParmDecl *PD = nullptr,
                             QualType TemplateArgType = QualType());
@@ -888,7 +888,8 @@ void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
   Out << "$B";
   mangleNumber(OffsetInVFTable);
   Out << 'A';
-  mangleCallingConvention(MD->getType()->castAs<FunctionProtoType>());
+  mangleCallingConvention(MD->getType()->castAs<FunctionProtoType>(),
+                          MD->getSourceRange());
 }
 
 void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
@@ -2768,7 +2769,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
     mangleQualifiers(Quals, /*IsMember=*/false);
   }
 
-  mangleCallingConvention(CC);
+  mangleCallingConvention(CC, Range);
 
   // <return-type> ::= <type>
   //               ::= @ # structors (they have no declared return type)
@@ -2949,7 +2950,8 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
     Out << 'Y';
   }
 }
-void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
+void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC,
+                                                      SourceRange Range) {
   // <calling-convention> ::= A # __cdecl
   //                      ::= B # __export __cdecl
   //                      ::= C # __pascal
@@ -2977,31 +2979,55 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
 
   switch (CC) {
     default:
-      llvm_unreachable("Unsupported CC for mangling");
+      break;
     case CC_Win64:
     case CC_X86_64SysV:
-    case CC_C: Out << 'A'; break;
-    case CC_X86Pascal: Out << 'C'; break;
-    case CC_X86ThisCall: Out << 'E'; break;
-    case CC_X86StdCall: Out << 'G'; break;
-    case CC_X86FastCall: Out << 'I'; break;
-    case CC_X86VectorCall: Out << 'Q'; break;
-    case CC_Swift: Out << 'S'; break;
-    case CC_SwiftAsync: Out << 'W'; break;
-    case CC_PreserveMost: Out << 'U'; break;
+    case CC_C:
+      Out << 'A';
+      return;
+    case CC_X86Pascal:
+      Out << 'C';
+      return;
+    case CC_X86ThisCall:
+      Out << 'E';
+      return;
+    case CC_X86StdCall:
+      Out << 'G';
+      return;
+    case CC_X86FastCall:
+      Out << 'I';
+      return;
+    case CC_X86VectorCall:
+      Out << 'Q';
+      return;
+    case CC_Swift:
+      Out << 'S';
+      return;
+    case CC_SwiftAsync:
+      Out << 'W';
+      return;
+    case CC_PreserveMost:
+      Out << 'U';
+      return;
     case CC_PreserveNone:
       Out << 'V';
-      break;
+      return;
     case CC_X86RegCall:
       if (getASTContext().getLangOpts().RegCall4)
         Out << "x";
       else
         Out << "w";
-      break;
+      return;
   }
+
+  DiagnosticsEngine &Diags = Context.getDiags();
+  unsigned DiagID = Diags.getCustomDiagID(
+      DiagnosticsEngine::Error, "cannot mangle this calling convention yet");
+  Diags.Report(Range.getBegin(), DiagID) << Range;
 }
-void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) {
-  mangleCallingConvention(T->getCallConv());
+void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,
+                                                      SourceRange Range) {
+  mangleCallingConvention(T->getCallConv(), Range);
 }
 
 void MicrosoftCXXNameMangler::mangleThrowSpecification(



More information about the cfe-commits mailing list