Skip to content

Commit 139c510

Browse files
committed
[clang-cl][AST] Fix auto NTTP MSVC 1920+ mangling
1 parent 5529278 commit 139c510

File tree

3 files changed

+98
-3
lines changed

3 files changed

+98
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ ABI Changes in This Version
8383
- Fixed Microsoft calling convention when returning classes that have a deleted
8484
copy assignment operator. Such a class should be returned indirectly.
8585

86+
- Fixed Microsoft name mangling for auto non-type template arguments of pointer
87+
type for MSVC 1920+. This change resolves incompatibilities with code compiled
88+
by MSVC 1920+ but will introduce incompatibilities with code compiled by
89+
earlier versions of Clang unless such code is built with the compiler option
90+
`-fms-compatibility-version=19.14` to imitate the MSVC 1914 mangling behavior.
91+
92+
8693
AST Dumping Potentially Breaking Changes
8794
----------------------------------------
8895

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,11 @@ class MicrosoftCXXNameMangler {
372372
void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
373373
const CXXMethodDecl *MD,
374374
StringRef Prefix = "$");
375+
void mangleFunctionPointer(const FunctionDecl *FD,
376+
const NonTypeTemplateParmDecl *PD,
377+
QualType TemplateArgType);
378+
void mangleVarDecl(const VarDecl *VD, const NonTypeTemplateParmDecl *PD,
379+
QualType TemplateArgType);
375380
void mangleMemberFunctionPointerInClassNTTP(const CXXRecordDecl *RD,
376381
const CXXMethodDecl *MD);
377382
void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
@@ -799,6 +804,50 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
799804
mangleNumber(VBTableOffset);
800805
}
801806

807+
void MicrosoftCXXNameMangler::mangleFunctionPointer(
808+
const FunctionDecl *FD, const NonTypeTemplateParmDecl *PD,
809+
QualType TemplateArgType) {
810+
// <func-ptr> ::= $1? <mangled-name>
811+
// <func-ptr> ::= <auto-nttp>
812+
//
813+
// <auto-nttp> ::= $ M <type> 1? <mangled-name>
814+
Out << '$';
815+
816+
if (getASTContext().getLangOpts().isCompatibleWithMSVC(
817+
LangOptions::MSVC2019) &&
818+
PD && PD->getType()->getTypeClass() == Type::Auto &&
819+
!TemplateArgType.isNull()) {
820+
Out << "M";
821+
mangleType(TemplateArgType, SourceRange(), QMM_Drop);
822+
}
823+
824+
Out << "1?";
825+
mangleName(FD);
826+
mangleFunctionEncoding(FD, /*ShouldMangle=*/true);
827+
}
828+
829+
void MicrosoftCXXNameMangler::mangleVarDecl(const VarDecl *VD,
830+
const NonTypeTemplateParmDecl *PD,
831+
QualType TemplateArgType) {
832+
// <var-ptr> ::= $1? <mangled-name>
833+
// <var-ptr> ::= <auto-nttp>
834+
//
835+
// <auto-nttp> ::= $ M <type> 1? <mangled-name>
836+
Out << '$';
837+
838+
if (getASTContext().getLangOpts().isCompatibleWithMSVC(
839+
LangOptions::MSVC2019) &&
840+
PD && PD->getType()->getTypeClass() == Type::Auto &&
841+
!TemplateArgType.isNull()) {
842+
Out << "M";
843+
mangleType(TemplateArgType, SourceRange(), QMM_Drop);
844+
}
845+
846+
Out << "1?";
847+
mangleName(VD);
848+
mangleVariableEncoding(VD);
849+
}
850+
802851
void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
803852
const CXXRecordDecl *RD, const CXXMethodDecl *MD) {
804853
// <nttp-class-member-function-pointer> ::= <member-function-pointer>
@@ -1552,6 +1601,9 @@ void MicrosoftCXXNameMangler::mangleIntegerLiteral(
15521601
const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,
15531602
QualType TemplateArgType) {
15541603
// <integer-literal> ::= $0 <number>
1604+
// <integer-literal> ::= <auto-nttp>
1605+
//
1606+
// <auto-nttp> ::= $ M <type> 0 <number>
15551607
Out << "$";
15561608

15571609
// Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when
@@ -1629,8 +1681,11 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
16291681
// ::= <member-data-pointer>
16301682
// ::= <member-function-pointer>
16311683
// ::= $ <constant-value>
1684+
// ::= $ <auto-nttp-constant-value>
16321685
// ::= <template-args>
16331686
//
1687+
// <auto-nttp-constant-value> ::= M <type> <constant-value>
1688+
//
16341689
// <constant-value> ::= 0 <number> # integer
16351690
// ::= 1 <mangled-name> # address of D
16361691
// ::= 2 <type> <typed-constant-value>* @ # struct
@@ -1678,15 +1733,17 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
16781733
mangleMemberFunctionPointer(
16791734
MD->getParent()->getMostRecentNonInjectedDecl(), MD);
16801735
} else {
1681-
Out << "$1?";
1682-
mangleName(FD);
1683-
mangleFunctionEncoding(FD, /*ShouldMangle=*/true);
1736+
mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
1737+
TA.getParamTypeForDecl());
16841738
}
16851739
} else if (TA.getParamTypeForDecl()->isRecordType()) {
16861740
Out << "$";
16871741
auto *TPO = cast<TemplateParamObjectDecl>(ND);
16881742
mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
16891743
TPO->getValue(), TplArgKind::ClassNTTP);
1744+
} else if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
1745+
mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
1746+
TA.getParamTypeForDecl());
16901747
} else {
16911748
mangle(ND, "$1?");
16921749
}

clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ auto AutoFunc() {
1818
return a;
1919
}
2020

21+
int Func();
22+
int Func2();
23+
24+
int i;
25+
int j;
26+
2127
void template_mangling() {
2228
AutoFunc<1>();
2329
// AFTER: call {{.*}} @"??$AutoFunc@$MH00@@YA?A?<auto>@@XZ"
@@ -44,4 +50,29 @@ void template_mangling() {
4450
AutoParmsTemplate<(unsigned long)1, 9223372036854775807LL> c2;
4551
// AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MK00$M_J0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
4652
// BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$00$0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
53+
54+
AutoFunc<&i>();
55+
// AFTER: call {{.*}} @"??$AutoFunc@$MPEAH1?i@@3HA@@YA?A?<auto>@@XZ"
56+
// BEFORE: call {{.*}} @"??$AutoFunc@$1?i@@3HA@@YA?A?<auto>@@XZ"
57+
58+
AutoParmTemplate<&i> auto_int_ptr;
59+
// AFTER: call {{.*}} @"??0?$AutoParmTemplate@$MPEAH1?i@@3HA@@QEAA@XZ"
60+
// BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$1?i@@3HA@@QEAA@XZ"
61+
62+
AutoParmsTemplate<&i, &j> auto_int_ptrs;
63+
// AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MPEAH1?i@@3HA$MPEAH1?j@@3HA@@QEAA@XZ"
64+
// BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$1?i@@3HA$1?j@@3HA@@QEAA@XZ"
65+
66+
AutoFunc<&Func>();
67+
// AFTER: call {{.*}} @"??$AutoFunc@$MP6AHXZ1?Func@@YAHXZ@@YA?A?<auto>@@XZ"
68+
// BEFORE: call {{.*}} @"??$AutoFunc@$1?Func@@YAHXZ@@YA?A?<auto>@@XZ"
69+
70+
AutoParmTemplate<&Func> auto_func_ptr;
71+
// AFTER: call {{.*}} @"??0?$AutoParmTemplate@$MP6AHXZ1?Func@@YAHXZ@@QEAA@XZ"
72+
// BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$1?Func@@YAHXZ@@QEAA@XZ"
73+
74+
AutoParmsTemplate<&Func, &Func2> auto_func_ptrs;
75+
// AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MP6AHXZ1?Func@@YAHXZ$MP6AHXZ1?Func2@@YAHXZ@@QEAA@XZ"
76+
// BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$1?Func@@YAHXZ$1?Func2@@YAHXZ@@QEAA@XZ"
77+
4778
}

0 commit comments

Comments
 (0)