clang: lib/AST/MicrosoftMangle.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

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

38#include

39

40using namespace clang;

41

42namespace {

43

44

47 if (auto *CD = dyn_cast(DC))

49 else if (auto *DD = dyn_cast(DC))

51 else

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

87getLambdaDefaultArgumentDeclContext(const Decl *D) {

88 if (const auto *RD = dyn_cast(D))

89 if (RD->isLambda())

90 if (const auto *Parm =

91 dyn_cast_or_null(RD->getLambdaContextDecl()))

92 return Parm->getDeclContext();

93 return nullptr;

94}

95

96

97

98static const DeclContext *getEffectiveDeclContext(const Decl *D) {

99

100

101

102

103

104

105 if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(D))

106 return LDADC;

107

108

109 if (const BlockDecl *BD = dyn_cast(D)) {

111 dyn_cast_or_null(BD->getBlockManglingContextDecl()))

112 return ContextParam->getDeclContext();

113 }

114

118 return getEffectiveDeclContext(cast(DC));

119 }

120

122}

123

125 return getEffectiveDeclContext(cast(DC));

126}

127

129 if (const auto *FTD = dyn_cast(ND))

131

133 if (const auto *FTD = FD->getPrimaryTemplate())

134 return FTD->getTemplatedDecl()->getCanonicalDecl();

135

136 return FD->getCanonicalDecl();

137}

138

139

140

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 void

196 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);

217 return false;

218

219

220

221 if (const auto *RD = dyn_cast(ND)) {

222 if (RD->isLambda()) {

223 disc = 1;

224 return true;

225 }

226 }

227

228

230 disc = getASTContext().getManglingNumber(ND, isAux());

231 return true;

232 }

233

234

235 if (const TagDecl *Tag = dyn_cast(ND)) {

236 if (Tag->hasNameForLinkage() &&

237 !getASTContext().getDeclaratorForUnnamedTagDecl(Tag) &&

238 !getASTContext().getTypedefNameForUnnamedTagDecl(Tag))

239 return false;

240 }

241

242

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

256 unsigned LambdaId;

257 const ParmVarDecl *Parm = dyn_cast_or_null(LambdaContextDecl);

258 const FunctionDecl *Func =

260

262 unsigned DefaultArgNo =

264 Name += llvm::utostr(DefaultArgNo);

265 Name += "_";

266 }

267

268 if (LambdaManglingNumber)

269 LambdaId = LambdaManglingNumber;

270 else

271 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!");

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!");

292 "RD must not have a mangling number!");

293

294 return LambdaIds.lookup(RD);

295 }

296

297

298

299 StringRef getAnonymousNamespaceHash() const {

300 return AnonymousNamespaceHash;

301 }

302

303private:

304 void mangleInitFiniStub(const VarDecl *D, char CharCode, raw_ostream &Out);

305};

306

307

308

309class MicrosoftCXXNameMangler {

310 MicrosoftMangleContextImpl &Context;

311 raw_ostream &Out;

312

313

314

315

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(

351

352 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,

354 : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),

355 TemplateArgStringStorage(TemplateArgStringStorageAlloc),

356 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(

358

359 MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,

361 : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),

362 TemplateArgStringStorage(TemplateArgStringStorageAlloc),

363 PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(

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);

397 void mangleArtificialTagType(TagTypeKind TK, StringRef UnqualifiedName,

398 ArrayRef 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 {

418 return AddrSpace == LangAS::ptr64 ||

419 (PointersAre64Bit && !(AddrSpace == LangAS::ptr32_sptr ||

420 AddrSpace == LangAS::ptr32_uptr));

421 }

422

423 void mangleUnqualifiedName(GlobalDecl GD) {

425 }

426 void mangleUnqualifiedName(GlobalDecl GD, DeclarationName Name);

429 void mangleQualifiers(Qualifiers Quals, bool IsMember);

431 void manglePointerCVQualifiers(Qualifiers Quals);

432 void manglePointerExtQualifiers(Qualifiers Quals, QualType PointeeType);

433 void manglePointerAuthQualifier(Qualifiers Quals);

434

435 void mangleUnscopedTemplateName(GlobalDecl GD);

436 void

437 mangleTemplateInstantiationName(GlobalDecl GD,

438 const TemplateArgumentList &TemplateArgs);

440

441 void mangleFunctionArgumentType(QualType T, SourceRange Range);

442 void manglePassObjectSizeArg(const PassObjectSizeAttr *POSA);

443

444 bool isArtificialTagType(QualType T) const;

445

446

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_TYPE

454#undef NON_CANONICAL_TYPE

455#undef TYPE

456

457 void mangleType(const TagDecl *TD);

458 void mangleDecayedArrayType(const ArrayType *T);

459 void mangleArrayType(const ArrayType *T);

460 void mangleFunctionClass(const FunctionDecl *FD);

463 void mangleIntegerLiteral(const llvm::APSInt &Number,

468

469 void mangleTemplateArgs(const TemplateDecl *TD,

473 void mangleTemplateArgValue(QualType T, const APValue &V, TplArgKind,

474 bool WithScalarType = false);

475

481

486};

487}

488

489MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(ASTContext &Context,

491 bool IsAux)

493

494

495

496

497

498

499

500

501

502

503

504

505

506

509

510 uint32_t TruncatedHash = uint32_t(xxh3_64bits(FE->getName()));

511 AnonymousNamespaceHash = llvm::utohexstr(TruncatedHash);

512 } else {

513

514 AnonymousNamespaceHash = "0";

515 }

516}

517

518bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {

519 if (const FunctionDecl *FD = dyn_cast(D)) {

521

522 if (FD->hasAttr())

523 return true;

524

525

526

527

528

529

530

531

532

533

534 if (FD->isMSVCRTEntryPoint())

535 return false;

536

537

538

540 return true;

541

542

544 return false;

545 }

546

547

548 if (!getASTContext().getLangOpts().CPlusPlus)

549 return false;

550

551 const VarDecl *VD = dyn_cast(D);

553

555 return false;

556

557

558 const DeclContext *DC = getEffectiveDeclContext(D);

559

562 DC = getEffectiveParentContext(DC);

563

566 return false;

567 }

568

569 return true;

570}

571

572bool

573MicrosoftMangleContextImpl::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();

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();

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

598 "cannot mangle this %0 yet");

599 return Diags.Report(DiagID) << thingy;

600}

601

602void MicrosoftCXXNameMangler::mangle(GlobalDecl GD, StringRef Prefix) {

604

605

606

607

608

609

610

611 Out << Prefix;

612 mangleName(GD);

613 if (const FunctionDecl *FD = dyn_cast(D))

614 mangleFunctionEncoding(GD, Context.shouldMangleDeclName(FD));

615 else if (const VarDecl *VD = dyn_cast(D))

616 mangleVariableEncoding(VD);

618

619

620 Out << "3U__s_GUID@@B";

622

623

624 } else

625 llvm_unreachable("Tried to mangle unexpected NamedDecl!");

626}

627

628void MicrosoftCXXNameMangler::mangleFunctionEncoding(GlobalDecl GD,

629 bool ShouldMangle) {

631

632

633

634

635

637

638

639

640 const FunctionProtoType *FT = FD->getType()->castAs();

641

642

643

644

645 if (ShouldMangle) {

646

647

648

649

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

663

664

665

666

667

668

669

671

673 default:

677 }

678 }

680 Out << '3';

681 else

682 Out << '4';

683

684

685

686

687

689 QualType Ty = VD->getType();

692 mangleType(Ty, SR, QMM_Drop);

693 manglePointerExtQualifiers(

694 Ty.getDesugaredType(getASTContext()).getLocalQualifiers(), QualType());

695 if (const MemberPointerType *MPT = Ty->getAs()) {

696 mangleQualifiers(MPT->getPointeeType().getQualifiers(), true);

697

698

699 mangleName(MPT->getMostRecentCXXRecordDecl());

700 } else

702 } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {

703

704 mangleDecayedArrayType(AT);

705 if (AT->getElementType()->isArrayType())

706 Out << 'A';

707 else

709 } else {

710 mangleType(Ty, SR, QMM_Drop);

712 }

713}

714

715void MicrosoftCXXNameMangler::mangleMemberDataPointer(

716 const CXXRecordDecl *RD, const ValueDecl *VD,

717 const NonTypeTemplateParmDecl *PD, QualType TemplateArgType,

718 StringRef Prefix) {

719

720

721

722

723

724

725

726

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 {

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) &&

760 !TemplateArgType.isNull()) {

761 Out << "M";

762 mangleType(TemplateArgType, SourceRange(), QMM_Drop);

763 }

764

765 Out << Code;

766

767 mangleNumber(FieldOffset);

768

769

770

771

773 mangleNumber(0);

775 mangleNumber(VBTableOffset);

776}

777

778void MicrosoftCXXNameMangler::mangleMemberDataPointerInClassNTTP(

779 const CXXRecordDecl *RD, const ValueDecl *VD) {

781

782

783

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

805

806

807

808

809

810

811

812

813

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

825

829 if (MD) {

830 Out << Prefix;

831

832 if (getASTContext().getLangOpts().isCompatibleWithMSVC(

833 LangOptions::MSVC2019) &&

835 !TemplateArgType.isNull()) {

836 Out << "M";

837 mangleType(TemplateArgType, SourceRange(), QMM_Drop);

838 }

839

840 Out << Code << '?';

842 MicrosoftVTableContext *VTContext =

844 MethodVFTableLocation ML =

846 mangleVirtualMemPtrThunk(MD, ML);

850 const ASTRecordLayout &Layout = getASTContext().getASTRecordLayout(RD);

852 }

853 } else {

854 mangleName(MD);

855 mangleFunctionEncoding(MD, true);

856 }

857

858 if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual)

859 NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();

860 } else {

861

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

872 mangleNumber(static_cast<uint32_t>(NVOffset));

874 mangleNumber(VBPtrOffset);

876 mangleNumber(VBTableOffset);

877}

878

879void MicrosoftCXXNameMangler::mangleFunctionPointer(

880 const FunctionDecl *FD, const NonTypeTemplateParmDecl *PD,

881 QualType TemplateArgType) {

882

883

884

885

886 Out << '$';

887

888 if (getASTContext().getLangOpts().isCompatibleWithMSVC(

889 LangOptions::MSVC2019) &&

891 !TemplateArgType.isNull()) {

892 Out << "M";

893 mangleType(TemplateArgType, SourceRange(), QMM_Drop);

894 }

895

896 Out << "1?";

897 mangleName(FD);

898 mangleFunctionEncoding(FD, true);

899}

900

901void MicrosoftCXXNameMangler::mangleVarDecl(const VarDecl *VD,

902 const NonTypeTemplateParmDecl *PD,

903 QualType TemplateArgType) {

904

905

906

907

908 Out << '$';

909

910 if (getASTContext().getLangOpts().isCompatibleWithMSVC(

911 LangOptions::MSVC2019) &&

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

926

927

928

929

930 if (!MD) {

932 return mangleMemberFunctionPointer(RD, MD, nullptr, QualType(), "");

933

934 Out << 'N';

935 return;

936 }

937

938 Out << "E?";

940 MicrosoftVTableContext *VTContext =

942 MethodVFTableLocation ML =

944 mangleVirtualMemPtrThunk(MD, ML);

945 } else {

946 mangleName(MD);

947 mangleFunctionEncoding(MD, true);

948 }

949}

950

951void MicrosoftCXXNameMangler::mangleVirtualMemPtrThunk(

952 const CXXMethodDecl *MD, const MethodVFTableLocation &ML) {

953

954 CharUnits PointerWidth = getASTContext().toCharUnitsFromBits(

955 getASTContext().getTargetInfo().getPointerWidth(LangAS::Default));

957

958 Out << "?_9";

960 Out << "$B";

961 mangleNumber(OffsetInVFTable);

962 Out << 'A';

963 mangleCallingConvention(MD->getType()->castAs(),

965}

966

967void MicrosoftCXXNameMangler::mangleName(GlobalDecl GD) {

968

969

970

971 mangleUnqualifiedName(GD);

972

973 mangleNestedName(GD);

974

975

976 Out << '@';

977}

978

979void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) {

980 mangleNumber(llvm::APSInt(llvm::APInt(64, Number), false));

981}

982

983void MicrosoftCXXNameMangler::mangleNumber(llvm::APSInt Number) {

984

985

986

987

988 unsigned Width = std::max(Number.getBitWidth(), 64U);

989 llvm::APInt Value = Number.extend(Width);

990

991

992

993

994

995

996

997 if (Value.isNegative()) {

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

1012

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) {

1039 Out << "A@";

1040 else if (Value.uge(1) && Value.ule(10))

1042 else {

1043

1044

1045

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

1058

1059 if (const FunctionDecl *FD = dyn_cast(ND)) {

1063 }

1064 }

1065

1066

1068 dyn_cast(ND)) {

1069 TemplateArgs = &Spec->getTemplateArgs();

1070 return GD.getWithDecl(Spec->getSpecializedTemplate());

1071 }

1072

1073

1075 dyn_cast(ND)) {

1076 TemplateArgs = &Spec->getTemplateArgs();

1077 return GD.getWithDecl(Spec->getSpecializedTemplate());

1078 }

1079

1081}

1082

1083void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,

1084 DeclarationName Name) {

1086

1087

1088

1089

1090

1091

1092 const TemplateArgumentList *TemplateArgs = nullptr;

1093 if (GlobalDecl TD = isTemplate(GD, TemplateArgs)) {

1094

1095

1096

1098 mangleTemplateInstantiationName(TD, *TemplateArgs);

1099 Out << '@';

1100 return;

1101 }

1102

1103

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113

1114

1115

1116

1117

1118

1119

1120

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

1127 llvm::SmallString<64> TemplateMangling;

1128 llvm::raw_svector_ostream Stream(TemplateMangling);

1129 MicrosoftCXXNameMangler Extra(Context, Stream);

1130 Extra.mangleTemplateInstantiationName(TD, *TemplateArgs);

1131

1132

1133 mangleSourceName(TemplateMangling);

1134

1135

1136

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 << '@';

1148 }

1149 } else {

1150 Out << Found->second;

1151 }

1152 return;

1153 }

1154

1158 bool IsDeviceStub =

1159 ND &&

1163 ->getTemplatedDecl()

1166 bool IsOCLDeviceStub =

1168 DeviceKernelAttr::isOpenCLSpelling(

1169 ND->getAttr()) &&

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 else

1178 mangleSourceName(II->getName());

1179 break;

1180 }

1181

1182

1183 assert(ND && "mangling empty name without declaration");

1184

1185 if (const NamespaceDecl *NS = dyn_cast(ND)) {

1186 if (NS->isAnonymousNamespace()) {

1187 Out << "?A0x" << Context.getAnonymousNamespaceHash() << '@';

1188 break;

1189 }

1190 }

1191

1192 if (const DecompositionDecl *DD = dyn_cast(ND)) {

1193

1194

1195 llvm::SmallString<64> Name("$S");

1196

1197 Name += llvm::utostr(Context.getAnonymousStructId(DD) + 1);

1198 mangleSourceName(Name);

1199 break;

1200 }

1201

1202 if (const VarDecl *VD = dyn_cast(ND)) {

1203

1205 assert(RD && "expected variable decl to have a record type");

1206

1207

1208

1209 llvm::SmallString<64> Name("$S");

1210

1211 Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);

1212 mangleSourceName(Name.str());

1213 break;

1214 }

1215

1216 if (const MSGuidDecl *GD = dyn_cast(ND)) {

1217

1218

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(ND)) {

1227 Out << "?__N";

1228 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),

1229 TPO->getValue(), TplArgKind::ClassNTTP);

1230 break;

1231 }

1232

1233

1237 "Typedef should not be in another decl context!");

1239 "Typedef was not named!");

1241 break;

1242 }

1243

1244 if (const CXXRecordDecl *Record = dyn_cast(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(LambdaContextDecl);

1253 const FunctionDecl *Func =

1255

1257 unsigned DefaultArgNo =

1259 Name += llvm::utostr(DefaultArgNo);

1260 Name += "_";

1261 }

1262

1263 if (LambdaManglingNumber)

1264 LambdaId = LambdaManglingNumber;

1265 else

1266 LambdaId = Context.getLambdaId(Record);

1267

1268 Name += llvm::utostr(LambdaId);

1269 Name += ">";

1270

1271 mangleSourceName(Name);

1272

1273

1274

1275 if (LambdaManglingNumber && LambdaContextDecl) {

1279 mangleUnqualifiedName(cast(LambdaContextDecl));

1280 }

1281 }

1282 break;

1283 }

1284 }

1285

1286 llvm::SmallString<64> Name;

1287 if (DeclaratorDecl *DD =

1289

1290

1291 Name += "<unnamed-type-";

1292 Name += DD->getName();

1293 } else if (TypedefNameDecl *TND =

1295 TD)) {

1296

1297

1298 Name += "<unnamed-type-";

1299 Name += TND->getName();

1302

1304 Name += "<unnamed-enum-";

1305 Name += ED->enumerator_begin()->getName();

1306 } else {

1307

1308 Name += "<unnamed-type-$S";

1309 Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);

1310 }

1311 Name += ">";

1312 mangleSourceName(Name.str());

1313 break;

1314 }

1315

1319

1320

1321

1322 llvm::SmallString<64> Name;

1323 mangleSourceName(Name.str());

1324 break;

1325 }

1326

1328 if (isStructorDecl(ND)) {

1330 Out << "?_O";

1331 return;

1332 }

1334 Out << "?_F";

1335 return;

1336 }

1337 }

1338 Out << "?0";

1339 return;

1340

1342 if (isStructorDecl(ND))

1343

1344

1345 mangleCXXDtorType(static_cast<CXXDtorType>(StructorType));

1346 else

1347

1348

1350 break;

1351

1353

1354

1355 Out << "?B";

1356 break;

1357

1359 mangleOperatorName(Name.getCXXOverloadedOperator(), ND->getLocation());

1360 break;

1361

1363 Out << "?__K";

1364 mangleSourceName(Name.getCXXLiteralIdentifier()->getName());

1365 break;

1366 }

1367

1369 llvm_unreachable("Can't mangle a deduction guide name!");

1370

1372 llvm_unreachable("Can't mangle a using directive name!");

1373 }

1374}

1375

1376

1377

1378void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {

1380

1381 if (const auto *ID = dyn_cast(ND))

1382 for (unsigned I = 1, IE = ID->getChainingSize(); I < IE; ++I)

1383 mangleSourceName("");

1384

1385 const DeclContext *DC = getEffectiveDeclContext(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(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, false);

1413

1414

1415

1416

1417 unsigned ParameterDiscriminator = 0;

1418 if (const auto *MC = BD->getBlockManglingContextDecl())

1419 if (const auto *P = dyn_cast(MC))

1420 if (const auto *F = dyn_cast(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

1430

1431

1432

1433 if (const auto *MC = BD->getBlockManglingContextDecl())

1435 if (const auto *ND = dyn_cast(MC))

1436 mangleUnqualifiedName(ND);

1437

1438

1439

1440 if (const auto *RD = dyn_cast(DC))

1441 mangleName(RD);

1442 else

1443 Out << '@';

1444

1445 Out << "YAX";

1446

1447 Out << 'P';

1448

1449 if (PointersAre64Bit)

1450 Out << 'E';

1451 Out << 'A';

1452 mangleArtificialTagType(TagTypeKind::Struct,

1453 Discriminate("__block_literal", Discriminator,

1454 ParameterDiscriminator));

1455 Out << "@Z";

1456

1457

1458

1460 break;

1461 continue;

1462 } else if (const ObjCMethodDecl *Method = dyn_cast(DC)) {

1466 if (const FunctionDecl *FD = dyn_cast(ND)) {

1467 mangle(getGlobalDeclAsDeclContext(FD), "?");

1468 break;

1469 } else {

1470 mangleUnqualifiedName(ND);

1471

1472

1473 if (const auto *LDADC = getLambdaDefaultArgumentDeclContext(ND)) {

1474 DC = LDADC;

1475 continue;

1476 }

1477 }

1478 }

1480 }

1481}

1482

1483void MicrosoftCXXNameMangler::mangleCXXDtorType(CXXDtorType T) {

1484

1485

1486

1487 switch (T) {

1488

1490

1492

1494

1496 Out << "?_E";

1497 return;

1499 llvm_unreachable("not expecting a COMDAT");

1501 llvm_unreachable("not expecting a unified dtor type");

1502 }

1503 llvm_unreachable("Unsupported dtor type?");

1504}

1505

1507 SourceLocation Loc) {

1508 switch (OO) {

1509

1510

1511

1512 case OO_New: Out << "?2"; break;

1513

1514 case OO_Delete: Out << "?3"; break;

1515

1516 case OO_Equal: Out << "?4"; break;

1517

1518 case OO_GreaterGreater: Out << "?5"; break;

1519

1520 case OO_LessLess: Out << "?6"; break;

1521

1522 case OO_Exclaim: Out << "?7"; break;

1523

1524 case OO_EqualEqual: Out << "?8"; break;

1525

1526 case OO_ExclaimEqual: Out << "?9"; break;

1527

1528 case OO_Subscript: Out << "?A"; break;

1529

1530

1531 case OO_Arrow: Out << "?C"; break;

1532

1533 case OO_Star: Out << "?D"; break;

1534

1535 case OO_PlusPlus: Out << "?E"; break;

1536

1537 case OO_MinusMinus: Out << "?F"; break;

1538

1539 case OO_Minus: Out << "?G"; break;

1540

1541 case OO_Plus: Out << "?H"; break;

1542

1543 case OO_Amp: Out << "?I"; break;

1544

1545 case OO_ArrowStar: Out << "?J"; break;

1546

1547 case OO_Slash: Out << "?K"; break;

1548

1549 case OO_Percent: Out << "?L"; break;

1550

1551 case OO_Less: Out << "?M"; break;

1552

1553 case OO_LessEqual: Out << "?N"; break;

1554

1555 case OO_Greater: Out << "?O"; break;

1556

1557 case OO_GreaterEqual: Out << "?P"; break;

1558

1559 case OO_Comma: Out << "?Q"; break;

1560

1561 case OO_Call: Out << "?R"; break;

1562

1563 case OO_Tilde: Out << "?S"; break;

1564

1565 case OO_Caret: Out << "?T"; break;

1566

1567 case OO_Pipe: Out << "?U"; break;

1568

1569 case OO_AmpAmp: Out << "?V"; break;

1570

1571 case OO_PipePipe: Out << "?W"; break;

1572

1573 case OO_StarEqual: Out << "?X"; break;

1574

1575 case OO_PlusEqual: Out << "?Y"; break;

1576

1577 case OO_MinusEqual: Out << "?Z"; break;

1578

1579 case OO_SlashEqual: Out << "?_0"; break;

1580

1581 case OO_PercentEqual: Out << "?_1"; break;

1582

1583 case OO_GreaterGreaterEqual: Out << "?_2"; break;

1584

1585 case OO_LessLessEqual: Out << "?_3"; break;

1586

1587 case OO_AmpEqual: Out << "?_4"; break;

1588

1589 case OO_PipeEqual: Out << "?_5"; break;

1590

1591 case OO_CaretEqual: Out << "?_6"; break;

1592

1593

1594

1595

1596

1597

1598

1599

1600

1601

1602

1603

1604

1605

1606

1607

1608

1609

1610

1611

1612

1613

1614

1615

1616

1617

1618

1619

1620 case OO_Array_New: Out << "?_U"; break;

1621

1622 case OO_Array_Delete: Out << "?_V"; break;

1623

1624 case OO_Coawait: Out << "?__L"; break;

1625

1626 case OO_Spaceship: Out << "?__M"; break;

1627

1628 case OO_Conditional: {

1629 Error(Loc, "conditional operator");

1630 break;

1631 }

1632

1635 llvm_unreachable("Not an overloaded operator");

1636 }

1637}

1638

1639void MicrosoftCXXNameMangler::mangleSourceName(StringRef Name) {

1640

1641 BackRefVec::iterator Found = llvm::find(NameBackReferences, Name);

1642 if (Found == NameBackReferences.end()) {

1643 if (NameBackReferences.size() < 10)

1644 NameBackReferences.push_back(std::string(Name));

1645 Out << Name << '@';

1646 } else {

1647 Out << (Found - NameBackReferences.begin());

1648 }

1649}

1650

1651void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {

1652 Context.mangleObjCMethodNameAsSourceName(MD, Out);

1653}

1654

1655void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(

1656 GlobalDecl GD, const TemplateArgumentList &TemplateArgs) {

1657

1658

1659

1660

1661

1662 ArgBackRefMap OuterFunArgsContext;

1663 ArgBackRefMap OuterTemplateArgsContext;

1664 BackRefVec OuterTemplateContext;

1665 PassObjectSizeArgsSet OuterPassObjectSizeArgs;

1666 NameBackReferences.swap(OuterTemplateContext);

1667 FunArgBackReferences.swap(OuterFunArgsContext);

1668 TemplateArgBackReferences.swap(OuterTemplateArgsContext);

1669 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);

1670

1671 mangleUnscopedTemplateName(GD);

1673

1674

1675 NameBackReferences.swap(OuterTemplateContext);

1676 FunArgBackReferences.swap(OuterFunArgsContext);

1677 TemplateArgBackReferences.swap(OuterTemplateArgsContext);

1678 PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);

1679}

1680

1681void MicrosoftCXXNameMangler::mangleUnscopedTemplateName(GlobalDecl GD) {

1682

1683 Out << "?$";

1684 mangleUnqualifiedName(GD);

1685}

1686

1687void MicrosoftCXXNameMangler::mangleIntegerLiteral(

1688 const llvm::APSInt &Value, const NonTypeTemplateParmDecl *PD,

1689 QualType TemplateArgType) {

1690

1691

1692

1693

1694 Out << "$";

1695

1696

1697

1698 if (getASTContext().getLangOpts().isCompatibleWithMSVC(

1699 LangOptions::MSVC2019) &&

1701 !TemplateArgType.isNull()) {

1702 Out << "M";

1703 mangleType(TemplateArgType, SourceRange(), QMM_Drop);

1704 }

1705

1706 Out << "0";

1707

1708 mangleNumber(Value);

1709}

1710

1711void MicrosoftCXXNameMangler::mangleExpression(

1712 const Expr *E, const NonTypeTemplateParmDecl *PD) {

1713

1714 if (std::optionalllvm::APSInt Value =

1716 mangleIntegerLiteral(*Value, PD, E->getType());

1717 return;

1718 }

1719

1720

1723}

1724

1725void MicrosoftCXXNameMangler::mangleTemplateArgs(

1726 const TemplateDecl *TD, const TemplateArgumentList &TemplateArgs) {

1727

1729 assert(TPL->size() == TemplateArgs.size() &&

1730 "size mismatch between args and parms!");

1731

1732 for (size_t i = 0; i < TemplateArgs.size(); ++i) {

1733 const TemplateArgument &TA = TemplateArgs[i];

1734

1735

1738 Out << "$$Z";

1739

1740 mangleTemplateArg(TD, TA, TPL->getParam(i));

1741 }

1742}

1743

1744

1745

1747

1748 if (T->isPointerType() || V.isLValue() || V.hasLValuePath() ||

1749 V.getLValueBase())

1750 return nullptr;

1751

1752 QualType BaseT = V.getLValueBase().getType();

1753 if (!BaseT->isArrayType() || V.getLValuePath().size() != 1 ||

1754 V.getLValuePath()[0].getAsArrayIndex() != 0)

1755 return nullptr;

1757 V.getLValueBase().dyn_cast<const ValueDecl *>());

1758}

1759

1760void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,

1761 const TemplateArgument &TA,

1762 const NamedDecl *Parm) {

1763

1764

1765

1766

1767

1768

1769

1770

1771

1772

1773

1774

1775

1776

1777

1778

1779

1780

1781

1782

1783

1784

1785

1786

1787

1788

1789

1790

1791

1792

1793

1794

1795

1796

1797

1800 llvm_unreachable("Can't mangle null template arguments!");

1802 llvm_unreachable("Can't mangle template expansion arguments!");

1805 mangleType(T, SourceRange(), QMM_Escape);

1806 break;

1807 }

1809 const NamedDecl *ND = TA.getAsDecl();

1811 mangleMemberDataPointer(

1815 } else if (const FunctionDecl *FD = dyn_cast(ND)) {

1816 const CXXMethodDecl *MD = dyn_cast(FD);

1821 } else {

1824 }

1826 Out << "$";

1828 mangleTemplateArgValue(TPO->getType().getUnqualifiedType(),

1829 TPO->getValue(), TplArgKind::ClassNTTP);

1830 } else if (const VarDecl *VD = dyn_cast(ND)) {

1833 } else {

1834 mangle(ND, "$1?");

1835 }

1836 break;

1837 }

1842 break;

1843 }

1846 if (const MemberPointerType *MPT = T->getAs()) {

1847 const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();

1848 if (MPT->isMemberFunctionPointerType() &&

1850 mangleMemberFunctionPointer(RD, nullptr, nullptr, QualType());

1851 return;

1852 }

1853 if (MPT->isMemberDataPointer()) {

1855 mangleMemberDataPointer(RD, nullptr, nullptr, QualType());

1856 return;

1857 }

1858

1859

1860

1861

1862

1863

1865 mangleIntegerLiteral(llvm::APSInt::get(-1),

1867 return;

1868 }

1869 }

1870 }

1871 mangleIntegerLiteral(llvm::APSInt::getUnsigned(0),

1873 break;

1874 }

1878

1879

1880

1881 return mangleTemplateArg(

1883 }

1884 Out << "$";

1887 ->getContainedDeducedType()) {

1888 Out << "M";

1890 }

1893 TplArgKind::StructuralValue,

1894 false);

1895 break;

1898 break;

1900 ArrayRef TemplateArgs = TA.getPackAsArray();

1901 if (TemplateArgs.empty()) {

1904

1905

1906 Out << (Context.getASTContext().getLangOpts().isCompatibleWithMSVC(

1907 LangOptions::MSVC2015)

1908 ? "$$V"

1909 : "$$$V");

1911 Out << "$S";

1912 else

1913 llvm_unreachable("unexpected template parameter decl!");

1914 } else {

1915 for (const TemplateArgument &PA : TemplateArgs)

1916 mangleTemplateArg(TD, PA, Parm);

1917 }

1918 break;

1919 }

1921 const NamedDecl *ND =

1923 if (const auto *TD = dyn_cast(ND)) {

1924 mangleType(TD);

1926 Out << "$$Y";

1927 mangleName(ND);

1928 } else {

1929 llvm_unreachable("unexpected template template NamedDecl!");

1930 }

1931 break;

1932 }

1933 }

1934}

1935

1936void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,

1938 TplArgKind TAK,

1939 bool WithScalarType) {

1940 switch (V.getKind()) {

1943

1944

1945 if (WithScalarType)

1946 mangleType(T, SourceRange(), QMM_Escape);

1947 Out << '@';

1948 return;

1949

1951 if (WithScalarType)

1952 mangleType(T, SourceRange(), QMM_Escape);

1953 Out << '0';

1954 mangleNumber(V.getInt());

1955 return;

1956

1958 if (WithScalarType)

1959 mangleType(T, SourceRange(), QMM_Escape);

1960 mangleFloat(V.getFloat());

1961 return;

1962

1964 if (WithScalarType)

1965 mangleType(T, SourceRange(), QMM_Escape);

1966

1967 APValue::LValueBase Base = V.getLValueBase();

1968

1969

1970

1971 if (V.isLValueOnePastTheEnd()) {

1972 Out << "5E";

1973 auto *VD = Base.dyn_cast<const ValueDecl *>();

1974 if (VD)

1975 mangle(VD);

1976 Out << "@";

1977 return;

1978 }

1979

1980 if (V.hasLValuePath() || V.getLValuePath().empty()) {

1981

1982 if (Base.isNull()) {

1983

1984

1985

1986

1987 Out << "0";

1988 mangleNumber(V.getLValueOffset().getQuantity());

1989 } else if (V.hasLValuePath()) {

1990

1991 Error("template argument (extension not comaptible with ms mangler)");

1992 return;

1993 } else if (auto *VD = Base.dyn_cast<const ValueDecl*>()) {

1994 Out << "E";

1995 mangle(VD);

1996 } else {

1997 Error("template argument (undeclared base)");

1998 return;

1999 }

2000 } else {

2001 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())

2002 Out << "5";

2003

2004 SmallVector<char, 2> EntryTypes;

2005 SmallVector<std::function<void()>, 2> EntryManglers;

2006 QualType ET = Base.getType();

2007 for (APValue::LValuePathEntry E : V.getLValuePath()) {

2009 EntryTypes.push_back('C');

2010 EntryManglers.push_back([this, I = E.getAsArrayIndex()] {

2011 Out << '0';

2012 mangleNumber(I);

2013 Out << '@';

2014 });

2015 ET = AT->getElementType();

2016 continue;

2017 }

2018

2019 const Decl *D = E.getAsBaseOrMember().getPointer();

2020 if (auto *FD = dyn_cast(D)) {

2024 continue;

2025 } else {

2027

2028

2029

2030 }

2031

2032 EntryTypes.push_back('6');

2033 EntryManglers.push_back([this, D] {

2035 Out << '@';

2036 });

2037 }

2038

2039 for (auto I = EntryTypes.rbegin(), E = EntryTypes.rend(); I != E; ++I)

2040 Out << *I;

2041

2042 auto *VD = Base.dyn_cast<const ValueDecl*>();

2043 if (!VD) {

2044 Error("template argument (null value decl)");

2045 return;

2046 }

2047 Out << (TAK == TplArgKind::ClassNTTP ? 'E' : '1');

2048 mangle(VD);

2049

2050 for (const std::function<void()> &Mangler : EntryManglers)

2051 Mangler();

2052 if (TAK == TplArgKind::ClassNTTP && T->isPointerType())

2053 Out << '@';

2054 }

2055

2056 return;

2057 }

2058

2060 if (WithScalarType)

2061 mangleType(T, SourceRange(), QMM_Escape);

2062

2063 const CXXRecordDecl *RD =

2064 T->castAs()->getMostRecentCXXRecordDecl();

2065 const ValueDecl *D = V.getMemberPointerDecl();

2066 if (TAK == TplArgKind::ClassNTTP) {

2068 mangleMemberDataPointerInClassNTTP(RD, D);

2069 else

2070 mangleMemberFunctionPointerInClassNTTP(RD,

2071 cast_or_null(D));

2072 } else {

2074 mangleMemberDataPointer(RD, D, nullptr, QualType(), "");

2075 else

2076 mangleMemberFunctionPointer(RD, cast_or_null(D), nullptr,

2077 QualType(), "");

2078 }

2079 return;

2080 }

2081

2083 Out << '2';

2084 mangleType(T, SourceRange(), QMM_Escape);

2086 assert(RD && "unexpected type for record value");

2087

2088 unsigned BaseIndex = 0;

2089 for (const CXXBaseSpecifier &B : RD->bases())

2090 mangleTemplateArgValue(B.getType(), V.getStructBase(BaseIndex++), TAK);

2091 for (const FieldDecl *FD : RD->fields())

2092 if (!FD->isUnnamedBitField())

2093 mangleTemplateArgValue(FD->getType(),

2094 V.getStructField(FD->getFieldIndex()), TAK,

2095 true);

2096 Out << '@';

2097 return;

2098 }

2099

2101 Out << '7';

2102 mangleType(T, SourceRange(), QMM_Escape);

2103 if (const FieldDecl *FD = V.getUnionField()) {

2104 mangleUnqualifiedName(FD);

2105 mangleTemplateArgValue(FD->getType(), V.getUnionValue(), TAK);

2106 }

2107 Out << '@';

2108 return;

2109

2111

2112 Out << '2';

2113 mangleType(T, SourceRange(), QMM_Escape);

2114 Out << '0';

2115 mangleNumber(V.getComplexIntReal());

2116 Out << '0';

2117 mangleNumber(V.getComplexIntImag());

2118 Out << '@';

2119 return;

2120

2122 Out << '2';

2123 mangleType(T, SourceRange(), QMM_Escape);

2124 mangleFloat(V.getComplexFloatReal());

2125 mangleFloat(V.getComplexFloatImag());

2126 Out << '@';

2127 return;

2128

2130 Out << '3';

2131 QualType ElemT = getASTContext().getAsArrayType(T)->getElementType();

2132 mangleType(ElemT, SourceRange(), QMM_Escape);

2133 for (unsigned I = 0, N = V.getArraySize(); I != N; ++I) {

2134 const APValue &ElemV = I < V.getArrayInitializedElts()

2135 ? V.getArrayInitializedElt(I)

2136 : V.getArrayFiller();

2137 mangleTemplateArgValue(ElemT, ElemV, TAK);

2138 Out << '@';

2139 }

2140 Out << '@';

2141 return;

2142 }

2143

2145

2146

2147 Out << '2';

2148 mangleType(T, SourceRange(), QMM_Escape);

2149 Out << '3';

2150 QualType ElemT = T->castAs()->getElementType();

2151 mangleType(ElemT, SourceRange(), QMM_Escape);

2152 for (unsigned I = 0, N = V.getVectorLength(); I != N; ++I) {

2154 mangleTemplateArgValue(ElemT, ElemV, TAK);

2155 Out << '@';

2156 }

2157 Out << "@@";

2158 return;

2159 }

2160

2162 Error("template argument (value type: address label diff)");

2163 return;

2164 }

2165

2167 Error("template argument (value type: fixed point)");

2168 return;

2169 }

2170 }

2171}

2172

2173void MicrosoftCXXNameMangler::mangleObjCProtocol(const ObjCProtocolDecl *PD) {

2174 llvm::SmallString<64> TemplateMangling;

2175 llvm::raw_svector_ostream Stream(TemplateMangling);

2176 MicrosoftCXXNameMangler Extra(Context, Stream);

2177

2178 Stream << "?$";

2179 Extra.mangleSourceName("Protocol");

2180 Extra.mangleArtificialTagType(TagTypeKind::Struct, PD->getName());

2181

2182 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});

2183}

2184

2185void MicrosoftCXXNameMangler::mangleObjCLifetime(const QualType Type,

2186 Qualifiers Quals,

2187 SourceRange Range) {

2188 llvm::SmallString<64> TemplateMangling;

2189 llvm::raw_svector_ostream Stream(TemplateMangling);

2190 MicrosoftCXXNameMangler Extra(Context, Stream);

2191

2192 Stream << "?$";

2196 break;

2198 Extra.mangleSourceName("Autoreleasing");

2199 break;

2201 Extra.mangleSourceName("Strong");

2202 break;

2204 Extra.mangleSourceName("Weak");

2205 break;

2206 }

2207 Extra.manglePointerCVQualifiers(Quals);

2208 Extra.manglePointerExtQualifiers(Quals, Type);

2210

2211 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});

2212}

2213

2214void MicrosoftCXXNameMangler::mangleObjCKindOfType(const ObjCObjectType *T,

2215 Qualifiers Quals,

2216 SourceRange Range) {

2217 llvm::SmallString<64> TemplateMangling;

2218 llvm::raw_svector_ostream Stream(TemplateMangling);

2219 MicrosoftCXXNameMangler Extra(Context, Stream);

2220

2221 Stream << "?$";

2222 Extra.mangleSourceName("KindOf");

2223 Extra.mangleType(QualType(T, 0)

2224 .stripObjCKindOfType(getASTContext())

2225 ->castAs(),

2226 Quals, Range);

2227

2228 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__ObjC"});

2229}

2230

2231void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,

2232 bool IsMember) {

2233

2234

2235

2236

2237

2238

2239

2240

2241

2242

2243

2244

2245

2246

2247

2248

2249

2250

2251

2252

2253

2254

2255

2256

2257

2258

2259

2260

2261

2262

2263

2264

2265

2266

2267

2268

2269

2270

2271

2272

2273

2274

2275

2276

2277

2278

2279

2280

2281

2282

2283

2284

2285 bool HasConst = Quals.hasConst(),

2287

2288 if (!IsMember) {

2289 if (HasConst && HasVolatile) {

2290 Out << 'D';

2291 } else if (HasVolatile) {

2292 Out << 'C';

2293 } else if (HasConst) {

2294 Out << 'B';

2295 } else {

2296 Out << 'A';

2297 }

2298 } else {

2299 if (HasConst && HasVolatile) {

2300 Out << 'T';

2301 } else if (HasVolatile) {

2302 Out << 'S';

2303 } else if (HasConst) {

2304 Out << 'R';

2305 } else {

2306 Out << 'Q';

2307 }

2308 }

2309

2310

2311}

2312

2313void

2314MicrosoftCXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {

2315

2316

2317 switch (RefQualifier) {

2319 break;

2320

2322 Out << 'G';

2323 break;

2324

2326 Out << 'H';

2327 break;

2328 }

2329}

2330

2331void MicrosoftCXXNameMangler::manglePointerExtQualifiers(Qualifiers Quals,

2332 QualType PointeeType) {

2333

2334 bool is64Bit = PointeeType.isNull() ? PointersAre64Bit :

2337 Out << 'E';

2338

2340 Out << 'I';

2341

2344 Out << 'F';

2345}

2346

2347void MicrosoftCXXNameMangler::manglePointerAuthQualifier(Qualifiers Quals) {

2348 PointerAuthQualifier PointerAuth = Quals.getPointerAuth();

2349 if (!PointerAuth)

2350 return;

2351

2352 Out << "__ptrauth";

2353 mangleNumber(PointerAuth.getKey());

2356}

2357

2358void MicrosoftCXXNameMangler::manglePointerCVQualifiers(Qualifiers Quals) {

2359

2360

2361

2362

2363 bool HasConst = Quals.hasConst(),

2365

2366 if (HasConst && HasVolatile) {

2367 Out << 'S';

2368 } else if (HasVolatile) {

2369 Out << 'R';

2370 } else if (HasConst) {

2371 Out << 'Q';

2372 } else {

2373 Out << 'P';

2374 }

2375}

2376

2377void MicrosoftCXXNameMangler::mangleFunctionArgumentType(QualType T,

2378 SourceRange Range) {

2379

2380

2381

2382

2383

2384

2385

2386 void *TypePtr;

2387 if (const auto *DT = T->getAs()) {

2388 QualType OriginalType = DT->getOriginalType();

2389

2390

2391 if (const auto *AT = getASTContext().getAsArrayType(OriginalType))

2392 OriginalType = getASTContext().getIncompleteArrayType(

2393 AT->getElementType(), AT->getSizeModifier(),

2394 AT->getIndexTypeCVRQualifiers());

2395

2397

2398

2399

2400

2401

2403 T = T.withConst();

2404 } else {

2405 TypePtr = T.getCanonicalType().getAsOpaquePtr();

2406 }

2407

2408 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);

2409

2410 if (Found == FunArgBackReferences.end()) {

2411 size_t OutSizeBefore = Out.tell();

2412

2413 mangleType(T, Range, QMM_Drop);

2414

2415

2416

2417

2418 bool LongerThanOneChar = (Out.tell() - OutSizeBefore > 1);

2419 if (LongerThanOneChar && FunArgBackReferences.size() < 10) {

2420 size_t Size = FunArgBackReferences.size();

2421 FunArgBackReferences[TypePtr] = Size;

2422 }

2423 } else {

2425 }

2426}

2427

2428void MicrosoftCXXNameMangler::manglePassObjectSizeArg(

2429 const PassObjectSizeAttr *POSA) {

2430 int Type = POSA->getType();

2431 bool Dynamic = POSA->isDynamic();

2432

2433 auto Iter = PassObjectSizeArgs.insert({Type, Dynamic}).first;

2434 auto *TypePtr = (const void *)&*Iter;

2435 ArgBackRefMap::iterator Found = FunArgBackReferences.find(TypePtr);

2436

2437 if (Found == FunArgBackReferences.end()) {

2438 std::string Name =

2439 Dynamic ? "__pass_dynamic_object_size" : "__pass_object_size";

2440 mangleArtificialTagType(TagTypeKind::Enum, Name + llvm::utostr(Type),

2441 {"__clang"});

2442

2443 if (FunArgBackReferences.size() < 10) {

2444 size_t Size = FunArgBackReferences.size();

2445 FunArgBackReferences[TypePtr] = Size;

2446 }

2447 } else {

2449 }

2450}

2451

2452void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,

2453 Qualifiers Quals,

2454 SourceRange Range) {

2455

2456

2457

2458

2459

2460

2461

2462

2463

2464

2465

2466

2467

2468 assert(Quals.hasAddressSpace() && "Not valid without address space");

2469 llvm::SmallString<32> ASMangling;

2470 llvm::raw_svector_ostream Stream(ASMangling);

2471 MicrosoftCXXNameMangler Extra(Context, Stream);

2472 Stream << "?$";

2473

2477 Extra.mangleSourceName("_AS");

2478 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(TargetAS));

2479 } else {

2480 switch (AS) {

2481 default:

2482 llvm_unreachable("Not a language specific address space");

2483 case LangAS::opencl_global:

2484 Extra.mangleSourceName("_ASCLglobal");

2485 break;

2486 case LangAS::opencl_global_device:

2487 Extra.mangleSourceName("_ASCLdevice");

2488 break;

2489 case LangAS::opencl_global_host:

2490 Extra.mangleSourceName("_ASCLhost");

2491 break;

2492 case LangAS::opencl_local:

2493 Extra.mangleSourceName("_ASCLlocal");

2494 break;

2495 case LangAS::opencl_constant:

2496 Extra.mangleSourceName("_ASCLconstant");

2497 break;

2498 case LangAS::opencl_private:

2499 Extra.mangleSourceName("_ASCLprivate");

2500 break;

2501 case LangAS::opencl_generic:

2502 Extra.mangleSourceName("_ASCLgeneric");

2503 break;

2504 case LangAS::cuda_device:

2505 Extra.mangleSourceName("_ASCUdevice");

2506 break;

2507 case LangAS::cuda_constant:

2508 Extra.mangleSourceName("_ASCUconstant");

2509 break;

2510 case LangAS::cuda_shared:

2511 Extra.mangleSourceName("_ASCUshared");

2512 break;

2513 case LangAS::ptr32_sptr:

2514 case LangAS::ptr32_uptr:

2515 case LangAS::ptr64:

2516 llvm_unreachable("don't mangle ptr address spaces with _AS");

2517 }

2518 }

2519

2520 Extra.mangleType(T, Range, QMM_Escape);

2521 mangleQualifiers(Qualifiers(), false);

2522 mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"});

2523}

2524

2525void MicrosoftCXXNameMangler::mangleAutoReturnType(QualType T,

2526 QualifierMangleMode QMM) {

2527 assert(getASTContext().getLangOpts().isCompatibleWithMSVC(

2528 LangOptions::MSVC2019) &&

2529 "Cannot mangle MSVC 2017 auto return types!");

2530

2533 Qualifiers Quals = T.getLocalQualifiers();

2534

2535 if (QMM == QMM_Result)

2536 Out << '?';

2537 if (QMM != QMM_Drop)

2538 mangleQualifiers(Quals, false);

2539 Out << (AT->isDecltypeAuto() ? "_T" : "_P");

2540 return;

2541 }

2542

2543 T = T.getDesugaredType(getASTContext());

2544 Qualifiers Quals = T.getLocalQualifiers();

2545

2546 switch (QMM) {

2547 case QMM_Drop:

2548 case QMM_Result:

2549 break;

2550 case QMM_Mangle:

2551 mangleQualifiers(Quals, false);

2552 break;

2553 default:

2554 llvm_unreachable("QMM_Escape unexpected");

2555 }

2556

2557 const Type *ty = T.getTypePtr();

2559 case Type::MemberPointer:

2561 break;

2562 case Type::Pointer:

2564 break;

2565 case Type::LValueReference:

2567 break;

2568 case Type::RValueReference:

2570 break;

2571 default:

2572 llvm_unreachable("Invalid type expected");

2573 }

2574}

2575

2576void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,

2577 QualifierMangleMode QMM) {

2578

2579

2580 T = T.getDesugaredType(getASTContext());

2581 Qualifiers Quals = T.getLocalQualifiers();

2582

2583 if (const ArrayType *AT = getASTContext().getAsArrayType(T)) {

2584

2585

2586 if (QMM == QMM_Mangle)

2587 Out << 'A';

2588 else if (QMM == QMM_Escape || QMM == QMM_Result)

2589 Out << "$$B";

2590 mangleArrayType(AT);

2591 return;

2592 }

2593

2596

2597 switch (QMM) {

2598 case QMM_Drop:

2601 break;

2602 case QMM_Mangle:

2603 if (const FunctionType *FT = dyn_cast(T)) {

2604 Out << '6';

2605 mangleFunctionType(FT);

2606 return;

2607 }

2608 mangleQualifiers(Quals, false);

2609 break;

2610 case QMM_Escape:

2611 if (!IsPointer && Quals) {

2612 Out << "$$C";

2613 mangleQualifiers(Quals, false);

2614 }

2615 break;

2616 case QMM_Result:

2617

2621 if ((!IsPointer && Quals) || isa(T) || isArtificialTagType(T)) {

2622 Out << '?';

2623 mangleQualifiers(Quals, false);

2624 }

2625 break;

2626 }

2627

2628 const Type *ty = T.getTypePtr();

2629

2631#define ABSTRACT_TYPE(CLASS, PARENT)

2632#define NON_CANONICAL_TYPE(CLASS, PARENT) \

2633 case Type::CLASS: \

2634 llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \

2635 return;

2636#define TYPE(CLASS, PARENT) \

2637 case Type::CLASS: \

2638 mangleType(cast<CLASS##Type>(ty), Quals, Range); \

2639 break;

2640#include "clang/AST/TypeNodes.inc"

2641#undef ABSTRACT_TYPE

2642#undef NON_CANONICAL_TYPE

2643#undef TYPE

2644 }

2645}

2646

2647void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,

2648 SourceRange Range) {

2649

2650

2651

2652

2653

2654

2655

2656

2657

2658

2659

2660

2661

2662

2663

2664

2665

2666

2667

2668

2669

2670

2671

2672

2673

2674

2675

2676 switch (T->getKind()) {

2677 case BuiltinType::Void:

2678 Out << 'X';

2679 break;

2680 case BuiltinType::SChar:

2681 Out << 'C';

2682 break;

2683 case BuiltinType::Char_U:

2684 case BuiltinType::Char_S:

2685 Out << 'D';

2686 break;

2687 case BuiltinType::UChar:

2688 Out << 'E';

2689 break;

2690 case BuiltinType::Short:

2691 Out << 'F';

2692 break;

2693 case BuiltinType::UShort:

2694 Out << 'G';

2695 break;

2696 case BuiltinType::Int:

2697 Out << 'H';

2698 break;

2699 case BuiltinType::UInt:

2700 Out << 'I';

2701 break;

2702 case BuiltinType::Long:

2703 Out << 'J';

2704 break;

2705 case BuiltinType::ULong:

2706 Out << 'K';

2707 break;

2708 case BuiltinType::Float:

2709 Out << 'M';

2710 break;

2711 case BuiltinType::Double:

2712 Out << 'N';

2713 break;

2714

2715 case BuiltinType::LongDouble:

2716 Out << 'O';

2717 break;

2718 case BuiltinType::LongLong:

2719 Out << "_J";

2720 break;

2721 case BuiltinType::ULongLong:

2722 Out << "_K";

2723 break;

2724 case BuiltinType::Int128:

2725 Out << "_L";

2726 break;

2727 case BuiltinType::UInt128:

2728 Out << "_M";

2729 break;

2730 case BuiltinType::Bool:

2731 Out << "_N";

2732 break;

2733 case BuiltinType::Char8:

2734 Out << "_Q";

2735 break;

2736 case BuiltinType::Char16:

2737 Out << "_S";

2738 break;

2739 case BuiltinType::Char32:

2740 Out << "_U";

2741 break;

2742 case BuiltinType::WChar_S:

2743 case BuiltinType::WChar_U:

2744 Out << "_W";

2745 break;

2746

2747#define BUILTIN_TYPE(Id, SingletonId)

2748#define PLACEHOLDER_TYPE(Id, SingletonId) \

2749 case BuiltinType::Id:

2750#include "clang/AST/BuiltinTypes.def"

2751 case BuiltinType::Dependent:

2752 llvm_unreachable("placeholder types shouldn't get to name mangling");

2753

2754 case BuiltinType::ObjCId:

2755 mangleArtificialTagType(TagTypeKind::Struct, "objc_object");

2756 break;

2757 case BuiltinType::ObjCClass:

2758 mangleArtificialTagType(TagTypeKind::Struct, "objc_class");

2759 break;

2760 case BuiltinType::ObjCSel:

2761 mangleArtificialTagType(TagTypeKind::Struct, "objc_selector");

2762 break;

2763

2764#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \

2765 case BuiltinType::Id: \

2766 Out << "PAUocl_" #ImgType "_" #Suffix "@@"; \

2767 break;

2768#include "clang/Basic/OpenCLImageTypes.def"

2769 case BuiltinType::OCLSampler:

2770 Out << "PA";

2771 mangleArtificialTagType(TagTypeKind::Struct, "ocl_sampler");

2772 break;

2773 case BuiltinType::OCLEvent:

2774 Out << "PA";

2775 mangleArtificialTagType(TagTypeKind::Struct, "ocl_event");

2776 break;

2777 case BuiltinType::OCLClkEvent:

2778 Out << "PA";

2779 mangleArtificialTagType(TagTypeKind::Struct, "ocl_clkevent");

2780 break;

2781 case BuiltinType::OCLQueue:

2782 Out << "PA";

2783 mangleArtificialTagType(TagTypeKind::Struct, "ocl_queue");

2784 break;

2785 case BuiltinType::OCLReserveID:

2786 Out << "PA";

2787 mangleArtificialTagType(TagTypeKind::Struct, "ocl_reserveid");

2788 break;

2789#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \

2790 case BuiltinType::Id: \

2791 mangleArtificialTagType(TagTypeKind::Struct, "ocl_" #ExtType); \

2792 break;

2793#include "clang/Basic/OpenCLExtensionTypes.def"

2794

2795 case BuiltinType::NullPtr:

2796 Out << "$$T";

2797 break;

2798

2799 case BuiltinType::Float16:

2800 mangleArtificialTagType(TagTypeKind::Struct, "_Float16", {"__clang"});

2801 break;

2802

2803 case BuiltinType::Half:

2804 if (!getASTContext().getLangOpts().HLSL)

2805 mangleArtificialTagType(TagTypeKind::Struct, "_Half", {"__clang"});

2806 else if (getASTContext().getLangOpts().NativeHalfType)

2807 Out << "$f16@";

2808 else

2809 Out << "$halff@";

2810 break;

2811

2812 case BuiltinType::BFloat16:

2813 mangleArtificialTagType(TagTypeKind::Struct, "__bf16", {"__clang"});

2814 break;

2815

2816 case BuiltinType::MFloat8:

2817 mangleArtificialTagType(TagTypeKind::Struct, "__mfp8", {"__clang"});

2818 break;

2819

2820#define WASM_REF_TYPE(InternalName, MangledName, Id, SingletonId, AS) \

2821 case BuiltinType::Id: \

2822 mangleArtificialTagType(TagTypeKind::Struct, MangledName); \

2823 mangleArtificialTagType(TagTypeKind::Struct, MangledName, {"__clang"}); \

2824 break;

2825

2826#include "clang/Basic/WebAssemblyReferenceTypes.def"

2827

2828#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \

2829 case BuiltinType::Id: \

2830 mangleArtificialTagType(TagTypeKind::Struct, #Name); \

2831 break;

2832#include "clang/Basic/HLSLIntangibleTypes.def"

2833

2834#define SVE_TYPE(Name, Id, SingletonId) \

2835 case BuiltinType::Id: \

2836 mangleArtificialTagType(TagTypeKind::Struct, #Name, {"__clang"}); \

2837 break;

2838#define SVE_SCALAR_TYPE(Name, MangledName, Id, SingletonId, Bits)

2839#include "clang/Basic/AArch64ACLETypes.def"

2840

2841

2842 default:

2843 Error(Range.getBegin(), "built-in type: ",

2846 break;

2847 }

2848}

2849

2850

2851void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers,

2852 SourceRange) {

2853

2854

2855

2857 Out << "$$A8@@";

2858 mangleFunctionType(T, nullptr, true);

2859 } else {

2860 Out << "$$A6";

2861 mangleFunctionType(T);

2862 }

2863}

2864void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,

2865 Qualifiers, SourceRange) {

2866 Out << "$$A6";

2867 mangleFunctionType(T);

2868}

2869

2870void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,

2871 const FunctionDecl *D,

2872 bool ForceThisQuals,

2873 bool MangleExceptionSpec) {

2874

2875

2876 const FunctionProtoType *Proto = dyn_cast(T);

2877

2878 SourceRange Range;

2880

2881 bool IsInLambda = false;

2882 bool IsStructor = false, HasThisQuals = ForceThisQuals, IsCtorClosure = false;

2884 if (const CXXMethodDecl *MD = dyn_cast_or_null(D)) {

2886 IsInLambda = true;

2888 HasThisQuals = true;

2890 IsStructor = true;

2892 IsStructor = true;

2895 isStructorDecl(MD);

2896 if (IsCtorClosure)

2897 CC = getASTContext().getDefaultCallingConvention(

2898 false, true);

2899 }

2900 }

2901

2902

2903

2904 if (HasThisQuals) {

2906 manglePointerExtQualifiers(Quals, QualType());

2908 mangleQualifiers(Quals, false);

2909 }

2910

2911 mangleCallingConvention(CC, Range);

2912

2913

2914

2915 if (IsStructor) {

2917

2918

2919

2920

2923 Out << (PointersAre64Bit ? "PEAXI@Z" : "PAXI@Z");

2924 return;

2925 }

2926

2928 Out << "XXZ";

2929 return;

2930 }

2931 }

2932 if (IsCtorClosure) {

2933

2934

2935 Out << 'X';

2936

2938

2939 Out << 'X';

2941

2942 mangleFunctionArgumentType(getASTContext().getLValueReferenceType(

2944 ->castAs()

2945 ->getPointeeType(),

2946 true),

2947 Range);

2948 Out << '@';

2949 } else {

2950 llvm_unreachable("unexpected constructor closure!");

2951 }

2952 Out << 'Z';

2953 return;

2954 }

2955 Out << '@';

2956 } else if (IsInLambda && isa_and_nonnull(D)) {

2957

2958

2959

2961 } else {

2964

2965

2966

2967 mangleType(ResultType, Range, QMM_Result);

2968 } else if (IsInLambda) {

2970 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&

2971 "shouldn't need to mangle __auto_type!");

2972 Out << '?';

2973 mangleQualifiers(ResultType.getLocalQualifiers(), false);

2974 Out << '?';

2975 mangleSourceName(AT->isDecltypeAuto() ? "" : "");

2976 Out << '@';

2977 } else {

2978 Out << '@';

2979 }

2981 assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&

2982 "shouldn't need to mangle __auto_type!");

2983

2984

2985

2986

2987

2988 auto UseClangMangling = [](QualType ResultType) {

2989 QualType T = ResultType;

2992 if (T.getQualifiers().hasAddressSpace())

2993 return true;

2994 }

2995 return false;

2996 };

2997

2998 if (getASTContext().getLangOpts().isCompatibleWithMSVC(

2999 LangOptions::MSVC2019) &&

3000 !UseClangMangling(ResultType)) {

3002 Out << '@';

3003 } else {

3009 ->castAs();

3011 }

3012 mangleAutoReturnType(ResultType, QMM_Result);

3013 }

3014 } else {

3015 Out << '?';

3016 mangleQualifiers(ResultType.getLocalQualifiers(), false);

3017 Out << '?';

3018 mangleSourceName(AT->isDecltypeAuto() ? "" : "");

3019 Out << '@';

3020 }

3021 } else {

3024 mangleType(ResultType, Range, QMM_Result);

3025 }

3026 }

3027

3028

3029

3030

3031 if (!Proto) {

3032

3033

3034

3035 Out << '@';

3037 Out << 'X';

3038 } else {

3039

3040 for (unsigned I = 0, E = Proto->getNumParams(); I != E; ++I) {

3041

3043 Out << "_V";

3044

3045 mangleFunctionArgumentType(Proto->getParamType(I), Range);

3046

3047

3048

3049

3050

3051

3052

3053

3054 if (D)

3056 manglePassObjectSizeArg(P);

3057 }

3058

3060 Out << 'Z';

3061 else

3062 Out << '@';

3063 }

3064

3065 if (MangleExceptionSpec && getASTContext().getLangOpts().CPlusPlus17 &&

3066 getASTContext().getLangOpts().isCompatibleWithMSVC(

3067 LangOptions::MSVC2017_5))

3068 mangleThrowSpecification(Proto);

3069 else

3070 Out << 'Z';

3071}

3072

3073void MicrosoftCXXNameMangler::mangleFunctionClass(const FunctionDecl *FD) {

3074

3075

3076

3077

3078

3079

3080

3081

3082

3083

3084

3085

3086

3087

3088

3089

3090

3091

3092

3093

3094

3095

3096

3097

3098 if (const CXXMethodDecl *MD = dyn_cast(FD)) {

3099 bool IsVirtual = MD->isVirtual();

3100

3101

3104 IsVirtual = false;

3105 }

3108 llvm_unreachable("Unsupported access specifier");

3111 Out << 'C';

3112 else if (IsVirtual)

3113 Out << 'E';

3114 else

3115 Out << 'A';

3116 break;

3119 Out << 'K';

3120 else if (IsVirtual)

3121 Out << 'M';

3122 else

3123 Out << 'I';

3124 break;

3127 Out << 'S';

3128 else if (IsVirtual)

3129 Out << 'U';

3130 else

3131 Out << 'Q';

3132 }

3133 } else {

3134 Out << 'Y';

3135 }

3136}

3137void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC,

3138 SourceRange Range) {

3139

3140

3141

3142

3143

3144

3145

3146

3147

3148

3149

3150

3151

3152

3153

3154

3155

3156

3157

3158

3159

3160

3161

3162

3163

3164 switch (CC) {

3165 default:

3166 break;

3170 Out << 'A';

3171 return;

3173 Out << 'C';

3174 return;

3176 Out << 'E';

3177 return;

3179 Out << 'G';

3180 return;

3182 Out << 'I';

3183 return;

3185 Out << 'Q';

3186 return;

3188 Out << 'S';

3189 return;

3191 Out << 'W';

3192 return;

3194 Out << 'U';

3195 return;

3197 Out << 'V';

3198 return;

3200 if (getASTContext().getLangOpts().RegCall4)

3201 Out << "x";

3202 else

3203 Out << "w";

3204 return;

3205 }

3206

3208}

3209void MicrosoftCXXNameMangler::mangleCallingConvention(const FunctionType *T,

3210 SourceRange Range) {

3211 mangleCallingConvention(T->getCallConv(), Range);

3212}

3213

3214void MicrosoftCXXNameMangler::mangleThrowSpecification(

3215 const FunctionProtoType *FT) {

3216

3217

3219 Out << 'Z';

3220 else

3221 Out << "_E";

3222}

3223

3224void MicrosoftCXXNameMangler::mangleType(const UnresolvedUsingType *T,

3225 Qualifiers, SourceRange Range) {

3226

3227

3228 Error(Range.getBegin(), "unresolved dependent type") << Range;

3229}

3230

3231

3232

3233

3234

3235

3236void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {

3237 switch (TTK) {

3238 case TagTypeKind::Union:

3239 Out << 'T';

3240 break;

3241 case TagTypeKind::Struct:

3242 case TagTypeKind::Interface:

3243 Out << 'U';

3244 break;

3245 case TagTypeKind::Class:

3246 Out << 'V';

3247 break;

3248 case TagTypeKind::Enum:

3249 Out << "W4";

3250 break;

3251 }

3252}

3253void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,

3254 SourceRange) {

3256}

3257void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,

3258 SourceRange) {

3260}

3261void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {

3262

3263

3266 mangleTagTypeKind(TD->getTagKind());

3267 mangleName(TD);

3268}

3269

3270

3271void MicrosoftCXXNameMangler::mangleArtificialTagType(

3272 TagTypeKind TK, StringRef UnqualifiedName,

3273 ArrayRef NestedNames) {

3274

3275 mangleTagTypeKind(TK);

3276

3277

3278 mangleSourceName(UnqualifiedName);

3279

3280 for (StringRef N : llvm::reverse(NestedNames))

3281 mangleSourceName(N);

3282

3283

3284 Out << '@';

3285}

3286

3287

3288

3289

3290

3291

3292

3293

3294void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {

3295

3296

3297 manglePointerCVQualifiers(T->getElementType().getQualifiers());

3298 mangleType(T->getElementType(), SourceRange());

3299}

3300void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T, Qualifiers,

3301 SourceRange) {

3302 llvm_unreachable("Should have been special cased");

3303}

3304void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T, Qualifiers,

3305 SourceRange) {

3306 llvm_unreachable("Should have been special cased");

3307}

3308void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,

3309 Qualifiers, SourceRange) {

3310 llvm_unreachable("Should have been special cased");

3311}

3312void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,

3313 Qualifiers, SourceRange) {

3314 llvm_unreachable("Should have been special cased");

3315}

3316void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {

3317 QualType ElementTy(T, 0);

3318 SmallVector<llvm::APInt, 3> Dimensions;

3319 for (;;) {

3320 if (ElementTy->isConstantArrayType()) {

3321 const ConstantArrayType *CAT =

3322 getASTContext().getAsConstantArrayType(ElementTy);

3323 Dimensions.push_back(CAT->getSize());

3325 } else if (ElementTy->isIncompleteArrayType()) {

3326 const IncompleteArrayType *IAT =

3327 getASTContext().getAsIncompleteArrayType(ElementTy);

3328 Dimensions.push_back(llvm::APInt(32, 0));

3330 } else if (ElementTy->isVariableArrayType()) {

3331 const VariableArrayType *VAT =

3332 getASTContext().getAsVariableArrayType(ElementTy);

3333 Dimensions.push_back(llvm::APInt(32, 0));

3335 } else if (ElementTy->isDependentSizedArrayType()) {

3336

3337 const DependentSizedArrayType *DSAT =

3338 getASTContext().getAsDependentSizedArrayType(ElementTy);

3341 return;

3342 } else {

3343 break;

3344 }

3345 }

3346 Out << 'Y';

3347

3348 mangleNumber(Dimensions.size());

3349 for (const llvm::APInt &Dimension : Dimensions)

3350 mangleNumber(Dimension.getLimitedValue());

3351 mangleType(ElementTy, SourceRange(), QMM_Escape);

3352}

3353

3354void MicrosoftCXXNameMangler::mangleType(const ArrayParameterType *T,

3355 Qualifiers, SourceRange) {

3357}

3358

3359

3360

3361

3362void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,

3363 Qualifiers Quals, SourceRange Range) {

3365 manglePointerCVQualifiers(Quals);

3366 manglePointerExtQualifiers(Quals, PointeeType);

3367 if (const FunctionProtoType *FPT = PointeeType->getAs()) {

3368 Out << '8';

3369 mangleName(T->getMostRecentCXXRecordDecl());

3370 mangleFunctionType(FPT, nullptr, true);

3371 } else {

3372 mangleQualifiers(PointeeType.getQualifiers(), true);

3373 mangleName(T->getMostRecentCXXRecordDecl());

3374 mangleType(PointeeType, Range, QMM_Drop);

3375 }

3376}

3377

3378void MicrosoftCXXNameMangler::mangleType(const TemplateTypeParmType *T,

3379 Qualifiers, SourceRange Range) {

3380 Out << '?';

3381

3382 llvm::SmallString<64> Name;

3383 Name += "<TTPT_";

3384 Name += llvm::utostr(T->getDepth());

3385 Name += "_";

3386 Name += llvm::utostr(T->getIndex());

3387 Name += ">";

3388 mangleSourceName(Name);

3389}

3390

3391void MicrosoftCXXNameMangler::mangleType(const SubstTemplateTypeParmPackType *T,

3392 Qualifiers, SourceRange Range) {

3393 Error(Range.getBegin(), "substituted parameter pack") << Range;

3394}

3395

3396void MicrosoftCXXNameMangler::mangleType(const SubstBuiltinTemplatePackType *T,

3397 Qualifiers, SourceRange Range) {

3398 Error(Range.getBegin(), "substituted builtin template pack") << Range;

3399}

3400

3401

3402

3403

3404void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals,

3405 SourceRange Range) {

3407 manglePointerCVQualifiers(Quals);

3408 manglePointerExtQualifiers(Quals, PointeeType);

3409 manglePointerAuthQualifier(Quals);

3410

3411

3412

3415 mangleType(PointeeType, Range);

3416 else

3417 mangleAddressSpaceType(PointeeType, PointeeType.getQualifiers(), Range);

3418}

3419

3420void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,

3421 Qualifiers Quals, SourceRange Range) {

3426 break;

3430 return mangleObjCLifetime(PointeeType, Quals, Range);

3431 }

3432 manglePointerCVQualifiers(Quals);

3433 manglePointerExtQualifiers(Quals, PointeeType);

3434 mangleType(PointeeType, Range);

3435}

3436

3437

3438

3439

3440void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,

3441 Qualifiers Quals, SourceRange Range) {

3443 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");

3444 Out << 'A';

3445 manglePointerExtQualifiers(Quals, PointeeType);

3446 mangleType(PointeeType, Range);

3447}

3448

3449

3450

3451

3452void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,

3453 Qualifiers Quals, SourceRange Range) {

3455 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");

3456 Out << "$$Q";

3457 manglePointerExtQualifiers(Quals, PointeeType);

3458 mangleType(PointeeType, Range);

3459}

3460

3461void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers,

3462 SourceRange Range) {

3463 QualType ElementType = T->getElementType();

3464

3465 llvm::SmallString<64> TemplateMangling;

3466 llvm::raw_svector_ostream Stream(TemplateMangling);

3467 MicrosoftCXXNameMangler Extra(Context, Stream);

3468 Stream << "?$";

3469 Extra.mangleSourceName("_Complex");

3470 Extra.mangleType(ElementType, Range, QMM_Escape);

3471

3472 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});

3473}

3474

3475

3476

3477

3478

3479

3480bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T) const {

3481 const Type *ty = T.getTypePtr();

3483 default:

3484 return false;

3485

3486 case Type::Vector: {

3487

3488

3489

3490 return true;

3491 }

3492 }

3493}

3494

3495void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,

3496 SourceRange Range) {

3497 QualType EltTy = T->getElementType();

3498 const BuiltinType *ET = EltTy->getAs();

3499 const BitIntType *BitIntTy = EltTy->getAs();

3500 assert((ET || BitIntTy) &&

3501 "vectors with non-builtin/_BitInt elements are unsupported");

3502 uint64_t Width = getASTContext().getTypeSize(T);

3503

3504

3505 size_t OutSizeBefore = Out.tell();

3507 if (getASTContext().getTargetInfo().getTriple().isX86() && ET) {

3508 if (Width == 64 && ET->getKind() == BuiltinType::LongLong) {

3509 mangleArtificialTagType(TagTypeKind::Union, "__m64");

3510 } else if (Width >= 128) {

3511 if (ET->getKind() == BuiltinType::Float)

3512 mangleArtificialTagType(TagTypeKind::Union,

3513 "__m" + llvm::utostr(Width));

3514 else if (ET->getKind() == BuiltinType::LongLong)

3515 mangleArtificialTagType(TagTypeKind::Union,

3516 "__m" + llvm::utostr(Width) + 'i');

3517 else if (ET->getKind() == BuiltinType::Double)

3518 mangleArtificialTagType(TagTypeKind::Struct,

3519 "__m" + llvm::utostr(Width) + 'd');

3520 }

3521 }

3522 }

3523

3524 bool IsBuiltin = Out.tell() != OutSizeBefore;

3525 if (!IsBuiltin) {

3526

3527

3528

3529

3530 llvm::SmallString<64> TemplateMangling;

3531 llvm::raw_svector_ostream Stream(TemplateMangling);

3532 MicrosoftCXXNameMangler Extra(Context, Stream);

3533 Stream << "?$";

3534 Extra.mangleSourceName("__vector");

3535 Extra.mangleType(QualType(ET ? static_cast<const Type *>(ET) : BitIntTy, 0),

3536 Range, QMM_Escape);

3537 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumElements()));

3538

3539 mangleArtificialTagType(TagTypeKind::Union, TemplateMangling, {"__clang"});

3540 }

3541}

3542

3543void MicrosoftCXXNameMangler::mangleType(const ExtVectorType *T,

3544 Qualifiers Quals, SourceRange Range) {

3545 mangleType(static_cast<const VectorType *>(T), Quals, Range);

3546}

3547

3548void MicrosoftCXXNameMangler::mangleType(const DependentVectorType *T,

3549 Qualifiers, SourceRange Range) {

3550 Error(Range.getBegin(), "dependent-sized vector type") << Range;

3551}

3552

3553void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,

3554 Qualifiers, SourceRange Range) {

3555 Error(Range.getBegin(), "dependent-sized extended vector type") << Range;

3556}

3557

3558void MicrosoftCXXNameMangler::mangleType(const ConstantMatrixType *T,

3559 Qualifiers quals, SourceRange Range) {

3560 QualType EltTy = T->getElementType();

3561

3562 llvm::SmallString<64> TemplateMangling;

3563 llvm::raw_svector_ostream Stream(TemplateMangling);

3564 MicrosoftCXXNameMangler Extra(Context, Stream);

3565

3566 Stream << "?$";

3567

3568 Extra.mangleSourceName("__matrix");

3569 Extra.mangleType(EltTy, Range, QMM_Escape);

3570

3571 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumRows()));

3572 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumColumns()));

3573

3574 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});

3575}

3576

3577void MicrosoftCXXNameMangler::mangleType(const DependentSizedMatrixType *T,

3578 Qualifiers quals, SourceRange Range) {

3579 Error(Range.getBegin(), "dependent-sized matrix type") << Range;

3580}

3581

3582void MicrosoftCXXNameMangler::mangleType(const DependentAddressSpaceType *T,

3583 Qualifiers, SourceRange Range) {

3584 Error(Range.getBegin(), "dependent address space type") << Range;

3585}

3586

3587void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,

3588 SourceRange) {

3589

3590 mangleTagTypeKind(TagTypeKind::Struct);

3591 mangleName(T->getDecl());

3592}

3593

3594void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T,

3595 Qualifiers Quals, SourceRange Range) {

3596 if (T->isKindOfType())

3597 return mangleObjCKindOfType(T, Quals, Range);

3598

3599 if (T->qual_empty() && T->isSpecialized())

3600 return mangleType(T->getBaseType(), Range, QMM_Drop);

3601

3602 ArgBackRefMap OuterFunArgsContext;

3603 ArgBackRefMap OuterTemplateArgsContext;

3604 BackRefVec OuterTemplateContext;

3605

3606 FunArgBackReferences.swap(OuterFunArgsContext);

3607 TemplateArgBackReferences.swap(OuterTemplateArgsContext);

3608 NameBackReferences.swap(OuterTemplateContext);

3609

3610 mangleTagTypeKind(TagTypeKind::Struct);

3611

3612 Out << "?$";

3613 if (T->isObjCId())

3614 mangleSourceName("objc_object");

3615 else if (T->isObjCClass())

3616 mangleSourceName("objc_class");

3617 else

3618 mangleSourceName(T->getInterface()->getName());

3619

3620 for (const auto &Q : T->quals())

3621 mangleObjCProtocol(Q);

3622

3623 if (T->isSpecialized())

3624 for (const auto &TA : T->getTypeArgs())

3625 mangleType(TA, Range, QMM_Drop);

3626

3627 Out << '@';

3628

3629 Out << '@';

3630

3631 FunArgBackReferences.swap(OuterFunArgsContext);

3632 TemplateArgBackReferences.swap(OuterTemplateArgsContext);

3633 NameBackReferences.swap(OuterTemplateContext);

3634}

3635

3636void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,

3637 Qualifiers Quals, SourceRange Range) {

3639 manglePointerCVQualifiers(Quals);

3640 manglePointerExtQualifiers(Quals, PointeeType);

3641

3642 Out << "_E";

3643

3644 mangleFunctionType(PointeeType->castAs());

3645}

3646

3647void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *,

3648 Qualifiers, SourceRange) {

3649 llvm_unreachable("Cannot mangle injected class name type.");

3650}

3651

3652void MicrosoftCXXNameMangler::mangleType(const TemplateSpecializationType *T,

3653 Qualifiers, SourceRange Range) {

3654 Error(Range.getBegin(), "template specialization type") << Range;

3655}

3656

3657void MicrosoftCXXNameMangler::mangleType(const DependentNameType *T, Qualifiers,

3658 SourceRange Range) {

3659 Error(Range.getBegin(), "dependent name type") << Range;

3660}

3661

3662void MicrosoftCXXNameMangler::mangleType(const PackExpansionType *T, Qualifiers,

3663 SourceRange Range) {

3665}

3666

3667void MicrosoftCXXNameMangler::mangleType(const PackIndexingType *T,

3668 Qualifiers Quals, SourceRange Range) {

3669 manglePointerCVQualifiers(Quals);

3670 mangleType(T->getSelectedType(), Range);

3671}

3672

3673void MicrosoftCXXNameMangler::mangleType(const TypeOfType *T, Qualifiers,

3674 SourceRange Range) {

3676}

3677

3678void MicrosoftCXXNameMangler::mangleType(const TypeOfExprType *T, Qualifiers,

3679 SourceRange Range) {

3681}

3682

3683void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T, Qualifiers,

3684 SourceRange Range) {

3686}

3687

3688void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T,

3689 Qualifiers, SourceRange Range) {

3690 Error(Range.getBegin(), "unary transform type") << Range;

3691}

3692

3693void MicrosoftCXXNameMangler::mangleType(const AutoType *T, Qualifiers,

3694 SourceRange Range) {

3695 assert(T->getDeducedType().isNull() && "expecting a dependent type!");

3696

3698}

3699

3700void MicrosoftCXXNameMangler::mangleType(

3701 const DeducedTemplateSpecializationType *T, Qualifiers, SourceRange Range) {

3702 assert(T->getDeducedType().isNull() && "expecting a dependent type!");

3703

3704 Error(Range.getBegin(), "deduced class template specialization type")

3706}

3707

3708void MicrosoftCXXNameMangler::mangleType(const AtomicType *T, Qualifiers,

3709 SourceRange Range) {

3710 QualType ValueType = T->getValueType();

3711

3712 llvm::SmallString<64> TemplateMangling;

3713 llvm::raw_svector_ostream Stream(TemplateMangling);

3714 MicrosoftCXXNameMangler Extra(Context, Stream);

3715 Stream << "?$";

3716 Extra.mangleSourceName("_Atomic");

3717 Extra.mangleType(ValueType, Range, QMM_Escape);

3718

3719 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});

3720}

3721

3722void MicrosoftCXXNameMangler::mangleType(const PipeType *T, Qualifiers,

3723 SourceRange Range) {

3724 QualType ElementType = T->getElementType();

3725

3726 llvm::SmallString<64> TemplateMangling;

3727 llvm::raw_svector_ostream Stream(TemplateMangling);

3728 MicrosoftCXXNameMangler Extra(Context, Stream);

3729 Stream << "?$";

3730 Extra.mangleSourceName("ocl_pipe");

3731 Extra.mangleType(ElementType, Range, QMM_Escape);

3732 Extra.mangleIntegerLiteral(llvm::APSInt::get(T->isReadOnly()));

3733

3734 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});

3735}

3736

3737void MicrosoftMangleContextImpl::mangleCXXName(GlobalDecl GD,

3738 raw_ostream &Out) {

3740 PrettyStackTraceDecl CrashInfo(D, SourceLocation(),

3741 getASTContext().getSourceManager(),

3742 "Mangling declaration");

3743

3744 msvc_hashing_ostream MHO(Out);

3745

3746 if (auto *CD = dyn_cast(D)) {

3748 MicrosoftCXXNameMangler mangler(*this, MHO, CD, Type);

3749 return mangler.mangle(GD);

3750 }

3751

3752 if (auto *DD = dyn_cast(D)) {

3754 MicrosoftCXXNameMangler mangler(*this, MHO, DD, Type);

3755 return mangler.mangle(GD);

3756 }

3757

3758 MicrosoftCXXNameMangler Mangler(*this, MHO);

3759 return Mangler.mangle(GD);

3760}

3761

3762void MicrosoftCXXNameMangler::mangleType(const BitIntType *T, Qualifiers,

3763 SourceRange Range) {

3764 llvm::SmallString<64> TemplateMangling;

3765 llvm::raw_svector_ostream Stream(TemplateMangling);

3766 MicrosoftCXXNameMangler Extra(Context, Stream);

3767 Stream << "?$";

3768 if (T->isUnsigned())

3769 Extra.mangleSourceName("_UBitInt");

3770 else

3771 Extra.mangleSourceName("_BitInt");

3772 Extra.mangleIntegerLiteral(llvm::APSInt::getUnsigned(T->getNumBits()));

3773

3774 mangleArtificialTagType(TagTypeKind::Struct, TemplateMangling, {"__clang"});

3775}

3776

3777void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,

3778 Qualifiers, SourceRange Range) {

3779 Error(Range.getBegin(), "DependentBitInt type") << Range;

3780}

3781

3782void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,

3783 Qualifiers, SourceRange Range) {

3784 llvm_unreachable("HLSL uses Itanium name mangling");

3785}

3786

3787void MicrosoftCXXNameMangler::mangleType(const HLSLInlineSpirvType *T,

3788 Qualifiers, SourceRange Range) {

3789 llvm_unreachable("HLSL uses Itanium name mangling");

3790}

3791

3792

3793

3794

3795

3796

3797

3798

3799

3800

3801

3802

3803

3804

3805

3806

3807

3808

3809

3810

3811

3812

3813

3814

3815

3818 MicrosoftCXXNameMangler &Mangler,

3819 raw_ostream &Out) {

3821 Out << '$';

3822 char AccessSpec;

3823 switch (AS) {

3825 llvm_unreachable("Unsupported access specifier");

3827 AccessSpec = '0';

3828 break;

3830 AccessSpec = '2';

3831 break;

3833 AccessSpec = '4';

3834 }

3836 Out << 'R' << AccessSpec;

3837 Mangler.mangleNumber(

3839 Mangler.mangleNumber(

3841 Mangler.mangleNumber(

3843 Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.NonVirtual));

3844 } else {

3845 Out << AccessSpec;

3846 Mangler.mangleNumber(

3848 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));

3849 }

3850 } else if (Adjustment.NonVirtual != 0) {

3851 switch (AS) {

3853 llvm_unreachable("Unsupported access specifier");

3855 Out << 'G';

3856 break;

3858 Out << 'O';

3859 break;

3861 Out << 'W';

3862 }

3863 Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual));

3864 } else {

3865 switch (AS) {

3867 llvm_unreachable("Unsupported access specifier");

3869 Out << 'A';

3870 break;

3872 Out << 'I';

3873 break;

3875 Out << 'Q';

3876 }

3877 }

3878}

3879

3880void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk(

3881 const CXXMethodDecl *MD, const MethodVFTableLocation &ML,

3882 raw_ostream &Out) {

3883 msvc_hashing_ostream MHO(Out);

3884 MicrosoftCXXNameMangler Mangler(*this, MHO);

3885 Mangler.getStream() << '?';

3886 Mangler.mangleVirtualMemPtrThunk(MD, ML);

3887}

3888

3889void MicrosoftMangleContextImpl::mangleThunk(const CXXMethodDecl *MD,

3890 const ThunkInfo &Thunk,

3891 bool ,

3892 raw_ostream &Out) {

3893 msvc_hashing_ostream MHO(Out);

3894 MicrosoftCXXNameMangler Mangler(*this, MHO);

3895 Mangler.getStream() << '?';

3896 Mangler.mangleName(MD);

3897

3898

3899

3900

3903

3905 assert(Thunk.Method != nullptr &&

3906 "Thunk info should hold the overridee decl");

3907

3908 const CXXMethodDecl *DeclForFPT = Thunk.Method ? Thunk.Method : MD;

3909 Mangler.mangleFunctionType(

3910 DeclForFPT->getType()->castAs(), MD);

3911}

3912

3913void MicrosoftMangleContextImpl::mangleCXXDtorThunk(const CXXDestructorDecl *DD,

3915 const ThunkInfo &Thunk,

3916 bool ,

3917 raw_ostream &Out) {

3918

3919

3920

3922 msvc_hashing_ostream MHO(Out);

3923 MicrosoftCXXNameMangler Mangler(*this, MHO, DD, Type);

3924 Mangler.getStream() << "??_E";

3925 Mangler.mangleName(DD->getParent());

3926 auto &Adjustment = Thunk.This;

3928 Mangler.mangleFunctionType(DD->getType()->castAs(), DD);

3929}

3930

3931void MicrosoftMangleContextImpl::mangleCXXVFTable(

3932 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,

3933 raw_ostream &Out) {

3934

3935

3936

3937

3938 msvc_hashing_ostream MHO(Out);

3939 MicrosoftCXXNameMangler Mangler(*this, MHO);

3940 if (Derived->hasAttr())

3941 Mangler.getStream() << "??_S";

3942 else

3943 Mangler.getStream() << "??_7";

3944 Mangler.mangleName(Derived);

3945 Mangler.getStream() << "6B";

3946 for (const CXXRecordDecl *RD : BasePath)

3947 Mangler.mangleName(RD);

3948 Mangler.getStream() << '@';

3949}

3950

3951void MicrosoftMangleContextImpl::mangleCXXVTable(const CXXRecordDecl *Derived,

3952 raw_ostream &Out) {

3953

3954 mangleCXXVFTable(Derived, {}, Out);

3955}

3956

3957void MicrosoftMangleContextImpl::mangleCXXVBTable(

3958 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,

3959 raw_ostream &Out) {

3960

3961

3962

3963

3964 msvc_hashing_ostream MHO(Out);

3965 MicrosoftCXXNameMangler Mangler(*this, MHO);

3966 Mangler.getStream() << "??_8";

3967 Mangler.mangleName(Derived);

3968 Mangler.getStream() << "7B";

3969 for (const CXXRecordDecl *RD : BasePath)

3970 Mangler.mangleName(RD);

3971 Mangler.getStream() << '@';

3972}

3973

3974void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {

3975 msvc_hashing_ostream MHO(Out);

3976 MicrosoftCXXNameMangler Mangler(*this, MHO);

3977 Mangler.getStream() << "??_R0";

3978 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);

3979 Mangler.getStream() << "@8";

3980}

3981

3982void MicrosoftMangleContextImpl::mangleCXXRTTIName(

3983 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {

3984 MicrosoftCXXNameMangler Mangler(*this, Out);

3985 Mangler.getStream() << '.';

3986 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);

3987}

3988

3989void MicrosoftMangleContextImpl::mangleCXXVirtualDisplacementMap(

3990 const CXXRecordDecl *SrcRD, const CXXRecordDecl *DstRD, raw_ostream &Out) {

3991 msvc_hashing_ostream MHO(Out);

3992 MicrosoftCXXNameMangler Mangler(*this, MHO);

3993 Mangler.getStream() << "??_K";

3994 Mangler.mangleName(SrcRD);

3995 Mangler.getStream() << "$C";

3996 Mangler.mangleName(DstRD);

3997}

3998

3999void MicrosoftMangleContextImpl::mangleCXXThrowInfo(QualType T, bool IsConst,

4000 bool IsVolatile,

4001 bool IsUnaligned,

4002 uint32_t NumEntries,

4003 raw_ostream &Out) {

4004 msvc_hashing_ostream MHO(Out);

4005 MicrosoftCXXNameMangler Mangler(*this, MHO);

4006 Mangler.getStream() << "_TI";

4007 if (IsConst)

4008 Mangler.getStream() << 'C';

4009 if (IsVolatile)

4010 Mangler.getStream() << 'V';

4011 if (IsUnaligned)

4012 Mangler.getStream() << 'U';

4013 Mangler.getStream() << NumEntries;

4014 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);

4015}

4016

4017void MicrosoftMangleContextImpl::mangleCXXCatchableTypeArray(

4018 QualType T, uint32_t NumEntries, raw_ostream &Out) {

4019 msvc_hashing_ostream MHO(Out);

4020 MicrosoftCXXNameMangler Mangler(*this, MHO);

4021 Mangler.getStream() << "_CTA";

4022 Mangler.getStream() << NumEntries;

4023 Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);

4024}

4025

4026void MicrosoftMangleContextImpl::mangleCXXCatchableType(

4027 QualType T, const CXXConstructorDecl *CD, CXXCtorType CT, uint32_t Size,

4028 uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBIndex,

4029 raw_ostream &Out) {

4030 MicrosoftCXXNameMangler Mangler(*this, Out);

4031 Mangler.getStream() << "_CT";

4032

4033 llvm::SmallString<64> RTTIMangling;

4034 {

4035 llvm::raw_svector_ostream Stream(RTTIMangling);

4036 msvc_hashing_ostream MHO(Stream);

4037 mangleCXXRTTI(T, MHO);

4038 }

4039 Mangler.getStream() << RTTIMangling;

4040

4041

4042

4043

4044

4045

4046

4047 bool OmitCopyCtor = getASTContext().getLangOpts().isCompatibleWithMSVC(

4048 LangOptions::MSVC2015) &&

4049 !getASTContext().getLangOpts().isCompatibleWithMSVC(

4050 LangOptions::MSVC2017_7);

4051 llvm::SmallString<64> CopyCtorMangling;

4052 if (!OmitCopyCtor && CD) {

4053 llvm::raw_svector_ostream Stream(CopyCtorMangling);

4054 msvc_hashing_ostream MHO(Stream);

4055 mangleCXXName(GlobalDecl(CD, CT), MHO);

4056 }

4057 Mangler.getStream() << CopyCtorMangling;

4058

4059 Mangler.getStream() << Size;

4060 if (VBPtrOffset == -1) {

4061 if (NVOffset) {

4062 Mangler.getStream() << NVOffset;

4063 }

4064 } else {

4065 Mangler.getStream() << NVOffset;

4066 Mangler.getStream() << VBPtrOffset;

4067 Mangler.getStream() << VBIndex;

4068 }

4069}

4070

4071void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassDescriptor(

4072 const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,

4073 uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) {

4074 msvc_hashing_ostream MHO(Out);

4075 MicrosoftCXXNameMangler Mangler(*this, MHO);

4076 Mangler.getStream() << "??_R1";

4077 Mangler.mangleNumber(NVOffset);

4078 Mangler.mangleNumber(VBPtrOffset);

4079 Mangler.mangleNumber(VBTableOffset);

4080 Mangler.mangleNumber(Flags);

4081 Mangler.mangleName(Derived);

4082 Mangler.getStream() << "8";

4083}

4084

4085void MicrosoftMangleContextImpl::mangleCXXRTTIBaseClassArray(

4086 const CXXRecordDecl *Derived, raw_ostream &Out) {

4087 msvc_hashing_ostream MHO(Out);

4088 MicrosoftCXXNameMangler Mangler(*this, MHO);

4089 Mangler.getStream() << "??_R2";

4090 Mangler.mangleName(Derived);

4091 Mangler.getStream() << "8";

4092}

4093

4094void MicrosoftMangleContextImpl::mangleCXXRTTIClassHierarchyDescriptor(

4095 const CXXRecordDecl *Derived, raw_ostream &Out) {

4096 msvc_hashing_ostream MHO(Out);

4097 MicrosoftCXXNameMangler Mangler(*this, MHO);

4098 Mangler.getStream() << "??_R3";

4099 Mangler.mangleName(Derived);

4100 Mangler.getStream() << "8";

4101}

4102

4103void MicrosoftMangleContextImpl::mangleCXXRTTICompleteObjectLocator(

4104 const CXXRecordDecl *Derived, ArrayRef<const CXXRecordDecl *> BasePath,

4105 raw_ostream &Out) {

4106

4107

4108

4109

4110 llvm::SmallString<64> VFTableMangling;

4111 llvm::raw_svector_ostream Stream(VFTableMangling);

4112 mangleCXXVFTable(Derived, BasePath, Stream);

4113

4114 if (VFTableMangling.starts_with("??@")) {

4115 assert(VFTableMangling.ends_with("@"));

4116 Out << VFTableMangling << "??_R4@";

4117 return;

4118 }

4119

4120 assert(VFTableMangling.starts_with("??_7") ||

4121 VFTableMangling.starts_with("??_S"));

4122

4123 Out << "??_R4" << VFTableMangling.str().drop_front(4);

4124}

4125

4126void MicrosoftMangleContextImpl::mangleSEHFilterExpression(

4127 GlobalDecl EnclosingDecl, raw_ostream &Out) {

4128 msvc_hashing_ostream MHO(Out);

4129 MicrosoftCXXNameMangler Mangler(*this, MHO);

4130

4131

4132

4133

4134 Mangler.getStream() << "?filt$" << SEHFilterIds[EnclosingDecl]++ << "@0@";

4135 Mangler.mangleName(EnclosingDecl);

4136}

4137

4138void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(

4139 GlobalDecl EnclosingDecl, raw_ostream &Out) {

4140 msvc_hashing_ostream MHO(Out);

4141 MicrosoftCXXNameMangler Mangler(*this, MHO);

4142

4143

4144

4145

4146 Mangler.getStream() << "?fin$" << SEHFinallyIds[EnclosingDecl]++ << "@0@";

4147 Mangler.mangleName(EnclosingDecl);

4148}

4149

4150void MicrosoftMangleContextImpl::mangleCanonicalTypeName(

4151 QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {

4152

4153

4154 MicrosoftCXXNameMangler Mangler(*this, Out);

4155 Mangler.getStream() << '?';

4156 Mangler.mangleType(T.getCanonicalType(), SourceRange());

4157}

4158

4159void MicrosoftMangleContextImpl::mangleReferenceTemporary(

4160 const VarDecl *VD, unsigned ManglingNumber, raw_ostream &Out) {

4161 msvc_hashing_ostream MHO(Out);

4162 MicrosoftCXXNameMangler Mangler(*this, MHO);

4163

4164 Mangler.getStream() << "?";

4165 Mangler.mangleSourceName("$RT" + llvm::utostr(ManglingNumber));

4166 Mangler.mangle(VD, "");

4167}

4168

4169void MicrosoftMangleContextImpl::mangleThreadSafeStaticGuardVariable(

4170 const VarDecl *VD, unsigned GuardNum, raw_ostream &Out) {

4171 msvc_hashing_ostream MHO(Out);

4172 MicrosoftCXXNameMangler Mangler(*this, MHO);

4173

4174 Mangler.getStream() << "?";

4175 Mangler.mangleSourceName("$TSS" + llvm::utostr(GuardNum));

4176 Mangler.mangleNestedName(VD);

4177 Mangler.getStream() << "@4HA";

4178}

4179

4180void MicrosoftMangleContextImpl::mangleStaticGuardVariable(const VarDecl *VD,

4181 raw_ostream &Out) {

4182

4183

4184

4185

4186

4187

4188

4189

4190

4191

4192 msvc_hashing_ostream MHO(Out);

4193 MicrosoftCXXNameMangler Mangler(*this, MHO);

4194

4196 if (Visible) {

4197 Mangler.getStream() << (VD->getTLSKind() ? "??__J" : "??_B");

4198 } else {

4199 Mangler.getStream() << "?$S1@";

4200 }

4201 unsigned ScopeDepth = 0;

4202 if (Visible && !getNextDiscriminator(VD, ScopeDepth))

4203

4204

4205

4206 Mangler.mangle(VD, "");

4207 else

4208 Mangler.mangleNestedName(VD);

4209 Mangler.getStream() << (Visible ? "@5" : "@4IA");

4210 if (ScopeDepth)

4211 Mangler.mangleNumber(ScopeDepth);

4212}

4213

4214void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,

4215 char CharCode,

4216 raw_ostream &Out) {

4217 msvc_hashing_ostream MHO(Out);

4218 MicrosoftCXXNameMangler Mangler(*this, MHO);

4219 Mangler.getStream() << "??__" << CharCode;

4221 Mangler.getStream() << '?';

4222 Mangler.mangleName(D);

4223 Mangler.mangleVariableEncoding(D);

4224 Mangler.getStream() << "@@";

4225 } else {

4226 Mangler.mangleName(D);

4227 }

4228

4229

4230 Mangler.getStream() << "YAXXZ";

4231}

4232

4233void MicrosoftMangleContextImpl::mangleDynamicInitializer(const VarDecl *D,

4234 raw_ostream &Out) {

4235

4236 mangleInitFiniStub(D, 'E', Out);

4237}

4238

4239void

4240MicrosoftMangleContextImpl::mangleDynamicAtExitDestructor(const VarDecl *D,

4241 raw_ostream &Out) {

4242

4243 mangleInitFiniStub(D, 'F', Out);

4244}

4245

4246void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,

4247 raw_ostream &Out) {

4248

4249

4250

4251

4252

4253

4254

4255

4256

4257

4258

4259

4260

4261

4262

4263

4264

4265

4266

4267 MicrosoftCXXNameMangler Mangler(*this, Out);

4268 Mangler.getStream() << "??_C@_";

4269

4270

4271

4272

4273

4274

4275

4276 unsigned StringLength =

4277 getASTContext().getAsConstantArrayType(SL->getType())->getZExtSize();

4278 unsigned StringByteLength = StringLength * SL->getCharByteWidth();

4279

4280

4282 Mangler.getStream() << '1';

4283 else

4284 Mangler.getStream() << '0';

4285

4286

4287

4288 Mangler.mangleNumber(StringByteLength);

4289

4290 auto GetLittleEndianByte = [&SL](unsigned Index) {

4292 if (Index / CharByteWidth >= SL->getLength())

4293 return static_cast<char>(0);

4295 unsigned OffsetInCodeUnit = Index % CharByteWidth;

4296 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);

4297 };

4298

4299 auto GetBigEndianByte = [&SL](unsigned Index) {

4301 if (Index / CharByteWidth >= SL->getLength())

4302 return static_cast<char>(0);

4304 unsigned OffsetInCodeUnit = (CharByteWidth - 1) - (Index % CharByteWidth);

4305 return static_cast<char>((CodeUnit >> (8 * OffsetInCodeUnit)) & 0xff);

4306 };

4307

4308

4309 llvm::JamCRC JC;

4310 for (unsigned I = 0, E = StringByteLength; I != E; ++I)

4311 JC.update(GetLittleEndianByte(I));

4312

4313

4314

4315 Mangler.mangleNumber(JC.getCRC());

4316

4317

4318

4319

4320

4321 auto MangleByte = [&Mangler](char Byte) {

4322

4323

4324

4325

4326

4327

4329 Mangler.getStream() << Byte;

4330 } else if (isLetter(Byte & 0x7f)) {

4331 Mangler.getStream() << '?' << static_cast<char>(Byte & 0x7f);

4332 } else {

4333 const char SpecialChars[] = {',', '/', '\\', ':', '.',

4334 ' ', '\n', '\t', '\'', '-'};

4335 const char *Pos = llvm::find(SpecialChars, Byte);

4336 if (Pos != std::end(SpecialChars)) {

4337 Mangler.getStream() << '?' << (Pos - std::begin(SpecialChars));

4338 } else {

4339 Mangler.getStream() << "?$";

4340 Mangler.getStream() << static_cast<char>('A' + ((Byte >> 4) & 0xf));

4341 Mangler.getStream() << static_cast<char>('A' + (Byte & 0xf));

4342 }

4343 }

4344 };

4345

4346

4347 unsigned MaxBytesToMangle = SL->isWide() ? 64U : 32U;

4348 unsigned NumBytesToMangle = std::min(MaxBytesToMangle, StringByteLength);

4349 for (unsigned I = 0; I != NumBytesToMangle; ++I) {

4351 MangleByte(GetBigEndianByte(I));

4352 else

4353 MangleByte(GetLittleEndianByte(I));

4354 }

4355

4356 Mangler.getStream() << '@';

4357}

4358

4359void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,

4360 Qualifiers Quals) {

4362 manglePointerCVQualifiers(Quals);

4363 manglePointerExtQualifiers(Quals, PointeeType);

4364 if (const FunctionProtoType *FPT = PointeeType->getAs()) {

4365 Out << '8';

4366 mangleName(T->getMostRecentCXXRecordDecl());

4367 mangleFunctionType(FPT, nullptr, true);

4368 } else {

4369 mangleQualifiers(PointeeType.getQualifiers(), true);

4370 mangleName(T->getMostRecentCXXRecordDecl());

4371 mangleAutoReturnType(PointeeType, QMM_Drop);

4372 }

4373}

4374

4375void MicrosoftCXXNameMangler::mangleAutoReturnType(const PointerType *T,

4376 Qualifiers Quals) {

4379 "Unexpected address space mangling required");

4380

4381 manglePointerCVQualifiers(Quals);

4382 manglePointerExtQualifiers(Quals, PointeeType);

4383

4384 if (const FunctionProtoType *FPT = PointeeType->getAs()) {

4385 Out << '6';

4386 mangleFunctionType(FPT);

4387 } else {

4388 mangleAutoReturnType(PointeeType, QMM_Mangle);

4389 }

4390}

4391

4392void MicrosoftCXXNameMangler::mangleAutoReturnType(const LValueReferenceType *T,

4393 Qualifiers Quals) {

4395 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");

4396 Out << 'A';

4397 manglePointerExtQualifiers(Quals, PointeeType);

4398 mangleAutoReturnType(PointeeType, QMM_Mangle);

4399}

4400

4401void MicrosoftCXXNameMangler::mangleAutoReturnType(const RValueReferenceType *T,

4402 Qualifiers Quals) {

4404 assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");

4405 Out << "$$Q";

4406 manglePointerExtQualifiers(Quals, PointeeType);

4407 mangleAutoReturnType(PointeeType, QMM_Mangle);

4408}

4409

4412 bool IsAux) {

4413 return new MicrosoftMangleContextImpl(Context, Diags, IsAux);

4414}

Enums/classes describing ABI related information about constructors, destructors and thunks.

Defines the clang::ASTContext interface.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

This file defines OpenMP nodes for declarative directives.

Defines the C++ template declaration subclasses.

Defines the clang::Expr interface and subclasses for C++ expressions.

TokenType getType() const

Returns the token's type, e.g.

static const GlobalDecl isTemplate(GlobalDecl GD, const TemplateArgumentList *&TemplateArgs)

static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)

llvm::MachO::Record Record

static ValueDecl * getAsArrayToPointerDecayedDecl(QualType T, const APValue &V)

If value V (with type T) represents a decayed pointer to the first element of an array,...

Definition MicrosoftMangle.cpp:1746

static void mangleThunkThisAdjustment(AccessSpecifier AS, const ThisAdjustment &Adjustment, MicrosoftCXXNameMangler &Mangler, raw_ostream &Out)

Definition MicrosoftMangle.cpp:3816

static bool hasAttr(const Decl *D, bool IgnoreImplicitAttr)

Defines the SourceManager interface.

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

APValue & getVectorElt(unsigned I)

@ Indeterminate

This object has an indeterminate value (C++ [basic.indet]).

@ None

There is no such object (it's outside its lifetime).

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

TypedefNameDecl * getTypedefNameForUnnamedTagDecl(const TagDecl *TD)

bool addressSpaceMapManglingFor(LangAS AS) const

const clang::PrintingPolicy & getPrintingPolicy() const

DeclaratorDecl * getDeclaratorForUnnamedTagDecl(const TagDecl *TD)

unsigned getTargetAddressSpace(LangAS AS) const

CharUnits getVBPtrOffset() const

getVBPtrOffset - Get the offset for virtual base table pointer.

Represents an array type, per C99 6.7.5.2 - Array Declarators.

QualType getElementType() const

Represents a block literal declaration, which is like an unnamed FunctionDecl.

bool isImplicitObjectMemberFunction() const

[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

Decl * getLambdaContextDecl() const

Retrieve the declaration that provides additional context for a lambda, when the normal declaration c...

CXXRecordDecl * getMostRecentDecl()

bool isLambda() const

Determine whether this class describes a lambda function object.

unsigned getLambdaManglingNumber() const

If this is the closure type of a lambda expression, retrieve the number to be used for name mangling ...

MSInheritanceModel getMSInheritanceModel() const

Returns the inheritance model used for this record.

bool nullFieldOffsetIsZero() const

In the Microsoft C++ ABI, use zero for the field offset of a null data member pointer if we can guara...

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

Represents a class template specialization, which refers to a class template with a given set of temp...

llvm::APInt getSize() const

Return the constant array size as an APInt.

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

bool isTranslationUnit() const

DeclContext * getRedeclContext()

getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...

bool isFunctionOrMethod() const

Decl - This represents one declaration (or definition), e.g.

SourceLocation getLocation() const

DeclContext * getDeclContext()

AccessSpecifier getAccess() const

IdentifierInfo * getAsIdentifierInfo() const

Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...

@ CXXConversionFunctionName

NameKind getNameKind() const

Determine what kind of name this is.

Expr * getSizeExpr() const

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

This represents one expression.

std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const

isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

Represents a function declaration or definition.

const ParmVarDecl * getParamDecl(unsigned i) const

FunctionTemplateDecl * getPrimaryTemplate() const

Retrieve the primary template that this function template specialization either specializes or was in...

FunctionDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

const TemplateArgumentList * getTemplateSpecializationArgs() const

Retrieve the template arguments used to produce this function template specialization from the primar...

bool isExternC() const

Determines whether this function is a function with external, C linkage.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

Represents a prototype with parameter type info, e.g.

unsigned getNumParams() const

Qualifiers getMethodQuals() const

QualType getParamType(unsigned i) const

CanThrowResult canThrow() const

Determine whether this function type has a non-throwing exception specification.

bool isVariadic() const

Whether this function prototype is variadic.

RefQualifierKind getRefQualifier() const

Retrieve the ref-qualifier associated with this function type.

FunctionDecl * getTemplatedDecl() const

Get the underlying function declaration of the template.

FunctionType - C99 6.7.5.3 - Function Declarators.

CallingConv getCallConv() const

QualType getReturnType() const

GlobalDecl - represents a global declaration.

CXXCtorType getCtorType() const

KernelReferenceKind getKernelReferenceKind() const

GlobalDecl getWithDecl(const Decl *D)

CXXDtorType getDtorType() const

const Decl * getDecl() const

StringRef getName() const

Return the actual identifier string.

An lvalue reference type, per C++11 [dcl.ref].

A pointer to member type per C++ 8.3.3 - Pointers to members.

static MicrosoftMangleContext * create(ASTContext &Context, DiagnosticsEngine &Diags, bool IsAux=false)

Definition MicrosoftMangle.cpp:4410

MicrosoftMangleContext(ASTContext &C, DiagnosticsEngine &D, bool IsAux=false)

MethodVFTableLocation getMethodVFTableLocation(GlobalDecl GD)

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

Linkage getFormalLinkage() const

Get the linkage from a semantic point of view.

bool hasLinkage() const

Determine whether this declaration has linkage.

bool isExternallyVisible() const

NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.

Represents an Objective-C protocol declaration.

Represents a parameter to a function.

unsigned getFunctionScopeIndex() const

Returns the index of this parameter in its prototype or method scope.

bool isExplicitObjectParameter() const

bool isAddressDiscriminated() const

unsigned getExtraDiscriminator() const

PointerType - C99 6.7.5.1 - Pointer Declarators.

A (possibly-)qualified type.

QualType getDesugaredType(const ASTContext &Context) const

Return the specified type with any "sugar" removed from the type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

QualType getCanonicalType() const

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

void * getAsOpaquePtr() const

Qualifiers getLocalQualifiers() const

Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...

The collection of all-type qualifiers we support.

@ OCL_Strong

Assigning into this object requires the old value to be released and the new value to be retained.

@ OCL_ExplicitNone

This object can be modified without requiring retains or releases.

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

@ OCL_Autoreleasing

Assigning into this object requires a lifetime extension.

bool hasUnaligned() const

bool hasAddressSpace() const

PointerAuthQualifier getPointerAuth() const

bool hasObjCLifetime() const

ObjCLifetime getObjCLifetime() const

Qualifiers withoutObjCLifetime() const

LangAS getAddressSpace() const

An rvalue reference type, per C++11 [dcl.ref].

field_range fields() const

bool isAnonymousStructOrUnion() const

Whether this is an anonymous struct or union.

decl_type * getFirstDecl()

Return the first declaration of this declaration or itself if this is the only declaration.

This class handles loading and caching of source files into memory.

A trivial tuple used to represent a source range.

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

const char * getStmtClassName() const

unsigned getLength() const

uint32_t getCodeUnit(size_t i) const

unsigned getCharByteWidth() const

Represents the declaration of a struct/union/class/enum.

TagDecl * getDefinition() const

Returns the TagDecl that actually defines this struct/union/class/enum.

TypedefNameDecl * getTypedefNameForAnonDecl() const

TagKind getTagKind() const

A template argument list.

unsigned size() const

Retrieve the number of template arguments in this template argument list.

Represents a template argument.

ArrayRef< TemplateArgument > getPackAsArray() const

Return the array of arguments in this template argument pack.

QualType getStructuralValueType() const

Get the type of a StructuralValue.

QualType getParamTypeForDecl() const

Expr * getAsExpr() const

Retrieve the template argument as an expression.

QualType getNonTypeTemplateArgumentType() const

If this is a non-type template argument, get its type.

QualType getAsType() const

Retrieve the type for a type template argument.

llvm::APSInt getAsIntegral() const

Retrieve the template argument as an integral value.

QualType getNullPtrType() const

Retrieve the type for null non-type template argument.

TemplateName getAsTemplate() const

Retrieve the template name for a template name argument.

QualType getIntegralType() const

Retrieve the type of the integral value.

ValueDecl * getAsDecl() const

Retrieve the declaration for a declaration non-type template argument.

@ Declaration

The template argument is a declaration that was provided for a pointer, reference,...

@ Template

The template argument is a template name that was provided for a template template parameter.

@ StructuralValue

The template argument is a non-type template argument that can't be represented by the special-case D...

@ Pack

The template argument is actually a parameter pack.

@ TemplateExpansion

The template argument is a pack expansion of a template name that was provided for a template templat...

@ NullPtr

The template argument is a null pointer or null pointer to member that was provided for a non-type te...

@ Type

The template argument is a type.

@ Null

Represents an empty template argument, e.g., one that has not been deduced.

@ Integral

The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...

@ Expression

The template argument is an expression, and we've not resolved it to one of the other forms yet,...

ArgKind getKind() const

Return the kind of stored template argument.

const APValue & getAsStructuralValue() const

Get the value of a StructuralValue.

The base class of all kinds of template declarations (e.g., class, function, etc.).

NamedDecl * getTemplatedDecl() const

Get the underlying, templated declaration.

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const

Retrieve the underlying template declaration that this template name refers to, if known.

NamedDecl * getParam(unsigned Idx)

bool isBlockPointerType() const

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

bool isPointerType() const

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

AutoType * getContainedAutoType() const

Get the AutoType whose type will be deduced for a variable with an initializer of this type.

bool isMemberDataPointerType() const

bool isMemberPointerType() const

const ArrayType * getAsArrayTypeUnsafe() const

A variant of getAs<> for array types which silently discards qualifiers from the outermost type.

bool isFunctionType() const

bool isAnyPointerType() const

TypeClass getTypeClass() const

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

TLSKind getTLSKind() const

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

bool isStaticDataMember() const

Determines whether this is a static data member.

bool isStaticLocal() const

Returns true if a variable with function scope is a static local variable.

bool isExternC() const

Determines whether this variable is a variable with external, C linkage.

Represents a variable template specialization, which refers to a variable template with a given set o...

Defines the clang::TargetInfo interface.

std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl

All declarations that can appear in a module declaration.

The JSON file list parser is used to communicate input to InstallAPI.

OverloadedOperatorKind

Enumeration specifying the different kinds of C++ overloaded operators.

@ OO_None

Not an overloaded operator.

@ NUM_OVERLOADED_OPERATORS

CXXCtorType

C++ constructor types.

@ Ctor_DefaultClosure

Default closure variant of a ctor.

@ Ctor_CopyingClosure

Copying closure variant of a ctor.

@ Ctor_Complete

Complete object ctor.

bool isa(CodeGen::Address addr)

CustomizableOptional< FileEntryRef > OptionalFileEntryRef

LLVM_READONLY bool isAsciiIdentifierContinue(unsigned char c)

RefQualifierKind

The kind of C++11 ref-qualifier associated with a function type.

@ RQ_None

No ref-qualifier was provided.

@ RQ_LValue

An lvalue ref-qualifier was provided (&).

@ RQ_RValue

An rvalue ref-qualifier was provided (&&).

bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, MSInheritanceModel Inheritance)

AccessSpecifier

A C++ access specifier (public, private, protected), plus the special value "none" which means differ...

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

LanguageLinkage

Describes the different kinds of language linkage (C++ [dcl.link]) that an entity may have.

bool inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance)

LLVM_READONLY bool isLetter(unsigned char c)

Return true if this character is an ASCII letter: [a-zA-Z].

bool inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance)

@ Result

The result type of a method or function.

const FunctionProtoType * T

CXXDtorType

C++ destructor types.

@ Dtor_VectorDeleting

Vector deleting dtor.

@ Dtor_Comdat

The COMDAT used for dtors.

@ Dtor_Unified

GCC-style unified dtor.

@ Dtor_Base

Base object dtor.

@ Dtor_Complete

Complete object dtor.

@ Dtor_Deleting

Deleting dtor.

TagTypeKind

The kind of a tag type.

@ Type

The name was classified as a type.

LangAS

Defines the address space values used by the address space qualifier of QualType.

bool isPtrSizeAddressSpace(LangAS AS)

MSInheritanceModel

Assigned inheritance model for a class in the MS C++ ABI.

CallingConv

CallingConv - Specifies the calling convention that a function uses.

U cast(CodeGen::Address addr)

void mangleObjCMethodName(raw_ostream &OS, bool includePrefixByte, bool isInstanceMethod, StringRef ClassName, std::optional< StringRef > CategoryName, StringRef MethodName)

Extract mangling function name from MangleContext such that swift can call it to prepare for ObjCDire...

int const char * function

const CXXRecordDecl * VBase

If nonnull, holds the last vbase which contains the vfptr that the method definition is adjusted to.

CharUnits VFPtrOffset

This is the offset of the vfptr from the start of the last vbase, or the complete type if there are n...

uint64_t VBTableIndex

If nonzero, holds the vbtable index of the virtual base with the vfptr.

uint64_t Index

Method's index in the vftable.

A this pointer adjustment.

union clang::ThisAdjustment::VirtualAdjustment Virtual

int64_t NonVirtual

The non-virtual adjustment from the derived object to its nearest virtual base.

ThisAdjustment This

The this pointer adjustment.

const CXXMethodDecl * Method

Holds a pointer to the overridden method this thunk is for, if needed by the ABI to distinguish diffe...

ReturnAdjustment Return

The return adjustment.

int32_t VtordispOffset

The offset of the vtordisp (in bytes), relative to the ECX.

struct clang::ThisAdjustment::VirtualAdjustment::@312251255113040203233347230177110330127151157305 Microsoft

int32_t VBOffsetOffset

The offset (in bytes) of the vbase offset in the vbtable.

int32_t VBPtrOffset

The offset of the vbptr of the derived class (in bytes), relative to the ECX after vtordisp adjustmen...