@@ -408,6 +408,8 @@ class MicrosoftCXXNameMangler {
408408 void mangleSourceName (StringRef Name);
409409 void mangleNestedName (GlobalDecl GD);
410410
411+ void mangleAutoReturnType (QualType T, QualifierMangleMode QMM);
412+
411413private:
412414 bool isStructorDecl (const NamedDecl *ND) const {
413415 return ND == Structor || getStructor (ND) == Structor;
@@ -477,6 +479,11 @@ class MicrosoftCXXNameMangler {
477479 SourceRange Range);
478480 void mangleObjCKindOfType (const ObjCObjectType *T, Qualifiers Quals,
479481 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);
480487};
481488}
482489
@@ -2494,6 +2501,57 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
24942501 mangleArtificialTagType (TagTypeKind::Struct, ASMangling, {" __clang" });
24952502}
24962503
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+
24972555void MicrosoftCXXNameMangler::mangleType (QualType T, SourceRange Range,
24982556 QualifierMangleMode QMM) {
24992557 // Don't use the canonical types. MSVC includes things like 'const' on
@@ -2907,17 +2965,60 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
29072965 // can differ by their calling convention and are typically deduced. So
29082966 // we make sure that this type gets mangled properly.
29092967 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 ()) {
29152982 assert (AT->getKeyword () != AutoTypeKeyword::GNUAutoType &&
29162983 " 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+ }
29213022 } else {
29223023 if (ResultType->isVoidType ())
29233024 ResultType = ResultType.getUnqualifiedType ();
@@ -4220,6 +4321,57 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
42204321 Mangler.getStream () << ' @' ;
42214322}
42224323
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+
42234375MicrosoftMangleContext *MicrosoftMangleContext::create (ASTContext &Context,
42244376 DiagnosticsEngine &Diags,
42254377 bool IsAux) {
0 commit comments