diff options
author | Max Winkler <max.enrico.winkler@gmail.com> | 2024-06-20 19:49:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-20 19:49:17 -0700 |
commit | 7b906d46f6e6915f32718dd5b313ba47a7cec259 (patch) | |
tree | 64a916f2834472ee99555c1a1fc72f8a35411df8 /clang | |
parent | e1c03ddc9b03b820b421d8b3bca6a94e4d1a4675 (diff) | |
download | llvm-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.rst | 7 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 63 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/mangle-ms-auto-templates.cpp | 31 |
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" + } |