summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp136
1 files changed, 107 insertions, 29 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp b/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp
index 76c368d..24b16f8 100644
--- a/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp
+++ b/contrib/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp
@@ -942,6 +942,9 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
break;
}
+ case DeclarationName::CXXDeductionGuideName:
+ llvm_unreachable("Can't mangle a deduction guide name!");
+
case DeclarationName::CXXUsingDirective:
llvm_unreachable("Can't mangle a using directive name!");
}
@@ -963,16 +966,71 @@ void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
}
if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
- DiagnosticsEngine &Diags = Context.getDiags();
- unsigned DiagID =
- Diags.getCustomDiagID(DiagnosticsEngine::Error,
- "cannot mangle a local inside this block yet");
- Diags.Report(BD->getLocation(), DiagID);
-
- // FIXME: This is completely, utterly, wrong; see ItaniumMangle
- // for how this should be done.
- Out << "__block_invoke" << Context.getBlockId(BD, false);
- Out << '@';
+ auto Discriminate =
+ [](StringRef Name, const unsigned Discriminator,
+ const unsigned ParameterDiscriminator) -> std::string {
+ std::string Buffer;
+ llvm::raw_string_ostream Stream(Buffer);
+ Stream << Name;
+ if (Discriminator)
+ Stream << '_' << Discriminator;
+ if (ParameterDiscriminator)
+ Stream << '_' << ParameterDiscriminator;
+ return Stream.str();
+ };
+
+ unsigned Discriminator = BD->getBlockManglingNumber();
+ if (!Discriminator)
+ Discriminator = Context.getBlockId(BD, /*Local=*/false);
+
+ // Mangle the parameter position as a discriminator to deal with unnamed
+ // parameters. Rather than mangling the unqualified parameter name,
+ // always use the position to give a uniform mangling.
+ unsigned ParameterDiscriminator = 0;
+ if (const auto *MC = BD->getBlockManglingContextDecl())
+ if (const auto *P = dyn_cast<ParmVarDecl>(MC))
+ if (const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))
+ ParameterDiscriminator =
+ F->getNumParams() - P->getFunctionScopeIndex();
+
+ DC = getEffectiveDeclContext(BD);
+
+ Out << '?';
+ mangleSourceName(Discriminate("_block_invoke", Discriminator,
+ ParameterDiscriminator));
+ // If we have a block mangling context, encode that now. This allows us
+ // to discriminate between named static data initializers in the same
+ // scope. This is handled differently from parameters, which use
+ // positions to discriminate between multiple instances.
+ if (const auto *MC = BD->getBlockManglingContextDecl())
+ if (!isa<ParmVarDecl>(MC))
+ if (const auto *ND = dyn_cast<NamedDecl>(MC))
+ mangleUnqualifiedName(ND);
+ // MS ABI and Itanium manglings are in inverted scopes. In the case of a
+ // RecordDecl, mangle the entire scope hierachy at this point rather than
+ // just the unqualified name to get the ordering correct.
+ if (const auto *RD = dyn_cast<RecordDecl>(DC))
+ mangleName(RD);
+ else
+ Out << '@';
+ // void __cdecl
+ Out << "YAX";
+ // struct __block_literal *
+ Out << 'P';
+ // __ptr64
+ if (PointersAre64Bit)
+ Out << 'E';
+ Out << 'A';
+ mangleArtificalTagType(TTK_Struct,
+ Discriminate("__block_literal", Discriminator,
+ ParameterDiscriminator));
+ Out << "@Z";
+
+ // If the effective context was a Record, we have fully mangled the
+ // qualified name and do not need to continue.
+ if (isa<RecordDecl>(DC))
+ break;
+ continue;
} else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
mangleObjCMethodName(Method);
} else if (isa<NamedDecl>(DC)) {
@@ -1686,6 +1744,8 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
// ::= _N # bool
// _O # <array in parameter>
// ::= _T # __float80 (Intel)
+ // ::= _S # char16_t
+ // ::= _U # char32_t
// ::= _W # wchar_t
// ::= _Z # __float80 (Digital Mars)
switch (T->getKind()) {
@@ -1797,10 +1857,6 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
Out << "PA";
mangleArtificalTagType(TTK_Struct, "ocl_queue");
break;
- case BuiltinType::OCLNDRange:
- Out << "PA";
- mangleArtificalTagType(TTK_Struct, "ocl_ndrange");
- break;
case BuiltinType::OCLReserveID:
Out << "PA";
mangleArtificalTagType(TTK_Struct, "ocl_reserveid");
@@ -1887,14 +1943,18 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// <return-type> ::= <type>
// ::= @ # structors (they have no declared return type)
if (IsStructor) {
- if (isa<CXXDestructorDecl>(D) && isStructorDecl(D) &&
- StructorType == Dtor_Deleting) {
- // The scalar deleting destructor takes an extra int argument.
- // However, the FunctionType generated has 0 arguments.
- // FIXME: This is a temporary hack.
- // Maybe should fix the FunctionType creation instead?
- Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
- return;
+ if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {
+ // The scalar deleting destructor takes an extra int argument which is not
+ // reflected in the AST.
+ if (StructorType == Dtor_Deleting) {
+ Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");
+ return;
+ }
+ // The vbase destructor returns void which is not reflected in the AST.
+ if (StructorType == Dtor_Complete) {
+ Out << "XXZ";
+ return;
+ }
}
if (IsCtorClosure) {
// Default constructor closure and copy constructor closure both return
@@ -1954,7 +2014,7 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// Happens for function pointer type arguments for example.
for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {
mangleArgumentType(Proto->getParamType(I), Range);
- // Mangle each pass_object_size parameter as if it's a paramater of enum
+ // Mangle each pass_object_size parameter as if it's a parameter of enum
// type passed directly after the parameter with the pass_object_size
// attribute. The aforementioned enum's name is __pass_object_size, and we
// pretend it resides in a top-level namespace called __clang.
@@ -2002,13 +2062,20 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
// <global-function> ::= Y # global near
// ::= Z # global far
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ bool IsVirtual = MD->isVirtual();
+ // When mangling vbase destructor variants, ignore whether or not the
+ // underlying destructor was defined to be virtual.
+ if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&
+ StructorType == Dtor_Complete) {
+ IsVirtual = false;
+ }
switch (MD->getAccess()) {
case AS_none:
llvm_unreachable("Unsupported access specifier");
case AS_private:
if (MD->isStatic())
Out << 'C';
- else if (MD->isVirtual())
+ else if (IsVirtual)
Out << 'E';
else
Out << 'A';
@@ -2016,7 +2083,7 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
case AS_protected:
if (MD->isStatic())
Out << 'K';
- else if (MD->isVirtual())
+ else if (IsVirtual)
Out << 'M';
else
Out << 'I';
@@ -2024,7 +2091,7 @@ void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {
case AS_public:
if (MD->isStatic())
Out << 'S';
- else if (MD->isVirtual())
+ else if (IsVirtual)
Out << 'U';
else
Out << 'Q';
@@ -2055,7 +2122,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
switch (CC) {
default:
llvm_unreachable("Unsupported CC for mangling");
- case CC_X86_64Win64:
+ case CC_Win64:
case CC_X86_64SysV:
case CC_C: Out << 'A'; break;
case CC_X86Pascal: Out << 'C'; break;
@@ -2474,6 +2541,17 @@ void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers,
<< Range;
}
+void MicrosoftCXXNameMangler::mangleType(
+ const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {
+ assert(T->getDeducedType().isNull() && "expecting a dependent type!");
+
+ DiagnosticsEngine &Diags = Context.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "cannot mangle this deduced class template specialization type yet");
+ Diags.Report(Range.getBegin(), DiagID)
+ << Range;
+}
+
void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,
SourceRange Range) {
QualType ValueType = T->getValueType();
@@ -2997,14 +3075,14 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
// N.B. The length is in terms of bytes, not characters.
Mangler.mangleNumber(SL->getByteLength() + SL->getCharByteWidth());
- auto GetLittleEndianByte = [&Mangler, &SL](unsigned Index) {
+ auto GetLittleEndianByte = [&SL](unsigned Index) {
unsigned CharByteWidth = SL->getCharByteWidth();
uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
unsigned OffsetInCodeUnit = Index % CharByteWidth;
return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);
};
- auto GetBigEndianByte = [&Mangler, &SL](unsigned Index) {
+ auto GetBigEndianByte = [&SL](unsigned Index) {
unsigned CharByteWidth = SL->getCharByteWidth();
uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);
unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);
OpenPOWER on IntegriCloud