aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorMax Winkler <max.enrico.winkler@gmail.com>2024-06-20 19:49:17 -0700
committerGitHub <noreply@github.com>2024-06-20 19:49:17 -0700
commit7b906d46f6e6915f32718dd5b313ba47a7cec259 (patch)
tree64a916f2834472ee99555c1a1fc72f8a35411df8 /clang
parente1c03ddc9b03b820b421d8b3bca6a94e4d1a4675 (diff)
downloadllvm-7b906d46f6e6915f32718dd5b313ba47a7cec259.zip
llvm-7b906d46f6e6915f32718dd5b313ba47a7cec259.tar.gz
llvm-7b906d46f6e6915f32718dd5b313ba47a7cec259.tar.bz2
[clang-cl][AST] Fix auto NTTP MSVC 1920+ mangling for pointer types (#92477)
https://godbolt.org/z/G1K8Wszn9 for reference. Starting with MSVC 1920+, VS2019, C++17 auto NTTP now adds `M <type>` to the mangled name to avoid name collisions with different deduced types. This PR fixes pointers. Pointers to members will be fixed in an upcoming PR. Here is a small example. The godbolt has more thorough examples. ``` template<auto> struct AutoParmTemplate { AutoParmTemplate() {} }; int i; int main() { // MSVC 1916: ??0?$AutoParmTemplate@$1?i@@3HA@@QEAA@XZ // MSVC 1929: ??0?$AutoParmTemplate@$MPEAH1?i@@3HA@@QEAA@XZ // Clang: ??0?$AutoParmTemplate@$1?i@@3HA@@QEAA@XZ AutoParmTemplate<&i> x; } ```
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/ReleaseNotes.rst7
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp63
-rw-r--r--clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp31
3 files changed, 98 insertions, 3 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0973db2..88969a0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -95,6 +95,13 @@ ABI Changes in This Version
- Fixed Microsoft calling convention when returning classes that have a deleted
copy assignment operator. Such a class should be returned indirectly.
+- Fixed Microsoft name mangling for auto non-type template arguments of pointer
+ type for MSVC 1920+. This change resolves incompatibilities with code compiled
+ by MSVC 1920+ but will introduce incompatibilities with code compiled by
+ earlier versions of Clang unless such code is built with the compiler option
+ `-fms-compatibility-version=19.14` to imitate the MSVC 1914 mangling behavior.
+
+
AST Dumping Potentially Breaking Changes
----------------------------------------
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index d87be5f..3923d34 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -372,6 +372,11 @@ public:
void mangleMemberFunctionPointer(const CXXRecordDecl *RD,
const CXXMethodDecl *MD,
StringRef Prefix = "$");
+ void mangleFunctionPointer(const FunctionDecl *FD,
+ const NonTypeTemplateParmDecl *PD,
+ QualType TemplateArgType);
+ void mangleVarDecl(const VarDecl *VD, const NonTypeTemplateParmDecl *PD,
+ QualType TemplateArgType);
void mangleMemberFunctionPointerInClassNTTP(const CXXRecordDecl *RD,
const CXXMethodDecl *MD);
void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
@@ -799,6 +804,50 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD,
mangleNumber(VBTableOffset);
}
+void MicrosoftCXXNameMangler::mangleFunctionPointer(
+ const FunctionDecl *FD, const NonTypeTemplateParmDecl *PD,
+ QualType TemplateArgType) {
+ // <func-ptr> ::= $1? <mangled-name>
+ // <func-ptr> ::= <auto-nttp>
+ //
+ // <auto-nttp> ::= $ M <type> 1? <mangled-name>
+ Out << '$';
+
+ if (getASTContext().getLangOpts().isCompatibleWithMSVC(
+ LangOptions::MSVC2019) &&
+ PD && PD->getType()->getTypeClass() == Type::Auto &&
+ !TemplateArgType.isNull()) {
+ Out << "M";
+ mangleType(TemplateArgType, SourceRange(), QMM_Drop);
+ }
+
+ Out << "1?";
+ mangleName(FD);
+ mangleFunctionEncoding(FD, /*ShouldMangle=*/true);
+}
+
+void MicrosoftCXXNameMangler::mangleVarDecl(const VarDecl *VD,
+ const NonTypeTemplateParmDecl *PD,
+ QualType TemplateArgType) {
+ // <var-ptr> ::= $1? <mangled-name>
+ // <var-ptr> ::= <auto-nttp>
+ //
+ // <auto-nttp> ::= $ M <type> 1? <mangled-name>
+ Out << '$';
+
+ if (getASTContext().getLangOpts().isCompatibleWithMSVC(
+ LangOptions::MSVC2019) &&
+ PD && PD->getType()->getTypeClass() == Type::Auto &&
+ !TemplateArgType.isNull()) {
+ Out << "M";
+ mangleType(TemplateArgType, SourceRange(), QMM_Drop);
+ }
+
+ Out << "1?";
+ mangleName(VD);
+ mangleVariableEncoding(VD);
+}
+
void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(
const CXXRecordDecl *RD, const CXXMethodDecl *MD) {
// <nttp-class-member-function-pointer> ::= <member-function-pointer>
@@ -1555,6 +1604,9 @@ void MicrosoftCXXNameMangler::mangleIntegerLiteral(
const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,
QualType TemplateArgType) {
// <integer-literal> ::= $0 <number>
+ // <integer-literal> ::= <auto-nttp>
+ //
+ // <auto-nttp> ::= $ M <type> 0 <number>
Out << "$";
// Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when
@@ -1632,8 +1684,11 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
// ::= <member-data-pointer>
// ::= <member-function-pointer>
// ::= $ <constant-value>
+ // ::= $ <auto-nttp-constant-value>
// ::= <template-args>
//
+ // <auto-nttp-constant-value> ::= M <type> <constant-value>
+ //
// <constant-value> ::= 0 <number> # integer
// ::= 1 <mangled-name> # address of D
// ::= 2 <type> <typed-constant-value>* @ # struct
@@ -1681,15 +1736,17 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
mangleMemberFunctionPointer(
MD->getParent()->getMostRecentNonInjectedDecl(), MD);
} else {
- Out << "$1?";
- mangleName(FD);
- mangleFunctionEncoding(FD, /*ShouldMangle=*/true);
+ mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
+ TA.getParamTypeForDecl());
}
} else if (TA.getParamTypeForDecl()->isRecordType()) {
Out << "$";
auto *TPO = cast<TemplateParamObjectDecl>(ND);
mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),
TPO->getValue(), TplArgKind::ClassNTTP);
+ } else if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
+ mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),
+ TA.getParamTypeForDecl());
} else {
mangle(ND, "$1?");
}
diff --git a/clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp b/clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp
index c17f5f5..ff5395c 100644
--- a/clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp
+++ b/clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp
@@ -18,6 +18,12 @@ auto AutoFunc() {
return a;
}
+int Func();
+int Func2();
+
+int i;
+int j;
+
void template_mangling() {
AutoFunc<1>();
// AFTER: call {{.*}} @"??$AutoFunc@$MH00@@YA?A?<auto>@@XZ"
@@ -44,4 +50,29 @@ void template_mangling() {
AutoParmsTemplate<(unsigned long)1, 9223372036854775807LL> c2;
// AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MK00$M_J0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
// BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$00$0HPPPPPPPPPPPPPPP@@@QEAA@XZ"
+
+ AutoFunc<&i>();
+ // AFTER: call {{.*}} @"??$AutoFunc@$MPEAH1?i@@3HA@@YA?A?<auto>@@XZ"
+ // BEFORE: call {{.*}} @"??$AutoFunc@$1?i@@3HA@@YA?A?<auto>@@XZ"
+
+ AutoParmTemplate<&i> auto_int_ptr;
+ // AFTER: call {{.*}} @"??0?$AutoParmTemplate@$MPEAH1?i@@3HA@@QEAA@XZ"
+ // BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$1?i@@3HA@@QEAA@XZ"
+
+ AutoParmsTemplate<&i, &j> auto_int_ptrs;
+ // AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MPEAH1?i@@3HA$MPEAH1?j@@3HA@@QEAA@XZ"
+ // BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$1?i@@3HA$1?j@@3HA@@QEAA@XZ"
+
+ AutoFunc<&Func>();
+ // AFTER: call {{.*}} @"??$AutoFunc@$MP6AHXZ1?Func@@YAHXZ@@YA?A?<auto>@@XZ"
+ // BEFORE: call {{.*}} @"??$AutoFunc@$1?Func@@YAHXZ@@YA?A?<auto>@@XZ"
+
+ AutoParmTemplate<&Func> auto_func_ptr;
+ // AFTER: call {{.*}} @"??0?$AutoParmTemplate@$MP6AHXZ1?Func@@YAHXZ@@QEAA@XZ"
+ // BEFORE: call {{.*}} @"??0?$AutoParmTemplate@$1?Func@@YAHXZ@@QEAA@XZ"
+
+ AutoParmsTemplate<&Func, &Func2> auto_func_ptrs;
+ // AFTER: call {{.*}} @"??0?$AutoParmsTemplate@$MP6AHXZ1?Func@@YAHXZ$MP6AHXZ1?Func2@@YAHXZ@@QEAA@XZ"
+ // BEFORE: call {{.*}} @"??0?$AutoParmsTemplate@$1?Func@@YAHXZ$1?Func2@@YAHXZ@@QEAA@XZ"
+
}