@@ -408,6 +408,8 @@ class MicrosoftCXXNameMangler {
408
408
void mangleSourceName (StringRef Name);
409
409
void mangleNestedName (GlobalDecl GD);
410
410
411
+ void mangleAutoReturnType (QualType T, QualifierMangleMode QMM);
412
+
411
413
private:
412
414
bool isStructorDecl (const NamedDecl *ND) const {
413
415
return ND == Structor || getStructor (ND) == Structor;
@@ -477,6 +479,11 @@ class MicrosoftCXXNameMangler {
477
479
SourceRange Range);
478
480
void mangleObjCKindOfType (const ObjCObjectType *T, Qualifiers Quals,
479
481
SourceRange Range);
482
+
483
+ void mangleAutoReturnType (const MemberPointerType *T, Qualifiers Quals);
484
+ void mangleAutoReturnType (const PointerType *T, Qualifiers Quals);
485
+ void mangleAutoReturnType (const LValueReferenceType *T, Qualifiers Quals);
486
+ void mangleAutoReturnType (const RValueReferenceType *T, Qualifiers Quals);
480
487
};
481
488
}
482
489
@@ -2494,6 +2501,57 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
2494
2501
mangleArtificialTagType (TagTypeKind::Struct, ASMangling, {" __clang" });
2495
2502
}
2496
2503
2504
+ void MicrosoftCXXNameMangler::mangleAutoReturnType (QualType T,
2505
+ QualifierMangleMode QMM) {
2506
+ assert (getASTContext ().getLangOpts ().isCompatibleWithMSVC (
2507
+ LangOptions::MSVC2019) &&
2508
+ " Cannot mangle MSVC 2017 auto return types!" );
2509
+
2510
+ if (isa<AutoType>(T)) {
2511
+ const auto *AT = T->getContainedAutoType ();
2512
+ Qualifiers Quals = T.getLocalQualifiers ();
2513
+
2514
+ if (QMM == QMM_Result)
2515
+ Out << ' ?' ;
2516
+ if (QMM != QMM_Drop)
2517
+ mangleQualifiers (Quals, false );
2518
+ Out << (AT->isDecltypeAuto () ? " _T" : " _P" );
2519
+ return ;
2520
+ }
2521
+
2522
+ T = T.getDesugaredType (getASTContext ());
2523
+ Qualifiers Quals = T.getLocalQualifiers ();
2524
+
2525
+ switch (QMM) {
2526
+ case QMM_Drop:
2527
+ case QMM_Result:
2528
+ break ;
2529
+ case QMM_Mangle:
2530
+ mangleQualifiers (Quals, false );
2531
+ break ;
2532
+ default :
2533
+ llvm_unreachable (" QMM_Escape unexpected" );
2534
+ }
2535
+
2536
+ const Type *ty = T.getTypePtr ();
2537
+ switch (ty->getTypeClass ()) {
2538
+ case Type::MemberPointer:
2539
+ mangleAutoReturnType (cast<MemberPointerType>(ty), Quals);
2540
+ break ;
2541
+ case Type::Pointer:
2542
+ mangleAutoReturnType (cast<PointerType>(ty), Quals);
2543
+ break ;
2544
+ case Type::LValueReference:
2545
+ mangleAutoReturnType (cast<LValueReferenceType>(ty), Quals);
2546
+ break ;
2547
+ case Type::RValueReference:
2548
+ mangleAutoReturnType (cast<RValueReferenceType>(ty), Quals);
2549
+ break ;
2550
+ default :
2551
+ llvm_unreachable (" Invalid type expected" );
2552
+ }
2553
+ }
2554
+
2497
2555
void MicrosoftCXXNameMangler::mangleType (QualType T, SourceRange Range,
2498
2556
QualifierMangleMode QMM) {
2499
2557
// Don't use the canonical types. MSVC includes things like 'const' on
@@ -2907,17 +2965,60 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
2907
2965
// can differ by their calling convention and are typically deduced. So
2908
2966
// we make sure that this type gets mangled properly.
2909
2967
mangleType (ResultType, Range, QMM_Result);
2910
- } else if (const auto *AT = dyn_cast_or_null<AutoType>(
2911
- ResultType->getContainedAutoType ())) {
2912
- Out << ' ?' ;
2913
- mangleQualifiers (ResultType.getLocalQualifiers (), /* IsMember=*/ false );
2914
- Out << ' ?' ;
2968
+ } else if (IsInLambda) {
2969
+ if (const auto *AT = ResultType->getContainedAutoType ()) {
2970
+ assert (AT->getKeyword () == AutoTypeKeyword::Auto &&
2971
+ " should only need to mangle auto!" );
2972
+ (void )AT;
2973
+ Out << ' ?' ;
2974
+ mangleQualifiers (ResultType.getLocalQualifiers (), /* IsMember=*/ false );
2975
+ Out << ' ?' ;
2976
+ mangleSourceName (" <auto>" );
2977
+ Out << ' @' ;
2978
+ } else {
2979
+ Out << ' @' ;
2980
+ }
2981
+ } else if (const auto *AT = ResultType->getContainedAutoType ()) {
2915
2982
assert (AT->getKeyword () != AutoTypeKeyword::GNUAutoType &&
2916
2983
" shouldn't need to mangle __auto_type!" );
2917
- mangleSourceName (AT->isDecltypeAuto () ? " <decltype-auto>" : " <auto>" );
2918
- Out << ' @' ;
2919
- } else if (IsInLambda) {
2920
- Out << ' @' ;
2984
+
2985
+ // If we have any pointer types with the clang address space extension
2986
+ // then defer to the custom clang mangling to keep backwards
2987
+ // compatibility. See `mangleType(const PointerType *T, Qualifiers Quals,
2988
+ // SourceRange Range)` for details.
2989
+ auto UseClangMangling = [](QualType ResultType) {
2990
+ QualType T = ResultType;
2991
+ while (isa<PointerType>(T.getTypePtr ())) {
2992
+ T = T->getPointeeType ();
2993
+ if (T.getQualifiers ().hasAddressSpace ())
2994
+ return true ;
2995
+ }
2996
+ return false ;
2997
+ };
2998
+
2999
+ if (getASTContext ().getLangOpts ().isCompatibleWithMSVC (
3000
+ LangOptions::MSVC2019) &&
3001
+ !UseClangMangling (ResultType)) {
3002
+ if (D && !D->getPrimaryTemplate ()) {
3003
+ Out << ' @' ;
3004
+ } else {
3005
+ if (D && D->getPrimaryTemplate ()) {
3006
+ const FunctionProtoType *FPT = D->getPrimaryTemplate ()
3007
+ ->getTemplatedDecl ()
3008
+ ->getFirstDecl ()
3009
+ ->getType ()
3010
+ ->castAs <FunctionProtoType>();
3011
+ ResultType = FPT->getReturnType ();
3012
+ }
3013
+ mangleAutoReturnType (ResultType, QMM_Result);
3014
+ }
3015
+ } else {
3016
+ Out << ' ?' ;
3017
+ mangleQualifiers (ResultType.getLocalQualifiers (), /* IsMember=*/ false );
3018
+ Out << ' ?' ;
3019
+ mangleSourceName (AT->isDecltypeAuto () ? " <decltype-auto>" : " <auto>" );
3020
+ Out << ' @' ;
3021
+ }
2921
3022
} else {
2922
3023
if (ResultType->isVoidType ())
2923
3024
ResultType = ResultType.getUnqualifiedType ();
@@ -4220,6 +4321,57 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
4220
4321
Mangler.getStream () << ' @' ;
4221
4322
}
4222
4323
4324
+ void MicrosoftCXXNameMangler::mangleAutoReturnType (const MemberPointerType *T,
4325
+ Qualifiers Quals) {
4326
+ QualType PointeeType = T->getPointeeType ();
4327
+ manglePointerCVQualifiers (Quals);
4328
+ manglePointerExtQualifiers (Quals, PointeeType);
4329
+ if (const FunctionProtoType *FPT = PointeeType->getAs <FunctionProtoType>()) {
4330
+ Out << ' 8' ;
4331
+ mangleName (T->getClass ()->castAs <RecordType>()->getDecl ());
4332
+ mangleFunctionType (FPT, nullptr , true );
4333
+ } else {
4334
+ mangleQualifiers (PointeeType.getQualifiers (), true );
4335
+ mangleName (T->getClass ()->castAs <RecordType>()->getDecl ());
4336
+ mangleAutoReturnType (PointeeType, QMM_Drop);
4337
+ }
4338
+ }
4339
+
4340
+ void MicrosoftCXXNameMangler::mangleAutoReturnType (const PointerType *T,
4341
+ Qualifiers Quals) {
4342
+ QualType PointeeType = T->getPointeeType ();
4343
+ assert (!PointeeType.getQualifiers ().hasAddressSpace () &&
4344
+ " Unexpected address space mangling required" );
4345
+
4346
+ manglePointerCVQualifiers (Quals);
4347
+ manglePointerExtQualifiers (Quals, PointeeType);
4348
+
4349
+ if (const FunctionProtoType *FPT = PointeeType->getAs <FunctionProtoType>()) {
4350
+ Out << ' 6' ;
4351
+ mangleFunctionType (FPT);
4352
+ } else {
4353
+ mangleAutoReturnType (PointeeType, QMM_Mangle);
4354
+ }
4355
+ }
4356
+
4357
+ void MicrosoftCXXNameMangler::mangleAutoReturnType (const LValueReferenceType *T,
4358
+ Qualifiers Quals) {
4359
+ QualType PointeeType = T->getPointeeType ();
4360
+ assert (!Quals.hasConst () && !Quals.hasVolatile () && " unexpected qualifier!" );
4361
+ Out << ' A' ;
4362
+ manglePointerExtQualifiers (Quals, PointeeType);
4363
+ mangleAutoReturnType (PointeeType, QMM_Mangle);
4364
+ }
4365
+
4366
+ void MicrosoftCXXNameMangler::mangleAutoReturnType (const RValueReferenceType *T,
4367
+ Qualifiers Quals) {
4368
+ QualType PointeeType = T->getPointeeType ();
4369
+ assert (!Quals.hasConst () && !Quals.hasVolatile () && " unexpected qualifier!" );
4370
+ Out << " $$Q" ;
4371
+ manglePointerExtQualifiers (Quals, PointeeType);
4372
+ mangleAutoReturnType (PointeeType, QMM_Mangle);
4373
+ }
4374
+
4223
4375
MicrosoftMangleContext *MicrosoftMangleContext::create (ASTContext &Context,
4224
4376
DiagnosticsEngine &Diags,
4225
4377
bool IsAux) {
0 commit comments