4411 lines · cpp
1//===--- MicrosoftMangle.cpp - Microsoft Visual C++ Name Mangling ---------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This provides C++ name mangling targeting the Microsoft Visual C++ ABI.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/ASTContext.h"14#include "clang/AST/Attr.h"15#include "clang/AST/CXXInheritance.h"16#include "clang/AST/CharUnits.h"17#include "clang/AST/Decl.h"18#include "clang/AST/DeclCXX.h"19#include "clang/AST/DeclObjC.h"20#include "clang/AST/DeclOpenMP.h"21#include "clang/AST/DeclTemplate.h"22#include "clang/AST/Expr.h"23#include "clang/AST/ExprCXX.h"24#include "clang/AST/GlobalDecl.h"25#include "clang/AST/Mangle.h"26#include "clang/AST/VTableBuilder.h"27#include "clang/Basic/ABI.h"28#include "clang/Basic/DiagnosticOptions.h"29#include "clang/Basic/SourceManager.h"30#include "clang/Basic/TargetInfo.h"31#include "llvm/ADT/SmallVector.h"32#include "llvm/ADT/StringExtras.h"33#include "llvm/Support/CRC.h"34#include "llvm/Support/MD5.h"35#include "llvm/Support/StringSaver.h"36#include "llvm/Support/xxhash.h"37#include <functional>38#include <optional>39 40using namespace clang;41 42namespace {43 44// Get GlobalDecl of DeclContext of local entities.45static GlobalDecl getGlobalDeclAsDeclContext(const DeclContext *DC) {46 GlobalDecl GD;47 if (auto *CD = dyn_cast<CXXConstructorDecl>(DC))48 GD = GlobalDecl(CD, Ctor_Complete);49 else if (auto *DD = dyn_cast<CXXDestructorDecl>(DC))50 GD = GlobalDecl(DD, Dtor_Complete);51 else52 GD = GlobalDecl(cast<FunctionDecl>(DC));53 return GD;54}55 56struct msvc_hashing_ostream : public llvm::raw_svector_ostream {57 raw_ostream &OS;58 llvm::SmallString<64> Buffer;59 60 msvc_hashing_ostream(raw_ostream &OS)61 : llvm::raw_svector_ostream(Buffer), OS(OS) {}62 ~msvc_hashing_ostream() override {63 StringRef MangledName = str();64 bool StartsWithEscape = MangledName.starts_with("\01");65 if (StartsWithEscape)66 MangledName = MangledName.drop_front(1);67 if (MangledName.size() < 4096) {68 OS << str();69 return;70 }71 72 llvm::MD5 Hasher;73 llvm::MD5::MD5Result Hash;74 Hasher.update(MangledName);75 Hasher.final(Hash);76 77 SmallString<32> HexString;78 llvm::MD5::stringifyResult(Hash, HexString);79 80 if (StartsWithEscape)81 OS << '\01';82 OS << "??@" << HexString << '@';83 }84};85 86static const DeclContext *87getLambdaDefaultArgumentDeclContext(const Decl *D) {88 if (const auto *RD = dyn_cast<CXXRecordDecl>(D))89 if (RD->isLambda())90 if (const auto *Parm =91 dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))92 return Parm->getDeclContext();93 return nullptr;94}95 96/// Retrieve the declaration context that should be used when mangling97/// the given declaration.98static const DeclContext *getEffectiveDeclContext(const Decl *D) {99 // The ABI assumes that lambda closure types that occur within100 // default arguments live in the context of the function. However, due to101 // the way in which Clang parses and creates function declarations, this is102 // not the case: the lambda closure type ends up living in the context103 // where the function itself resides, because the function declaration itself104 // had not yet been created. Fix the context here.105 if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))106 return LDADC;107 108 // Perform the same check for block literals.109 if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {110 if (ParmVarDecl *ContextParam =111 dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))112 return ContextParam->getDeclContext();113 }114 115 const DeclContext *DC = D->getDeclContext();116 if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||117 isa<OMPDeclareMapperDecl>(DC)) {118 return getEffectiveDeclContext(cast<Decl>(DC));119 }120 121 return DC->getRedeclContext();122}123 124static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {125 return getEffectiveDeclContext(cast<Decl>(DC));126}127 128static const FunctionDecl *getStructor(const NamedDecl *ND) {129 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))130 return FTD->getTemplatedDecl()->getCanonicalDecl();131 132 const auto *FD = cast<FunctionDecl>(ND);133 if (const auto *FTD = FD->getPrimaryTemplate())134 return FTD->getTemplatedDecl()->getCanonicalDecl();135 136 return FD->getCanonicalDecl();137}138 139/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the140/// Microsoft Visual C++ ABI.141class MicrosoftMangleContextImpl : public MicrosoftMangleContext {142 typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;143 llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;144 llvm::DenseMap<const NamedDecl *, unsigned> Uniquifier;145 llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;146 llvm::DenseMap<GlobalDecl, unsigned> SEHFilterIds;147 llvm::DenseMap<GlobalDecl, unsigned> SEHFinallyIds;148 SmallString<16> AnonymousNamespaceHash;149 150public:151 MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags,152 bool IsAux = false);153 bool shouldMangleCXXName(const NamedDecl *D) override;154 bool shouldMangleStringLiteral(const StringLiteral *SL) override;155 void mangleCXXName(GlobalDecl GD, raw_ostream &Out) override;156 void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,157 const MethodVFTableLocation &ML,158 raw_ostream &Out) override;159 void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk,160 bool ElideOverrideInfo, raw_ostream &) override;161 void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,162 const ThunkInfo &Thunk, bool ElideOverrideInfo,163 raw_ostream &) override;164 void mangleCXXVFTable(const CXXRecordDecl *Derived,165 ArrayRef<const CXXRecordDecl *> BasePath,166 raw_ostream &Out) override;167 void mangleCXXVBTable(const CXXRecordDecl *Derived,168 ArrayRef<const CXXRecordDecl *> BasePath,169 raw_ostream &Out) override;170 171 void mangleCXXVTable(const CXXRecordDecl *, raw_ostream &) override;172 void mangleCXXVirtualDisplacementMap(const CXXRecordDecl *SrcRD,173 const CXXRecordDecl *DstRD,174 raw_ostream &Out) override;175 void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile,176 bool IsUnaligned, uint32_t NumEntries,177 raw_ostream &Out) override;178 void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries,179 raw_ostream &Out) override;180 void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD,181 CXXCtorType CT, uint32_t Size, uint32_t NVOffset,182 int32_t VBPtrOffset, uint32_t VBIndex,183 raw_ostream &Out) override;184 void mangleCXXRTTI(QualType T, raw_ostream &Out) override;185 void mangleCXXRTTIName(QualType T, raw_ostream &Out,186 bool NormalizeIntegers) override;187 void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived,188 uint32_t NVOffset, int32_t VBPtrOffset,189 uint32_t VBTableOffset, uint32_t Flags,190 raw_ostream &Out) override;191 void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,192 raw_ostream &Out) override;193 void mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,194 raw_ostream &Out) override;195 void196 mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,197 ArrayRef<const CXXRecordDecl *> BasePath,198 raw_ostream &Out) override;199 void mangleCanonicalTypeName(QualType T, raw_ostream &,200 bool NormalizeIntegers) override;201 void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber,202 raw_ostream &) override;203 void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;204 void mangleThreadSafeStaticGuardVariable(const VarDecl *D, unsigned GuardNum,205 raw_ostream &Out) override;206 void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) override;207 void mangleDynamicAtExitDestructor(const VarDecl *D,208 raw_ostream &Out) override;209 void mangleSEHFilterExpression(GlobalDecl EnclosingDecl,210 raw_ostream &Out) override;211 void mangleSEHFinallyBlock(GlobalDecl EnclosingDecl,212 raw_ostream &Out) override;213 void mangleStringLiteral(const StringLiteral *SL, raw_ostream &Out) override;214 bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {215 const DeclContext *DC = getEffectiveDeclContext(ND);216 if (!DC->isFunctionOrMethod())217 return false;218 219 // Lambda closure types are already numbered, give out a phony number so220 // that they demangle nicely.221 if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {222 if (RD->isLambda()) {223 disc = 1;224 return true;225 }226 }227 228 // Use the canonical number for externally visible decls.229 if (ND->isExternallyVisible()) {230 disc = getASTContext().getManglingNumber(ND, isAux());231 return true;232 }233 234 // Anonymous tags are already numbered.235 if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {236 if (!Tag->hasNameForLinkage() &&237 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&238 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))239 return false;240 }241 242 // Make up a reasonable number for internal decls.243 unsigned &discriminator = Uniquifier[ND];244 if (!discriminator)245 discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())];246 disc = discriminator + 1;247 return true;248 }249 250 std::string getLambdaString(const CXXRecordDecl *Lambda) override {251 assert(Lambda->isLambda() && "RD must be a lambda!");252 std::string Name("<lambda_");253 254 Decl *LambdaContextDecl = Lambda->getLambdaContextDecl();255 unsigned LambdaManglingNumber = Lambda->getLambdaManglingNumber();256 unsigned LambdaId;257 const ParmVarDecl *Parm = dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);258 const FunctionDecl *Func =259 Parm ? dyn_cast<FunctionDecl>(Parm->getDeclContext()) : nullptr;260 261 if (Func) {262 unsigned DefaultArgNo =263 Func->getNumParams() - Parm->getFunctionScopeIndex();264 Name += llvm::utostr(DefaultArgNo);265 Name += "_";266 }267 268 if (LambdaManglingNumber)269 LambdaId = LambdaManglingNumber;270 else271 LambdaId = getLambdaIdForDebugInfo(Lambda);272 273 Name += llvm::utostr(LambdaId);274 Name += ">";275 return Name;276 }277 278 unsigned getLambdaId(const CXXRecordDecl *RD) {279 assert(RD->isLambda() && "RD must be a lambda!");280 assert(!RD->isExternallyVisible() && "RD must not be visible!");281 assert(RD->getLambdaManglingNumber() == 0 &&282 "RD must not have a mangling number!");283 std::pair<llvm::DenseMap<const CXXRecordDecl *, unsigned>::iterator, bool>284 Result = LambdaIds.insert(std::make_pair(RD, LambdaIds.size()));285 return Result.first->second;286 }287 288 unsigned getLambdaIdForDebugInfo(const CXXRecordDecl *RD) {289 assert(RD->isLambda() && "RD must be a lambda!");290 assert(!RD->isExternallyVisible() && "RD must not be visible!");291 assert(RD->getLambdaManglingNumber() == 0 &&292 "RD must not have a mangling number!");293 // The lambda should exist, but return 0 in case it doesn't.294 return LambdaIds.lookup(RD);295 }296 297 /// Return a character sequence that is (somewhat) unique to the TU suitable298 /// for mangling anonymous namespaces.299 StringRef getAnonymousNamespaceHash() const {300 return AnonymousNamespaceHash;301 }302 303private:304 void mangleInitFiniStub(const VarDecl *D, char CharCode, raw_ostream &Out);305};306 307/// MicrosoftCXXNameMangler - Manage the mangling of a single name for the308/// Microsoft Visual C++ ABI.309class MicrosoftCXXNameMangler {310 MicrosoftMangleContextImpl &Context;311 raw_ostream &Out;312 313 /// The "structor" is the top-level declaration being mangled, if314 /// that's not a template specialization; otherwise it's the pattern315 /// for that specialization.316 const NamedDecl *Structor;317 unsigned StructorType;318 319 typedef llvm::SmallVector<std::string, 10> BackRefVec;320 BackRefVec NameBackReferences;321 322 typedef llvm::DenseMap<const void *, unsigned> ArgBackRefMap;323 ArgBackRefMap FunArgBackReferences;324 ArgBackRefMap TemplateArgBackReferences;325 326 typedef llvm::DenseMap<const void *, StringRef> TemplateArgStringMap;327 TemplateArgStringMap TemplateArgStrings;328 llvm::BumpPtrAllocator TemplateArgStringStorageAlloc;329 llvm::StringSaver TemplateArgStringStorage;330 331 typedef std::set<std::pair<int, bool>> PassObjectSizeArgsSet;332 PassObjectSizeArgsSet PassObjectSizeArgs;333 334 ASTContext &getASTContext() const { return Context.getASTContext(); }335 336 const bool PointersAre64Bit;337 338 DiagnosticBuilder Error(SourceLocation, StringRef, StringRef);339 DiagnosticBuilder Error(SourceLocation, StringRef);340 DiagnosticBuilder Error(StringRef);341 342public:343 enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };344 enum class TplArgKind { ClassNTTP, StructuralValue };345 346 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)347 : Context(C), Out(Out_), Structor(nullptr), StructorType(-1),348 TemplateArgStringStorage(TemplateArgStringStorageAlloc),349 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(350 LangAS::Default) == 64) {}351 352 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,353 const CXXConstructorDecl *D, CXXCtorType Type)354 : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),355 TemplateArgStringStorage(TemplateArgStringStorageAlloc),356 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(357 LangAS::Default) == 64) {}358 359 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,360 const CXXDestructorDecl *D, CXXDtorType Type)361 : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),362 TemplateArgStringStorage(TemplateArgStringStorageAlloc),363 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(364 LangAS::Default) == 64) {}365 366 raw_ostream &getStream() const { return Out; }367 368 void mangle(GlobalDecl GD, StringRef Prefix = "?");369 void mangleName(GlobalDecl GD);370 void mangleFunctionEncoding(GlobalDecl GD, bool ShouldMangle);371 void mangleVariableEncoding(const VarDecl *VD);372 void mangleMemberDataPointer(const CXXRecordDecl *RD, const ValueDecl *VD,373 const NonTypeTemplateParmDecl *PD,374 QualType TemplateArgType,375 StringRef Prefix = "$");376 void mangleMemberDataPointerInClassNTTP(const CXXRecordDecl *,377 const ValueDecl *);378 void mangleMemberFunctionPointer(const CXXRecordDecl *RD,379 const CXXMethodDecl *MD,380 const NonTypeTemplateParmDecl *PD,381 QualType TemplateArgType,382 StringRef Prefix = "$");383 void mangleFunctionPointer(const FunctionDecl *FD,384 const NonTypeTemplateParmDecl *PD,385 QualType TemplateArgType);386 void mangleVarDecl(const VarDecl *VD, const NonTypeTemplateParmDecl *PD,387 QualType TemplateArgType);388 void mangleMemberFunctionPointerInClassNTTP(const CXXRecordDecl *RD,389 const CXXMethodDecl *MD);390 void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,391 const MethodVFTableLocation &ML);392 void mangleNumber(int64_t Number);393 void mangleNumber(llvm::APSInt Number);394 void mangleFloat(llvm::APFloat Number);395 void mangleBits(llvm::APInt Number);396 void mangleTagTypeKind(TagTypeKind TK);397 void mangleArtificialTagType(TagTypeKind TK, StringRef UnqualifiedName,398 ArrayRef<StringRef> NestedNames = {});399 void mangleAddressSpaceType(QualType T, Qualifiers Quals, SourceRange Range);400 void mangleType(QualType T, SourceRange Range,401 QualifierMangleMode QMM = QMM_Mangle);402 void mangleFunctionType(const FunctionType *T,403 const FunctionDecl *D = nullptr,404 bool ForceThisQuals = false,405 bool MangleExceptionSpec = true);406 void mangleSourceName(StringRef Name);407 void mangleNestedName(GlobalDecl GD);408 409 void mangleAutoReturnType(QualType T, QualifierMangleMode QMM);410 411private:412 bool isStructorDecl(const NamedDecl *ND) const {413 return ND == Structor || getStructor(ND) == Structor;414 }415 416 bool is64BitPointer(Qualifiers Quals) const {417 LangAS AddrSpace = Quals.getAddressSpace();418 return AddrSpace == LangAS::ptr64 ||419 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||420 AddrSpace == LangAS::ptr32_uptr));421 }422 423 void mangleUnqualifiedName(GlobalDecl GD) {424 mangleUnqualifiedName(GD, cast<NamedDecl>(GD.getDecl())->getDeclName());425 }426 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);427 void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);428 void mangleCXXDtorType(CXXDtorType T);429 void mangleQualifiers(Qualifiers Quals, bool IsMember);430 void mangleRefQualifier(RefQualifierKind RefQualifier);431 void manglePointerCVQualifiers(Qualifiers Quals);432 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);433 void manglePointerAuthQualifier(Qualifiers Quals);434 435 void mangleUnscopedTemplateName(GlobalDecl GD);436 void437 mangleTemplateInstantiationName(GlobalDecl GD,438 const TemplateArgumentList &TemplateArgs);439 void mangleObjCMethodName(const ObjCMethodDecl *MD);440 441 void mangleFunctionArgumentType(QualType T, SourceRange Range);442 void manglePassObjectSizeArg(const PassObjectSizeAttr *POSA);443 444 bool isArtificialTagType(QualType T) const;445 446 // Declare manglers for every type class.447#define ABSTRACT_TYPE(CLASS, PARENT)448#define NON_CANONICAL_TYPE(CLASS, PARENT)449#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T, \450 Qualifiers Quals, \451 SourceRange Range);452#include "clang/AST/TypeNodes.inc"453#undef ABSTRACT_TYPE454#undef NON_CANONICAL_TYPE455#undef TYPE456 457 void mangleType(const TagDecl *TD);458 void mangleDecayedArrayType(const ArrayType *T);459 void mangleArrayType(const ArrayType *T);460 void mangleFunctionClass(const FunctionDecl *FD);461 void mangleCallingConvention(CallingConv CC, SourceRange Range);462 void mangleCallingConvention(const FunctionType *T, SourceRange Range);463 void mangleIntegerLiteral(const llvm::APSInt &Number,464 const NonTypeTemplateParmDecl *PD = nullptr,465 QualType TemplateArgType = QualType());466 void mangleExpression(const Expr *E, const NonTypeTemplateParmDecl *PD);467 void mangleThrowSpecification(const FunctionProtoType *T);468 469 void mangleTemplateArgs(const TemplateDecl *TD,470 const TemplateArgumentList &TemplateArgs);471 void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA,472 const NamedDecl *Parm);473 void mangleTemplateArgValue(QualType T, const APValue &V, TplArgKind,474 bool WithScalarType = false);475 476 void mangleObjCProtocol(const ObjCProtocolDecl *PD);477 void mangleObjCLifetime(const QualType T, Qualifiers Quals,478 SourceRange Range);479 void mangleObjCKindOfType(const ObjCObjectType *T, Qualifiers Quals,480 SourceRange Range);481 482 void mangleAutoReturnType(const MemberPointerType *T, Qualifiers Quals);483 void mangleAutoReturnType(const PointerType *T, Qualifiers Quals);484 void mangleAutoReturnType(const LValueReferenceType *T, Qualifiers Quals);485 void mangleAutoReturnType(const RValueReferenceType *T, Qualifiers Quals);486};487}488 489MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(ASTContext &Context,490 DiagnosticsEngine &Diags,491 bool IsAux)492 : MicrosoftMangleContext(Context, Diags, IsAux) {493 // To mangle anonymous namespaces, hash the path to the main source file. The494 // path should be whatever (probably relative) path was passed on the command495 // line. The goal is for the compiler to produce the same output regardless of496 // working directory, so use the uncanonicalized relative path.497 //498 // It's important to make the mangled names unique because, when CodeView499 // debug info is in use, the debugger uses mangled type names to distinguish500 // between otherwise identically named types in anonymous namespaces.501 //502 // These symbols are always internal, so there is no need for the hash to503 // match what MSVC produces. For the same reason, clang is free to change the504 // hash at any time without breaking compatibility with old versions of clang.505 // The generated names are intended to look similar to what MSVC generates,506 // which are something like "?A0x01234567@".507 SourceManager &SM = Context.getSourceManager();508 if (OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getMainFileID())) {509 // Truncate the hash so we get 8 characters of hexadecimal.510 uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));511 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);512 } else {513 // If we don't have a path to the main file, we'll just use 0.514 AnonymousNamespaceHash = "0";515 }516}517 518bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {519 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {520 LanguageLinkage L = FD->getLanguageLinkage();521 // Overloadable functions need mangling.522 if (FD->hasAttr<OverloadableAttr>())523 return true;524 525 // The ABI expects that we would never mangle "typical" user-defined entry526 // points regardless of visibility or freestanding-ness.527 //528 // N.B. This is distinct from asking about "main". "main" has a lot of529 // special rules associated with it in the standard while these530 // user-defined entry points are outside of the purview of the standard.531 // For example, there can be only one definition for "main" in a standards532 // compliant program; however nothing forbids the existence of wmain and533 // WinMain in the same translation unit.534 if (FD->isMSVCRTEntryPoint())535 return false;536 537 // C++ functions and those whose names are not a simple identifier need538 // mangling.539 if (!FD->getDeclName().isIdentifier() || L == CXXLanguageLinkage)540 return true;541 542 // C functions are not mangled.543 if (L == CLanguageLinkage)544 return false;545 }546 547 // Otherwise, no mangling is done outside C++ mode.548 if (!getASTContext().getLangOpts().CPlusPlus)549 return false;550 551 const VarDecl *VD = dyn_cast<VarDecl>(D);552 if (VD && !isa<DecompositionDecl>(D)) {553 // C variables are not mangled.554 if (VD->isExternC())555 return false;556 557 // Variables at global scope with internal linkage are not mangled.558 const DeclContext *DC = getEffectiveDeclContext(D);559 // Check for extern variable declared locally.560 if (DC->isFunctionOrMethod() && D->hasLinkage())561 while (!DC->isNamespace() && !DC->isTranslationUnit())562 DC = getEffectiveParentContext(DC);563 564 if (DC->isTranslationUnit() && D->getFormalLinkage() == Linkage::Internal &&565 !isa<VarTemplateSpecializationDecl>(D) && D->getIdentifier() != nullptr)566 return false;567 }568 569 return true;570}571 572bool573MicrosoftMangleContextImpl::shouldMangleStringLiteral(const StringLiteral *SL) {574 return true;575}576 577DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,578 StringRef thing1,579 StringRef thing2) {580 DiagnosticsEngine &Diags = Context.getDiags();581 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,582 "cannot mangle this %0 %1 yet");583 return Diags.Report(loc, DiagID) << thing1 << thing2;584}585 586DiagnosticBuilder MicrosoftCXXNameMangler::Error(SourceLocation loc,587 StringRef thingy) {588 DiagnosticsEngine &Diags = Context.getDiags();589 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,590 "cannot mangle this %0 yet");591 return Diags.Report(loc, DiagID) << thingy;592}593 594DiagnosticBuilder MicrosoftCXXNameMangler::Error(StringRef thingy) {595 DiagnosticsEngine &Diags = Context.getDiags();596 // extra placeholders are ignored quietly when not used597 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,598 "cannot mangle this %0 yet");599 return Diags.Report(DiagID) << thingy;600}601 602void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {603 const NamedDecl *D = cast<NamedDecl>(GD.getDecl());604 // MSVC doesn't mangle C++ names the same way it mangles extern "C" names.605 // Therefore it's really important that we don't decorate the606 // name with leading underscores or leading/trailing at signs. So, by607 // default, we emit an asm marker at the start so we get the name right.608 // Callers can override this with a custom prefix.609 610 // <mangled-name> ::= ? <name> <type-encoding>611 Out << Prefix;612 mangleName(GD);613 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))614 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));615 else if (const VarDecl *VD = dyn_cast<VarDecl>(D))616 mangleVariableEncoding(VD);617 else if (isa<MSGuidDecl>(D))618 // MSVC appears to mangle GUIDs as if they were variables of type619 // 'const struct __s_GUID'.620 Out << "3U__s_GUID@@B";621 else if (isa<TemplateParamObjectDecl>(D)) {622 // Template parameter objects don't get a <type-encoding>; their type is623 // specified as part of their value.624 } else625 llvm_unreachable("Tried to mangle unexpected NamedDecl!");626}627 628void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,629 bool ShouldMangle) {630 const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());631 // <type-encoding> ::= <function-class> <function-type>632 633 // Since MSVC operates on the type as written and not the canonical type, it634 // actually matters which decl we have here. MSVC appears to choose the635 // first, since it is most likely to be the declaration in a header file.636 FD = FD->getFirstDecl();637 638 // We should never ever see a FunctionNoProtoType at this point.639 // We don't even know how to mangle their types anyway :).640 const FunctionProtoType *FT = FD->getType()->castAs<FunctionProtoType>();641 642 // extern "C" functions can hold entities that must be mangled.643 // As it stands, these functions still need to get expressed in the full644 // external name. They have their class and type omitted, replaced with '9'.645 if (ShouldMangle) {646 // We would like to mangle all extern "C" functions using this additional647 // component but this would break compatibility with MSVC's behavior.648 // Instead, do this when we know that compatibility isn't important (in649 // other words, when it is an overloaded extern "C" function).650 if (FD->isExternC() && FD->hasAttr<OverloadableAttr>())651 Out << "$$J0";652 653 mangleFunctionClass(FD);654 655 mangleFunctionType(FT, FD, false, false);656 } else {657 Out << '9';658 }659}660 661void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {662 // <type-encoding> ::= <storage-class> <variable-type>663 // <storage-class> ::= 0 # private static member664 // ::= 1 # protected static member665 // ::= 2 # public static member666 // ::= 3 # global667 // ::= 4 # static local668 669 // The first character in the encoding (after the name) is the storage class.670 if (VD->isStaticDataMember()) {671 // If it's a static member, it also encodes the access level.672 switch (VD->getAccess()) {673 default:674 case AS_private: Out << '0'; break;675 case AS_protected: Out << '1'; break;676 case AS_public: Out << '2'; break;677 }678 }679 else if (!VD->isStaticLocal())680 Out << '3';681 else682 Out << '4';683 // Now mangle the type.684 // <variable-type> ::= <type> <cvr-qualifiers>685 // ::= <type> <pointee-cvr-qualifiers> # pointers, references686 // Pointers and references are odd. The type of 'int * const foo;' gets687 // mangled as 'QAHA' instead of 'PAHB', for example.688 SourceRange SR = VD->getSourceRange();689 QualType Ty = VD->getType();690 if (Ty->isPointerType() || Ty->isReferenceType() ||691 Ty->isMemberPointerType()) {692 mangleType(Ty, SR, QMM_Drop);693 manglePointerExtQualifiers(694 Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), QualType());695 if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()) {696 mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);697 // Member pointers are suffixed with a back reference to the member698 // pointer's class name.699 mangleName(MPT->getMostRecentCXXRecordDecl());700 } else701 mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);702 } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {703 // Global arrays are funny, too.704 mangleDecayedArrayType(AT);705 if (AT->getElementType()->isArrayType())706 Out << 'A';707 else708 mangleQualifiers(Ty.getQualifiers(), false);709 } else {710 mangleType(Ty, SR, QMM_Drop);711 mangleQualifiers(Ty.getQualifiers(), false);712 }713}714 715void MicrosoftCXXNameMangler::mangleMemberDataPointer(716 const CXXRecordDecl *RD, const ValueDecl *VD,717 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,718 StringRef Prefix) {719 // <member-data-pointer> ::= <integer-literal>720 // ::= $F <number> <number>721 // ::= $G <number> <number> <number>722 //723 // <auto-nttp> ::= $ M <type> <integer-literal>724 // <auto-nttp> ::= $ M <type> F <name> <number>725 // <auto-nttp> ::= $ M <type> G <name> <number> <number>726 727 int64_t FieldOffset;728 int64_t VBTableOffset;729 MSInheritanceModel IM = RD->getMSInheritanceModel();730 if (VD) {731 FieldOffset = getASTContext().getFieldOffset(VD);732 assert(FieldOffset % getASTContext().getCharWidth() == 0 &&733 "cannot take address of bitfield");734 FieldOffset /= getASTContext().getCharWidth();735 736 VBTableOffset = 0;737 738 if (IM == MSInheritanceModel::Virtual)739 FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();740 } else {741 FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1;742 743 VBTableOffset = -1;744 }745 746 char Code = '\0';747 switch (IM) {748 case MSInheritanceModel::Single: Code = '0'; break;749 case MSInheritanceModel::Multiple: Code = '0'; break;750 case MSInheritanceModel::Virtual: Code = 'F'; break;751 case MSInheritanceModel::Unspecified: Code = 'G'; break;752 }753 754 Out << Prefix;755 756 if (VD &&757 getASTContext().getLangOpts().isCompatibleWithMSVC(758 LangOptions::MSVC2019) &&759 PD && PD->getType()->getTypeClass() == Type::Auto &&760 !TemplateArgType.isNull()) {761 Out << "M";762 mangleType(TemplateArgType, SourceRange(), QMM_Drop);763 }764 765 Out << Code;766 767 mangleNumber(FieldOffset);768 769 // The C++ standard doesn't allow base-to-derived member pointer conversions770 // in template parameter contexts, so the vbptr offset of data member pointers771 // is always zero.772 if (inheritanceModelHasVBPtrOffsetField(IM))773 mangleNumber(0);774 if (inheritanceModelHasVBTableOffsetField(IM))775 mangleNumber(VBTableOffset);776}777 778void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(779 const CXXRecordDecl *RD, const ValueDecl *VD) {780 MSInheritanceModel IM = RD->getMSInheritanceModel();781 // <nttp-class-member-data-pointer> ::= <member-data-pointer>782 // ::= N783 // ::= 8 <postfix> @ <unqualified-name> @784 785 if (IM != MSInheritanceModel::Single && IM != MSInheritanceModel::Multiple)786 return mangleMemberDataPointer(RD, VD, nullptr, QualType(), "");787 788 if (!VD) {789 Out << 'N';790 return;791 }792 793 Out << '8';794 mangleNestedName(VD);795 Out << '@';796 mangleUnqualifiedName(VD);797 Out << '@';798}799 800void MicrosoftCXXNameMangler::mangleMemberFunctionPointer(801 const CXXRecordDecl *RD, const CXXMethodDecl *MD,802 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,803 StringRef Prefix) {804 // <member-function-pointer> ::= $1? <name>805 // ::= $H? <name> <number>806 // ::= $I? <name> <number> <number>807 // ::= $J? <name> <number> <number> <number>808 //809 // <auto-nttp> ::= $ M <type> 1? <name>810 // <auto-nttp> ::= $ M <type> H? <name> <number>811 // <auto-nttp> ::= $ M <type> I? <name> <number> <number>812 // <auto-nttp> ::= $ M <type> J? <name> <number> <number> <number>813 814 MSInheritanceModel IM = RD->getMSInheritanceModel();815 816 char Code = '\0';817 switch (IM) {818 case MSInheritanceModel::Single: Code = '1'; break;819 case MSInheritanceModel::Multiple: Code = 'H'; break;820 case MSInheritanceModel::Virtual: Code = 'I'; break;821 case MSInheritanceModel::Unspecified: Code = 'J'; break;822 }823 824 // If non-virtual, mangle the name. If virtual, mangle as a virtual memptr825 // thunk.826 uint64_t NVOffset = 0;827 uint64_t VBTableOffset = 0;828 uint64_t VBPtrOffset = 0;829 if (MD) {830 Out << Prefix;831 832 if (getASTContext().getLangOpts().isCompatibleWithMSVC(833 LangOptions::MSVC2019) &&834 PD && PD->getType()->getTypeClass() == Type::Auto &&835 !TemplateArgType.isNull()) {836 Out << "M";837 mangleType(TemplateArgType, SourceRange(), QMM_Drop);838 }839 840 Out << Code << '?';841 if (MD->isVirtual()) {842 MicrosoftVTableContext *VTContext =843 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());844 MethodVFTableLocation ML =845 VTContext->getMethodVFTableLocation(GlobalDecl(MD));846 mangleVirtualMemPtrThunk(MD, ML);847 NVOffset = ML.VFPtrOffset.getQuantity();848 VBTableOffset = ML.VBTableIndex * 4;849 if (ML.VBase) {850 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);851 VBPtrOffset = Layout.getVBPtrOffset().getQuantity();852 }853 } else {854 mangleName(MD);855 mangleFunctionEncoding(MD, /*ShouldMangle=*/true);856 }857 858 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)859 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();860 } else {861 // Null single inheritance member functions are encoded as a simple nullptr.862 if (IM == MSInheritanceModel::Single) {863 Out << Prefix << "0A@";864 return;865 }866 if (IM == MSInheritanceModel::Unspecified)867 VBTableOffset = -1;868 Out << Prefix << Code;869 }870 871 if (inheritanceModelHasNVOffsetField(/*IsMemberFunction=*/true, IM))872 mangleNumber(static_cast<uint32_t>(NVOffset));873 if (inheritanceModelHasVBPtrOffsetField(IM))874 mangleNumber(VBPtrOffset);875 if (inheritanceModelHasVBTableOffsetField(IM))876 mangleNumber(VBTableOffset);877}878 879void MicrosoftCXXNameMangler::mangleFunctionPointer(880 const FunctionDecl *FD, const NonTypeTemplateParmDecl *PD,881 QualType TemplateArgType) {882 // <func-ptr> ::= $1? <mangled-name>883 // <func-ptr> ::= <auto-nttp>884 //885 // <auto-nttp> ::= $ M <type> 1? <mangled-name>886 Out << '$';887 888 if (getASTContext().getLangOpts().isCompatibleWithMSVC(889 LangOptions::MSVC2019) &&890 PD && PD->getType()->getTypeClass() == Type::Auto &&891 !TemplateArgType.isNull()) {892 Out << "M";893 mangleType(TemplateArgType, SourceRange(), QMM_Drop);894 }895 896 Out << "1?";897 mangleName(FD);898 mangleFunctionEncoding(FD, /*ShouldMangle=*/true);899}900 901void MicrosoftCXXNameMangler::mangleVarDecl(const VarDecl *VD,902 const NonTypeTemplateParmDecl *PD,903 QualType TemplateArgType) {904 // <var-ptr> ::= $1? <mangled-name>905 // <var-ptr> ::= <auto-nttp>906 //907 // <auto-nttp> ::= $ M <type> 1? <mangled-name>908 Out << '$';909 910 if (getASTContext().getLangOpts().isCompatibleWithMSVC(911 LangOptions::MSVC2019) &&912 PD && PD->getType()->getTypeClass() == Type::Auto &&913 !TemplateArgType.isNull()) {914 Out << "M";915 mangleType(TemplateArgType, SourceRange(), QMM_Drop);916 }917 918 Out << "1?";919 mangleName(VD);920 mangleVariableEncoding(VD);921}922 923void MicrosoftCXXNameMangler::mangleMemberFunctionPointerInClassNTTP(924 const CXXRecordDecl *RD, const CXXMethodDecl *MD) {925 // <nttp-class-member-function-pointer> ::= <member-function-pointer>926 // ::= N927 // ::= E? <virtual-mem-ptr-thunk>928 // ::= E? <mangled-name> <type-encoding>929 930 if (!MD) {931 if (RD->getMSInheritanceModel() != MSInheritanceModel::Single)932 return mangleMemberFunctionPointer(RD, MD, nullptr, QualType(), "");933 934 Out << 'N';935 return;936 }937 938 Out << "E?";939 if (MD->isVirtual()) {940 MicrosoftVTableContext *VTContext =941 cast<MicrosoftVTableContext>(getASTContext().getVTableContext());942 MethodVFTableLocation ML =943 VTContext->getMethodVFTableLocation(GlobalDecl(MD));944 mangleVirtualMemPtrThunk(MD, ML);945 } else {946 mangleName(MD);947 mangleFunctionEncoding(MD, /*ShouldMangle=*/true);948 }949}950 951void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(952 const CXXMethodDecl *MD, const MethodVFTableLocation &ML) {953 // Get the vftable offset.954 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(955 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));956 uint64_t OffsetInVFTable = ML.Index * PointerWidth.getQuantity();957 958 Out << "?_9";959 mangleName(MD->getParent());960 Out << "$B";961 mangleNumber(OffsetInVFTable);962 Out << 'A';963 mangleCallingConvention(MD->getType()->castAs<FunctionProtoType>(),964 MD->getSourceRange());965}966 967void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {968 // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @969 970 // Always start with the unqualified name.971 mangleUnqualifiedName(GD);972 973 mangleNestedName(GD);974 975 // Terminate the whole name with an '@'.976 Out << '@';977}978 979void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {980 mangleNumber(llvm::APSInt(llvm::APInt(64, Number), /*IsUnsigned*/false));981}982 983void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {984 // MSVC never mangles any integer wider than 64 bits. In general it appears985 // to convert every integer to signed 64 bit before mangling (including986 // unsigned 64 bit values). Do the same, but preserve bits beyond the bottom987 // 64.988 unsigned Width = std::max(Number.getBitWidth(), 64U);989 llvm::APInt Value = Number.extend(Width);990 991 // <non-negative integer> ::= A@ # when Number == 0992 // ::= <decimal digit> # when 1 <= Number <= 10993 // ::= <hex digit>+ @ # when Number >= 10994 //995 // <number> ::= [?] <non-negative integer>996 997 if (Value.isNegative()) {998 Value = -Value;999 Out << '?';1000 }1001 mangleBits(Value);1002}1003 1004void MicrosoftCXXNameMangler::mangleFloat(llvm::APFloat Number) {1005 using llvm::APFloat;1006 1007 switch (APFloat::SemanticsToEnum(Number.getSemantics())) {1008 case APFloat::S_IEEEsingle: Out << 'A'; break;1009 case APFloat::S_IEEEdouble: Out << 'B'; break;1010 1011 // The following are all Clang extensions. We try to pick manglings that are1012 // unlikely to conflict with MSVC's scheme.1013 case APFloat::S_IEEEhalf: Out << 'V'; break;1014 case APFloat::S_BFloat: Out << 'W'; break;1015 case APFloat::S_x87DoubleExtended: Out << 'X'; break;1016 case APFloat::S_IEEEquad: Out << 'Y'; break;1017 case APFloat::S_PPCDoubleDouble: Out << 'Z'; break;1018 case APFloat::S_PPCDoubleDoubleLegacy:1019 case APFloat::S_Float8E5M2:1020 case APFloat::S_Float8E4M3:1021 case APFloat::S_Float8E4M3FN:1022 case APFloat::S_Float8E5M2FNUZ:1023 case APFloat::S_Float8E4M3FNUZ:1024 case APFloat::S_Float8E4M3B11FNUZ:1025 case APFloat::S_Float8E3M4:1026 case APFloat::S_FloatTF32:1027 case APFloat::S_Float8E8M0FNU:1028 case APFloat::S_Float6E3M2FN:1029 case APFloat::S_Float6E2M3FN:1030 case APFloat::S_Float4E2M1FN:1031 llvm_unreachable("Tried to mangle unexpected APFloat semantics");1032 }1033 1034 mangleBits(Number.bitcastToAPInt());1035}1036 1037void MicrosoftCXXNameMangler::mangleBits(llvm::APInt Value) {1038 if (Value == 0)1039 Out << "A@";1040 else if (Value.uge(1) && Value.ule(10))1041 Out << (Value - 1);1042 else {1043 // Numbers that are not encoded as decimal digits are represented as nibbles1044 // in the range of ASCII characters 'A' to 'P'.1045 // The number 0x123450 would be encoded as 'BCDEFA'1046 llvm::SmallString<32> EncodedNumberBuffer;1047 for (; Value != 0; Value.lshrInPlace(4))1048 EncodedNumberBuffer.push_back('A' + (Value & 0xf).getZExtValue());1049 std::reverse(EncodedNumberBuffer.begin(), EncodedNumberBuffer.end());1050 Out.write(EncodedNumberBuffer.data(), EncodedNumberBuffer.size());1051 Out << '@';1052 }1053}1054 1055static GlobalDecl isTemplate(GlobalDecl GD,1056 const TemplateArgumentList *&TemplateArgs) {1057 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());1058 // Check if we have a function template.1059 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {1060 if (const TemplateDecl *TD = FD->getPrimaryTemplate()) {1061 TemplateArgs = FD->getTemplateSpecializationArgs();1062 return GD.getWithDecl(TD);1063 }1064 }1065 1066 // Check if we have a class template.1067 if (const ClassTemplateSpecializationDecl *Spec =1068 dyn_cast<ClassTemplateSpecializationDecl>(ND)) {1069 TemplateArgs = &Spec->getTemplateArgs();1070 return GD.getWithDecl(Spec->getSpecializedTemplate());1071 }1072 1073 // Check if we have a variable template.1074 if (const VarTemplateSpecializationDecl *Spec =1075 dyn_cast<VarTemplateSpecializationDecl>(ND)) {1076 TemplateArgs = &Spec->getTemplateArgs();1077 return GD.getWithDecl(Spec->getSpecializedTemplate());1078 }1079 1080 return GlobalDecl();1081}1082 1083void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,1084 DeclarationName Name) {1085 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());1086 // <unqualified-name> ::= <operator-name>1087 // ::= <ctor-dtor-name>1088 // ::= <source-name>1089 // ::= <template-name>1090 1091 // Check if we have a template.1092 const TemplateArgumentList *TemplateArgs = nullptr;1093 if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) {1094 // Function templates aren't considered for name back referencing. This1095 // makes sense since function templates aren't likely to occur multiple1096 // times in a symbol.1097 if (isa<FunctionTemplateDecl>(TD.getDecl())) {1098 mangleTemplateInstantiationName(TD, *TemplateArgs);1099 Out << '@';1100 return;1101 }1102 1103 // Here comes the tricky thing: if we need to mangle something like1104 // void foo(A::X<Y>, B::X<Y>),1105 // the X<Y> part is aliased. However, if you need to mangle1106 // void foo(A::X<A::Y>, A::X<B::Y>),1107 // the A::X<> part is not aliased.1108 // That is, from the mangler's perspective we have a structure like this:1109 // namespace[s] -> type[ -> template-parameters]1110 // but from the Clang perspective we have1111 // type [ -> template-parameters]1112 // \-> namespace[s]1113 // What we do is we create a new mangler, mangle the same type (without1114 // a namespace suffix) to a string using the extra mangler and then use1115 // the mangled type name as a key to check the mangling of different types1116 // for aliasing.1117 1118 // It's important to key cache reads off ND, not TD -- the same TD can1119 // be used with different TemplateArgs, but ND uniquely identifies1120 // TD / TemplateArg pairs.1121 ArgBackRefMap::iterator Found = TemplateArgBackReferences.find(ND);1122 if (Found == TemplateArgBackReferences.end()) {1123 1124 TemplateArgStringMap::iterator Found = TemplateArgStrings.find(ND);1125 if (Found == TemplateArgStrings.end()) {1126 // Mangle full template name into temporary buffer.1127 llvm::SmallString<64> TemplateMangling;1128 llvm::raw_svector_ostream Stream(TemplateMangling);1129 MicrosoftCXXNameMangler Extra(Context, Stream);1130 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);1131 1132 // Use the string backref vector to possibly get a back reference.1133 mangleSourceName(TemplateMangling);1134 1135 // Memoize back reference for this type if one exist, else memoize1136 // the mangling itself.1137 BackRefVec::iterator StringFound =1138 llvm::find(NameBackReferences, TemplateMangling);1139 if (StringFound != NameBackReferences.end()) {1140 TemplateArgBackReferences[ND] =1141 StringFound - NameBackReferences.begin();1142 } else {1143 TemplateArgStrings[ND] =1144 TemplateArgStringStorage.save(TemplateMangling.str());1145 }1146 } else {1147 Out << Found->second << '@'; // Outputs a StringRef.1148 }1149 } else {1150 Out << Found->second; // Outputs a back reference (an int).1151 }1152 return;1153 }1154 1155 switch (Name.getNameKind()) {1156 case DeclarationName::Identifier: {1157 if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) {1158 bool IsDeviceStub =1159 ND &&1160 ((isa<FunctionDecl>(ND) && ND->hasAttr<CUDAGlobalAttr>()) ||1161 (isa<FunctionTemplateDecl>(ND) &&1162 cast<FunctionTemplateDecl>(ND)1163 ->getTemplatedDecl()1164 ->hasAttr<CUDAGlobalAttr>())) &&1165 GD.getKernelReferenceKind() == KernelReferenceKind::Stub;1166 bool IsOCLDeviceStub =1167 ND && isa<FunctionDecl>(ND) &&1168 DeviceKernelAttr::isOpenCLSpelling(1169 ND->getAttr<DeviceKernelAttr>()) &&1170 GD.getKernelReferenceKind() == KernelReferenceKind::Stub;1171 if (IsDeviceStub)1172 mangleSourceName(1173 (llvm::Twine("__device_stub__") + II->getName()).str());1174 else if (IsOCLDeviceStub)1175 mangleSourceName(1176 (llvm::Twine("__clang_ocl_kern_imp_") + II->getName()).str());1177 else1178 mangleSourceName(II->getName());1179 break;1180 }1181 1182 // Otherwise, an anonymous entity. We must have a declaration.1183 assert(ND && "mangling empty name without declaration");1184 1185 if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {1186 if (NS->isAnonymousNamespace()) {1187 Out << "?A0x" << Context.getAnonymousNamespaceHash() << '@';1188 break;1189 }1190 }1191 1192 if (const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) {1193 // Decomposition declarations are considered anonymous, and get1194 // numbered with a $S prefix.1195 llvm::SmallString<64> Name("$S");1196 // Get a unique id for the anonymous struct.1197 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);1198 mangleSourceName(Name);1199 break;1200 }1201 1202 if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {1203 // We must have an anonymous union or struct declaration.1204 const CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl();1205 assert(RD && "expected variable decl to have a record type");1206 // Anonymous types with no tag or typedef get the name of their1207 // declarator mangled in. If they have no declarator, number them with1208 // a $S prefix.1209 llvm::SmallString<64> Name("$S");1210 // Get a unique id for the anonymous struct.1211 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);1212 mangleSourceName(Name.str());1213 break;1214 }1215 1216 if (const MSGuidDecl *GD = dyn_cast<MSGuidDecl>(ND)) {1217 // Mangle a GUID object as if it were a variable with the corresponding1218 // mangled name.1219 SmallString<sizeof("_GUID_12345678_1234_1234_1234_1234567890ab")> GUID;1220 llvm::raw_svector_ostream GUIDOS(GUID);1221 Context.mangleMSGuidDecl(GD, GUIDOS);1222 mangleSourceName(GUID);1223 break;1224 }1225 1226 if (const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {1227 Out << "?__N";1228 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),1229 TPO->getValue(), TplArgKind::ClassNTTP);1230 break;1231 }1232 1233 // We must have an anonymous struct.1234 const TagDecl *TD = cast<TagDecl>(ND);1235 if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {1236 assert(TD->getDeclContext() == D->getDeclContext() &&1237 "Typedef should not be in another decl context!");1238 assert(D->getDeclName().getAsIdentifierInfo() &&1239 "Typedef was not named!");1240 mangleSourceName(D->getDeclName().getAsIdentifierInfo()->getName());1241 break;1242 }1243 1244 if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) {1245 if (Record->isLambda()) {1246 llvm::SmallString<10> Name("<lambda_");1247 1248 Decl *LambdaContextDecl = Record->getLambdaContextDecl();1249 unsigned LambdaManglingNumber = Record->getLambdaManglingNumber();1250 unsigned LambdaId;1251 const ParmVarDecl *Parm =1252 dyn_cast_or_null<ParmVarDecl>(LambdaContextDecl);1253 const FunctionDecl *Func =1254 Parm ? dyn_cast<FunctionDecl>(Parm->getDeclContext()) : nullptr;1255 1256 if (Func) {1257 unsigned DefaultArgNo =1258 Func->getNumParams() - Parm->getFunctionScopeIndex();1259 Name += llvm::utostr(DefaultArgNo);1260 Name += "_";1261 }1262 1263 if (LambdaManglingNumber)1264 LambdaId = LambdaManglingNumber;1265 else1266 LambdaId = Context.getLambdaId(Record);1267 1268 Name += llvm::utostr(LambdaId);1269 Name += ">";1270 1271 mangleSourceName(Name);1272 1273 // If the context is a variable or a class member and not a parameter,1274 // it is encoded in a qualified name.1275 if (LambdaManglingNumber && LambdaContextDecl) {1276 if ((isa<VarDecl>(LambdaContextDecl) ||1277 isa<FieldDecl>(LambdaContextDecl)) &&1278 !isa<ParmVarDecl>(LambdaContextDecl)) {1279 mangleUnqualifiedName(cast<NamedDecl>(LambdaContextDecl));1280 }1281 }1282 break;1283 }1284 }1285 1286 llvm::SmallString<64> Name;1287 if (DeclaratorDecl *DD =1288 Context.getASTContext().getDeclaratorForUnnamedTagDecl(TD)) {1289 // Anonymous types without a name for linkage purposes have their1290 // declarator mangled in if they have one.1291 Name += "<unnamed-type-";1292 Name += DD->getName();1293 } else if (TypedefNameDecl *TND =1294 Context.getASTContext().getTypedefNameForUnnamedTagDecl(1295 TD)) {1296 // Anonymous types without a name for linkage purposes have their1297 // associate typedef mangled in if they have one.1298 Name += "<unnamed-type-";1299 Name += TND->getName();1300 } else if (isa<EnumDecl>(TD) &&1301 !cast<EnumDecl>(TD)->enumerators().empty()) {1302 // Anonymous non-empty enums mangle in the first enumerator.1303 auto *ED = cast<EnumDecl>(TD);1304 Name += "<unnamed-enum-";1305 Name += ED->enumerator_begin()->getName();1306 } else {1307 // Otherwise, number the types using a $S prefix.1308 Name += "<unnamed-type-$S";1309 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);1310 }1311 Name += ">";1312 mangleSourceName(Name.str());1313 break;1314 }1315 1316 case DeclarationName::ObjCZeroArgSelector:1317 case DeclarationName::ObjCOneArgSelector:1318 case DeclarationName::ObjCMultiArgSelector: {1319 // This is reachable only when constructing an outlined SEH finally1320 // block. Nothing depends on this mangling and it's used only with1321 // functinos with internal linkage.1322 llvm::SmallString<64> Name;1323 mangleSourceName(Name.str());1324 break;1325 }1326 1327 case DeclarationName::CXXConstructorName:1328 if (isStructorDecl(ND)) {1329 if (StructorType == Ctor_CopyingClosure) {1330 Out << "?_O";1331 return;1332 }1333 if (StructorType == Ctor_DefaultClosure) {1334 Out << "?_F";1335 return;1336 }1337 }1338 Out << "?0";1339 return;1340 1341 case DeclarationName::CXXDestructorName:1342 if (isStructorDecl(ND))1343 // If the named decl is the C++ destructor we're mangling,1344 // use the type we were given.1345 mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));1346 else1347 // Otherwise, use the base destructor name. This is relevant if a1348 // class with a destructor is declared within a destructor.1349 mangleCXXDtorType(Dtor_Base);1350 break;1351 1352 case DeclarationName::CXXConversionFunctionName:1353 // <operator-name> ::= ?B # (cast)1354 // The target type is encoded as the return type.1355 Out << "?B";1356 break;1357 1358 case DeclarationName::CXXOperatorName:1359 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());1360 break;1361 1362 case DeclarationName::CXXLiteralOperatorName: {1363 Out << "?__K";1364 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());1365 break;1366 }1367 1368 case DeclarationName::CXXDeductionGuideName:1369 llvm_unreachable("Can't mangle a deduction guide name!");1370 1371 case DeclarationName::CXXUsingDirective:1372 llvm_unreachable("Can't mangle a using directive name!");1373 }1374}1375 1376// <postfix> ::= <unqualified-name> [<postfix>]1377// ::= <substitution> [<postfix>]1378void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {1379 const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());1380 1381 if (const auto *ID = dyn_cast<IndirectFieldDecl>(ND))1382 for (unsigned I = 1, IE = ID->getChainingSize(); I < IE; ++I)1383 mangleSourceName("<unnamed-tag>");1384 1385 const DeclContext *DC = getEffectiveDeclContext(ND);1386 while (!DC->isTranslationUnit()) {1387 if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {1388 unsigned Disc;1389 if (Context.getNextDiscriminator(ND, Disc)) {1390 Out << '?';1391 mangleNumber(Disc);1392 Out << '?';1393 }1394 }1395 1396 if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {1397 auto Discriminate =1398 [](StringRef Name, const unsigned Discriminator,1399 const unsigned ParameterDiscriminator) -> std::string {1400 std::string Buffer;1401 llvm::raw_string_ostream Stream(Buffer);1402 Stream << Name;1403 if (Discriminator)1404 Stream << '_' << Discriminator;1405 if (ParameterDiscriminator)1406 Stream << '_' << ParameterDiscriminator;1407 return Buffer;1408 };1409 1410 unsigned Discriminator = BD->getBlockManglingNumber();1411 if (!Discriminator)1412 Discriminator = Context.getBlockId(BD, /*Local=*/false);1413 1414 // Mangle the parameter position as a discriminator to deal with unnamed1415 // parameters. Rather than mangling the unqualified parameter name,1416 // always use the position to give a uniform mangling.1417 unsigned ParameterDiscriminator = 0;1418 if (const auto *MC = BD->getBlockManglingContextDecl())1419 if (const auto *P = dyn_cast<ParmVarDecl>(MC))1420 if (const auto *F = dyn_cast<FunctionDecl>(P->getDeclContext()))1421 ParameterDiscriminator =1422 F->getNumParams() - P->getFunctionScopeIndex();1423 1424 DC = getEffectiveDeclContext(BD);1425 1426 Out << '?';1427 mangleSourceName(Discriminate("_block_invoke", Discriminator,1428 ParameterDiscriminator));1429 // If we have a block mangling context, encode that now. This allows us1430 // to discriminate between named static data initializers in the same1431 // scope. This is handled differently from parameters, which use1432 // positions to discriminate between multiple instances.1433 if (const auto *MC = BD->getBlockManglingContextDecl())1434 if (!isa<ParmVarDecl>(MC))1435 if (const auto *ND = dyn_cast<NamedDecl>(MC))1436 mangleUnqualifiedName(ND);1437 // MS ABI and Itanium manglings are in inverted scopes. In the case of a1438 // RecordDecl, mangle the entire scope hierarchy at this point rather than1439 // just the unqualified name to get the ordering correct.1440 if (const auto *RD = dyn_cast<RecordDecl>(DC))1441 mangleName(RD);1442 else1443 Out << '@';1444 // void __cdecl1445 Out << "YAX";1446 // struct __block_literal *1447 Out << 'P';1448 // __ptr641449 if (PointersAre64Bit)1450 Out << 'E';1451 Out << 'A';1452 mangleArtificialTagType(TagTypeKind::Struct,1453 Discriminate("__block_literal", Discriminator,1454 ParameterDiscriminator));1455 Out << "@Z";1456 1457 // If the effective context was a Record, we have fully mangled the1458 // qualified name and do not need to continue.1459 if (isa<RecordDecl>(DC))1460 break;1461 continue;1462 } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {1463 mangleObjCMethodName(Method);1464 } else if (isa<NamedDecl>(DC)) {1465 ND = cast<NamedDecl>(DC);1466 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {1467 mangle(getGlobalDeclAsDeclContext(FD), "?");1468 break;1469 } else {1470 mangleUnqualifiedName(ND);1471 // Lambdas in default arguments conceptually belong to the function the1472 // parameter corresponds to.1473 if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {1474 DC = LDADC;1475 continue;1476 }1477 }1478 }1479 DC = DC->getParent();1480 }1481}1482 1483void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {1484 // Microsoft uses the names on the case labels for these dtor variants. Clang1485 // uses the Itanium terminology internally. Everything in this ABI delegates1486 // towards the base dtor.1487 switch (T) {1488 // <operator-name> ::= ?1 # destructor1489 case Dtor_Base: Out << "?1"; return;1490 // <operator-name> ::= ?_D # vbase destructor1491 case Dtor_Complete: Out << "?_D"; return;1492 // <operator-name> ::= ?_G # scalar deleting destructor1493 case Dtor_Deleting: Out << "?_G"; return;1494 // <operator-name> ::= ?_E # vector deleting destructor1495 // FIXME: Add a vector deleting dtor type. It goes in the vtable, so we need1496 // it.1497 case Dtor_Comdat:1498 llvm_unreachable("not expecting a COMDAT");1499 case Dtor_Unified:1500 llvm_unreachable("not expecting a unified dtor type");1501 }1502 llvm_unreachable("Unsupported dtor type?");1503}1504 1505void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,1506 SourceLocation Loc) {1507 switch (OO) {1508 // ?0 # constructor1509 // ?1 # destructor1510 // <operator-name> ::= ?2 # new1511 case OO_New: Out << "?2"; break;1512 // <operator-name> ::= ?3 # delete1513 case OO_Delete: Out << "?3"; break;1514 // <operator-name> ::= ?4 # =1515 case OO_Equal: Out << "?4"; break;1516 // <operator-name> ::= ?5 # >>1517 case OO_GreaterGreater: Out << "?5"; break;1518 // <operator-name> ::= ?6 # <<1519 case OO_LessLess: Out << "?6"; break;1520 // <operator-name> ::= ?7 # !1521 case OO_Exclaim: Out << "?7"; break;1522 // <operator-name> ::= ?8 # ==1523 case OO_EqualEqual: Out << "?8"; break;1524 // <operator-name> ::= ?9 # !=1525 case OO_ExclaimEqual: Out << "?9"; break;1526 // <operator-name> ::= ?A # []1527 case OO_Subscript: Out << "?A"; break;1528 // ?B # conversion1529 // <operator-name> ::= ?C # ->1530 case OO_Arrow: Out << "?C"; break;1531 // <operator-name> ::= ?D # *1532 case OO_Star: Out << "?D"; break;1533 // <operator-name> ::= ?E # ++1534 case OO_PlusPlus: Out << "?E"; break;1535 // <operator-name> ::= ?F # --1536 case OO_MinusMinus: Out << "?F"; break;1537 // <operator-name> ::= ?G # -1538 case OO_Minus: Out << "?G"; break;1539 // <operator-name> ::= ?H # +1540 case OO_Plus: Out << "?H"; break;1541 // <operator-name> ::= ?I # &1542 case OO_Amp: Out << "?I"; break;1543 // <operator-name> ::= ?J # ->*1544 case OO_ArrowStar: Out << "?J"; break;1545 // <operator-name> ::= ?K # /1546 case OO_Slash: Out << "?K"; break;1547 // <operator-name> ::= ?L # %1548 case OO_Percent: Out << "?L"; break;1549 // <operator-name> ::= ?M # <1550 case OO_Less: Out << "?M"; break;1551 // <operator-name> ::= ?N # <=1552 case OO_LessEqual: Out << "?N"; break;1553 // <operator-name> ::= ?O # >1554 case OO_Greater: Out << "?O"; break;1555 // <operator-name> ::= ?P # >=1556 case OO_GreaterEqual: Out << "?P"; break;1557 // <operator-name> ::= ?Q # ,1558 case OO_Comma: Out << "?Q"; break;1559 // <operator-name> ::= ?R # ()1560 case OO_Call: Out << "?R"; break;1561 // <operator-name> ::= ?S # ~1562 case OO_Tilde: Out << "?S"; break;1563 // <operator-name> ::= ?T # ^1564 case OO_Caret: Out << "?T"; break;1565 // <operator-name> ::= ?U # |1566 case OO_Pipe: Out << "?U"; break;1567 // <operator-name> ::= ?V # &&1568 case OO_AmpAmp: Out << "?V"; break;1569 // <operator-name> ::= ?W # ||1570 case OO_PipePipe: Out << "?W"; break;1571 // <operator-name> ::= ?X # *=1572 case OO_StarEqual: Out << "?X"; break;1573 // <operator-name> ::= ?Y # +=1574 case OO_PlusEqual: Out << "?Y"; break;1575 // <operator-name> ::= ?Z # -=1576 case OO_MinusEqual: Out << "?Z"; break;1577 // <operator-name> ::= ?_0 # /=1578 case OO_SlashEqual: Out << "?_0"; break;1579 // <operator-name> ::= ?_1 # %=1580 case OO_PercentEqual: Out << "?_1"; break;1581 // <operator-name> ::= ?_2 # >>=1582 case OO_GreaterGreaterEqual: Out << "?_2"; break;1583 // <operator-name> ::= ?_3 # <<=1584 case OO_LessLessEqual: Out << "?_3"; break;1585 // <operator-name> ::= ?_4 # &=1586 case OO_AmpEqual: Out << "?_4"; break;1587 // <operator-name> ::= ?_5 # |=1588 case OO_PipeEqual: Out << "?_5"; break;1589 // <operator-name> ::= ?_6 # ^=1590 case OO_CaretEqual: Out << "?_6"; break;1591 // ?_7 # vftable1592 // ?_8 # vbtable1593 // ?_9 # vcall1594 // ?_A # typeof1595 // ?_B # local static guard1596 // ?_C # string1597 // ?_D # vbase destructor1598 // ?_E # vector deleting destructor1599 // ?_F # default constructor closure1600 // ?_G # scalar deleting destructor1601 // ?_H # vector constructor iterator1602 // ?_I # vector destructor iterator1603 // ?_J # vector vbase constructor iterator1604 // ?_K # virtual displacement map1605 // ?_L # eh vector constructor iterator1606 // ?_M # eh vector destructor iterator1607 // ?_N # eh vector vbase constructor iterator1608 // ?_O # copy constructor closure1609 // ?_P<name> # udt returning <name>1610 // ?_Q # <unknown>1611 // ?_R0 # RTTI Type Descriptor1612 // ?_R1 # RTTI Base Class Descriptor at (a,b,c,d)1613 // ?_R2 # RTTI Base Class Array1614 // ?_R3 # RTTI Class Hierarchy Descriptor1615 // ?_R4 # RTTI Complete Object Locator1616 // ?_S # local vftable1617 // ?_T # local vftable constructor closure1618 // <operator-name> ::= ?_U # new[]1619 case OO_Array_New: Out << "?_U"; break;1620 // <operator-name> ::= ?_V # delete[]1621 case OO_Array_Delete: Out << "?_V"; break;1622 // <operator-name> ::= ?__L # co_await1623 case OO_Coawait: Out << "?__L"; break;1624 // <operator-name> ::= ?__M # <=>1625 case OO_Spaceship: Out << "?__M"; break;1626 1627 case OO_Conditional: {1628 Error(Loc, "conditional operator");1629 break;1630 }1631 1632 case OO_None:1633 case NUM_OVERLOADED_OPERATORS:1634 llvm_unreachable("Not an overloaded operator");1635 }1636}1637 1638void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {1639 // <source name> ::= <identifier> @1640 BackRefVec::iterator Found = llvm::find(NameBackReferences, Name);1641 if (Found == NameBackReferences.end()) {1642 if (NameBackReferences.size() < 10)1643 NameBackReferences.push_back(std::string(Name));1644 Out << Name << '@';1645 } else {1646 Out << (Found - NameBackReferences.begin());1647 }1648}1649 1650void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {1651 Context.mangleObjCMethodNameAsSourceName(MD, Out);1652}1653 1654void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(1655 GlobalDecl GD, const TemplateArgumentList &TemplateArgs) {1656 // <template-name> ::= <unscoped-template-name> <template-args>1657 // ::= <substitution>1658 // Always start with the unqualified name.1659 1660 // Templates have their own context for back references.1661 ArgBackRefMap OuterFunArgsContext;1662 ArgBackRefMap OuterTemplateArgsContext;1663 BackRefVec OuterTemplateContext;1664 PassObjectSizeArgsSet OuterPassObjectSizeArgs;1665 NameBackReferences.swap(OuterTemplateContext);1666 FunArgBackReferences.swap(OuterFunArgsContext);1667 TemplateArgBackReferences.swap(OuterTemplateArgsContext);1668 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);1669 1670 mangleUnscopedTemplateName(GD);1671 mangleTemplateArgs(cast<TemplateDecl>(GD.getDecl()), TemplateArgs);1672 1673 // Restore the previous back reference contexts.1674 NameBackReferences.swap(OuterTemplateContext);1675 FunArgBackReferences.swap(OuterFunArgsContext);1676 TemplateArgBackReferences.swap(OuterTemplateArgsContext);1677 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);1678}1679 1680void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {1681 // <unscoped-template-name> ::= ?$ <unqualified-name>1682 Out << "?$";1683 mangleUnqualifiedName(GD);1684}1685 1686void MicrosoftCXXNameMangler::mangleIntegerLiteral(1687 const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,1688 QualType TemplateArgType) {1689 // <integer-literal> ::= $0 <number>1690 // <integer-literal> ::= <auto-nttp>1691 //1692 // <auto-nttp> ::= $ M <type> 0 <number>1693 Out << "$";1694 1695 // Since MSVC 2019, add 'M[<type>]' after '$' for auto template parameter when1696 // argument is integer.1697 if (getASTContext().getLangOpts().isCompatibleWithMSVC(1698 LangOptions::MSVC2019) &&1699 PD && PD->getType()->getTypeClass() == Type::Auto &&1700 !TemplateArgType.isNull()) {1701 Out << "M";1702 mangleType(TemplateArgType, SourceRange(), QMM_Drop);1703 }1704 1705 Out << "0";1706 1707 mangleNumber(Value);1708}1709 1710void MicrosoftCXXNameMangler::mangleExpression(1711 const Expr *E, const NonTypeTemplateParmDecl *PD) {1712 // See if this is a constant expression.1713 if (std::optional<llvm::APSInt> Value =1714 E->getIntegerConstantExpr(Context.getASTContext())) {1715 mangleIntegerLiteral(*Value, PD, E->getType());1716 return;1717 }1718 1719 // As bad as this diagnostic is, it's better than crashing.1720 Error(E->getExprLoc(), "expression type: ", E->getStmtClassName())1721 << E->getSourceRange();1722}1723 1724void MicrosoftCXXNameMangler::mangleTemplateArgs(1725 const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {1726 // <template-args> ::= <template-arg>+1727 const TemplateParameterList *TPL = TD->getTemplateParameters();1728 assert(TPL->size() == TemplateArgs.size() &&1729 "size mismatch between args and parms!");1730 1731 for (size_t i = 0; i < TemplateArgs.size(); ++i) {1732 const TemplateArgument &TA = TemplateArgs[i];1733 1734 // Separate consecutive packs by $$Z.1735 if (i > 0 && TA.getKind() == TemplateArgument::Pack &&1736 TemplateArgs[i - 1].getKind() == TemplateArgument::Pack)1737 Out << "$$Z";1738 1739 mangleTemplateArg(TD, TA, TPL->getParam(i));1740 }1741}1742 1743/// If value V (with type T) represents a decayed pointer to the first element1744/// of an array, return that array.1745static ValueDecl *getAsArrayToPointerDecayedDecl(QualType T, const APValue &V) {1746 // Must be a pointer...1747 if (!T->isPointerType() || !V.isLValue() || !V.hasLValuePath() ||1748 !V.getLValueBase())1749 return nullptr;1750 // ... to element 0 of an array.1751 QualType BaseT = V.getLValueBase().getType();1752 if (!BaseT->isArrayType() || V.getLValuePath().size() != 1 ||1753 V.getLValuePath()[0].getAsArrayIndex() != 0)1754 return nullptr;1755 return const_cast<ValueDecl *>(1756 V.getLValueBase().dyn_cast<const ValueDecl *>());1757}1758 1759void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,1760 const TemplateArgument &TA,1761 const NamedDecl *Parm) {1762 // <template-arg> ::= <type>1763 // ::= <integer-literal>1764 // ::= <member-data-pointer>1765 // ::= <member-function-pointer>1766 // ::= $ <constant-value>1767 // ::= $ <auto-nttp-constant-value>1768 // ::= <template-args>1769 //1770 // <auto-nttp-constant-value> ::= M <type> <constant-value>1771 //1772 // <constant-value> ::= 0 <number> # integer1773 // ::= 1 <mangled-name> # address of D1774 // ::= 2 <type> <typed-constant-value>* @ # struct1775 // ::= 3 <type> <constant-value>* @ # array1776 // ::= 4 ??? # string1777 // ::= 5 <constant-value> @ # address of subobject1778 // ::= 6 <constant-value> <unqualified-name> @ # a.b1779 // ::= 7 <type> [<unqualified-name> <constant-value>] @1780 // # union, with or without an active member1781 // # pointer to member, symbolically1782 // ::= 8 <class> <unqualified-name> @1783 // ::= A <type> <non-negative integer> # float1784 // ::= B <type> <non-negative integer> # double1785 // # pointer to member, by component value1786 // ::= F <number> <number>1787 // ::= G <number> <number> <number>1788 // ::= H <mangled-name> <number>1789 // ::= I <mangled-name> <number> <number>1790 // ::= J <mangled-name> <number> <number> <number>1791 //1792 // <typed-constant-value> ::= [<type>] <constant-value>1793 //1794 // The <type> appears to be included in a <typed-constant-value> only in the1795 // '0', '1', '8', 'A', 'B', and 'E' cases.1796 1797 switch (TA.getKind()) {1798 case TemplateArgument::Null:1799 llvm_unreachable("Can't mangle null template arguments!");1800 case TemplateArgument::TemplateExpansion:1801 llvm_unreachable("Can't mangle template expansion arguments!");1802 case TemplateArgument::Type: {1803 QualType T = TA.getAsType();1804 mangleType(T, SourceRange(), QMM_Escape);1805 break;1806 }1807 case TemplateArgument::Declaration: {1808 const NamedDecl *ND = TA.getAsDecl();1809 if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {1810 mangleMemberDataPointer(1811 cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),1812 cast<ValueDecl>(ND), cast<NonTypeTemplateParmDecl>(Parm),1813 TA.getParamTypeForDecl());1814 } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {1815 const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);1816 if (MD && MD->isInstance()) {1817 mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD,1818 cast<NonTypeTemplateParmDecl>(Parm),1819 TA.getParamTypeForDecl());1820 } else {1821 mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),1822 TA.getParamTypeForDecl());1823 }1824 } else if (TA.getParamTypeForDecl()->isRecordType()) {1825 Out << "$";1826 auto *TPO = cast<TemplateParamObjectDecl>(ND);1827 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),1828 TPO->getValue(), TplArgKind::ClassNTTP);1829 } else if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {1830 mangleVarDecl(VD, cast<NonTypeTemplateParmDecl>(Parm),1831 TA.getParamTypeForDecl());1832 } else {1833 mangle(ND, "$1?");1834 }1835 break;1836 }1837 case TemplateArgument::Integral: {1838 QualType T = TA.getIntegralType();1839 mangleIntegerLiteral(TA.getAsIntegral(),1840 cast<NonTypeTemplateParmDecl>(Parm), T);1841 break;1842 }1843 case TemplateArgument::NullPtr: {1844 QualType T = TA.getNullPtrType();1845 if (const MemberPointerType *MPT = T->getAs<MemberPointerType>()) {1846 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();1847 if (MPT->isMemberFunctionPointerType() &&1848 !isa<FunctionTemplateDecl>(TD)) {1849 mangleMemberFunctionPointer(RD, nullptr, nullptr, QualType());1850 return;1851 }1852 if (MPT->isMemberDataPointer()) {1853 if (!isa<FunctionTemplateDecl>(TD)) {1854 mangleMemberDataPointer(RD, nullptr, nullptr, QualType());1855 return;1856 }1857 // nullptr data pointers are always represented with a single field1858 // which is initialized with either 0 or -1. Why -1? Well, we need to1859 // distinguish the case where the data member is at offset zero in the1860 // record.1861 // However, we are free to use 0 *if* we would use multiple fields for1862 // non-nullptr member pointers.1863 if (!RD->nullFieldOffsetIsZero()) {1864 mangleIntegerLiteral(llvm::APSInt::get(-1),1865 cast<NonTypeTemplateParmDecl>(Parm), T);1866 return;1867 }1868 }1869 }1870 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),1871 cast<NonTypeTemplateParmDecl>(Parm), T);1872 break;1873 }1874 case TemplateArgument::StructuralValue:1875 if (ValueDecl *D = getAsArrayToPointerDecayedDecl(1876 TA.getStructuralValueType(), TA.getAsStructuralValue())) {1877 // Mangle the result of array-to-pointer decay as if it were a reference1878 // to the original declaration, to match MSVC's behavior. This can result1879 // in mangling collisions in some cases!1880 return mangleTemplateArg(1881 TD, TemplateArgument(D, TA.getStructuralValueType()), Parm);1882 }1883 Out << "$";1884 if (cast<NonTypeTemplateParmDecl>(Parm)1885 ->getType()1886 ->getContainedDeducedType()) {1887 Out << "M";1888 mangleType(TA.getNonTypeTemplateArgumentType(), SourceRange(), QMM_Drop);1889 }1890 mangleTemplateArgValue(TA.getStructuralValueType(),1891 TA.getAsStructuralValue(),1892 TplArgKind::StructuralValue,1893 /*WithScalarType=*/false);1894 break;1895 case TemplateArgument::Expression:1896 mangleExpression(TA.getAsExpr(), cast<NonTypeTemplateParmDecl>(Parm));1897 break;1898 case TemplateArgument::Pack: {1899 ArrayRef<TemplateArgument> TemplateArgs = TA.getPackAsArray();1900 if (TemplateArgs.empty()) {1901 if (isa<TemplateTypeParmDecl>(Parm) ||1902 isa<TemplateTemplateParmDecl>(Parm))1903 // MSVC 2015 changed the mangling for empty expanded template packs,1904 // use the old mangling for link compatibility for old versions.1905 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(1906 LangOptions::MSVC2015)1907 ? "$$V"1908 : "$$$V");1909 else if (isa<NonTypeTemplateParmDecl>(Parm))1910 Out << "$S";1911 else1912 llvm_unreachable("unexpected template parameter decl!");1913 } else {1914 for (const TemplateArgument &PA : TemplateArgs)1915 mangleTemplateArg(TD, PA, Parm);1916 }1917 break;1918 }1919 case TemplateArgument::Template: {1920 const NamedDecl *ND =1921 TA.getAsTemplate().getAsTemplateDecl()->getTemplatedDecl();1922 if (const auto *TD = dyn_cast<TagDecl>(ND)) {1923 mangleType(TD);1924 } else if (isa<TypeAliasDecl>(ND)) {1925 Out << "$$Y";1926 mangleName(ND);1927 } else {1928 llvm_unreachable("unexpected template template NamedDecl!");1929 }1930 break;1931 }1932 }1933}1934 1935void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,1936 const APValue &V,1937 TplArgKind TAK,1938 bool WithScalarType) {1939 switch (V.getKind()) {1940 case APValue::None:1941 case APValue::Indeterminate:1942 // FIXME: MSVC doesn't allow this, so we can't be sure how it should be1943 // mangled.1944 if (WithScalarType)1945 mangleType(T, SourceRange(), QMM_Escape);1946 Out << '@';1947 return;1948 1949 case APValue::Int:1950 if (WithScalarType)1951 mangleType(T, SourceRange(), QMM_Escape);1952 Out << '0';1953 mangleNumber(V.getInt());1954 return;1955 1956 case APValue::Float:1957 if (WithScalarType)1958 mangleType(T, SourceRange(), QMM_Escape);1959 mangleFloat(V.getFloat());1960 return;1961 1962 case APValue::LValue: {1963 if (WithScalarType)1964 mangleType(T, SourceRange(), QMM_Escape);1965 1966 APValue::LValueBase Base = V.getLValueBase();1967 1968 // this might not cover every case but did cover issue 977561969 // see test CodeGen/ms_mangler_templatearg_opte1970 if (V.isLValueOnePastTheEnd()) {1971 Out << "5E";1972 auto *VD = Base.dyn_cast<const ValueDecl *>();1973 if (VD)1974 mangle(VD);1975 Out << "@";1976 return;1977 }1978 1979 if (!V.hasLValuePath() || V.getLValuePath().empty()) {1980 // Taking the address of a complete object has a special-case mangling.1981 if (Base.isNull()) {1982 // MSVC emits 0A@ for null pointers. Generalize this for arbitrary1983 // integers cast to pointers.1984 // FIXME: This mangles 0 cast to a pointer the same as a null pointer,1985 // even in cases where the two are different values.1986 Out << "0";1987 mangleNumber(V.getLValueOffset().getQuantity());1988 } else if (!V.hasLValuePath()) {1989 // FIXME: This can only happen as an extension. Invent a mangling.1990 Error("template argument (extension not comaptible with ms mangler)");1991 return;1992 } else if (auto *VD = Base.dyn_cast<const ValueDecl*>()) {1993 Out << "E";1994 mangle(VD);1995 } else {1996 Error("template argument (undeclared base)");1997 return;1998 }1999 } else {2000 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())2001 Out << "5";2002 2003 SmallVector<char, 2> EntryTypes;2004 SmallVector<std::function<void()>, 2> EntryManglers;2005 QualType ET = Base.getType();2006 for (APValue::LValuePathEntry E : V.getLValuePath()) {2007 if (auto *AT = ET->getAsArrayTypeUnsafe()) {2008 EntryTypes.push_back('C');2009 EntryManglers.push_back([this, I = E.getAsArrayIndex()] {2010 Out << '0';2011 mangleNumber(I);2012 Out << '@';2013 });2014 ET = AT->getElementType();2015 continue;2016 }2017 2018 const Decl *D = E.getAsBaseOrMember().getPointer();2019 if (auto *FD = dyn_cast<FieldDecl>(D)) {2020 ET = FD->getType();2021 if (const auto *RD = ET->getAsRecordDecl())2022 if (RD->isAnonymousStructOrUnion())2023 continue;2024 } else {2025 ET = getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(D));2026 // Bug in MSVC: fully qualified name of base class should be used for2027 // mangling to prevent collisions e.g. on base classes with same names2028 // in different namespaces.2029 }2030 2031 EntryTypes.push_back('6');2032 EntryManglers.push_back([this, D] {2033 mangleUnqualifiedName(cast<NamedDecl>(D));2034 Out << '@';2035 });2036 }2037 2038 for (auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)2039 Out << *I;2040 2041 auto *VD = Base.dyn_cast<const ValueDecl*>();2042 if (!VD) {2043 Error("template argument (null value decl)");2044 return;2045 }2046 Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1');2047 mangle(VD);2048 2049 for (const std::function<void()> &Mangler : EntryManglers)2050 Mangler();2051 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())2052 Out << '@';2053 }2054 2055 return;2056 }2057 2058 case APValue::MemberPointer: {2059 if (WithScalarType)2060 mangleType(T, SourceRange(), QMM_Escape);2061 2062 const CXXRecordDecl *RD =2063 T->castAs<MemberPointerType>()->getMostRecentCXXRecordDecl();2064 const ValueDecl *D = V.getMemberPointerDecl();2065 if (TAK == TplArgKind::ClassNTTP) {2066 if (T->isMemberDataPointerType())2067 mangleMemberDataPointerInClassNTTP(RD, D);2068 else2069 mangleMemberFunctionPointerInClassNTTP(RD,2070 cast_or_null<CXXMethodDecl>(D));2071 } else {2072 if (T->isMemberDataPointerType())2073 mangleMemberDataPointer(RD, D, nullptr, QualType(), "");2074 else2075 mangleMemberFunctionPointer(RD, cast_or_null<CXXMethodDecl>(D), nullptr,2076 QualType(), "");2077 }2078 return;2079 }2080 2081 case APValue::Struct: {2082 Out << '2';2083 mangleType(T, SourceRange(), QMM_Escape);2084 const CXXRecordDecl *RD = T->getAsCXXRecordDecl();2085 assert(RD && "unexpected type for record value");2086 2087 unsigned BaseIndex = 0;2088 for (const CXXBaseSpecifier &B : RD->bases())2089 mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++), TAK);2090 for (const FieldDecl *FD : RD->fields())2091 if (!FD->isUnnamedBitField())2092 mangleTemplateArgValue(FD->getType(),2093 V.getStructField(FD->getFieldIndex()), TAK,2094 /*WithScalarType*/ true);2095 Out << '@';2096 return;2097 }2098 2099 case APValue::Union:2100 Out << '7';2101 mangleType(T, SourceRange(), QMM_Escape);2102 if (const FieldDecl *FD = V.getUnionField()) {2103 mangleUnqualifiedName(FD);2104 mangleTemplateArgValue(FD->getType(), V.getUnionValue(), TAK);2105 }2106 Out << '@';2107 return;2108 2109 case APValue::ComplexInt:2110 // We mangle complex types as structs, so mangle the value as a struct too.2111 Out << '2';2112 mangleType(T, SourceRange(), QMM_Escape);2113 Out << '0';2114 mangleNumber(V.getComplexIntReal());2115 Out << '0';2116 mangleNumber(V.getComplexIntImag());2117 Out << '@';2118 return;2119 2120 case APValue::ComplexFloat:2121 Out << '2';2122 mangleType(T, SourceRange(), QMM_Escape);2123 mangleFloat(V.getComplexFloatReal());2124 mangleFloat(V.getComplexFloatImag());2125 Out << '@';2126 return;2127 2128 case APValue::Array: {2129 Out << '3';2130 QualType ElemT = getASTContext().getAsArrayType(T)->getElementType();2131 mangleType(ElemT, SourceRange(), QMM_Escape);2132 for (unsigned I = 0, N = V.getArraySize(); I != N; ++I) {2133 const APValue &ElemV = I < V.getArrayInitializedElts()2134 ? V.getArrayInitializedElt(I)2135 : V.getArrayFiller();2136 mangleTemplateArgValue(ElemT, ElemV, TAK);2137 Out << '@';2138 }2139 Out << '@';2140 return;2141 }2142 2143 case APValue::Vector: {2144 // __m128 is mangled as a struct containing an array. We follow this2145 // approach for all vector types.2146 Out << '2';2147 mangleType(T, SourceRange(), QMM_Escape);2148 Out << '3';2149 QualType ElemT = T->castAs<VectorType>()->getElementType();2150 mangleType(ElemT, SourceRange(), QMM_Escape);2151 for (unsigned I = 0, N = V.getVectorLength(); I != N; ++I) {2152 const APValue &ElemV = V.getVectorElt(I);2153 mangleTemplateArgValue(ElemT, ElemV, TAK);2154 Out << '@';2155 }2156 Out << "@@";2157 return;2158 }2159 2160 case APValue::AddrLabelDiff: {2161 Error("template argument (value type: address label diff)");2162 return;2163 }2164 2165 case APValue::FixedPoint: {2166 Error("template argument (value type: fixed point)");2167 return;2168 }2169 }2170}2171 2172void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) {2173 llvm::SmallString<64> TemplateMangling;2174 llvm::raw_svector_ostream Stream(TemplateMangling);2175 MicrosoftCXXNameMangler Extra(Context, Stream);2176 2177 Stream << "?$";2178 Extra.mangleSourceName("Protocol");2179 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->getName());2180 2181 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});2182}2183 2184void MicrosoftCXXNameMangler::mangleObjCLifetime(const QualType Type,2185 Qualifiers Quals,2186 SourceRange Range) {2187 llvm::SmallString<64> TemplateMangling;2188 llvm::raw_svector_ostream Stream(TemplateMangling);2189 MicrosoftCXXNameMangler Extra(Context, Stream);2190 2191 Stream << "?$";2192 switch (Quals.getObjCLifetime()) {2193 case Qualifiers::OCL_None:2194 case Qualifiers::OCL_ExplicitNone:2195 break;2196 case Qualifiers::OCL_Autoreleasing:2197 Extra.mangleSourceName("Autoreleasing");2198 break;2199 case Qualifiers::OCL_Strong:2200 Extra.mangleSourceName("Strong");2201 break;2202 case Qualifiers::OCL_Weak:2203 Extra.mangleSourceName("Weak");2204 break;2205 }2206 Extra.manglePointerCVQualifiers(Quals);2207 Extra.manglePointerExtQualifiers(Quals, Type);2208 Extra.mangleType(Type, Range);2209 2210 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});2211}2212 2213void MicrosoftCXXNameMangler::mangleObjCKindOfType(const ObjCObjectType *T,2214 Qualifiers Quals,2215 SourceRange Range) {2216 llvm::SmallString<64> TemplateMangling;2217 llvm::raw_svector_ostream Stream(TemplateMangling);2218 MicrosoftCXXNameMangler Extra(Context, Stream);2219 2220 Stream << "?$";2221 Extra.mangleSourceName("KindOf");2222 Extra.mangleType(QualType(T, 0)2223 .stripObjCKindOfType(getASTContext())2224 ->castAs<ObjCObjectType>(),2225 Quals, Range);2226 2227 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});2228}2229 2230void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,2231 bool IsMember) {2232 // <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>2233 // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only);2234 // 'I' means __restrict (32/64-bit).2235 // Note that the MSVC __restrict keyword isn't the same as the C99 restrict2236 // keyword!2237 // <base-cvr-qualifiers> ::= A # near2238 // ::= B # near const2239 // ::= C # near volatile2240 // ::= D # near const volatile2241 // ::= E # far (16-bit)2242 // ::= F # far const (16-bit)2243 // ::= G # far volatile (16-bit)2244 // ::= H # far const volatile (16-bit)2245 // ::= I # huge (16-bit)2246 // ::= J # huge const (16-bit)2247 // ::= K # huge volatile (16-bit)2248 // ::= L # huge const volatile (16-bit)2249 // ::= M <basis> # based2250 // ::= N <basis> # based const2251 // ::= O <basis> # based volatile2252 // ::= P <basis> # based const volatile2253 // ::= Q # near member2254 // ::= R # near const member2255 // ::= S # near volatile member2256 // ::= T # near const volatile member2257 // ::= U # far member (16-bit)2258 // ::= V # far const member (16-bit)2259 // ::= W # far volatile member (16-bit)2260 // ::= X # far const volatile member (16-bit)2261 // ::= Y # huge member (16-bit)2262 // ::= Z # huge const member (16-bit)2263 // ::= 0 # huge volatile member (16-bit)2264 // ::= 1 # huge const volatile member (16-bit)2265 // ::= 2 <basis> # based member2266 // ::= 3 <basis> # based const member2267 // ::= 4 <basis> # based volatile member2268 // ::= 5 <basis> # based const volatile member2269 // ::= 6 # near function (pointers only)2270 // ::= 7 # far function (pointers only)2271 // ::= 8 # near method (pointers only)2272 // ::= 9 # far method (pointers only)2273 // ::= _A <basis> # based function (pointers only)2274 // ::= _B <basis> # based function (far?) (pointers only)2275 // ::= _C <basis> # based method (pointers only)2276 // ::= _D <basis> # based method (far?) (pointers only)2277 // ::= _E # block (Clang)2278 // <basis> ::= 0 # __based(void)2279 // ::= 1 # __based(segment)?2280 // ::= 2 <name> # __based(name)2281 // ::= 3 # ?2282 // ::= 4 # ?2283 // ::= 5 # not really based2284 bool HasConst = Quals.hasConst(),2285 HasVolatile = Quals.hasVolatile();2286 2287 if (!IsMember) {2288 if (HasConst && HasVolatile) {2289 Out << 'D';2290 } else if (HasVolatile) {2291 Out << 'C';2292 } else if (HasConst) {2293 Out << 'B';2294 } else {2295 Out << 'A';2296 }2297 } else {2298 if (HasConst && HasVolatile) {2299 Out << 'T';2300 } else if (HasVolatile) {2301 Out << 'S';2302 } else if (HasConst) {2303 Out << 'R';2304 } else {2305 Out << 'Q';2306 }2307 }2308 2309 // FIXME: For now, just drop all extension qualifiers on the floor.2310}2311 2312void2313MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {2314 // <ref-qualifier> ::= G # lvalue reference2315 // ::= H # rvalue-reference2316 switch (RefQualifier) {2317 case RQ_None:2318 break;2319 2320 case RQ_LValue:2321 Out << 'G';2322 break;2323 2324 case RQ_RValue:2325 Out << 'H';2326 break;2327 }2328}2329 2330void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,2331 QualType PointeeType) {2332 // Check if this is a default 64-bit pointer or has __ptr64 qualifier.2333 bool is64Bit = PointeeType.isNull() ? PointersAre64Bit :2334 is64BitPointer(PointeeType.getQualifiers());2335 if (is64Bit && (PointeeType.isNull() || !PointeeType->isFunctionType()))2336 Out << 'E';2337 2338 if (Quals.hasRestrict())2339 Out << 'I';2340 2341 if (Quals.hasUnaligned() ||2342 (!PointeeType.isNull() && PointeeType.getLocalQualifiers().hasUnaligned()))2343 Out << 'F';2344}2345 2346void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {2347 PointerAuthQualifier PointerAuth = Quals.getPointerAuth();2348 if (!PointerAuth)2349 return;2350 2351 Out << "__ptrauth";2352 mangleNumber(PointerAuth.getKey());2353 mangleNumber(PointerAuth.isAddressDiscriminated());2354 mangleNumber(PointerAuth.getExtraDiscriminator());2355}2356 2357void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {2358 // <pointer-cv-qualifiers> ::= P # no qualifiers2359 // ::= Q # const2360 // ::= R # volatile2361 // ::= S # const volatile2362 bool HasConst = Quals.hasConst(),2363 HasVolatile = Quals.hasVolatile();2364 2365 if (HasConst && HasVolatile) {2366 Out << 'S';2367 } else if (HasVolatile) {2368 Out << 'R';2369 } else if (HasConst) {2370 Out << 'Q';2371 } else {2372 Out << 'P';2373 }2374}2375 2376void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType T,2377 SourceRange Range) {2378 // MSVC will backreference two canonically equivalent types that have slightly2379 // different manglings when mangled alone.2380 2381 // Decayed types do not match up with non-decayed versions of the same type.2382 //2383 // e.g.2384 // void (*x)(void) will not form a backreference with void x(void)2385 void *TypePtr;2386 if (const auto *DT = T->getAs<DecayedType>()) {2387 QualType OriginalType = DT->getOriginalType();2388 // All decayed ArrayTypes should be treated identically; as-if they were2389 // a decayed IncompleteArrayType.2390 if (const auto *AT = getASTContext().getAsArrayType(OriginalType))2391 OriginalType = getASTContext().getIncompleteArrayType(2392 AT->getElementType(), AT->getSizeModifier(),2393 AT->getIndexTypeCVRQualifiers());2394 2395 TypePtr = OriginalType.getCanonicalType().getAsOpaquePtr();2396 // If the original parameter was textually written as an array,2397 // instead treat the decayed parameter like it's const.2398 //2399 // e.g.2400 // int [] -> int * const2401 if (OriginalType->isArrayType())2402 T = T.withConst();2403 } else {2404 TypePtr = T.getCanonicalType().getAsOpaquePtr();2405 }2406 2407 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);2408 2409 if (Found == FunArgBackReferences.end()) {2410 size_t OutSizeBefore = Out.tell();2411 2412 mangleType(T, Range, QMM_Drop);2413 2414 // See if it's worth creating a back reference.2415 // Only types longer than 1 character are considered2416 // and only 10 back references slots are available:2417 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);2418 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {2419 size_t Size = FunArgBackReferences.size();2420 FunArgBackReferences[TypePtr] = Size;2421 }2422 } else {2423 Out << Found->second;2424 }2425}2426 2427void MicrosoftCXXNameMangler::manglePassObjectSizeArg(2428 const PassObjectSizeAttr *POSA) {2429 int Type = POSA->getType();2430 bool Dynamic = POSA->isDynamic();2431 2432 auto Iter = PassObjectSizeArgs.insert({Type, Dynamic}).first;2433 auto *TypePtr = (const void *)&*Iter;2434 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);2435 2436 if (Found == FunArgBackReferences.end()) {2437 std::string Name =2438 Dynamic ? "__pass_dynamic_object_size" : "__pass_object_size";2439 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(Type),2440 {"__clang"});2441 2442 if (FunArgBackReferences.size() < 10) {2443 size_t Size = FunArgBackReferences.size();2444 FunArgBackReferences[TypePtr] = Size;2445 }2446 } else {2447 Out << Found->second;2448 }2449}2450 2451void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,2452 Qualifiers Quals,2453 SourceRange Range) {2454 // Address space is mangled as an unqualified templated type in the __clang2455 // namespace. The demangled version of this is:2456 // In the case of a language specific address space:2457 // __clang::struct _AS[language_addr_space]<Type>2458 // where:2459 // <language_addr_space> ::= <OpenCL-addrspace> | <CUDA-addrspace>2460 // <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |2461 // "private"| "generic" | "device" | "host" ]2462 // <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]2463 // Note that the above were chosen to match the Itanium mangling for this.2464 //2465 // In the case of a non-language specific address space:2466 // __clang::struct _AS<TargetAS, Type>2467 assert(Quals.hasAddressSpace() && "Not valid without address space");2468 llvm::SmallString<32> ASMangling;2469 llvm::raw_svector_ostream Stream(ASMangling);2470 MicrosoftCXXNameMangler Extra(Context, Stream);2471 Stream << "?$";2472 2473 LangAS AS = Quals.getAddressSpace();2474 if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {2475 unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);2476 Extra.mangleSourceName("_AS");2477 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));2478 } else {2479 switch (AS) {2480 default:2481 llvm_unreachable("Not a language specific address space");2482 case LangAS::opencl_global:2483 Extra.mangleSourceName("_ASCLglobal");2484 break;2485 case LangAS::opencl_global_device:2486 Extra.mangleSourceName("_ASCLdevice");2487 break;2488 case LangAS::opencl_global_host:2489 Extra.mangleSourceName("_ASCLhost");2490 break;2491 case LangAS::opencl_local:2492 Extra.mangleSourceName("_ASCLlocal");2493 break;2494 case LangAS::opencl_constant:2495 Extra.mangleSourceName("_ASCLconstant");2496 break;2497 case LangAS::opencl_private:2498 Extra.mangleSourceName("_ASCLprivate");2499 break;2500 case LangAS::opencl_generic:2501 Extra.mangleSourceName("_ASCLgeneric");2502 break;2503 case LangAS::cuda_device:2504 Extra.mangleSourceName("_ASCUdevice");2505 break;2506 case LangAS::cuda_constant:2507 Extra.mangleSourceName("_ASCUconstant");2508 break;2509 case LangAS::cuda_shared:2510 Extra.mangleSourceName("_ASCUshared");2511 break;2512 case LangAS::ptr32_sptr:2513 case LangAS::ptr32_uptr:2514 case LangAS::ptr64:2515 llvm_unreachable("don't mangle ptr address spaces with _AS");2516 }2517 }2518 2519 Extra.mangleType(T, Range, QMM_Escape);2520 mangleQualifiers(Qualifiers(), false);2521 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"});2522}2523 2524void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T,2525 QualifierMangleMode QMM) {2526 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(2527 LangOptions::MSVC2019) &&2528 "Cannot mangle MSVC 2017 auto return types!");2529 2530 if (isa<AutoType>(T)) {2531 const auto *AT = T->getContainedAutoType();2532 Qualifiers Quals = T.getLocalQualifiers();2533 2534 if (QMM == QMM_Result)2535 Out << '?';2536 if (QMM != QMM_Drop)2537 mangleQualifiers(Quals, false);2538 Out << (AT->isDecltypeAuto() ? "_T" : "_P");2539 return;2540 }2541 2542 T = T.getDesugaredType(getASTContext());2543 Qualifiers Quals = T.getLocalQualifiers();2544 2545 switch (QMM) {2546 case QMM_Drop:2547 case QMM_Result:2548 break;2549 case QMM_Mangle:2550 mangleQualifiers(Quals, false);2551 break;2552 default:2553 llvm_unreachable("QMM_Escape unexpected");2554 }2555 2556 const Type *ty = T.getTypePtr();2557 switch (ty->getTypeClass()) {2558 case Type::MemberPointer:2559 mangleAutoReturnType(cast<MemberPointerType>(ty), Quals);2560 break;2561 case Type::Pointer:2562 mangleAutoReturnType(cast<PointerType>(ty), Quals);2563 break;2564 case Type::LValueReference:2565 mangleAutoReturnType(cast<LValueReferenceType>(ty), Quals);2566 break;2567 case Type::RValueReference:2568 mangleAutoReturnType(cast<RValueReferenceType>(ty), Quals);2569 break;2570 default:2571 llvm_unreachable("Invalid type expected");2572 }2573}2574 2575void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,2576 QualifierMangleMode QMM) {2577 // Don't use the canonical types. MSVC includes things like 'const' on2578 // pointer arguments to function pointers that canonicalization strips away.2579 T = T.getDesugaredType(getASTContext());2580 Qualifiers Quals = T.getLocalQualifiers();2581 2582 if (const ArrayType *AT = getASTContext().getAsArrayType(T)) {2583 // If there were any Quals, getAsArrayType() pushed them onto the array2584 // element type.2585 if (QMM == QMM_Mangle)2586 Out << 'A';2587 else if (QMM == QMM_Escape || QMM == QMM_Result)2588 Out << "$$B";2589 mangleArrayType(AT);2590 return;2591 }2592 2593 bool IsPointer = T->isAnyPointerType() || T->isMemberPointerType() ||2594 T->isReferenceType() || T->isBlockPointerType();2595 2596 switch (QMM) {2597 case QMM_Drop:2598 if (Quals.hasObjCLifetime())2599 Quals = Quals.withoutObjCLifetime();2600 break;2601 case QMM_Mangle:2602 if (const FunctionType *FT = dyn_cast<FunctionType>(T)) {2603 Out << '6';2604 mangleFunctionType(FT);2605 return;2606 }2607 mangleQualifiers(Quals, false);2608 break;2609 case QMM_Escape:2610 if (!IsPointer && Quals) {2611 Out << "$$C";2612 mangleQualifiers(Quals, false);2613 }2614 break;2615 case QMM_Result:2616 // Presence of __unaligned qualifier shouldn't affect mangling here.2617 Quals.removeUnaligned();2618 if (Quals.hasObjCLifetime())2619 Quals = Quals.withoutObjCLifetime();2620 if ((!IsPointer && Quals) || isa<TagType>(T) || isArtificialTagType(T)) {2621 Out << '?';2622 mangleQualifiers(Quals, false);2623 }2624 break;2625 }2626 2627 const Type *ty = T.getTypePtr();2628 2629 switch (ty->getTypeClass()) {2630#define ABSTRACT_TYPE(CLASS, PARENT)2631#define NON_CANONICAL_TYPE(CLASS, PARENT) \2632 case Type::CLASS: \2633 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \2634 return;2635#define TYPE(CLASS, PARENT) \2636 case Type::CLASS: \2637 mangleType(cast<CLASS##Type>(ty), Quals, Range); \2638 break;2639#include "clang/AST/TypeNodes.inc"2640#undef ABSTRACT_TYPE2641#undef NON_CANONICAL_TYPE2642#undef TYPE2643 }2644}2645 2646void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,2647 SourceRange Range) {2648 // <type> ::= <builtin-type>2649 // <builtin-type> ::= X # void2650 // ::= C # signed char2651 // ::= D # char2652 // ::= E # unsigned char2653 // ::= F # short2654 // ::= G # unsigned short (or wchar_t if it's not a builtin)2655 // ::= H # int2656 // ::= I # unsigned int2657 // ::= J # long2658 // ::= K # unsigned long2659 // L # <none>2660 // ::= M # float2661 // ::= N # double2662 // ::= O # long double (__float80 is mangled differently)2663 // ::= _J # long long, __int642664 // ::= _K # unsigned long long, __int642665 // ::= _L # __int1282666 // ::= _M # unsigned __int1282667 // ::= _N # bool2668 // _O # <array in parameter>2669 // ::= _Q # char8_t2670 // ::= _S # char16_t2671 // ::= _T # __float80 (Intel)2672 // ::= _U # char32_t2673 // ::= _W # wchar_t2674 // ::= _Z # __float80 (Digital Mars)2675 switch (T->getKind()) {2676 case BuiltinType::Void:2677 Out << 'X';2678 break;2679 case BuiltinType::SChar:2680 Out << 'C';2681 break;2682 case BuiltinType::Char_U:2683 case BuiltinType::Char_S:2684 Out << 'D';2685 break;2686 case BuiltinType::UChar:2687 Out << 'E';2688 break;2689 case BuiltinType::Short:2690 Out << 'F';2691 break;2692 case BuiltinType::UShort:2693 Out << 'G';2694 break;2695 case BuiltinType::Int:2696 Out << 'H';2697 break;2698 case BuiltinType::UInt:2699 Out << 'I';2700 break;2701 case BuiltinType::Long:2702 Out << 'J';2703 break;2704 case BuiltinType::ULong:2705 Out << 'K';2706 break;2707 case BuiltinType::Float:2708 Out << 'M';2709 break;2710 case BuiltinType::Double:2711 Out << 'N';2712 break;2713 // TODO: Determine size and mangle accordingly2714 case BuiltinType::LongDouble:2715 Out << 'O';2716 break;2717 case BuiltinType::LongLong:2718 Out << "_J";2719 break;2720 case BuiltinType::ULongLong:2721 Out << "_K";2722 break;2723 case BuiltinType::Int128:2724 Out << "_L";2725 break;2726 case BuiltinType::UInt128:2727 Out << "_M";2728 break;2729 case BuiltinType::Bool:2730 Out << "_N";2731 break;2732 case BuiltinType::Char8:2733 Out << "_Q";2734 break;2735 case BuiltinType::Char16:2736 Out << "_S";2737 break;2738 case BuiltinType::Char32:2739 Out << "_U";2740 break;2741 case BuiltinType::WChar_S:2742 case BuiltinType::WChar_U:2743 Out << "_W";2744 break;2745 2746#define BUILTIN_TYPE(Id, SingletonId)2747#define PLACEHOLDER_TYPE(Id, SingletonId) \2748 case BuiltinType::Id:2749#include "clang/AST/BuiltinTypes.def"2750 case BuiltinType::Dependent:2751 llvm_unreachable("placeholder types shouldn't get to name mangling");2752 2753 case BuiltinType::ObjCId:2754 mangleArtificialTagType(TagTypeKind::Struct, "objc_object");2755 break;2756 case BuiltinType::ObjCClass:2757 mangleArtificialTagType(TagTypeKind::Struct, "objc_class");2758 break;2759 case BuiltinType::ObjCSel:2760 mangleArtificialTagType(TagTypeKind::Struct, "objc_selector");2761 break;2762 2763#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \2764 case BuiltinType::Id: \2765 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \2766 break;2767#include "clang/Basic/OpenCLImageTypes.def"2768 case BuiltinType::OCLSampler:2769 Out << "PA";2770 mangleArtificialTagType(TagTypeKind::Struct, "ocl_sampler");2771 break;2772 case BuiltinType::OCLEvent:2773 Out << "PA";2774 mangleArtificialTagType(TagTypeKind::Struct, "ocl_event");2775 break;2776 case BuiltinType::OCLClkEvent:2777 Out << "PA";2778 mangleArtificialTagType(TagTypeKind::Struct, "ocl_clkevent");2779 break;2780 case BuiltinType::OCLQueue:2781 Out << "PA";2782 mangleArtificialTagType(TagTypeKind::Struct, "ocl_queue");2783 break;2784 case BuiltinType::OCLReserveID:2785 Out << "PA";2786 mangleArtificialTagType(TagTypeKind::Struct, "ocl_reserveid");2787 break;2788#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \2789 case BuiltinType::Id: \2790 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \2791 break;2792#include "clang/Basic/OpenCLExtensionTypes.def"2793 2794 case BuiltinType::NullPtr:2795 Out << "$$T";2796 break;2797 2798 case BuiltinType::Float16:2799 mangleArtificialTagType(TagTypeKind::Struct, "_Float16", {"__clang"});2800 break;2801 2802 case BuiltinType::Half:2803 if (!getASTContext().getLangOpts().HLSL)2804 mangleArtificialTagType(TagTypeKind::Struct, "_Half", {"__clang"});2805 else if (getASTContext().getLangOpts().NativeHalfType)2806 Out << "$f16@";2807 else2808 Out << "$halff@";2809 break;2810 2811 case BuiltinType::BFloat16:2812 mangleArtificialTagType(TagTypeKind::Struct, "__bf16", {"__clang"});2813 break;2814 2815 case BuiltinType::MFloat8:2816 mangleArtificialTagType(TagTypeKind::Struct, "__mfp8", {"__clang"});2817 break;2818 2819#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \2820 case BuiltinType::Id: \2821 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \2822 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \2823 break;2824 2825#include "clang/Basic/WebAssemblyReferenceTypes.def"2826 2827#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \2828 case BuiltinType::Id: \2829 mangleArtificialTagType(TagTypeKind::Struct, #Name); \2830 break;2831#include "clang/Basic/HLSLIntangibleTypes.def"2832 2833#define SVE_TYPE(Name, Id, SingletonId) \2834 case BuiltinType::Id: \2835 mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \2836 break;2837#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)2838#include "clang/Basic/AArch64ACLETypes.def"2839 2840 // Issue an error for any type not explicitly handled.2841 default:2842 Error(Range.getBegin(), "built-in type: ",2843 T->getName(Context.getASTContext().getPrintingPolicy()))2844 << Range;2845 break;2846 }2847}2848 2849// <type> ::= <function-type>2850void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers,2851 SourceRange) {2852 // Structors only appear in decls, so at this point we know it's not a2853 // structor type.2854 // FIXME: This may not be lambda-friendly.2855 if (T->getMethodQuals() || T->getRefQualifier() != RQ_None) {2856 Out << "$$A8@@";2857 mangleFunctionType(T, /*D=*/nullptr, /*ForceThisQuals=*/true);2858 } else {2859 Out << "$$A6";2860 mangleFunctionType(T);2861 }2862}2863void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,2864 Qualifiers, SourceRange) {2865 Out << "$$A6";2866 mangleFunctionType(T);2867}2868 2869void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,2870 const FunctionDecl *D,2871 bool ForceThisQuals,2872 bool MangleExceptionSpec) {2873 // <function-type> ::= <this-cvr-qualifiers> <calling-convention>2874 // <return-type> <argument-list> <throw-spec>2875 const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);2876 2877 SourceRange Range;2878 if (D) Range = D->getSourceRange();2879 2880 bool IsInLambda = false;2881 bool IsStructor = false, HasThisQuals = ForceThisQuals, IsCtorClosure = false;2882 CallingConv CC = T->getCallConv();2883 if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {2884 if (MD->getParent()->isLambda())2885 IsInLambda = true;2886 if (MD->isImplicitObjectMemberFunction())2887 HasThisQuals = true;2888 if (isa<CXXDestructorDecl>(MD)) {2889 IsStructor = true;2890 } else if (isa<CXXConstructorDecl>(MD)) {2891 IsStructor = true;2892 IsCtorClosure = (StructorType == Ctor_CopyingClosure ||2893 StructorType == Ctor_DefaultClosure) &&2894 isStructorDecl(MD);2895 if (IsCtorClosure)2896 CC = getASTContext().getDefaultCallingConvention(2897 /*IsVariadic=*/false, /*IsCXXMethod=*/true);2898 }2899 }2900 2901 // If this is a C++ instance method, mangle the CVR qualifiers for the2902 // this pointer.2903 if (HasThisQuals) {2904 Qualifiers Quals = Proto->getMethodQuals();2905 manglePointerExtQualifiers(Quals, /*PointeeType=*/QualType());2906 mangleRefQualifier(Proto->getRefQualifier());2907 mangleQualifiers(Quals, /*IsMember=*/false);2908 }2909 2910 mangleCallingConvention(CC, Range);2911 2912 // <return-type> ::= <type>2913 // ::= @ # structors (they have no declared return type)2914 if (IsStructor) {2915 if (isa<CXXDestructorDecl>(D) && isStructorDecl(D)) {2916 // The scalar deleting destructor takes an extra int argument which is not2917 // reflected in the AST.2918 if (StructorType == Dtor_Deleting) {2919 Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");2920 return;2921 }2922 // The vbase destructor returns void which is not reflected in the AST.2923 if (StructorType == Dtor_Complete) {2924 Out << "XXZ";2925 return;2926 }2927 }2928 if (IsCtorClosure) {2929 // Default constructor closure and copy constructor closure both return2930 // void.2931 Out << 'X';2932 2933 if (StructorType == Ctor_DefaultClosure) {2934 // Default constructor closure always has no arguments.2935 Out << 'X';2936 } else if (StructorType == Ctor_CopyingClosure) {2937 // Copy constructor closure always takes an unqualified reference.2938 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(2939 Proto->getParamType(0)2940 ->castAs<LValueReferenceType>()2941 ->getPointeeType(),2942 /*SpelledAsLValue=*/true),2943 Range);2944 Out << '@';2945 } else {2946 llvm_unreachable("unexpected constructor closure!");2947 }2948 Out << 'Z';2949 return;2950 }2951 Out << '@';2952 } else if (IsInLambda && isa_and_nonnull<CXXConversionDecl>(D)) {2953 // The only lambda conversion operators are to function pointers, which2954 // can differ by their calling convention and are typically deduced. So2955 // we make sure that this type gets mangled properly.2956 mangleType(T->getReturnType(), Range, QMM_Result);2957 } else {2958 QualType ResultType = T->getReturnType();2959 if (IsInLambda && isa<CXXConversionDecl>(D)) {2960 // The only lambda conversion operators are to function pointers, which2961 // can differ by their calling convention and are typically deduced. So2962 // we make sure that this type gets mangled properly.2963 mangleType(ResultType, Range, QMM_Result);2964 } else if (IsInLambda) {2965 if (const auto *AT = ResultType->getContainedAutoType()) {2966 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&2967 "shouldn't need to mangle __auto_type!");2968 Out << '?';2969 mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);2970 Out << '?';2971 mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");2972 Out << '@';2973 } else {2974 Out << '@';2975 }2976 } else if (const auto *AT = ResultType->getContainedAutoType()) {2977 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&2978 "shouldn't need to mangle __auto_type!");2979 2980 // If we have any pointer types with the clang address space extension2981 // then defer to the custom clang mangling to keep backwards2982 // compatibility. See `mangleType(const PointerType *T, Qualifiers Quals,2983 // SourceRange Range)` for details.2984 auto UseClangMangling = [](QualType ResultType) {2985 QualType T = ResultType;2986 while (isa<PointerType>(T.getTypePtr())) {2987 T = T->getPointeeType();2988 if (T.getQualifiers().hasAddressSpace())2989 return true;2990 }2991 return false;2992 };2993 2994 if (getASTContext().getLangOpts().isCompatibleWithMSVC(2995 LangOptions::MSVC2019) &&2996 !UseClangMangling(ResultType)) {2997 if (D && !D->getPrimaryTemplate()) {2998 Out << '@';2999 } else {3000 if (D && D->getPrimaryTemplate()) {3001 const FunctionProtoType *FPT = D->getPrimaryTemplate()3002 ->getTemplatedDecl()3003 ->getFirstDecl()3004 ->getType()3005 ->castAs<FunctionProtoType>();3006 ResultType = FPT->getReturnType();3007 }3008 mangleAutoReturnType(ResultType, QMM_Result);3009 }3010 } else {3011 Out << '?';3012 mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);3013 Out << '?';3014 mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");3015 Out << '@';3016 }3017 } else {3018 if (ResultType->isVoidType())3019 ResultType = ResultType.getUnqualifiedType();3020 mangleType(ResultType, Range, QMM_Result);3021 }3022 }3023 3024 // <argument-list> ::= X # void3025 // ::= <type>+ @3026 // ::= <type>* Z # varargs3027 if (!Proto) {3028 // Function types without prototypes can arise when mangling a function type3029 // within an overloadable function in C. We mangle these as the absence of3030 // any parameter types (not even an empty parameter list).3031 Out << '@';3032 } else if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {3033 Out << 'X';3034 } else {3035 // Happens for function pointer type arguments for example.3036 for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {3037 // Explicit object parameters are prefixed by "_V".3038 if (I == 0 && D && D->getParamDecl(I)->isExplicitObjectParameter())3039 Out << "_V";3040 3041 mangleFunctionArgumentType(Proto->getParamType(I), Range);3042 // Mangle each pass_object_size parameter as if it's a parameter of enum3043 // type passed directly after the parameter with the pass_object_size3044 // attribute. The aforementioned enum's name is __pass_object_size, and we3045 // pretend it resides in a top-level namespace called __clang.3046 //3047 // FIXME: Is there a defined extension notation for the MS ABI, or is it3048 // necessary to just cross our fingers and hope this type+namespace3049 // combination doesn't conflict with anything?3050 if (D)3051 if (const auto *P = D->getParamDecl(I)->getAttr<PassObjectSizeAttr>())3052 manglePassObjectSizeArg(P);3053 }3054 // <builtin-type> ::= Z # ellipsis3055 if (Proto->isVariadic())3056 Out << 'Z';3057 else3058 Out << '@';3059 }3060 3061 if (MangleExceptionSpec && getASTContext().getLangOpts().CPlusPlus17 &&3062 getASTContext().getLangOpts().isCompatibleWithMSVC(3063 LangOptions::MSVC2017_5))3064 mangleThrowSpecification(Proto);3065 else3066 Out << 'Z';3067}3068 3069void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {3070 // <function-class> ::= <member-function> E? # E designates a 64-bit 'this'3071 // # pointer. in 64-bit mode *all*3072 // # 'this' pointers are 64-bit.3073 // ::= <global-function>3074 // <member-function> ::= A # private: near3075 // ::= B # private: far3076 // ::= C # private: static near3077 // ::= D # private: static far3078 // ::= E # private: virtual near3079 // ::= F # private: virtual far3080 // ::= I # protected: near3081 // ::= J # protected: far3082 // ::= K # protected: static near3083 // ::= L # protected: static far3084 // ::= M # protected: virtual near3085 // ::= N # protected: virtual far3086 // ::= Q # public: near3087 // ::= R # public: far3088 // ::= S # public: static near3089 // ::= T # public: static far3090 // ::= U # public: virtual near3091 // ::= V # public: virtual far3092 // <global-function> ::= Y # global near3093 // ::= Z # global far3094 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {3095 bool IsVirtual = MD->isVirtual();3096 // When mangling vbase destructor variants, ignore whether or not the3097 // underlying destructor was defined to be virtual.3098 if (isa<CXXDestructorDecl>(MD) && isStructorDecl(MD) &&3099 StructorType == Dtor_Complete) {3100 IsVirtual = false;3101 }3102 switch (MD->getAccess()) {3103 case AS_none:3104 llvm_unreachable("Unsupported access specifier");3105 case AS_private:3106 if (!MD->isImplicitObjectMemberFunction())3107 Out << 'C';3108 else if (IsVirtual)3109 Out << 'E';3110 else3111 Out << 'A';3112 break;3113 case AS_protected:3114 if (!MD->isImplicitObjectMemberFunction())3115 Out << 'K';3116 else if (IsVirtual)3117 Out << 'M';3118 else3119 Out << 'I';3120 break;3121 case AS_public:3122 if (!MD->isImplicitObjectMemberFunction())3123 Out << 'S';3124 else if (IsVirtual)3125 Out << 'U';3126 else3127 Out << 'Q';3128 }3129 } else {3130 Out << 'Y';3131 }3132}3133void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC,3134 SourceRange Range) {3135 // <calling-convention> ::= A # __cdecl3136 // ::= B # __export __cdecl3137 // ::= C # __pascal3138 // ::= D # __export __pascal3139 // ::= E # __thiscall3140 // ::= F # __export __thiscall3141 // ::= G # __stdcall3142 // ::= H # __export __stdcall3143 // ::= I # __fastcall3144 // ::= J # __export __fastcall3145 // ::= Q # __vectorcall3146 // ::= S # __attribute__((__swiftcall__)) // Clang-only3147 // ::= W # __attribute__((__swiftasynccall__))3148 // ::= U # __attribute__((__preserve_most__))3149 // ::= V # __attribute__((__preserve_none__)) //3150 // Clang-only3151 // // Clang-only3152 // ::= w # __regcall3153 // ::= x # __regcall43154 // The 'export' calling conventions are from a bygone era3155 // (*cough*Win16*cough*) when functions were declared for export with3156 // that keyword. (It didn't actually export them, it just made them so3157 // that they could be in a DLL and somebody from another module could call3158 // them.)3159 3160 switch (CC) {3161 default:3162 break;3163 case CC_Win64:3164 case CC_X86_64SysV:3165 case CC_C:3166 Out << 'A';3167 return;3168 case CC_X86Pascal:3169 Out << 'C';3170 return;3171 case CC_X86ThisCall:3172 Out << 'E';3173 return;3174 case CC_X86StdCall:3175 Out << 'G';3176 return;3177 case CC_X86FastCall:3178 Out << 'I';3179 return;3180 case CC_X86VectorCall:3181 Out << 'Q';3182 return;3183 case CC_Swift:3184 Out << 'S';3185 return;3186 case CC_SwiftAsync:3187 Out << 'W';3188 return;3189 case CC_PreserveMost:3190 Out << 'U';3191 return;3192 case CC_PreserveNone:3193 Out << 'V';3194 return;3195 case CC_X86RegCall:3196 if (getASTContext().getLangOpts().RegCall4)3197 Out << "x";3198 else3199 Out << "w";3200 return;3201 }3202 3203 Error(Range.getBegin(), "calling convention") << Range;3204}3205void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,3206 SourceRange Range) {3207 mangleCallingConvention(T->getCallConv(), Range);3208}3209 3210void MicrosoftCXXNameMangler::mangleThrowSpecification(3211 const FunctionProtoType *FT) {3212 // <throw-spec> ::= Z # (default)3213 // ::= _E # noexcept3214 if (FT->canThrow())3215 Out << 'Z';3216 else3217 Out << "_E";3218}3219 3220void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,3221 Qualifiers, SourceRange Range) {3222 // Probably should be mangled as a template instantiation; need to see what3223 // VC does first.3224 Error(Range.getBegin(), "unresolved dependent type") << Range;3225}3226 3227// <type> ::= <union-type> | <struct-type> | <class-type> | <enum-type>3228// <union-type> ::= T <name>3229// <struct-type> ::= U <name>3230// <class-type> ::= V <name>3231// <enum-type> ::= W4 <name>3232void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {3233 switch (TTK) {3234 case TagTypeKind::Union:3235 Out << 'T';3236 break;3237 case TagTypeKind::Struct:3238 case TagTypeKind::Interface:3239 Out << 'U';3240 break;3241 case TagTypeKind::Class:3242 Out << 'V';3243 break;3244 case TagTypeKind::Enum:3245 Out << "W4";3246 break;3247 }3248}3249void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,3250 SourceRange) {3251 mangleType(cast<TagType>(T)->getDecl());3252}3253void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,3254 SourceRange) {3255 mangleType(cast<TagType>(T)->getDecl());3256}3257void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {3258 // MSVC chooses the tag kind of the definition if it exists, otherwise it3259 // always picks the first declaration.3260 const auto *Def = TD->getDefinition();3261 TD = Def ? Def : TD->getFirstDecl();3262 mangleTagTypeKind(TD->getTagKind());3263 mangleName(TD);3264}3265 3266// If you add a call to this, consider updating isArtificialTagType() too.3267void MicrosoftCXXNameMangler::mangleArtificialTagType(3268 TagTypeKind TK, StringRef UnqualifiedName,3269 ArrayRef<StringRef> NestedNames) {3270 // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @3271 mangleTagTypeKind(TK);3272 3273 // Always start with the unqualified name.3274 mangleSourceName(UnqualifiedName);3275 3276 for (StringRef N : llvm::reverse(NestedNames))3277 mangleSourceName(N);3278 3279 // Terminate the whole name with an '@'.3280 Out << '@';3281}3282 3283// <type> ::= <array-type>3284// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>3285// [Y <dimension-count> <dimension>+]3286// <element-type> # as global, E is never required3287// It's supposed to be the other way around, but for some strange reason, it3288// isn't. Today this behavior is retained for the sole purpose of backwards3289// compatibility.3290void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {3291 // This isn't a recursive mangling, so now we have to do it all in this3292 // one call.3293 manglePointerCVQualifiers(T->getElementType().getQualifiers());3294 mangleType(T->getElementType(), SourceRange());3295}3296void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, Qualifiers,3297 SourceRange) {3298 llvm_unreachable("Should have been special cased");3299}3300void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T, Qualifiers,3301 SourceRange) {3302 llvm_unreachable("Should have been special cased");3303}3304void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,3305 Qualifiers, SourceRange) {3306 llvm_unreachable("Should have been special cased");3307}3308void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,3309 Qualifiers, SourceRange) {3310 llvm_unreachable("Should have been special cased");3311}3312void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {3313 QualType ElementTy(T, 0);3314 SmallVector<llvm::APInt, 3> Dimensions;3315 for (;;) {3316 if (ElementTy->isConstantArrayType()) {3317 const ConstantArrayType *CAT =3318 getASTContext().getAsConstantArrayType(ElementTy);3319 Dimensions.push_back(CAT->getSize());3320 ElementTy = CAT->getElementType();3321 } else if (ElementTy->isIncompleteArrayType()) {3322 const IncompleteArrayType *IAT =3323 getASTContext().getAsIncompleteArrayType(ElementTy);3324 Dimensions.push_back(llvm::APInt(32, 0));3325 ElementTy = IAT->getElementType();3326 } else if (ElementTy->isVariableArrayType()) {3327 const VariableArrayType *VAT =3328 getASTContext().getAsVariableArrayType(ElementTy);3329 Dimensions.push_back(llvm::APInt(32, 0));3330 ElementTy = VAT->getElementType();3331 } else if (ElementTy->isDependentSizedArrayType()) {3332 // The dependent expression has to be folded into a constant (TODO).3333 const DependentSizedArrayType *DSAT =3334 getASTContext().getAsDependentSizedArrayType(ElementTy);3335 Error(DSAT->getSizeExpr()->getExprLoc(), "dependent-length")3336 << DSAT->getSizeExpr()->getSourceRange();3337 return;3338 } else {3339 break;3340 }3341 }3342 Out << 'Y';3343 // <dimension-count> ::= <number> # number of extra dimensions3344 mangleNumber(Dimensions.size());3345 for (const llvm::APInt &Dimension : Dimensions)3346 mangleNumber(Dimension.getLimitedValue());3347 mangleType(ElementTy, SourceRange(), QMM_Escape);3348}3349 3350void MicrosoftCXXNameMangler::mangleType(const ArrayParameterType *T,3351 Qualifiers, SourceRange) {3352 mangleArrayType(cast<ConstantArrayType>(T));3353}3354 3355// <type> ::= <pointer-to-member-type>3356// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>3357// <class name> <type>3358void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,3359 Qualifiers Quals, SourceRange Range) {3360 QualType PointeeType = T->getPointeeType();3361 manglePointerCVQualifiers(Quals);3362 manglePointerExtQualifiers(Quals, PointeeType);3363 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {3364 Out << '8';3365 mangleName(T->getMostRecentCXXRecordDecl());3366 mangleFunctionType(FPT, nullptr, true);3367 } else {3368 mangleQualifiers(PointeeType.getQualifiers(), true);3369 mangleName(T->getMostRecentCXXRecordDecl());3370 mangleType(PointeeType, Range, QMM_Drop);3371 }3372}3373 3374void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T,3375 Qualifiers, SourceRange Range) {3376 Out << '?';3377 3378 llvm::SmallString<64> Name;3379 Name += "<TTPT_";3380 Name += llvm::utostr(T->getDepth());3381 Name += "_";3382 Name += llvm::utostr(T->getIndex());3383 Name += ">";3384 mangleSourceName(Name);3385}3386 3387void MicrosoftCXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T,3388 Qualifiers, SourceRange Range) {3389 Error(Range.getBegin(), "substituted parameter pack") << Range;3390}3391 3392void MicrosoftCXXNameMangler::mangleType(const SubstBuiltinTemplatePackType *T,3393 Qualifiers, SourceRange Range) {3394 Error(Range.getBegin(), "substituted builtin template pack") << Range;3395}3396 3397// <type> ::= <pointer-type>3398// <pointer-type> ::= E? <pointer-cvr-qualifiers> <cvr-qualifiers> <type>3399// # the E is required for 64-bit non-static pointers3400void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals,3401 SourceRange Range) {3402 QualType PointeeType = T->getPointeeType();3403 manglePointerCVQualifiers(Quals);3404 manglePointerExtQualifiers(Quals, PointeeType);3405 manglePointerAuthQualifier(Quals);3406 3407 // For pointer size address spaces, go down the same type mangling path as3408 // non address space types.3409 LangAS AddrSpace = PointeeType.getQualifiers().getAddressSpace();3410 if (isPtrSizeAddressSpace(AddrSpace) || AddrSpace == LangAS::Default)3411 mangleType(PointeeType, Range);3412 else3413 mangleAddressSpaceType(PointeeType, PointeeType.getQualifiers(), Range);3414}3415 3416void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,3417 Qualifiers Quals, SourceRange Range) {3418 QualType PointeeType = T->getPointeeType();3419 switch (Quals.getObjCLifetime()) {3420 case Qualifiers::OCL_None:3421 case Qualifiers::OCL_ExplicitNone:3422 break;3423 case Qualifiers::OCL_Autoreleasing:3424 case Qualifiers::OCL_Strong:3425 case Qualifiers::OCL_Weak:3426 return mangleObjCLifetime(PointeeType, Quals, Range);3427 }3428 manglePointerCVQualifiers(Quals);3429 manglePointerExtQualifiers(Quals, PointeeType);3430 mangleType(PointeeType, Range);3431}3432 3433// <type> ::= <reference-type>3434// <reference-type> ::= A E? <cvr-qualifiers> <type>3435// # the E is required for 64-bit non-static lvalue references3436void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,3437 Qualifiers Quals, SourceRange Range) {3438 QualType PointeeType = T->getPointeeType();3439 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");3440 Out << 'A';3441 manglePointerExtQualifiers(Quals, PointeeType);3442 mangleType(PointeeType, Range);3443}3444 3445// <type> ::= <r-value-reference-type>3446// <r-value-reference-type> ::= $$Q E? <cvr-qualifiers> <type>3447// # the E is required for 64-bit non-static rvalue references3448void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,3449 Qualifiers Quals, SourceRange Range) {3450 QualType PointeeType = T->getPointeeType();3451 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");3452 Out << "$$Q";3453 manglePointerExtQualifiers(Quals, PointeeType);3454 mangleType(PointeeType, Range);3455}3456 3457void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers,3458 SourceRange Range) {3459 QualType ElementType = T->getElementType();3460 3461 llvm::SmallString<64> TemplateMangling;3462 llvm::raw_svector_ostream Stream(TemplateMangling);3463 MicrosoftCXXNameMangler Extra(Context, Stream);3464 Stream << "?$";3465 Extra.mangleSourceName("_Complex");3466 Extra.mangleType(ElementType, Range, QMM_Escape);3467 3468 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});3469}3470 3471// Returns true for types that mangleArtificialTagType() gets called for with3472// TagTypeKind Union, Struct, Class and where compatibility with MSVC's3473// mangling matters.3474// (It doesn't matter for Objective-C types and the like that cl.exe doesn't3475// support.)3476bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T) const {3477 const Type *ty = T.getTypePtr();3478 switch (ty->getTypeClass()) {3479 default:3480 return false;3481 3482 case Type::Vector: {3483 // For ABI compatibility only __m64, __m128(id), and __m256(id) matter,3484 // but since mangleType(VectorType*) always calls mangleArtificialTagType()3485 // just always return true (the other vector types are clang-only).3486 return true;3487 }3488 }3489}3490 3491void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,3492 SourceRange Range) {3493 QualType EltTy = T->getElementType();3494 const BuiltinType *ET = EltTy->getAs<BuiltinType>();3495 const BitIntType *BitIntTy = EltTy->getAs<BitIntType>();3496 assert((ET || BitIntTy) &&3497 "vectors with non-builtin/_BitInt elements are unsupported");3498 uint64_t Width = getASTContext().getTypeSize(T);3499 // Pattern match exactly the typedefs in our intrinsic headers. Anything that3500 // doesn't match the Intel types uses a custom mangling below.3501 size_t OutSizeBefore = Out.tell();3502 if (!isa<ExtVectorType>(T)) {3503 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {3504 if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {3505 mangleArtificialTagType(TagTypeKind::Union, "__m64");3506 } else if (Width >= 128) {3507 if (ET->getKind() == BuiltinType::Float)3508 mangleArtificialTagType(TagTypeKind::Union,3509 "__m" + llvm::utostr(Width));3510 else if (ET->getKind() == BuiltinType::LongLong)3511 mangleArtificialTagType(TagTypeKind::Union,3512 "__m" + llvm::utostr(Width) + 'i');3513 else if (ET->getKind() == BuiltinType::Double)3514 mangleArtificialTagType(TagTypeKind::Struct,3515 "__m" + llvm::utostr(Width) + 'd');3516 }3517 }3518 }3519 3520 bool IsBuiltin = Out.tell() != OutSizeBefore;3521 if (!IsBuiltin) {3522 // The MS ABI doesn't have a special mangling for vector types, so we define3523 // our own mangling to handle uses of __vector_size__ on user-specified3524 // types, and for extensions like __v4sf.3525 3526 llvm::SmallString<64> TemplateMangling;3527 llvm::raw_svector_ostream Stream(TemplateMangling);3528 MicrosoftCXXNameMangler Extra(Context, Stream);3529 Stream << "?$";3530 Extra.mangleSourceName("__vector");3531 Extra.mangleType(QualType(ET ? static_cast<const Type *>(ET) : BitIntTy, 0),3532 Range, QMM_Escape);3533 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()));3534 3535 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {"__clang"});3536 }3537}3538 3539void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,3540 Qualifiers Quals, SourceRange Range) {3541 mangleType(static_cast<const VectorType *>(T), Quals, Range);3542}3543 3544void MicrosoftCXXNameMangler::mangleType(const DependentVectorType *T,3545 Qualifiers, SourceRange Range) {3546 Error(Range.getBegin(), "dependent-sized vector type") << Range;3547}3548 3549void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,3550 Qualifiers, SourceRange Range) {3551 Error(Range.getBegin(), "dependent-sized extended vector type") << Range;3552}3553 3554void MicrosoftCXXNameMangler::mangleType(const ConstantMatrixType *T,3555 Qualifiers quals, SourceRange Range) {3556 QualType EltTy = T->getElementType();3557 3558 llvm::SmallString<64> TemplateMangling;3559 llvm::raw_svector_ostream Stream(TemplateMangling);3560 MicrosoftCXXNameMangler Extra(Context, Stream);3561 3562 Stream << "?$";3563 3564 Extra.mangleSourceName("__matrix");3565 Extra.mangleType(EltTy, Range, QMM_Escape);3566 3567 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumRows()));3568 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumColumns()));3569 3570 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});3571}3572 3573void MicrosoftCXXNameMangler::mangleType(const DependentSizedMatrixType *T,3574 Qualifiers quals, SourceRange Range) {3575 Error(Range.getBegin(), "dependent-sized matrix type") << Range;3576}3577 3578void MicrosoftCXXNameMangler::mangleType(const DependentAddressSpaceType *T,3579 Qualifiers, SourceRange Range) {3580 Error(Range.getBegin(), "dependent address space type") << Range;3581}3582 3583void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,3584 SourceRange) {3585 // ObjC interfaces have structs underlying them.3586 mangleTagTypeKind(TagTypeKind::Struct);3587 mangleName(T->getDecl());3588}3589 3590void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,3591 Qualifiers Quals, SourceRange Range) {3592 if (T->isKindOfType())3593 return mangleObjCKindOfType(T, Quals, Range);3594 3595 if (T->qual_empty() && !T->isSpecialized())3596 return mangleType(T->getBaseType(), Range, QMM_Drop);3597 3598 ArgBackRefMap OuterFunArgsContext;3599 ArgBackRefMap OuterTemplateArgsContext;3600 BackRefVec OuterTemplateContext;3601 3602 FunArgBackReferences.swap(OuterFunArgsContext);3603 TemplateArgBackReferences.swap(OuterTemplateArgsContext);3604 NameBackReferences.swap(OuterTemplateContext);3605 3606 mangleTagTypeKind(TagTypeKind::Struct);3607 3608 Out << "?$";3609 if (T->isObjCId())3610 mangleSourceName("objc_object");3611 else if (T->isObjCClass())3612 mangleSourceName("objc_class");3613 else3614 mangleSourceName(T->getInterface()->getName());3615 3616 for (const auto &Q : T->quals())3617 mangleObjCProtocol(Q);3618 3619 if (T->isSpecialized())3620 for (const auto &TA : T->getTypeArgs())3621 mangleType(TA, Range, QMM_Drop);3622 3623 Out << '@';3624 3625 Out << '@';3626 3627 FunArgBackReferences.swap(OuterFunArgsContext);3628 TemplateArgBackReferences.swap(OuterTemplateArgsContext);3629 NameBackReferences.swap(OuterTemplateContext);3630}3631 3632void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,3633 Qualifiers Quals, SourceRange Range) {3634 QualType PointeeType = T->getPointeeType();3635 manglePointerCVQualifiers(Quals);3636 manglePointerExtQualifiers(Quals, PointeeType);3637 3638 Out << "_E";3639 3640 mangleFunctionType(PointeeType->castAs<FunctionProtoType>());3641}3642 3643void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *,3644 Qualifiers, SourceRange) {3645 llvm_unreachable("Cannot mangle injected class name type.");3646}3647 3648void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T,3649 Qualifiers, SourceRange Range) {3650 Error(Range.getBegin(), "template specialization type") << Range;3651}3652 3653void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, Qualifiers,3654 SourceRange Range) {3655 Error(Range.getBegin(), "dependent name type") << Range;3656}3657 3658void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, Qualifiers,3659 SourceRange Range) {3660 Error(Range.getBegin(), "pack expansion") << Range;3661}3662 3663void MicrosoftCXXNameMangler::mangleType(const PackIndexingType *T,3664 Qualifiers Quals, SourceRange Range) {3665 manglePointerCVQualifiers(Quals);3666 mangleType(T->getSelectedType(), Range);3667}3668 3669void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, Qualifiers,3670 SourceRange Range) {3671 Error(Range.getBegin(), "typeof(type)") << Range;3672}3673 3674void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, Qualifiers,3675 SourceRange Range) {3676 Error(Range.getBegin(), "typeof(expression)") << Range;3677}3678 3679void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, Qualifiers,3680 SourceRange Range) {3681 Error(Range.getBegin(), "decltype()") << Range;3682}3683 3684void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,3685 Qualifiers, SourceRange Range) {3686 Error(Range.getBegin(), "unary transform type") << Range;3687}3688 3689void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers,3690 SourceRange Range) {3691 assert(T->getDeducedType().isNull() && "expecting a dependent type!");3692 3693 Error(Range.getBegin(), "'auto' type") << Range;3694}3695 3696void MicrosoftCXXNameMangler::mangleType(3697 const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {3698 assert(T->getDeducedType().isNull() && "expecting a dependent type!");3699 3700 Error(Range.getBegin(), "deduced class template specialization type")3701 << Range;3702}3703 3704void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,3705 SourceRange Range) {3706 QualType ValueType = T->getValueType();3707 3708 llvm::SmallString<64> TemplateMangling;3709 llvm::raw_svector_ostream Stream(TemplateMangling);3710 MicrosoftCXXNameMangler Extra(Context, Stream);3711 Stream << "?$";3712 Extra.mangleSourceName("_Atomic");3713 Extra.mangleType(ValueType, Range, QMM_Escape);3714 3715 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});3716}3717 3718void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers,3719 SourceRange Range) {3720 QualType ElementType = T->getElementType();3721 3722 llvm::SmallString<64> TemplateMangling;3723 llvm::raw_svector_ostream Stream(TemplateMangling);3724 MicrosoftCXXNameMangler Extra(Context, Stream);3725 Stream << "?$";3726 Extra.mangleSourceName("ocl_pipe");3727 Extra.mangleType(ElementType, Range, QMM_Escape);3728 Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()));3729 3730 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});3731}3732 3733void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,3734 raw_ostream &Out) {3735 const NamedDecl *D = cast<NamedDecl>(GD.getDecl());3736 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),3737 getASTContext().getSourceManager(),3738 "Mangling declaration");3739 3740 msvc_hashing_ostream MHO(Out);3741 3742 if (auto *CD = dyn_cast<CXXConstructorDecl>(D)) {3743 auto Type = GD.getCtorType();3744 MicrosoftCXXNameMangler mangler(*this, MHO, CD, Type);3745 return mangler.mangle(GD);3746 }3747 3748 if (auto *DD = dyn_cast<CXXDestructorDecl>(D)) {3749 auto Type = GD.getDtorType();3750 MicrosoftCXXNameMangler mangler(*this, MHO, DD, Type);3751 return mangler.mangle(GD);3752 }3753 3754 MicrosoftCXXNameMangler Mangler(*this, MHO);3755 return Mangler.mangle(GD);3756}3757 3758void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers,3759 SourceRange Range) {3760 llvm::SmallString<64> TemplateMangling;3761 llvm::raw_svector_ostream Stream(TemplateMangling);3762 MicrosoftCXXNameMangler Extra(Context, Stream);3763 Stream << "?$";3764 if (T->isUnsigned())3765 Extra.mangleSourceName("_UBitInt");3766 else3767 Extra.mangleSourceName("_BitInt");3768 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));3769 3770 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});3771}3772 3773void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,3774 Qualifiers, SourceRange Range) {3775 Error(Range.getBegin(), "DependentBitInt type") << Range;3776}3777 3778void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,3779 Qualifiers, SourceRange Range) {3780 llvm_unreachable("HLSL uses Itanium name mangling");3781}3782 3783void MicrosoftCXXNameMangler::mangleType(const HLSLInlineSpirvType *T,3784 Qualifiers, SourceRange Range) {3785 llvm_unreachable("HLSL uses Itanium name mangling");3786}3787 3788// <this-adjustment> ::= <no-adjustment> | <static-adjustment> |3789// <virtual-adjustment>3790// <no-adjustment> ::= A # private near3791// ::= B # private far3792// ::= I # protected near3793// ::= J # protected far3794// ::= Q # public near3795// ::= R # public far3796// <static-adjustment> ::= G <static-offset> # private near3797// ::= H <static-offset> # private far3798// ::= O <static-offset> # protected near3799// ::= P <static-offset> # protected far3800// ::= W <static-offset> # public near3801// ::= X <static-offset> # public far3802// <virtual-adjustment> ::= $0 <virtual-shift> <static-offset> # private near3803// ::= $1 <virtual-shift> <static-offset> # private far3804// ::= $2 <virtual-shift> <static-offset> # protected near3805// ::= $3 <virtual-shift> <static-offset> # protected far3806// ::= $4 <virtual-shift> <static-offset> # public near3807// ::= $5 <virtual-shift> <static-offset> # public far3808// <virtual-shift> ::= <vtordisp-shift> | <vtordispex-shift>3809// <vtordisp-shift> ::= <offset-to-vtordisp>3810// <vtordispex-shift> ::= <offset-to-vbptr> <vbase-offset-offset>3811// <offset-to-vtordisp>3812static void mangleThunkThisAdjustment(AccessSpecifier AS,3813 const ThisAdjustment &Adjustment,3814 MicrosoftCXXNameMangler &Mangler,3815 raw_ostream &Out) {3816 if (!Adjustment.Virtual.isEmpty()) {3817 Out << '$';3818 char AccessSpec;3819 switch (AS) {3820 case AS_none:3821 llvm_unreachable("Unsupported access specifier");3822 case AS_private:3823 AccessSpec = '0';3824 break;3825 case AS_protected:3826 AccessSpec = '2';3827 break;3828 case AS_public:3829 AccessSpec = '4';3830 }3831 if (Adjustment.Virtual.Microsoft.VBPtrOffset) {3832 Out << 'R' << AccessSpec;3833 Mangler.mangleNumber(3834 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBPtrOffset));3835 Mangler.mangleNumber(3836 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBOffsetOffset));3837 Mangler.mangleNumber(3838 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));3839 Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.NonVirtual));3840 } else {3841 Out << AccessSpec;3842 Mangler.mangleNumber(3843 static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset));3844 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));3845 }3846 } else if (Adjustment.NonVirtual != 0) {3847 switch (AS) {3848 case AS_none:3849 llvm_unreachable("Unsupported access specifier");3850 case AS_private:3851 Out << 'G';3852 break;3853 case AS_protected:3854 Out << 'O';3855 break;3856 case AS_public:3857 Out << 'W';3858 }3859 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));3860 } else {3861 switch (AS) {3862 case AS_none:3863 llvm_unreachable("Unsupported access specifier");3864 case AS_private:3865 Out << 'A';3866 break;3867 case AS_protected:3868 Out << 'I';3869 break;3870 case AS_public:3871 Out << 'Q';3872 }3873 }3874}3875 3876void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(3877 const CXXMethodDecl *MD, const MethodVFTableLocation &ML,3878 raw_ostream &Out) {3879 msvc_hashing_ostream MHO(Out);3880 MicrosoftCXXNameMangler Mangler(*this, MHO);3881 Mangler.getStream() << '?';3882 Mangler.mangleVirtualMemPtrThunk(MD, ML);3883}3884 3885void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,3886 const ThunkInfo &Thunk,3887 bool /*ElideOverrideInfo*/,3888 raw_ostream &Out) {3889 msvc_hashing_ostream MHO(Out);3890 MicrosoftCXXNameMangler Mangler(*this, MHO);3891 Mangler.getStream() << '?';3892 Mangler.mangleName(MD);3893 3894 // Usually the thunk uses the access specifier of the new method, but if this3895 // is a covariant return thunk, then MSVC always uses the public access3896 // specifier, and we do the same.3897 AccessSpecifier AS = Thunk.Return.isEmpty() ? MD->getAccess() : AS_public;3898 mangleThunkThisAdjustment(AS, Thunk.This, Mangler, MHO);3899 3900 if (!Thunk.Return.isEmpty())3901 assert(Thunk.Method != nullptr &&3902 "Thunk info should hold the overridee decl");3903 3904 const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;3905 Mangler.mangleFunctionType(3906 DeclForFPT->getType()->castAs<FunctionProtoType>(), MD);3907}3908 3909void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,3910 CXXDtorType Type,3911 const ThunkInfo &Thunk,3912 bool /*ElideOverrideInfo*/,3913 raw_ostream &Out) {3914 // FIXME: Actually, the dtor thunk should be emitted for vector deleting3915 // dtors rather than scalar deleting dtors. Just use the vector deleting dtor3916 // mangling manually until we support both deleting dtor types.3917 assert(Type == Dtor_Deleting);3918 msvc_hashing_ostream MHO(Out);3919 MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type);3920 Mangler.getStream() << "??_E";3921 Mangler.mangleName(DD->getParent());3922 auto &Adjustment = Thunk.This;3923 mangleThunkThisAdjustment(DD->getAccess(), Adjustment, Mangler, MHO);3924 Mangler.mangleFunctionType(DD->getType()->castAs<FunctionProtoType>(), DD);3925}3926 3927void MicrosoftMangleContextImpl::mangleCXXVFTable(3928 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,3929 raw_ostream &Out) {3930 // <mangled-name> ::= ?_7 <class-name> <storage-class>3931 // <cvr-qualifiers> [<name>] @3932 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>3933 // is always '6' for vftables.3934 msvc_hashing_ostream MHO(Out);3935 MicrosoftCXXNameMangler Mangler(*this, MHO);3936 if (Derived->hasAttr<DLLImportAttr>())3937 Mangler.getStream() << "??_S";3938 else3939 Mangler.getStream() << "??_7";3940 Mangler.mangleName(Derived);3941 Mangler.getStream() << "6B"; // '6' for vftable, 'B' for const.3942 for (const CXXRecordDecl *RD : BasePath)3943 Mangler.mangleName(RD);3944 Mangler.getStream() << '@';3945}3946 3947void MicrosoftMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *Derived,3948 raw_ostream &Out) {3949 // TODO: Determine appropriate mangling for MSABI3950 mangleCXXVFTable(Derived, {}, Out);3951}3952 3953void MicrosoftMangleContextImpl::mangleCXXVBTable(3954 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,3955 raw_ostream &Out) {3956 // <mangled-name> ::= ?_8 <class-name> <storage-class>3957 // <cvr-qualifiers> [<name>] @3958 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>3959 // is always '7' for vbtables.3960 msvc_hashing_ostream MHO(Out);3961 MicrosoftCXXNameMangler Mangler(*this, MHO);3962 Mangler.getStream() << "??_8";3963 Mangler.mangleName(Derived);3964 Mangler.getStream() << "7B"; // '7' for vbtable, 'B' for const.3965 for (const CXXRecordDecl *RD : BasePath)3966 Mangler.mangleName(RD);3967 Mangler.getStream() << '@';3968}3969 3970void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {3971 msvc_hashing_ostream MHO(Out);3972 MicrosoftCXXNameMangler Mangler(*this, MHO);3973 Mangler.getStream() << "??_R0";3974 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);3975 Mangler.getStream() << "@8";3976}3977 3978void MicrosoftMangleContextImpl::mangleCXXRTTIName(3979 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {3980 MicrosoftCXXNameMangler Mangler(*this, Out);3981 Mangler.getStream() << '.';3982 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);3983}3984 3985void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(3986 const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out) {3987 msvc_hashing_ostream MHO(Out);3988 MicrosoftCXXNameMangler Mangler(*this, MHO);3989 Mangler.getStream() << "??_K";3990 Mangler.mangleName(SrcRD);3991 Mangler.getStream() << "$C";3992 Mangler.mangleName(DstRD);3993}3994 3995void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst,3996 bool IsVolatile,3997 bool IsUnaligned,3998 uint32_t NumEntries,3999 raw_ostream &Out) {4000 msvc_hashing_ostream MHO(Out);4001 MicrosoftCXXNameMangler Mangler(*this, MHO);4002 Mangler.getStream() << "_TI";4003 if (IsConst)4004 Mangler.getStream() << 'C';4005 if (IsVolatile)4006 Mangler.getStream() << 'V';4007 if (IsUnaligned)4008 Mangler.getStream() << 'U';4009 Mangler.getStream() << NumEntries;4010 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);4011}4012 4013void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(4014 QualType T, uint32_t NumEntries, raw_ostream &Out) {4015 msvc_hashing_ostream MHO(Out);4016 MicrosoftCXXNameMangler Mangler(*this, MHO);4017 Mangler.getStream() << "_CTA";4018 Mangler.getStream() << NumEntries;4019 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);4020}4021 4022void MicrosoftMangleContextImpl::mangleCXXCatchableType(4023 QualType T, const CXXConstructorDecl *CD, CXXCtorType CT, uint32_t Size,4024 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,4025 raw_ostream &Out) {4026 MicrosoftCXXNameMangler Mangler(*this, Out);4027 Mangler.getStream() << "_CT";4028 4029 llvm::SmallString<64> RTTIMangling;4030 {4031 llvm::raw_svector_ostream Stream(RTTIMangling);4032 msvc_hashing_ostream MHO(Stream);4033 mangleCXXRTTI(T, MHO);4034 }4035 Mangler.getStream() << RTTIMangling;4036 4037 // VS2015 and VS2017.1 omit the copy-constructor in the mangled name but4038 // both older and newer versions include it.4039 // FIXME: It is known that the Ctor is present in 2013, and in 2017.74040 // (_MSC_VER 1914) and newer, and that it's omitted in 2015 and 2017.44041 // (_MSC_VER 1911), but it's unknown when exactly it reappeared (1914?4042 // Or 1912, 1913 already?).4043 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(4044 LangOptions::MSVC2015) &&4045 !getASTContext().getLangOpts().isCompatibleWithMSVC(4046 LangOptions::MSVC2017_7);4047 llvm::SmallString<64> CopyCtorMangling;4048 if (!OmitCopyCtor && CD) {4049 llvm::raw_svector_ostream Stream(CopyCtorMangling);4050 msvc_hashing_ostream MHO(Stream);4051 mangleCXXName(GlobalDecl(CD, CT), MHO);4052 }4053 Mangler.getStream() << CopyCtorMangling;4054 4055 Mangler.getStream() << Size;4056 if (VBPtrOffset == -1) {4057 if (NVOffset) {4058 Mangler.getStream() << NVOffset;4059 }4060 } else {4061 Mangler.getStream() << NVOffset;4062 Mangler.getStream() << VBPtrOffset;4063 Mangler.getStream() << VBIndex;4064 }4065}4066 4067void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(4068 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,4069 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {4070 msvc_hashing_ostream MHO(Out);4071 MicrosoftCXXNameMangler Mangler(*this, MHO);4072 Mangler.getStream() << "??_R1";4073 Mangler.mangleNumber(NVOffset);4074 Mangler.mangleNumber(VBPtrOffset);4075 Mangler.mangleNumber(VBTableOffset);4076 Mangler.mangleNumber(Flags);4077 Mangler.mangleName(Derived);4078 Mangler.getStream() << "8";4079}4080 4081void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(4082 const CXXRecordDecl *Derived, raw_ostream &Out) {4083 msvc_hashing_ostream MHO(Out);4084 MicrosoftCXXNameMangler Mangler(*this, MHO);4085 Mangler.getStream() << "??_R2";4086 Mangler.mangleName(Derived);4087 Mangler.getStream() << "8";4088}4089 4090void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(4091 const CXXRecordDecl *Derived, raw_ostream &Out) {4092 msvc_hashing_ostream MHO(Out);4093 MicrosoftCXXNameMangler Mangler(*this, MHO);4094 Mangler.getStream() << "??_R3";4095 Mangler.mangleName(Derived);4096 Mangler.getStream() << "8";4097}4098 4099void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(4100 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,4101 raw_ostream &Out) {4102 // <mangled-name> ::= ?_R4 <class-name> <storage-class>4103 // <cvr-qualifiers> [<name>] @4104 // NOTE: <cvr-qualifiers> here is always 'B' (const). <storage-class>4105 // is always '6' for vftables.4106 llvm::SmallString<64> VFTableMangling;4107 llvm::raw_svector_ostream Stream(VFTableMangling);4108 mangleCXXVFTable(Derived, BasePath, Stream);4109 4110 if (VFTableMangling.starts_with("??@")) {4111 assert(VFTableMangling.ends_with("@"));4112 Out << VFTableMangling << "??_R4@";4113 return;4114 }4115 4116 assert(VFTableMangling.starts_with("??_7") ||4117 VFTableMangling.starts_with("??_S"));4118 4119 Out << "??_R4" << VFTableMangling.str().drop_front(4);4120}4121 4122void MicrosoftMangleContextImpl::mangleSEHFilterExpression(4123 GlobalDecl EnclosingDecl, raw_ostream &Out) {4124 msvc_hashing_ostream MHO(Out);4125 MicrosoftCXXNameMangler Mangler(*this, MHO);4126 // The function body is in the same comdat as the function with the handler,4127 // so the numbering here doesn't have to be the same across TUs.4128 //4129 // <mangled-name> ::= ?filt$ <filter-number> @04130 Mangler.getStream() << "?filt$" << SEHFilterIds[EnclosingDecl]++ << "@0@";4131 Mangler.mangleName(EnclosingDecl);4132}4133 4134void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(4135 GlobalDecl EnclosingDecl, raw_ostream &Out) {4136 msvc_hashing_ostream MHO(Out);4137 MicrosoftCXXNameMangler Mangler(*this, MHO);4138 // The function body is in the same comdat as the function with the handler,4139 // so the numbering here doesn't have to be the same across TUs.4140 //4141 // <mangled-name> ::= ?fin$ <filter-number> @04142 Mangler.getStream() << "?fin$" << SEHFinallyIds[EnclosingDecl]++ << "@0@";4143 Mangler.mangleName(EnclosingDecl);4144}4145 4146void MicrosoftMangleContextImpl::mangleCanonicalTypeName(4147 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {4148 // This is just a made up unique string for the purposes of tbaa. undname4149 // does *not* know how to demangle it.4150 MicrosoftCXXNameMangler Mangler(*this, Out);4151 Mangler.getStream() << '?';4152 Mangler.mangleType(T.getCanonicalType(), SourceRange());4153}4154 4155void MicrosoftMangleContextImpl::mangleReferenceTemporary(4156 const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) {4157 msvc_hashing_ostream MHO(Out);4158 MicrosoftCXXNameMangler Mangler(*this, MHO);4159 4160 Mangler.getStream() << "?";4161 Mangler.mangleSourceName("$RT" + llvm::utostr(ManglingNumber));4162 Mangler.mangle(VD, "");4163}4164 4165void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(4166 const VarDecl *VD, unsigned GuardNum, raw_ostream &Out) {4167 msvc_hashing_ostream MHO(Out);4168 MicrosoftCXXNameMangler Mangler(*this, MHO);4169 4170 Mangler.getStream() << "?";4171 Mangler.mangleSourceName("$TSS" + llvm::utostr(GuardNum));4172 Mangler.mangleNestedName(VD);4173 Mangler.getStream() << "@4HA";4174}4175 4176void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,4177 raw_ostream &Out) {4178 // <guard-name> ::= ?_B <postfix> @5 <scope-depth>4179 // ::= ?__J <postfix> @5 <scope-depth>4180 // ::= ?$S <guard-num> @ <postfix> @4IA4181 4182 // The first mangling is what MSVC uses to guard static locals in inline4183 // functions. It uses a different mangling in external functions to support4184 // guarding more than 32 variables. MSVC rejects inline functions with more4185 // than 32 static locals. We don't fully implement the second mangling4186 // because those guards are not externally visible, and instead use LLVM's4187 // default renaming when creating a new guard variable.4188 msvc_hashing_ostream MHO(Out);4189 MicrosoftCXXNameMangler Mangler(*this, MHO);4190 4191 bool Visible = VD->isExternallyVisible();4192 if (Visible) {4193 Mangler.getStream() << (VD->getTLSKind() ? "??__J" : "??_B");4194 } else {4195 Mangler.getStream() << "?$S1@";4196 }4197 unsigned ScopeDepth = 0;4198 if (Visible && !getNextDiscriminator(VD, ScopeDepth))4199 // If we do not have a discriminator and are emitting a guard variable for4200 // use at global scope, then mangling the nested name will not be enough to4201 // remove ambiguities.4202 Mangler.mangle(VD, "");4203 else4204 Mangler.mangleNestedName(VD);4205 Mangler.getStream() << (Visible ? "@5" : "@4IA");4206 if (ScopeDepth)4207 Mangler.mangleNumber(ScopeDepth);4208}4209 4210void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,4211 char CharCode,4212 raw_ostream &Out) {4213 msvc_hashing_ostream MHO(Out);4214 MicrosoftCXXNameMangler Mangler(*this, MHO);4215 Mangler.getStream() << "??__" << CharCode;4216 if (D->isStaticDataMember()) {4217 Mangler.getStream() << '?';4218 Mangler.mangleName(D);4219 Mangler.mangleVariableEncoding(D);4220 Mangler.getStream() << "@@";4221 } else {4222 Mangler.mangleName(D);4223 }4224 // This is the function class mangling. These stubs are global, non-variadic,4225 // cdecl functions that return void and take no args.4226 Mangler.getStream() << "YAXXZ";4227}4228 4229void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D,4230 raw_ostream &Out) {4231 // <initializer-name> ::= ?__E <name> YAXXZ4232 mangleInitFiniStub(D, 'E', Out);4233}4234 4235void4236MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,4237 raw_ostream &Out) {4238 // <destructor-name> ::= ?__F <name> YAXXZ4239 mangleInitFiniStub(D, 'F', Out);4240}4241 4242void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,4243 raw_ostream &Out) {4244 // <char-type> ::= 0 # char, char16_t, char32_t4245 // # (little endian char data in mangling)4246 // ::= 1 # wchar_t (big endian char data in mangling)4247 //4248 // <literal-length> ::= <non-negative integer> # the length of the literal4249 //4250 // <encoded-crc> ::= <hex digit>+ @ # crc of the literal including4251 // # trailing null bytes4252 //4253 // <encoded-string> ::= <simple character> # uninteresting character4254 // ::= '?$' <hex digit> <hex digit> # these two nibbles4255 // # encode the byte for the4256 // # character4257 // ::= '?' [a-z] # \xe1 - \xfa4258 // ::= '?' [A-Z] # \xc1 - \xda4259 // ::= '?' [0-9] # [,/\:. \n\t'-]4260 //4261 // <literal> ::= '??_C@_' <char-type> <literal-length> <encoded-crc>4262 // <encoded-string> '@'4263 MicrosoftCXXNameMangler Mangler(*this, Out);4264 Mangler.getStream() << "??_C@_";4265 4266 // The actual string length might be different from that of the string literal4267 // in cases like:4268 // char foo[3] = "foobar";4269 // char bar[42] = "foobar";4270 // Where it is truncated or zero-padded to fit the array. This is the length4271 // used for mangling, and any trailing null-bytes also need to be mangled.4272 unsigned StringLength =4273 getASTContext().getAsConstantArrayType(SL->getType())->getZExtSize();4274 unsigned StringByteLength = StringLength * SL->getCharByteWidth();4275 4276 // <char-type>: The "kind" of string literal is encoded into the mangled name.4277 if (SL->isWide())4278 Mangler.getStream() << '1';4279 else4280 Mangler.getStream() << '0';4281 4282 // <literal-length>: The next part of the mangled name consists of the length4283 // of the string in bytes.4284 Mangler.mangleNumber(StringByteLength);4285 4286 auto GetLittleEndianByte = [&SL](unsigned Index) {4287 unsigned CharByteWidth = SL->getCharByteWidth();4288 if (Index / CharByteWidth >= SL->getLength())4289 return static_cast<char>(0);4290 uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);4291 unsigned OffsetInCodeUnit = Index % CharByteWidth;4292 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);4293 };4294 4295 auto GetBigEndianByte = [&SL](unsigned Index) {4296 unsigned CharByteWidth = SL->getCharByteWidth();4297 if (Index / CharByteWidth >= SL->getLength())4298 return static_cast<char>(0);4299 uint32_t CodeUnit = SL->getCodeUnit(Index / CharByteWidth);4300 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);4301 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);4302 };4303 4304 // CRC all the bytes of the StringLiteral.4305 llvm::JamCRC JC;4306 for (unsigned I = 0, E = StringByteLength; I != E; ++I)4307 JC.update(GetLittleEndianByte(I));4308 4309 // <encoded-crc>: The CRC is encoded utilizing the standard number mangling4310 // scheme.4311 Mangler.mangleNumber(JC.getCRC());4312 4313 // <encoded-string>: The mangled name also contains the first 32 bytes4314 // (including null-terminator bytes) of the encoded StringLiteral.4315 // Each character is encoded by splitting them into bytes and then encoding4316 // the constituent bytes.4317 auto MangleByte = [&Mangler](char Byte) {4318 // There are five different manglings for characters:4319 // - [a-zA-Z0-9_$]: A one-to-one mapping.4320 // - ?[a-z]: The range from \xe1 to \xfa.4321 // - ?[A-Z]: The range from \xc1 to \xda.4322 // - ?[0-9]: The set of [,/\:. \n\t'-].4323 // - ?$XX: A fallback which maps nibbles.4324 if (isAsciiIdentifierContinue(Byte, /*AllowDollar=*/true)) {4325 Mangler.getStream() << Byte;4326 } else if (isLetter(Byte & 0x7f)) {4327 Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);4328 } else {4329 const char SpecialChars[] = {',', '/', '\\', ':', '.',4330 ' ', '\n', '\t', '\'', '-'};4331 const char *Pos = llvm::find(SpecialChars, Byte);4332 if (Pos != std::end(SpecialChars)) {4333 Mangler.getStream() << '?' << (Pos - std::begin(SpecialChars));4334 } else {4335 Mangler.getStream() << "?$";4336 Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf));4337 Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf));4338 }4339 }4340 };4341 4342 // Enforce our 32 bytes max, except wchar_t which gets 32 chars instead.4343 unsigned MaxBytesToMangle = SL->isWide() ? 64U : 32U;4344 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);4345 for (unsigned I = 0; I != NumBytesToMangle; ++I) {4346 if (SL->isWide())4347 MangleByte(GetBigEndianByte(I));4348 else4349 MangleByte(GetLittleEndianByte(I));4350 }4351 4352 Mangler.getStream() << '@';4353}4354 4355void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,4356 Qualifiers Quals) {4357 QualType PointeeType = T->getPointeeType();4358 manglePointerCVQualifiers(Quals);4359 manglePointerExtQualifiers(Quals, PointeeType);4360 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {4361 Out << '8';4362 mangleName(T->getMostRecentCXXRecordDecl());4363 mangleFunctionType(FPT, nullptr, true);4364 } else {4365 mangleQualifiers(PointeeType.getQualifiers(), true);4366 mangleName(T->getMostRecentCXXRecordDecl());4367 mangleAutoReturnType(PointeeType, QMM_Drop);4368 }4369}4370 4371void MicrosoftCXXNameMangler::mangleAutoReturnType(const PointerType *T,4372 Qualifiers Quals) {4373 QualType PointeeType = T->getPointeeType();4374 assert(!PointeeType.getQualifiers().hasAddressSpace() &&4375 "Unexpected address space mangling required");4376 4377 manglePointerCVQualifiers(Quals);4378 manglePointerExtQualifiers(Quals, PointeeType);4379 4380 if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {4381 Out << '6';4382 mangleFunctionType(FPT);4383 } else {4384 mangleAutoReturnType(PointeeType, QMM_Mangle);4385 }4386}4387 4388void MicrosoftCXXNameMangler::mangleAutoReturnType(const LValueReferenceType *T,4389 Qualifiers Quals) {4390 QualType PointeeType = T->getPointeeType();4391 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");4392 Out << 'A';4393 manglePointerExtQualifiers(Quals, PointeeType);4394 mangleAutoReturnType(PointeeType, QMM_Mangle);4395}4396 4397void MicrosoftCXXNameMangler::mangleAutoReturnType(const RValueReferenceType *T,4398 Qualifiers Quals) {4399 QualType PointeeType = T->getPointeeType();4400 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");4401 Out << "$$Q";4402 manglePointerExtQualifiers(Quals, PointeeType);4403 mangleAutoReturnType(PointeeType, QMM_Mangle);4404}4405 4406MicrosoftMangleContext *MicrosoftMangleContext::create(ASTContext &Context,4407 DiagnosticsEngine &Diags,4408 bool IsAux) {4409 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);4410}4411