Skip to content

Commit 5dcf3d5

Browse files
authored
[MS ABI]: Support preserve_none in MS ABI (#96487)
Fixes ICE when compiling preserve_nonecc functions on Windows and adds support for the calling convention on AArch64 for Windows targets.
1 parent c7adfb5 commit 5dcf3d5

File tree

4 files changed

+81
-19
lines changed

4 files changed

+81
-19
lines changed

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,8 @@ class MicrosoftCXXNameMangler {
447447
void mangleDecayedArrayType(const ArrayType *T);
448448
void mangleArrayType(const ArrayType *T);
449449
void mangleFunctionClass(const FunctionDecl *FD);
450-
void mangleCallingConvention(CallingConv CC);
451-
void mangleCallingConvention(const FunctionType *T);
450+
void mangleCallingConvention(CallingConv CC, SourceRange Range);
451+
void mangleCallingConvention(const FunctionType *T, SourceRange Range);
452452
void mangleIntegerLiteral(const llvm::APSInt &Number,
453453
const NonTypeTemplateParmDecl *PD = nullptr,
454454
QualType TemplateArgType = QualType());
@@ -888,7 +888,8 @@ void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(
888888
Out << "$B";
889889
mangleNumber(OffsetInVFTable);
890890
Out << 'A';
891-
mangleCallingConvention(MD->getType()->castAs<FunctionProtoType>());
891+
mangleCallingConvention(MD->getType()->castAs<FunctionProtoType>(),
892+
MD->getSourceRange());
892893
}
893894

894895
void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {
@@ -2768,7 +2769,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
27682769
mangleQualifiers(Quals, /*IsMember=*/false);
27692770
}
27702771

2771-
mangleCallingConvention(CC);
2772+
mangleCallingConvention(CC, Range);
27722773

27732774
// <return-type> ::= <type>
27742775
// ::= @ # structors (they have no declared return type)
@@ -2949,7 +2950,8 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
29492950
Out << 'Y';
29502951
}
29512952
}
2952-
void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
2953+
void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC,
2954+
SourceRange Range) {
29532955
// <calling-convention> ::= A # __cdecl
29542956
// ::= B # __export __cdecl
29552957
// ::= C # __pascal
@@ -2962,7 +2964,10 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
29622964
// ::= J # __export __fastcall
29632965
// ::= Q # __vectorcall
29642966
// ::= S # __attribute__((__swiftcall__)) // Clang-only
2965-
// ::= T # __attribute__((__swiftasynccall__))
2967+
// ::= W # __attribute__((__swiftasynccall__))
2968+
// ::= U # __attribute__((__preserve_most__))
2969+
// ::= V # __attribute__((__preserve_none__)) //
2970+
// Clang-only
29662971
// // Clang-only
29672972
// ::= w # __regcall
29682973
// ::= x # __regcall4
@@ -2974,28 +2979,55 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
29742979

29752980
switch (CC) {
29762981
default:
2977-
llvm_unreachable("Unsupported CC for mangling");
2982+
break;
29782983
case CC_Win64:
29792984
case CC_X86_64SysV:
2980-
case CC_C: Out << 'A'; break;
2981-
case CC_X86Pascal: Out << 'C'; break;
2982-
case CC_X86ThisCall: Out << 'E'; break;
2983-
case CC_X86StdCall: Out << 'G'; break;
2984-
case CC_X86FastCall: Out << 'I'; break;
2985-
case CC_X86VectorCall: Out << 'Q'; break;
2986-
case CC_Swift: Out << 'S'; break;
2987-
case CC_SwiftAsync: Out << 'W'; break;
2988-
case CC_PreserveMost: Out << 'U'; break;
2985+
case CC_C:
2986+
Out << 'A';
2987+
return;
2988+
case CC_X86Pascal:
2989+
Out << 'C';
2990+
return;
2991+
case CC_X86ThisCall:
2992+
Out << 'E';
2993+
return;
2994+
case CC_X86StdCall:
2995+
Out << 'G';
2996+
return;
2997+
case CC_X86FastCall:
2998+
Out << 'I';
2999+
return;
3000+
case CC_X86VectorCall:
3001+
Out << 'Q';
3002+
return;
3003+
case CC_Swift:
3004+
Out << 'S';
3005+
return;
3006+
case CC_SwiftAsync:
3007+
Out << 'W';
3008+
return;
3009+
case CC_PreserveMost:
3010+
Out << 'U';
3011+
return;
3012+
case CC_PreserveNone:
3013+
Out << 'V';
3014+
return;
29893015
case CC_X86RegCall:
29903016
if (getASTContext().getLangOpts().RegCall4)
29913017
Out << "x";
29923018
else
29933019
Out << "w";
2994-
break;
3020+
return;
29953021
}
3022+
3023+
DiagnosticsEngine &Diags = Context.getDiags();
3024+
unsigned DiagID = Diags.getCustomDiagID(
3025+
DiagnosticsEngine::Error, "cannot mangle this calling convention yet");
3026+
Diags.Report(Range.getBegin(), DiagID) << Range;
29963027
}
2997-
void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T) {
2998-
mangleCallingConvention(T->getCallConv());
3028+
void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,
3029+
SourceRange Range) {
3030+
mangleCallingConvention(T->getCallConv(), Range);
29993031
}
30003032

30013033
void MicrosoftCXXNameMangler::mangleThrowSpecification(

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,7 @@ WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
15361536
case CC_OpenCLKernel:
15371537
case CC_PreserveMost:
15381538
case CC_PreserveAll:
1539+
case CC_PreserveNone:
15391540
case CC_Swift:
15401541
case CC_SwiftAsync:
15411542
case CC_Win64:
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -triple aarch64-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s
3+
4+
void __attribute__((__preserve_none__)) f() {}
5+
// CHECK-DAG: @"?f@@YVXXZ"
6+
7+
void (__attribute__((__preserve_none__)) *p)();
8+
// CHECK-DAG: @"?p@@3P6VXXZEA
9+
10+
namespace {
11+
void __attribute__((__preserve_none__)) __attribute__((__used__)) f() { }
12+
}
13+
// CHECK-DAG: @"?f@?A0x{{[^@]*}}@@YVXXZ"
14+
15+
namespace n {
16+
void __attribute__((__preserve_none__)) f() {}
17+
}
18+
// CHECK-DAG: @"?f@n@@YVXXZ"
19+
20+
struct __declspec(dllexport) S {
21+
S(const S &) = delete;
22+
S & operator=(const S &) = delete;
23+
void __attribute__((__preserve_none__)) m() { }
24+
};
25+
// CHECK-DAG: @"?m@S@@QEAVXXZ"
26+
27+
void f(void (__attribute__((__preserve_none__))())) {}
28+
// CHECK-DAG: @"?f@@YAXP6VXXZ@Z"

clang/test/Sema/preserve-none-call-conv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 %s -fsyntax-only -triple x86_64-unknown-unknown -verify
2+
// RUN: %clang_cc1 %s -fsyntax-only -triple aarch64-unknown-unknown -verify
23

34
typedef void typedef_fun_t(int);
45

0 commit comments

Comments
 (0)