diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
| commit | b60736ec1405bb0a8dd40989f67ef4c93da068ab (patch) | |
| tree | 5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /clang/lib/AST/MicrosoftMangle.cpp | |
| parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) | |
Diffstat (limited to 'clang/lib/AST/MicrosoftMangle.cpp')
| -rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 424 |
1 files changed, 370 insertions, 54 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 529f301e4696..df6c566abc7d 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -50,7 +50,7 @@ struct msvc_hashing_ostream : public llvm::raw_svector_ostream { bool StartsWithEscape = MangledName.startswith("\01"); if (StartsWithEscape) MangledName = MangledName.drop_front(1); - if (MangledName.size() <= 4096) { + if (MangledName.size() < 4096) { OS << str(); return; } @@ -308,12 +308,17 @@ public: void mangleName(const NamedDecl *ND); void mangleFunctionEncoding(const FunctionDecl *FD, bool ShouldMangle); void mangleVariableEncoding(const VarDecl *VD); - void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD); + void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD, + StringRef Prefix = "$"); void mangleMemberFunctionPointer(const CXXRecordDecl *RD, - const CXXMethodDecl *MD); + const CXXMethodDecl *MD, + StringRef Prefix = "$"); void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, const MethodVFTableLocation &ML); void mangleNumber(int64_t Number); + void mangleNumber(llvm::APSInt Number); + void mangleFloat(llvm::APFloat Number); + void mangleBits(llvm::APInt Number); void mangleTagTypeKind(TagTypeKind TK); void mangleArtificialTagType(TagTypeKind TK, StringRef UnqualifiedName, ArrayRef<StringRef> NestedNames = None); @@ -378,14 +383,18 @@ private: void mangleFunctionClass(const FunctionDecl *FD); void mangleCallingConvention(CallingConv CC); void mangleCallingConvention(const FunctionType *T); - void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean); - void mangleExpression(const Expr *E); + void mangleIntegerLiteral(const llvm::APSInt &Number, + const NonTypeTemplateParmDecl *PD = nullptr, + QualType TemplateArgType = QualType()); + void mangleExpression(const Expr *E, const NonTypeTemplateParmDecl *PD); void mangleThrowSpecification(const FunctionProtoType *T); void mangleTemplateArgs(const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs); void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA, const NamedDecl *Parm); + void mangleTemplateArgValue(QualType T, const APValue &V, + bool WithScalarType = false); void mangleObjCProtocol(const ObjCProtocolDecl *PD); void mangleObjCLifetime(const QualType T, Qualifiers Quals, @@ -501,7 +510,10 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, StringRef Prefix) { // MSVC appears to mangle GUIDs as if they were variables of type // 'const struct __s_GUID'. Out << "3U__s_GUID@@B"; - else + else if (isa<TemplateParamObjectDecl>(D)) { + // Template parameter objects don't get a <type-encoding>; their type is + // specified as part of their value. + } else llvm_unreachable("Tried to mangle unexpected NamedDecl!"); } @@ -592,7 +604,8 @@ void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) { } void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD, - const ValueDecl *VD) { + const ValueDecl *VD, + StringRef Prefix) { // <member-data-pointer> ::= <integer-literal> // ::= $F <number> <number> // ::= $G <number> <number> <number> @@ -624,7 +637,7 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD, case MSInheritanceModel::Unspecified: Code = 'G'; break; } - Out << '$' << Code; + Out << Prefix << Code; mangleNumber(FieldOffset); @@ -639,7 +652,8 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD, void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, - const CXXMethodDecl *MD) { + const CXXMethodDecl *MD, + StringRef Prefix) { // <member-function-pointer> ::= $1? <name> // ::= $H? <name> <number> // ::= $I? <name> <number> <number> @@ -661,7 +675,7 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, uint64_t VBTableOffset = 0; uint64_t VBPtrOffset = 0; if (MD) { - Out << '$' << Code << '?'; + Out << Prefix << Code << '?'; if (MD->isVirtual()) { MicrosoftVTableContext *VTContext = cast<MicrosoftVTableContext>(getASTContext().getVTableContext()); @@ -684,12 +698,12 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, } else { // Null single inheritance member functions are encoded as a simple nullptr. if (IM == MSInheritanceModel::Single) { - Out << "$0A@"; + Out << Prefix << "0A@"; return; } if (IM == MSInheritanceModel::Unspecified) VBTableOffset = -1; - Out << '$' << Code; + Out << Prefix << Code; } if (inheritanceModelHasNVOffsetField(/*IsMemberFunction=*/true, IM)) @@ -728,32 +742,63 @@ void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) { } void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) { + mangleNumber(llvm::APSInt(llvm::APInt(64, Number), /*IsUnsigned*/false)); +} + +void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) { + // MSVC never mangles any integer wider than 64 bits. In general it appears + // to convert every integer to signed 64 bit before mangling (including + // unsigned 64 bit values). Do the same, but preserve bits beyond the bottom + // 64. + llvm::APInt Value = + Number.isSigned() ? Number.sextOrSelf(64) : Number.zextOrSelf(64); + // <non-negative integer> ::= A@ # when Number == 0 // ::= <decimal digit> # when 1 <= Number <= 10 // ::= <hex digit>+ @ # when Number >= 10 // // <number> ::= [?] <non-negative integer> - uint64_t Value = static_cast<uint64_t>(Number); - if (Number < 0) { + if (Value.isNegative()) { Value = -Value; Out << '?'; } + mangleBits(Value); +} + +void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) { + using llvm::APFloat; + + switch (APFloat::SemanticsToEnum(Number.getSemantics())) { + case APFloat::S_IEEEsingle: Out << 'A'; break; + case APFloat::S_IEEEdouble: Out << 'B'; break; + // The following are all Clang extensions. We try to pick manglings that are + // unlikely to conflict with MSVC's scheme. + case APFloat::S_IEEEhalf: Out << 'V'; break; + case APFloat::S_BFloat: Out << 'W'; break; + case APFloat::S_x87DoubleExtended: Out << 'X'; break; + case APFloat::S_IEEEquad: Out << 'Y'; break; + case APFloat::S_PPCDoubleDouble: Out << 'Z'; break; + } + + mangleBits(Number.bitcastToAPInt()); +} + +void MicrosoftCXXNameMangler::mangleBits(llvm::APInt Value) { if (Value == 0) Out << "A@"; - else if (Value >= 1 && Value <= 10) + else if (Value.uge(1) && Value.ule(10)) Out << (Value - 1); else { // Numbers that are not encoded as decimal digits are represented as nibbles // in the range of ASCII characters 'A' to 'P'. // The number 0x123450 would be encoded as 'BCDEFA' - char EncodedNumberBuffer[sizeof(uint64_t) * 2]; - MutableArrayRef<char> BufferRef(EncodedNumberBuffer); - MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin(); - for (; Value != 0; Value >>= 4) - *I++ = 'A' + (Value & 0xf); - Out.write(I.base(), I - BufferRef.rbegin()); + llvm::SmallString<32> EncodedNumberBuffer; + for (; Value != 0; Value.lshrInPlace(4)) + EncodedNumberBuffer.push_back('A' + (Value & 0xf).getZExtValue()); + std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end()); + Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size()); Out << '@'; } } @@ -907,6 +952,13 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, break; } + if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) { + Out << "?__N"; + mangleTemplateArgValue(TPO->getType().getUnqualifiedType(), + TPO->getValue()); + break; + } + // We must have an anonymous struct. const TagDecl *TD = cast<TagDecl>(ND); if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) { @@ -1321,7 +1373,7 @@ void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) { } void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { - Context.mangleObjCMethodName(MD, Out); + Context.mangleObjCMethodNameAsSourceName(MD, Out); } void MicrosoftCXXNameMangler::mangleTemplateInstantiationName( @@ -1357,24 +1409,33 @@ MicrosoftCXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *TD) { mangleUnqualifiedName(TD); } -void MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value, - bool IsBoolean) { +void MicrosoftCXXNameMangler::mangleIntegerLiteral( + const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD, + QualType TemplateArgType) { // <integer-literal> ::= $0 <number> - Out << "$0"; - // Make sure booleans are encoded as 0/1. - if (IsBoolean && Value.getBoolValue()) - mangleNumber(1); - else if (Value.isSigned()) - mangleNumber(Value.getSExtValue()); - else - mangleNumber(Value.getZExtValue()); + Out << "$"; + + // Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when + // argument is integer. + if (getASTContext().getLangOpts().isCompatibleWithMSVC( + LangOptions::MSVC2019) && + PD && PD->getType()->getTypeClass() == Type::Auto && + !TemplateArgType.isNull()) { + Out << "M"; + mangleType(TemplateArgType, SourceRange(), QMM_Drop); + } + + Out << "0"; + + mangleNumber(Value); } -void MicrosoftCXXNameMangler::mangleExpression(const Expr *E) { +void MicrosoftCXXNameMangler::mangleExpression( + const Expr *E, const NonTypeTemplateParmDecl *PD) { // See if this is a constant expression. - llvm::APSInt Value; - if (E->isIntegerConstantExpr(Value, Context.getASTContext())) { - mangleIntegerLiteral(Value, E->getType()->isBooleanType()); + if (Optional<llvm::APSInt> Value = + E->getIntegerConstantExpr(Context.getASTContext())) { + mangleIntegerLiteral(*Value, PD, E->getType()); return; } @@ -1412,10 +1473,34 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, // ::= <integer-literal> // ::= <member-data-pointer> // ::= <member-function-pointer> - // ::= $E? <name> <type-encoding> - // ::= $1? <name> <type-encoding> - // ::= $0A@ + // ::= $ <constant-value> // ::= <template-args> + // + // <constant-value> ::= 0 <number> # integer + // ::= 1 <mangled-name> # address of D + // ::= 2 <type> <typed-constant-value>* @ # struct + // ::= 3 <type> <constant-value>* @ # array + // ::= 4 ??? # string + // ::= 5 <constant-value> @ # address of subobject + // ::= 6 <constant-value> <unqualified-name> @ # a.b + // ::= 7 <type> [<unqualified-name> <constant-value>] @ + // # union, with or without an active member + // # pointer to member, symbolically + // ::= 8 <class> <unqualified-name> @ + // ::= A <type> <non-negative integer> # float + // ::= B <type> <non-negative integer> # double + // ::= E <mangled-name> # reference to D + // # pointer to member, by component value + // ::= F <number> <number> + // ::= G <number> <number> <number> + // ::= H <mangled-name> <number> + // ::= I <mangled-name> <number> <number> + // ::= J <mangled-name> <number> <number> <number> + // + // <typed-constant-value> ::= [<type>] <constant-value> + // + // The <type> appears to be included in a <typed-constant-value> only in the + // '0', '1', '8', 'A', 'B', and 'E' cases. switch (TA.getKind()) { case TemplateArgument::Null: @@ -1443,15 +1528,22 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, mangleName(FD); mangleFunctionEncoding(FD, /*ShouldMangle=*/true); } + } else if (TA.getParamTypeForDecl()->isRecordType()) { + Out << "$"; + auto *TPO = cast<TemplateParamObjectDecl>(ND); + mangleTemplateArgValue(TPO->getType().getUnqualifiedType(), + TPO->getValue()); } else { mangle(ND, TA.getParamTypeForDecl()->isReferenceType() ? "$E?" : "$1?"); } break; } - case TemplateArgument::Integral: + case TemplateArgument::Integral: { + QualType T = TA.getIntegralType(); mangleIntegerLiteral(TA.getAsIntegral(), - TA.getIntegralType()->isBooleanType()); + cast<NonTypeTemplateParmDecl>(Parm), T); break; + } case TemplateArgument::NullPtr: { QualType T = TA.getNullPtrType(); if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) { @@ -1473,16 +1565,18 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, // However, we are free to use 0 *if* we would use multiple fields for // non-nullptr member pointers. if (!RD->nullFieldOffsetIsZero()) { - mangleIntegerLiteral(llvm::APSInt::get(-1), /*IsBoolean=*/false); + mangleIntegerLiteral(llvm::APSInt::get(-1), + cast<NonTypeTemplateParmDecl>(Parm), T); return; } } } - mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), /*IsBoolean=*/false); + mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), + cast<NonTypeTemplateParmDecl>(Parm), T); break; } case TemplateArgument::Expression: - mangleExpression(TA.getAsExpr()); + mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm)); break; case TemplateArgument::Pack: { ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray(); @@ -1521,6 +1615,212 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD, } } +void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T, + const APValue &V, + bool WithScalarType) { + switch (V.getKind()) { + case APValue::None: + case APValue::Indeterminate: + // FIXME: MSVC doesn't allow this, so we can't be sure how it should be + // mangled. + if (WithScalarType) + mangleType(T, SourceRange(), QMM_Escape); + Out << '@'; + return; + + case APValue::Int: + if (WithScalarType) + mangleType(T, SourceRange(), QMM_Escape); + Out << '0'; + mangleNumber(V.getInt()); + return; + + case APValue::Float: + if (WithScalarType) + mangleType(T, SourceRange(), QMM_Escape); + mangleFloat(V.getFloat()); + return; + + case APValue::LValue: { + if (WithScalarType) + mangleType(T, SourceRange(), QMM_Escape); + + // We don't know how to mangle past-the-end pointers yet. + if (V.isLValueOnePastTheEnd()) + break; + + APValue::LValueBase Base = V.getLValueBase(); + if (!V.hasLValuePath() || V.getLValuePath().empty()) { + // Taking the address of a complete object has a special-case mangling. + if (Base.isNull()) { + // MSVC emits 0A@ for null pointers. Generalize this for arbitrary + // integers cast to pointers. + // FIXME: This mangles 0 cast to a pointer the same as a null pointer, + // even in cases where the two are different values. + Out << "0"; + mangleNumber(V.getLValueOffset().getQuantity()); + } else if (!V.hasLValuePath()) { + // FIXME: This can only happen as an extension. Invent a mangling. + break; + } else if (auto *VD = Base.dyn_cast<const ValueDecl*>()) { + Out << (T->isReferenceType() ? "E" : "1"); + mangle(VD); + } else { + break; + } + } else { + unsigned NumAts = 0; + if (T->isPointerType()) { + Out << "5"; + ++NumAts; + } + + QualType T = Base.getType(); + for (APValue::LValuePathEntry E : V.getLValuePath()) { + // We don't know how to mangle array subscripting yet. + if (T->isArrayType()) + goto mangling_unknown; + + const Decl *D = E.getAsBaseOrMember().getPointer(); + auto *FD = dyn_cast<FieldDecl>(D); + // We don't know how to mangle derived-to-base conversions yet. + if (!FD) + goto mangling_unknown; + + Out << "6"; + ++NumAts; + T = FD->getType(); + } + + auto *VD = Base.dyn_cast<const ValueDecl*>(); + if (!VD) + break; + Out << "E"; + mangle(VD); + + for (APValue::LValuePathEntry E : V.getLValuePath()) { + const Decl *D = E.getAsBaseOrMember().getPointer(); + mangleUnqualifiedName(cast<FieldDecl>(D)); + } + for (unsigned I = 0; I != NumAts; ++I) + Out << '@'; + } + + return; + } + + case APValue::MemberPointer: { + if (WithScalarType) + mangleType(T, SourceRange(), QMM_Escape); + + // FIXME: The below manglings don't include a conversion, so bail if there + // would be one. MSVC mangles the (possibly converted) value of the + // pointer-to-member object as if it were a struct, leading to collisions + // in some cases. + if (!V.getMemberPointerPath().empty()) + break; + + const CXXRecordDecl *RD = + T->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl(); + const ValueDecl *D = V.getMemberPointerDecl(); + if (T->isMemberDataPointerType()) + mangleMemberDataPointer(RD, D, ""); + else + mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D), ""); + return; + } + + case APValue::Struct: { + Out << '2'; + mangleType(T, SourceRange(), QMM_Escape); + const CXXRecordDecl *RD = T->getAsCXXRecordDecl(); + assert(RD && "unexpected type for record value"); + + unsigned BaseIndex = 0; + for (const CXXBaseSpecifier &B : RD->bases()) + mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++)); + for (const FieldDecl *FD : RD->fields()) + if (!FD->isUnnamedBitfield()) + mangleTemplateArgValue(FD->getType(), + V.getStructField(FD->getFieldIndex()), + /*WithScalarType*/ true); + Out << '@'; + return; + } + + case APValue::Union: + Out << '7'; + mangleType(T, SourceRange(), QMM_Escape); + if (const FieldDecl *FD = V.getUnionField()) { + mangleUnqualifiedName(FD); + mangleTemplateArgValue(FD->getType(), V.getUnionValue()); + } + Out << '@'; + return; + + case APValue::ComplexInt: + // We mangle complex types as structs, so mangle the value as a struct too. + Out << '2'; + mangleType(T, SourceRange(), QMM_Escape); + Out << '0'; + mangleNumber(V.getComplexIntReal()); + Out << '0'; + mangleNumber(V.getComplexIntImag()); + Out << '@'; + return; + + case APValue::ComplexFloat: + Out << '2'; + mangleType(T, SourceRange(), QMM_Escape); + mangleFloat(V.getComplexFloatReal()); + mangleFloat(V.getComplexFloatImag()); + Out << '@'; + return; + + case APValue::Array: { + Out << '3'; + QualType ElemT = getASTContext().getAsArrayType(T)->getElementType(); + mangleType(ElemT, SourceRange(), QMM_Escape); + for (unsigned I = 0, N = V.getArraySize(); I != N; ++I) { + const APValue &ElemV = I < V.getArrayInitializedElts() + ? V.getArrayInitializedElt(I) + : V.getArrayFiller(); + mangleTemplateArgValue(ElemT, ElemV); + Out << '@'; + } + Out << '@'; + return; + } + + case APValue::Vector: { + // __m128 is mangled as a struct containing an array. We follow this + // approach for all vector types. + Out << '2'; + mangleType(T, SourceRange(), QMM_Escape); + Out << '3'; + QualType ElemT = T->castAs<VectorType>()->getElementType(); + mangleType(ElemT, SourceRange(), QMM_Escape); + for (unsigned I = 0, N = V.getVectorLength(); I != N; ++I) { + const APValue &ElemV = V.getVectorElt(I); + mangleTemplateArgValue(ElemT, ElemV); + Out << '@'; + } + Out << "@@"; + return; + } + + case APValue::AddrLabelDiff: + case APValue::FixedPoint: + break; + } + +mangling_unknown: + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID( + DiagnosticsEngine::Error, "cannot mangle this template argument yet"); + Diags.Report(DiagID); +} + void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) { llvm::SmallString<64> TemplateMangling; llvm::raw_svector_ostream Stream(TemplateMangling); @@ -1798,7 +2098,7 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T, // where: // <language_addr_space> ::= <OpenCL-addrspace> | <CUDA-addrspace> // <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" | - // "private"| "generic" ] + // "private"| "generic" | "device" | "host" ] // <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ] // Note that the above were chosen to match the Itanium mangling for this. // @@ -1814,8 +2114,7 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T, if (Context.getASTContext().addressSpaceMapManglingFor(AS)) { unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS); Extra.mangleSourceName("_AS"); - Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS), - /*IsBoolean*/ false); + Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS)); } else { switch (AS) { default: @@ -1823,6 +2122,12 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T, case LangAS::opencl_global: Extra.mangleSourceName("_ASCLglobal"); break; + case LangAS::opencl_global_device: + Extra.mangleSourceName("_ASCLdevice"); + break; + case LangAS::opencl_global_host: + Extra.mangleSourceName("_ASCLhost"); + break; case LangAS::opencl_local: Extra.mangleSourceName("_ASCLlocal"); break; @@ -2090,6 +2395,9 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, #define SVE_TYPE(Name, Id, SingletonId) \ case BuiltinType::Id: #include "clang/Basic/AArch64SVEACLETypes.def" +#define PPC_VECTOR_TYPE(Name, Id, Size) \ + case BuiltinType::Id: +#include "clang/Basic/PPCTypes.def" case BuiltinType::ShortAccum: case BuiltinType::Accum: case BuiltinType::LongAccum: @@ -2229,10 +2537,20 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T, return; } Out << '@'; + } else if (IsInLambda && D && isa<CXXConversionDecl>(D)) { + // The only lambda conversion operators are to function pointers, which + // can differ by their calling convention and are typically deduced. So + // we make sure that this type gets mangled properly. + mangleType(T->getReturnType(), Range, QMM_Result); } else { QualType ResultType = T->getReturnType(); - if (const auto *AT = - dyn_cast_or_null<AutoType>(ResultType->getContainedAutoType())) { + if (IsInLambda && isa<CXXConversionDecl>(D)) { + // The only lambda conversion operators are to function pointers, which + // can differ by their calling convention and are typically deduced. So + // we make sure that this type gets mangled properly. + mangleType(ResultType, Range, QMM_Result); + } else if (const auto *AT = dyn_cast_or_null<AutoType>( + ResultType->getContainedAutoType())) { Out << '?'; mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false); Out << '?'; @@ -2701,8 +3019,7 @@ void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals, Stream << "?$"; Extra.mangleSourceName("__vector"); Extra.mangleType(QualType(ET, 0), Range, QMM_Escape); - Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()), - /*IsBoolean=*/false); + Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements())); mangleArtificialTagType(TTK_Union, TemplateMangling, {"__clang"}); } @@ -2941,7 +3258,7 @@ void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers, Stream << "?$"; Extra.mangleSourceName("ocl_pipe"); Extra.mangleType(ElementType, Range, QMM_Escape); - Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()), true); + Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly())); mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"}); } @@ -2981,8 +3298,7 @@ void MicrosoftCXXNameMangler::mangleType(const ExtIntType *T, Qualifiers, Extra.mangleSourceName("_UExtInt"); else Extra.mangleSourceName("_ExtInt"); - Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()), - /*IsBoolean=*/false); + Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits())); mangleArtificialTagType(TTK_Struct, TemplateMangling, {"__clang"}); } |
