aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/MicrosoftMangle.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /clang/lib/AST/MicrosoftMangle.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Diffstat (limited to 'clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp424
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"});
}