brintos

brintos / llvm-project-archived public Read only

0
0
Text · 164.0 KiB · f1baf9f Raw
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