diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 4cb1ab56a1e61..a11dbe22b196e 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -841,8 +841,17 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) { AbiTagList ReturnTypeAbiTags = makeFunctionReturnTypeTags(FD); if (ReturnTypeAbiTags.empty()) { - // There are no tags for return type, the simplest case. + // There are no tags for return type, the simplest case. Enter the function + // parameter scope before mangling the name, because a template using + // constrained `auto` can have references to its parameters within its + // template argument list: + // + // template void f(T x, C auto) + // ... is mangled as ... + // template U> void f(T, U) + FunctionTypeDepthState Saved = FunctionTypeDepth.push(); mangleName(GD); + FunctionTypeDepth.pop(Saved); mangleFunctionEncodingBareType(FD); return; } @@ -855,7 +864,10 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) { CXXNameMangler FunctionEncodingMangler(*this, FunctionEncodingStream); // Output name of the function. FunctionEncodingMangler.disableDerivedAbiTags(); + + FunctionTypeDepthState Saved = FunctionTypeDepth.push(); FunctionEncodingMangler.mangleNameWithAbiTags(FD, nullptr); + FunctionTypeDepth.pop(Saved); // Remember length of the function name in the buffer. size_t EncodingPositionStart = FunctionEncodingStream.str().size(); @@ -873,7 +885,9 @@ void CXXNameMangler::mangleFunctionEncoding(GlobalDecl GD) { AdditionalAbiTags.end()); // Output name with implicit tags and function encoding from temporary buffer. + Saved = FunctionTypeDepth.push(); mangleNameWithAbiTags(FD, &AdditionalAbiTags); + FunctionTypeDepth.pop(Saved); Out << FunctionEncodingStream.str().substr(EncodingPositionStart); // Function encoding could create new substitutions so we have to add diff --git a/clang/test/CodeGenCXX/mangle-concept.cpp b/clang/test/CodeGenCXX/mangle-concept.cpp index 391cf09ede855..efab169903395 100644 --- a/clang/test/CodeGenCXX/mangle-concept.cpp +++ b/clang/test/CodeGenCXX/mangle-concept.cpp @@ -228,3 +228,15 @@ namespace gh67244 { // CHECK: define {{.*}} @_ZN7gh672441fITkNS_1CIifEEiEEvT_( template void f(int); } + +namespace gh67356 { + template concept C = true; + template void f(T t, C auto) {} + // CHECK: define {{.*}} @_ZN7gh673561fIiTkNS_1CIDtfL0p_EEEiEEvT_T0_( + template void f(int, int); + + // Note, we use `fL0p` not `fp` above because: + template void g(T t, C decltype(f(t, u))> auto) {} + // CHECK: define {{.*}} @_ZN7gh673561gIiTkNS_1CIFDTcl1ffL0p_fp_EET_EEEiEEvS3_T0_( + template void g(int, int); +}