void mangleCXXCtorType(CXXCtorType T, const CXXRecordDecl *InheritedFrom);
void mangleCXXDtorType(CXXDtorType T);
- void mangleTemplateArgs(TemplateName TN,
- const TemplateArgumentLoc *TemplateArgs,
+ void mangleTemplateArgs(const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs);
- void mangleTemplateArgs(TemplateName TN, const TemplateArgument *TemplateArgs,
+ void mangleTemplateArgs(const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs);
- void mangleTemplateArgs(TemplateName TN, const TemplateArgumentList &AL);
- void mangleTemplateArg(TemplateArgument A, bool NeedExactType);
- void mangleValueInTemplateArg(QualType T, const APValue &V, bool TopLevel,
- bool NeedExactType = false);
+ void mangleTemplateArgs(const TemplateArgumentList &AL);
+ void mangleTemplateArg(TemplateArgument A);
+ void mangleValueInTemplateArg(QualType T, const APValue &V);
void mangleTemplateParameter(unsigned Depth, unsigned Index);
return GlobalDecl();
}
-static TemplateName asTemplateName(GlobalDecl GD) {
- const TemplateDecl *TD = dyn_cast_or_null<TemplateDecl>(GD.getDecl());
- return TemplateName(const_cast<TemplateDecl*>(TD));
-}
-
void CXXNameMangler::mangleName(GlobalDecl GD) {
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
const TemplateArgumentList *TemplateArgs = nullptr;
if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) {
mangleUnscopedTemplateName(TD, AdditionalAbiTags);
- mangleTemplateArgs(asTemplateName(TD), *TemplateArgs);
+ mangleTemplateArgs(*TemplateArgs);
return;
}
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
mangleUnscopedTemplateName(TD, nullptr);
- mangleTemplateArgs(asTemplateName(TD), TemplateArgs, NumTemplateArgs);
+ mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
} else {
mangleNestedName(TD, TemplateArgs, NumTemplateArgs);
}
// FIXME: GCC does not appear to mangle the template arguments when
// the template in question is a dependent template name. Should we
// emulate that badness?
- mangleTemplateArgs(TST->getTemplateName(), TST->getArgs(),
- TST->getNumArgs());
+ mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());
addSubstitution(QualType(TST, 0));
}
} else if (const auto *DTST =
// FIXME: GCC does not appear to mangle the template arguments when
// the template in question is a dependent template name. Should we
// emulate that badness?
- mangleTemplateArgs(Template, DTST->getArgs(), DTST->getNumArgs());
+ mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs());
addSubstitution(QualType(DTST, 0));
}
} else {
// The <simple-id> and on <operator-name> productions end in an optional
// <template-args>.
if (TemplateArgs)
- mangleTemplateArgs(TemplateName(), TemplateArgs, NumTemplateArgs);
+ mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
}
void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
if (auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
// Proposed in https://github.com/itanium-cxx-abi/cxx-abi/issues/63.
- Out << "TA";
+ Out << "TAX";
mangleValueInTemplateArg(TPO->getType().getUnqualifiedType(),
- TPO->getValue(), /*TopLevel=*/true);
+ TPO->getValue());
+ Out << "E";
break;
}
case DeclarationName::CXXConstructorName: {
const CXXRecordDecl *InheritedFrom = nullptr;
- TemplateName InheritedTemplateName;
const TemplateArgumentList *InheritedTemplateArgs = nullptr;
if (auto Inherited =
cast<CXXConstructorDecl>(ND)->getInheritedConstructor()) {
InheritedFrom = Inherited.getConstructor()->getParent();
- InheritedTemplateName =
- TemplateName(Inherited.getConstructor()->getPrimaryTemplate());
InheritedTemplateArgs =
Inherited.getConstructor()->getTemplateSpecializationArgs();
}
// FIXME: The template arguments are part of the enclosing prefix or
// nested-name, but it's more convenient to mangle them here.
if (InheritedTemplateArgs)
- mangleTemplateArgs(InheritedTemplateName, *InheritedTemplateArgs);
+ mangleTemplateArgs(*InheritedTemplateArgs);
writeAbiTags(ND, AdditionalAbiTags);
break;
const TemplateArgumentList *TemplateArgs = nullptr;
if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) {
mangleTemplatePrefix(TD, NoFunction);
- mangleTemplateArgs(asTemplateName(TD), *TemplateArgs);
+ mangleTemplateArgs(*TemplateArgs);
}
else {
manglePrefix(DC, NoFunction);
Out << 'N';
mangleTemplatePrefix(TD);
- mangleTemplateArgs(asTemplateName(TD), TemplateArgs, NumTemplateArgs);
+ mangleTemplateArgs(TemplateArgs, NumTemplateArgs);
Out << 'E';
}
= cast<NamedDecl>(Context)->getIdentifier()) {
mangleSourceName(Name);
const TemplateArgumentList *TemplateArgs = nullptr;
- if (GlobalDecl TD = isTemplate(cast<NamedDecl>(Context), TemplateArgs))
- mangleTemplateArgs(asTemplateName(TD), *TemplateArgs);
+ if (isTemplate(cast<NamedDecl>(Context), TemplateArgs))
+ mangleTemplateArgs(*TemplateArgs);
Out << 'M';
}
}
const TemplateArgumentList *TemplateArgs = nullptr;
if (GlobalDecl TD = isTemplate(ND, TemplateArgs)) {
mangleTemplatePrefix(TD);
- mangleTemplateArgs(asTemplateName(TD), *TemplateArgs);
+ mangleTemplateArgs(*TemplateArgs);
} else {
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
mangleUnqualifiedName(ND, nullptr);
}
}
- mangleTemplateArgs(TN, TST->getArgs(), TST->getNumArgs());
+ mangleTemplateArgs(TST->getArgs(), TST->getNumArgs());
break;
}
case Type::DependentTemplateSpecialization: {
const DependentTemplateSpecializationType *DTST =
cast<DependentTemplateSpecializationType>(Ty);
- TemplateName Template = getASTContext().getDependentTemplateName(
- DTST->getQualifier(), DTST->getIdentifier());
mangleSourceName(DTST->getIdentifier());
- mangleTemplateArgs(Template, DTST->getArgs(), DTST->getNumArgs());
+ mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs());
break;
}
Out << "u" << VendorQualifier.size() << VendorQualifier;
Out << "I";
- mangleTemplateArg(T->getRowExpr(), false);
- mangleTemplateArg(T->getColumnExpr(), false);
+ mangleTemplateArg(T->getRowExpr());
+ mangleTemplateArg(T->getColumnExpr());
mangleType(T->getElementType());
Out << "E";
}
// FIXME: GCC does not appear to mangle the template arguments when
// the template in question is a dependent template name. Should we
// emulate that badness?
- mangleTemplateArgs(T->getTemplateName(), T->getArgs(), T->getNumArgs());
+ mangleTemplateArgs(T->getArgs(), T->getNumArgs());
addSubstitution(QualType(T, 0));
}
}
// FIXME: GCC does not appear to mangle the template arguments when
// the template in question is a dependent template name. Should we
// emulate that badness?
- mangleTemplateArgs(Prefix, T->getArgs(), T->getNumArgs());
+ mangleTemplateArgs(T->getArgs(), T->getNumArgs());
Out << 'E';
}
llvm::APSInt BW(32, true);
BW = T->getNumBits();
TemplateArgument TA(Context.getASTContext(), BW, getASTContext().IntTy);
- mangleTemplateArgs(TemplateName(), &TA, 1);
+ mangleTemplateArgs(&TA, 1);
if (T->isUnsigned())
Out << "j";
else
void CXXNameMangler::mangleType(const DependentExtIntType *T) {
Out << "U7_ExtInt";
TemplateArgument TA(T->getNumBitsExpr());
- mangleTemplateArgs(TemplateName(), &TA, 1);
+ mangleTemplateArgs(&TA, 1);
if (T->isUnsigned())
Out << "j";
else
if (SPE->isPartiallySubstituted()) {
Out << "sP";
for (const auto &A : SPE->getPartialArguments())
- mangleTemplateArg(A, false);
+ mangleTemplateArg(A);
Out << "E";
break;
}
}
}
-namespace {
-// Helper to provide ancillary information on a template used to mangle its
-// arguments.
-struct TemplateArgManglingInfo {
- TemplateDecl *ResolvedTemplate = nullptr;
- bool SeenPackExpansionIntoNonPack = false;
-
- TemplateArgManglingInfo(TemplateName TN) {
- if (TemplateDecl *TD = TN.getAsTemplateDecl())
- ResolvedTemplate = TD;
- }
-
- /// Do we need to mangle template arguments with exactly correct types?
- ///
- /// This should be called exactly once for each parameter / argument pair, in
- /// order.
- bool needExactType(unsigned ParamIdx, const TemplateArgument &Arg) {
- // We need correct types when the template-name is unresolved or when it
- // names a template that is able to be overloaded.
- if (!ResolvedTemplate || SeenPackExpansionIntoNonPack)
- return true;
-
- // If we encounter a pack argument that is expanded into a non-pack
- // parameter, we can no longer track parameter / argument correspondence,
- // and need to use exact types from this point onwards.
- assert(ParamIdx < ResolvedTemplate->getTemplateParameters()->size() &&
- "no parameter for argument");
- const NamedDecl *Param =
- ResolvedTemplate->getTemplateParameters()->getParam(ParamIdx);
- if (!Param->isParameterPack() && Arg.isPackExpansion()) {
- SeenPackExpansionIntoNonPack = true;
- return true;
- }
-
- assert(Param->isParameterPack() ==
- (Arg.getKind() == TemplateArgument::Pack) &&
- "should have formed pack argument for pack parameter");
-
- // We need exact types for function template arguments because they might be
- // overloaded on template parameter type. As a special case, a member
- // function template of a generic lambda is not overloadable.
- if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ResolvedTemplate)) {
- auto *RD = dyn_cast<CXXRecordDecl>(FTD->getDeclContext());
- if (!RD || !RD->isGenericLambda())
- return true;
- }
-
- // Otherwise, we only need a correct type if the parameter has a deduced
- // type.
- auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param);
- return NTTP && NTTP->getType()->getContainedDeducedType();
- }
-};
-}
-
-void CXXNameMangler::mangleTemplateArgs(TemplateName TN,
- const TemplateArgumentLoc *TemplateArgs,
+void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs) {
// <template-args> ::= I <template-arg>+ E
Out << 'I';
- TemplateArgManglingInfo Info(TN);
for (unsigned i = 0; i != NumTemplateArgs; ++i)
- mangleTemplateArg(TemplateArgs[i].getArgument(),
- Info.needExactType(i, TemplateArgs[i].getArgument()));
+ mangleTemplateArg(TemplateArgs[i].getArgument());
Out << 'E';
}
-void CXXNameMangler::mangleTemplateArgs(TemplateName TN,
- const TemplateArgumentList &AL) {
+void CXXNameMangler::mangleTemplateArgs(const TemplateArgumentList &AL) {
// <template-args> ::= I <template-arg>+ E
Out << 'I';
- TemplateArgManglingInfo Info(TN);
for (unsigned i = 0, e = AL.size(); i != e; ++i)
- mangleTemplateArg(AL[i], Info.needExactType(i, AL[i]));
+ mangleTemplateArg(AL[i]);
Out << 'E';
}
-void CXXNameMangler::mangleTemplateArgs(TemplateName TN,
- const TemplateArgument *TemplateArgs,
+void CXXNameMangler::mangleTemplateArgs(const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs) {
// <template-args> ::= I <template-arg>+ E
Out << 'I';
- TemplateArgManglingInfo Info(TN);
for (unsigned i = 0; i != NumTemplateArgs; ++i)
- mangleTemplateArg(TemplateArgs[i], Info.needExactType(i, TemplateArgs[i]));
+ mangleTemplateArg(TemplateArgs[i]);
Out << 'E';
}
-void CXXNameMangler::mangleTemplateArg(TemplateArgument A, bool NeedExactType) {
+void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
// <template-arg> ::= <type> # type or template
// ::= X <expression> E # expression
// ::= <expr-primary> # simple expressions
// Template parameter objects are modeled by reproducing a source form
// produced as if by aggregate initialization.
if (A.getParamTypeForDecl()->isRecordType()) {
+ Out << 'X';
auto *TPO = cast<TemplateParamObjectDecl>(D);
mangleValueInTemplateArg(TPO->getType().getUnqualifiedType(),
- TPO->getValue(), /*TopLevel=*/true,
- NeedExactType);
+ TPO->getValue());
+ Out << 'E';
break;
}
- ASTContext &Ctx = Context.getASTContext();
- APValue Value;
- if (D->isCXXInstanceMember())
- // Simple pointer-to-member with no conversion.
- Value = APValue(D, /*IsDerivedMember=*/false, /*Path=*/{});
- else if (D->getType()->isArrayType() &&
- Ctx.hasSimilarType(Ctx.getDecayedType(D->getType()),
- A.getParamTypeForDecl()) &&
- Ctx.getLangOpts().getClangABICompat() >
- LangOptions::ClangABI::Ver11)
- // Build a value corresponding to this implicit array-to-pointer decay.
- Value = APValue(APValue::LValueBase(D), CharUnits::Zero(),
- {APValue::LValuePathEntry::ArrayIndex(0)},
- /*OnePastTheEnd=*/false);
- else
- // Regular pointer or reference to a declaration.
- Value = APValue(APValue::LValueBase(D), CharUnits::Zero(),
- ArrayRef<APValue::LValuePathEntry>(),
- /*OnePastTheEnd=*/false);
- mangleValueInTemplateArg(A.getParamTypeForDecl(), Value, /*TopLevel=*/true,
- NeedExactType);
+ // Clang produces AST's where pointer-to-member-function expressions
+ // and pointer-to-function expressions are represented as a declaration not
+ // an expression. We compensate for it here to produce the correct mangling.
+ bool compensateMangling = !A.getParamTypeForDecl()->isReferenceType();
+ if (compensateMangling) {
+ Out << 'X';
+ mangleOperatorName(OO_Amp, 1);
+ }
+
+ mangleDeclRefExpr(D);
+
+ if (compensateMangling)
+ Out << 'E';
+
break;
}
case TemplateArgument::NullPtr: {
// <template-arg> ::= J <template-arg>* E
Out << 'J';
for (const auto &P : A.pack_elements())
- mangleTemplateArg(P, NeedExactType);
+ mangleTemplateArg(P);
Out << 'E';
}
}
llvm_unreachable("Unhandled APValue::ValueKind enum");
}
-static QualType getLValueType(ASTContext &Ctx, const APValue &LV) {
- QualType T = LV.getLValueBase().getType();
- for (APValue::LValuePathEntry E : LV.getLValuePath()) {
- if (const ArrayType *AT = Ctx.getAsArrayType(T))
- T = AT->getElementType();
- else if (const FieldDecl *FD =
- dyn_cast<FieldDecl>(E.getAsBaseOrMember().getPointer()))
- T = FD->getType();
- else
- T = Ctx.getRecordType(
- cast<CXXRecordDecl>(E.getAsBaseOrMember().getPointer()));
- }
- return T;
-}
-
-void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V,
- bool TopLevel,
- bool NeedExactType) {
+void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V) {
// Ignore all top-level cv-qualifiers, to match GCC.
Qualifiers Quals;
T = getASTContext().getUnqualifiedArrayType(T, Quals);
- // A top-level expression that's not a primary expression is wrapped in X...E.
- bool IsPrimaryExpr = true;
- auto NotPrimaryExpr = [&] {
- if (TopLevel && IsPrimaryExpr)
- Out << 'X';
- IsPrimaryExpr = false;
- };
-
// Proposed in https://github.com/itanium-cxx-abi/cxx-abi/issues/63.
switch (V.getKind()) {
case APValue::None:
Out << 'L';
mangleType(T);
Out << 'E';
- break;
+ return;
case APValue::AddrLabelDiff:
llvm_unreachable("unexpected value kind in template argument");
}
// <expression> ::= tl <type> <braced-expression>* E
- NotPrimaryExpr();
Out << "tl";
mangleType(T);
for (unsigned I = 0, N = Bases.size(); I != N; ++I)
- mangleValueInTemplateArg(Bases[I].getType(), V.getStructBase(I), false);
+ mangleValueInTemplateArg(Bases[I].getType(), V.getStructBase(I));
for (unsigned I = 0, N = Fields.size(); I != N; ++I) {
if (Fields[I]->isUnnamedBitfield())
continue;
mangleValueInTemplateArg(Fields[I]->getType(),
- V.getStructField(Fields[I]->getFieldIndex()),
- false);
+ V.getStructField(Fields[I]->getFieldIndex()));
}
Out << 'E';
- break;
+ return;
}
case APValue::Union: {
Out << 'L';
mangleType(T);
Out << 'E';
- break;
+ return;
}
// <braced-expression> ::= di <field source-name> <braced-expression>
- NotPrimaryExpr();
Out << "tl";
mangleType(T);
if (!isZeroInitialized(T, V)) {
Out << "di";
mangleSourceName(FD->getIdentifier());
- mangleValueInTemplateArg(FD->getType(), V.getUnionValue(), false);
+ mangleValueInTemplateArg(FD->getType(), V.getUnionValue());
}
Out << 'E';
- break;
+ return;
}
case APValue::Array: {
QualType ElemT(T->getArrayElementTypeNoTypeQual(), 0);
- NotPrimaryExpr();
Out << "tl";
mangleType(T);
const APValue &Elem = I < V.getArrayInitializedElts()
? V.getArrayInitializedElt(I)
: V.getArrayFiller();
- mangleValueInTemplateArg(ElemT, Elem, false);
+ mangleValueInTemplateArg(ElemT, Elem);
}
Out << 'E';
- break;
+ return;
}
case APValue::Vector: {
const VectorType *VT = T->castAs<VectorType>();
- NotPrimaryExpr();
Out << "tl";
mangleType(T);
unsigned N = V.getVectorLength();
while (N && isZeroInitialized(VT->getElementType(), V.getVectorElt(N - 1)))
--N;
for (unsigned I = 0; I != N; ++I)
- mangleValueInTemplateArg(VT->getElementType(), V.getVectorElt(I), false);
+ mangleValueInTemplateArg(VT->getElementType(), V.getVectorElt(I));
Out << 'E';
- break;
+ return;
}
case APValue::Int:
mangleIntegerLiteral(T, V.getInt());
- break;
+ return;
case APValue::Float:
mangleFloatLiteral(T, V.getFloat());
- break;
+ return;
case APValue::FixedPoint:
mangleFixedPointLiteral();
- break;
+ return;
case APValue::ComplexFloat: {
const ComplexType *CT = T->castAs<ComplexType>();
- NotPrimaryExpr();
Out << "tl";
mangleType(T);
if (!V.getComplexFloatReal().isPosZero() ||
if (!V.getComplexFloatImag().isPosZero())
mangleFloatLiteral(CT->getElementType(), V.getComplexFloatImag());
Out << 'E';
- break;
+ return;
}
case APValue::ComplexInt: {
const ComplexType *CT = T->castAs<ComplexType>();
- NotPrimaryExpr();
Out << "tl";
mangleType(T);
if (V.getComplexIntReal().getBoolValue() ||
if (V.getComplexIntImag().getBoolValue())
mangleIntegerLiteral(CT->getElementType(), V.getComplexIntImag());
Out << 'E';
- break;
+ return;
}
case APValue::LValue: {
if (V.isNullPointer()) {
mangleNullPointer(T);
- break;
+ return;
}
APValue::LValueBase B = V.getLValueBase();
if (Offset.isZero()) {
// This is reinterpret_cast<T*>(0), not a null pointer. Mangle this as
// a cast, because L <type> 0 E means something else.
- NotPrimaryExpr();
Out << "rc";
mangleType(T);
Out << "Li0E";
- if (TopLevel)
- Out << 'E';
} else {
Out << "L";
mangleType(T);
Out << Offset.getQuantity() << 'E';
}
- break;
+ return;
}
- ASTContext &Ctx = Context.getASTContext();
-
enum { Base, Offset, Path } Kind;
if (!V.hasLValuePath()) {
// Mangle as (T*)((char*)&base + N).
if (T->isReferenceType()) {
- NotPrimaryExpr();
Out << "decvP";
mangleType(T->getPointeeType());
} else {
- NotPrimaryExpr();
Out << "cv";
mangleType(T);
}
Out << "plcvPcad";
Kind = Offset;
} else {
+ if (T->isPointerType())
+ Out << "ad";
if (!V.getLValuePath().empty() || V.isLValueOnePastTheEnd()) {
- NotPrimaryExpr();
- // A final conversion to the template parameter's type is usually
- // folded into the 'so' mangling, but we can't do that for 'void*'
- // parameters without introducing collisions.
- if (NeedExactType && T->isVoidPointerType()) {
- Out << "cv";
- mangleType(T);
- }
- if (T->isPointerType())
- Out << "ad";
Out << "so";
- mangleType(T->isVoidPointerType()
- ? getLValueType(Ctx, V).getUnqualifiedType()
- : T->getPointeeType());
+ mangleType(T->getPointeeType());
Kind = Path;
} else {
- if (NeedExactType &&
- !Ctx.hasSameType(T->getPointeeType(), getLValueType(Ctx, V)) &&
- Ctx.getLangOpts().getClangABICompat() >
- LangOptions::ClangABI::Ver11) {
- NotPrimaryExpr();
- Out << "cv";
- mangleType(T);
- }
- if (T->isPointerType()) {
- NotPrimaryExpr();
- Out << "ad";
- }
Kind = Base;
}
}
- QualType TypeSoFar = B.getType();
+ QualType TypeSoFar;
if (auto *VD = B.dyn_cast<const ValueDecl*>()) {
Out << 'L';
mangle(VD);
Out << 'E';
+ TypeSoFar = VD->getType();
} else if (auto *E = B.dyn_cast<const Expr*>()) {
- NotPrimaryExpr();
mangleExpression(E);
+ TypeSoFar = E->getType();
} else if (auto TI = B.dyn_cast<TypeInfoLValue>()) {
- NotPrimaryExpr();
Out << "ti";
mangleType(QualType(TI.getType(), 0));
+ TypeSoFar = B.getTypeInfoType();
} else {
// We should never see dynamic allocations here.
llvm_unreachable("unexpected lvalue base kind in template argument");
case Offset:
Out << 'L';
- mangleType(Ctx.getPointerDiffType());
+ mangleType(Context.getASTContext().getPointerDiffType());
mangleNumber(V.getLValueOffset().getQuantity());
Out << 'E';
break;
}
TypeSoFar = FD->getType();
} else {
- TypeSoFar = Ctx.getRecordType(cast<CXXRecordDecl>(D));
+ TypeSoFar =
+ Context.getASTContext().getRecordType(cast<CXXRecordDecl>(D));
}
}
}
break;
}
- break;
+ return;
}
case APValue::MemberPointer:
// Proposed in https://github.com/itanium-cxx-abi/cxx-abi/issues/47.
if (!V.getMemberPointerDecl()) {
mangleNullPointer(T);
- break;
+ return;
}
- ASTContext &Ctx = Context.getASTContext();
-
- NotPrimaryExpr();
if (!V.getMemberPointerPath().empty()) {
Out << "mc";
mangleType(T);
- } else if (NeedExactType &&
- !Ctx.hasSameType(
- T->castAs<MemberPointerType>()->getPointeeType(),
- V.getMemberPointerDecl()->getType()) &&
- Ctx.getLangOpts().getClangABICompat() >
- LangOptions::ClangABI::Ver11) {
- Out << "cv";
- mangleType(T);
}
Out << "adL";
mangle(V.getMemberPointerDecl());
mangleNumber(Offset.getQuantity());
Out << 'E';
}
- break;
+ return;
}
-
- if (TopLevel && !IsPrimaryExpr)
- Out << 'E';
}
void CXXNameMangler::mangleTemplateParameter(unsigned Depth, unsigned Index) {