[clang] Fix recursive mangling for lambda init-captures (PR #182667)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 21 03:21:08 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Tommy Chiang (oToToT)
<details>
<summary>Changes</summary>
During lambda numbering, ItaniumNumberingContext::getManglingNumber() computes
the lambda’s <lambda-sig> by mangling the call operator type. If that type
contains decltype(init-capture), mangling re-enters the init-capture VarDecl.
For problematic cases, this recurses back into operator() mangling.
Make init-capture handling in mangleLocalName() explicit:
* If the init-capture belongs to a lambda that has a closure-prefix context,
mangle it directly with mangleNestedNameWithClosurePrefix().
* Otherwise keep local-name mangling, but for local lambdas use the parent
local container as the function-encoding base to avoid self-recursion.
Also publish lambda ContextDecl early in Sema::handleLambdaNumbering() before
calling getManglingNumber(Method), via a dedicated
CXXRecordDecl::setLambdaContextDecl() helper. This provides the needed context
for context-sensitive mangling without publishing provisional numbering state.
Add non-local regression tests in mangle-lambdas.cpp for:
* variable-template lambda init-capture used in decltype(x)
* static inline member lambda init-capture used in decltype(x)
This PR
* Fixes https://github.com/llvm/llvm-project/issues/63271
* Fixes https://github.com/llvm/llvm-project/issues/86240
* Fixes https://github.com/llvm/llvm-project/issues/139089
---
Patch is 64.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/182667.diff
5 Files Affected:
- (modified) clang/include/clang/AST/DeclCXX.h (+3)
- (modified) clang/lib/AST/DeclCXX.cpp (+5)
- (modified) clang/lib/AST/ItaniumMangle.cpp (+443-305)
- (modified) clang/lib/Sema/SemaLambda.cpp (+7)
- (modified) clang/test/CodeGenCXX/mangle-lambdas.cpp (+66)
``````````diff
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 5c4ad3c45da19..0c9bba17d09ef 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -1785,6 +1785,9 @@ class CXXRecordDecl : public RecordDecl {
/// the declaration context suffices.
Decl *getLambdaContextDecl() const;
+ /// Set the context declaration for a lambda class.
+ void setLambdaContextDecl(Decl *ContextDecl);
+
/// Retrieve the index of this lambda within the context declaration returned
/// by getLambdaContextDecl().
unsigned getLambdaIndexInContext() const {
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index c16b1bb7a3453..55c34605f7513 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1831,6 +1831,11 @@ Decl *CXXRecordDecl::getLambdaContextDecl() const {
return getLambdaData().ContextDecl.get(Source);
}
+void CXXRecordDecl::setLambdaContextDecl(Decl *ContextDecl) {
+ assert(isLambda() && "Not a lambda closure type!");
+ getLambdaData().ContextDecl = ContextDecl;
+}
+
void CXXRecordDecl::setLambdaNumbering(LambdaNumbering Numbering) {
assert(isLambda() && "Not a lambda closure type!");
getLambdaData().ManglingNumber = Numbering.ManglingNumber;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 70acc8a78ed52..6017f3bb3cd5f 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -68,9 +68,9 @@ static bool isLambda(const NamedDecl *ND) {
static const unsigned UnknownArity = ~0U;
class ItaniumMangleContextImpl : public ItaniumMangleContext {
- typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy;
+ typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
- llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
+ llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;
const DiscriminatorOverrideTy DiscriminatorOverride = nullptr;
NamespaceDecl *StdNamespace = nullptr;
@@ -162,7 +162,7 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
}
if (discriminator == 1)
return false;
- disc = discriminator-2;
+ disc = discriminator - 2;
return true;
}
@@ -249,14 +249,10 @@ class CXXNameMangler {
FunctionTypeDepthState() = default;
/// The number of function types we're inside.
- unsigned getDepth() const {
- return Bits >> 1;
- }
+ unsigned getDepth() const { return Bits >> 1; }
/// True if we're in the return type of the innermost function type.
- bool isInResultType() const {
- return Bits & InResultTypeMask;
- }
+ bool isInResultType() const { return Bits & InResultTypeMask; }
FunctionTypeDepthState push() {
FunctionTypeDepthState tmp = *this;
@@ -264,13 +260,9 @@ class CXXNameMangler {
return tmp;
}
- void enterResultType() {
- Bits |= InResultTypeMask;
- }
+ void enterResultType() { Bits |= InResultTypeMask; }
- void leaveResultType() {
- Bits &= ~InResultTypeMask;
- }
+ void leaveResultType() { Bits &= ~InResultTypeMask; }
void pop(FunctionTypeDepthState saved) {
assert(getDepth() == saved.getDepth() + 1);
@@ -334,13 +326,9 @@ class CXXNameMangler {
}
const AbiTagList &getUsedAbiTags() const { return UsedAbiTags; }
- void setUsedAbiTags(const AbiTagList &AbiTags) {
- UsedAbiTags = AbiTags;
- }
+ void setUsedAbiTags(const AbiTagList &AbiTags) { UsedAbiTags = AbiTags; }
- const AbiTagList &getEmittedAbiTags() const {
- return EmittedAbiTags;
- }
+ const AbiTagList &getEmittedAbiTags() const { return EmittedAbiTags; }
const AbiTagList &getSortedUniqueUsedAbiTags() {
llvm::sort(UsedAbiTags);
@@ -406,8 +394,7 @@ class CXXNameMangler {
: Context(C), Out(Out_), NullOut(NullOut_), Structor(getStructor(D)),
AbiTagsRoot(AbiTags) {
// These can't be mangled without a ctor type or dtor type.
- assert(!D || (!isa<CXXDestructorDecl>(D) &&
- !isa<CXXConstructorDecl>(D)));
+ assert(!D || (!isa<CXXDestructorDecl>(D) && !isa<CXXConstructorDecl>(D)));
}
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
const CXXConstructorDecl *D, CXXCtorType Type)
@@ -434,7 +421,9 @@ class CXXNameMangler {
NullOut = true;
}
- struct WithTemplateDepthOffset { unsigned Offset; };
+ struct WithTemplateDepthOffset {
+ unsigned Offset;
+ };
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out,
WithTemplateDepthOffset Offset)
: CXXNameMangler(C, Out) {
@@ -481,7 +470,7 @@ class CXXNameMangler {
void addSubstitution(TemplateName Template);
void addSubstitution(uintptr_t Ptr);
// Destructive copy substitutions from other mangler.
- void extendSubstitutions(CXXNameMangler* Other);
+ void extendSubstitutions(CXXNameMangler *Other);
void mangleUnresolvedPrefix(NestedNameSpecifier Qualifier,
bool recursive = false);
@@ -513,10 +502,10 @@ class CXXNameMangler {
void mangleRegCallName(const IdentifierInfo *II);
void mangleDeviceStubName(const IdentifierInfo *II);
void mangleOCLDeviceStubName(const IdentifierInfo *II);
- void mangleSourceNameWithAbiTags(
- const NamedDecl *ND, const AbiTagList *AdditionalAbiTags = nullptr);
- void mangleLocalName(GlobalDecl GD,
- const AbiTagList *AdditionalAbiTags);
+ void
+ mangleSourceNameWithAbiTags(const NamedDecl *ND,
+ const AbiTagList *AdditionalAbiTags = nullptr);
+ void mangleLocalName(GlobalDecl GD, const AbiTagList *AdditionalAbiTags);
void mangleBlockForPrefix(const BlockDecl *Block);
void mangleUnqualifiedBlock(const BlockDecl *Block);
void mangleTemplateParamDecl(const NamedDecl *Decl);
@@ -528,16 +517,16 @@ class CXXNameMangler {
void mangleLambda(const CXXRecordDecl *Lambda);
void mangleNestedName(GlobalDecl GD, const DeclContext *DC,
const AbiTagList *AdditionalAbiTags,
- bool NoFunction=false);
+ bool NoFunction = false);
void mangleNestedName(const TemplateDecl *TD,
ArrayRef<TemplateArgument> Args);
void mangleNestedNameWithClosurePrefix(GlobalDecl GD,
const NamedDecl *PrefixND,
const AbiTagList *AdditionalAbiTags);
void manglePrefix(NestedNameSpecifier Qualifier);
- void manglePrefix(const DeclContext *DC, bool NoFunction=false);
+ void manglePrefix(const DeclContext *DC, bool NoFunction = false);
void manglePrefix(QualType type);
- void mangleTemplatePrefix(GlobalDecl GD, bool NoFunction=false);
+ void mangleTemplatePrefix(GlobalDecl GD, bool NoFunction = false);
void mangleTemplatePrefix(TemplateName Template);
const NamedDecl *getClosurePrefix(const Decl *ND);
void mangleClosurePrefix(const NamedDecl *ND, bool NoFunction = false);
@@ -545,7 +534,8 @@ class CXXNameMangler {
StringRef Prefix = "");
void mangleOperatorName(DeclarationName Name, unsigned Arity);
void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
- void mangleQualifiers(Qualifiers Quals, const DependentAddressSpaceType *DAST = nullptr);
+ void mangleQualifiers(Qualifiers Quals,
+ const DependentAddressSpaceType *DAST = nullptr);
void mangleRefQualifier(RefQualifierKind RefQualifier);
void mangleObjCMethodName(const ObjCMethodDecl *MD);
@@ -556,7 +546,7 @@ class CXXNameMangler {
#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T);
#include "clang/AST/TypeNodes.inc"
- void mangleType(const TagType*);
+ void mangleType(const TagType *);
void mangleType(TemplateName);
static StringRef getCallingConvQualifierName(CallingConv CC);
void mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo info);
@@ -610,8 +600,7 @@ class CXXNameMangler {
void mangleFunctionParam(const ParmVarDecl *parm);
- void writeAbiTags(const NamedDecl *ND,
- const AbiTagList *AdditionalAbiTags);
+ void writeAbiTags(const NamedDecl *ND, const AbiTagList *AdditionalAbiTags);
// Returns sorted unique list of ABI tags.
AbiTagList makeFunctionReturnTypeTags(const FunctionDecl *FD);
@@ -619,7 +608,7 @@ class CXXNameMangler {
AbiTagList makeVariableTypeTags(const VarDecl *VD);
};
-}
+} // namespace
NamespaceDecl *ItaniumMangleContextImpl::getStdNamespace() {
if (!StdNamespace) {
@@ -962,8 +951,8 @@ bool CXXNameMangler::isStdNamespace(const DeclContext *DC) {
return isStd(cast<NamespaceDecl>(DC));
}
-static const GlobalDecl
-isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs) {
+static const GlobalDecl isTemplate(GlobalDecl GD,
+ const TemplateArgumentList *&TemplateArgs) {
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
// Check if we have a function template.
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
@@ -975,7 +964,7 @@ isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs) {
// Check if we have a class template.
if (const ClassTemplateSpecializationDecl *Spec =
- dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
+ dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
TemplateArgs = &Spec->getTemplateArgs();
return GD.getWithDecl(Spec->getSpecializedTemplate());
}
@@ -992,7 +981,7 @@ isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs) {
static TemplateName asTemplateName(GlobalDecl GD) {
const TemplateDecl *TD = dyn_cast_or_null<TemplateDecl>(GD.getDecl());
- return TemplateName(const_cast<TemplateDecl*>(TD));
+ return TemplateName(const_cast<TemplateDecl *>(TD));
}
void CXXNameMangler::mangleName(GlobalDecl GD) {
@@ -1040,8 +1029,8 @@ const RecordDecl *CXXNameMangler::GetLocalClassDecl(const Decl *D) {
return nullptr;
}
-void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
- const AbiTagList *AdditionalAbiTags) {
+void CXXNameMangler::mangleNameWithAbiTags(
+ GlobalDecl GD, const AbiTagList *AdditionalAbiTags) {
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
// <name> ::= [<module-name>] <nested-name>
// ::= [<module-name>] <unscoped-name>
@@ -1230,10 +1219,8 @@ void CXXNameMangler::mangleFloat(const llvm::APFloat &f) {
hexDigit &= 0xF;
// Map that over to a lowercase hex digit.
- static const char charForHex[16] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
- };
+ static const char charForHex[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
buffer[stringIndex] = charForHex[hexDigit];
}
@@ -1420,32 +1407,32 @@ void CXXNameMangler::mangleUnresolvedName(
if (Qualifier)
mangleUnresolvedPrefix(Qualifier);
switch (name.getNameKind()) {
- // <base-unresolved-name> ::= <simple-id>
- case DeclarationName::Identifier:
- mangleSourceName(name.getAsIdentifierInfo());
- break;
- // <base-unresolved-name> ::= dn <destructor-name>
- case DeclarationName::CXXDestructorName:
- Out << "dn";
- mangleUnresolvedTypeOrSimpleId(name.getCXXNameType());
- break;
- // <base-unresolved-name> ::= on <operator-name>
- case DeclarationName::CXXConversionFunctionName:
- case DeclarationName::CXXLiteralOperatorName:
- case DeclarationName::CXXOperatorName:
- Out << "on";
- mangleOperatorName(name, knownArity);
- break;
- case DeclarationName::CXXConstructorName:
- llvm_unreachable("Can't mangle a constructor name!");
- case DeclarationName::CXXUsingDirective:
- llvm_unreachable("Can't mangle a using directive name!");
- case DeclarationName::CXXDeductionGuideName:
- llvm_unreachable("Can't mangle a deduction guide name!");
- case DeclarationName::ObjCMultiArgSelector:
- case DeclarationName::ObjCOneArgSelector:
- case DeclarationName::ObjCZeroArgSelector:
- llvm_unreachable("Can't mangle Objective-C selector names here!");
+ // <base-unresolved-name> ::= <simple-id>
+ case DeclarationName::Identifier:
+ mangleSourceName(name.getAsIdentifierInfo());
+ break;
+ // <base-unresolved-name> ::= dn <destructor-name>
+ case DeclarationName::CXXDestructorName:
+ Out << "dn";
+ mangleUnresolvedTypeOrSimpleId(name.getCXXNameType());
+ break;
+ // <base-unresolved-name> ::= on <operator-name>
+ case DeclarationName::CXXConversionFunctionName:
+ case DeclarationName::CXXLiteralOperatorName:
+ case DeclarationName::CXXOperatorName:
+ Out << "on";
+ mangleOperatorName(name, knownArity);
+ break;
+ case DeclarationName::CXXConstructorName:
+ llvm_unreachable("Can't mangle a constructor name!");
+ case DeclarationName::CXXUsingDirective:
+ llvm_unreachable("Can't mangle a using directive name!");
+ case DeclarationName::CXXDeductionGuideName:
+ llvm_unreachable("Can't mangle a deduction guide name!");
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCZeroArgSelector:
+ llvm_unreachable("Can't mangle Objective-C selector names here!");
}
// The <simple-id> and on <operator-name> productions end in an optional
@@ -1531,9 +1518,9 @@ void CXXNameMangler::mangleUnqualifiedName(
if (Context.isInternalLinkageDecl(ND))
Out << 'L';
- bool IsRegCall = FD &&
- FD->getType()->castAs<FunctionType>()->getCallConv() ==
- clang::CC_X86RegCall;
+ bool IsRegCall =
+ FD && FD->getType()->castAs<FunctionType>()->getCallConv() ==
+ clang::CC_X86RegCall;
bool IsDeviceStub =
FD && FD->hasAttr<CUDAGlobalAttr>() &&
GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
@@ -1578,14 +1565,15 @@ void CXXNameMangler::mangleUnqualifiedName(
// the data members in the union are unnamed), then there is no way for
// a program to refer to the anonymous union, and there is therefore no
// need to mangle its name.
- assert(RD->isAnonymousStructOrUnion()
- && "Expected anonymous struct or union!");
+ assert(RD->isAnonymousStructOrUnion() &&
+ "Expected anonymous struct or union!");
const FieldDecl *FD = RD->findFirstNamedDataMember();
// It's actually possible for various reasons for us to get here
// with an empty anonymous struct / union. Fortunately, it
// doesn't really matter what name we generate.
- if (!FD) break;
+ if (!FD)
+ break;
assert(FD->getIdentifier() && "Data member name isn't an identifier!");
mangleSourceName(FD->getIdentifier());
@@ -1778,8 +1766,7 @@ void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
Out << II->getLength() << II->getName();
}
-void CXXNameMangler::mangleNestedName(GlobalDecl GD,
- const DeclContext *DC,
+void CXXNameMangler::mangleNestedName(GlobalDecl GD, const DeclContext *DC,
const AbiTagList *AdditionalAbiTags,
bool NoFunction) {
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
@@ -1868,17 +1855,40 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
const RecordDecl *RD = GetLocalClassDecl(D);
const DeclContext *DC = Context.getEffectiveDeclContext(RD ? RD : D);
+ if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture()) {
+ if (const auto *MethodDC = dyn_cast<CXXMethodDecl>(DC)) {
+ // Init-captures in non-local lambdas should be mangled in the lambda's
+ // closure-prefix context, not as local entities of operator().
+ if (const NamedDecl *PrefixND = getClosurePrefix(MethodDC->getParent())) {
+ mangleNestedNameWithClosurePrefix(GD, PrefixND, AdditionalAbiTags);
+ return;
+ }
+ }
+ }
+
Out << 'Z';
{
AbiTagState LocalAbiTags(AbiTags);
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC))
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) {
mangleObjCMethodName(MD);
- else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC))
+ } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
mangleBlockForPrefix(BD);
- else
- mangleFunctionEncoding(getParentOfLocalEntity(DC));
+ } else {
+ const DeclContext *MangleDC = DC;
+ if (const auto *VD = dyn_cast<VarDecl>(D); VD && VD->isInitCapture()) {
+ if (const auto *MethodDC = dyn_cast<CXXMethodDecl>(DC)) {
+ const DeclContext *ParentDC =
+ Context.getEffectiveParentContext(MethodDC->getDeclContext());
+ // For local lambdas, use the parent context as the local-name base
+ // to avoid recursively mangling the lambda call operator.
+ if (isLocalContainerContext(ParentDC))
+ MangleDC = ParentDC;
+ }
+ }
+ mangleFunctionEncoding(getParentOfLocalEntity(MangleDC));
+ }
// Implicit ABI tags (from namespace) are not available in the following
// entity; reset to actually emitted tags, which are available.
@@ -1898,10 +1908,10 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
// -- other default arguments do not affect its encoding.
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD);
if (CXXRD && CXXRD->isLambda()) {
- if (const ParmVarDecl *Parm
- = dyn_cast_or_null<ParmVarDecl>(CXXRD->getLambdaContextDecl())) {
- if (const FunctionDecl *Func
- = dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
+ if (const ParmVarDecl *Parm =
+ dyn_cast_or_null<ParmVarDecl>(CXXRD->getLambdaContextDecl())) {
+ if (const FunctionDecl *Func =
+ dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
Out << 'd';
unsigned Num = Func->getNumParams() - Parm->getFunctionScopeIndex();
if (Num > 1)
@@ -1913,7 +1923,7 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
// Mangle the name relative to the closest enclosing function.
// equality ok because RD derived from ND above
- if (D == RD) {
+ if (D == RD) {
mangleUnqualifiedName(RD, DC, AdditionalAbiTags);
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
if (const NamedDecl *PrefixND = getClosurePrefix(BD))
@@ -1930,10 +1940,10 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
// Mangle a block in a default parameter; see above explanation for
// lambdas.
- if (const ParmVarDecl *Parm
- = dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl())) {
- if (const FunctionDecl *Func
- = dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
+ if (const ParmVarDecl *Parm =
+ dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl())) {
+ if (const FunctionDecl *Func =
+ dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
Out << 'd';
unsigned Num = Func->getNumParams() - Parm->getFunctionScopeIndex();
if (Num > 1)
@@ -2101,8 +2111,8 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
if (isCompatibleWith(LangOptions::ClangABI::Ver12) &&
(isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&
!isa<ParmVarDecl>(Context)) {
- if (const IdentifierInfo *Name
- = cast<NamedDecl>(Context)->getIdentifier()) {
+ if (const IdentifierInfo *Name =
+ cast<NamedDecl>(Context)->getIdentifier()) {
mangleSourceName(Name);
const TemplateArgumentList *TemplateArgs = nullptr;
if (GlobalDecl TD = isTemplate(cast<NamedDecl>(Context), TemplateArgs))
@@ -2242,8 +2252,7 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) {
addSubstitution(Template);
}
-void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD,
- bool NoFunction) {
+void CXXNameMangler::mang...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/182667
More information about the cfe-commits
mailing list