Skip to content

Commit 05f6630

Browse files
committed
Revert "[Clang] [AST] Fix placeholder return type name mangling for MSVC 1920+ / VS2019+ (#102848)"
It cause builds to start failing with Invalid type expected UNREACHABLE executed at clang/lib/AST/MicrosoftMangle.cpp:2551! see comments on the PR. > Partial fix for #92204. > This PR just fixes VS2019+ since that is the suite of compilers that I > require link compatibility with at the moment. > I still intend to fix VS2017 and to update llvm-undname in future PRs. > Once those are also finished and merged I'll close out > #92204. > I am hoping to get the llvm-undname PR up in a couple of weeks to be > able to demangle the VS2019+ name mangling. > > MSVC 1920+ mangles placeholder return types for non-templated functions > with "@". > For example `auto foo() { return 0; }` is mangled as `?foo@@ya@XZ`. > > MSVC 1920+ mangles placeholder return types for templated functions as > the qualifiers of the AutoType followed by "_P" for `auto` and "_T" for > `decltype(auto)`. > For example `template<class T> auto foo() { return 0; }` is mangled as > `??$foo@H@@ya?A_PXZ` when `foo` is instantiated as follows `foo<int>()`. > > Lambdas with placeholder return types are still mangled with clang's > custom mangling since MSVC lambda mangling hasn't been deciphered yet. > Similarly any pointers in the return type with an address space are > mangled with clang's custom mangling since that is a clang extension. > > We cannot augment `mangleType` to support this mangling scheme as the > mangling schemes for variables and functions differ. > auto variables are encoded with the fully deduced type where auto return > types are not. > The following two functions with a static variable are mangled the same > ``` > template<class T> > int test() > { > static int i = 0; // "?i@?1???$test@H@@yahxz@4HA" > return i; > } > > template<class T> > int test() > { > static auto i = 0; // "?i@?1???$test@H@@yahxz@4HA" > return i; > } > ``` > Inside `mangleType` once we get to mangling the `AutoType` we have no > context if we are from a variable encoding or some other encoding. > Therefore it was easier to handle any special casing for `AutoType` > return types with a separate function instead of using the `mangleType` > infrastructure. This reverts commit e0d173d and the wollow-up fa343be.
1 parent 5e95571 commit 05f6630

6 files changed

+19
-534
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ C++ Specific Potentially Breaking Changes
7777
ABI Changes in This Version
7878
---------------------------
7979

80-
- Fixed Microsoft name mangling of placeholder, auto and decltype(auto), return types for MSVC 1920+. This change resolves incompatibilities with code compiled by MSVC 1920+ but will introduce incompatibilities with code compiled by earlier versions of Clang unless such code is built with the compiler option -fms-compatibility-version=19.14 to imitate the MSVC 1914 mangling behavior.
81-
8280
AST Dumping Potentially Breaking Changes
8381
----------------------------------------
8482

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 9 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,6 @@ class MicrosoftCXXNameMangler {
408408
void mangleSourceName(StringRef Name);
409409
void mangleNestedName(GlobalDecl GD);
410410

411-
void mangleAutoReturnType(QualType T, QualifierMangleMode QMM);
412-
413411
private:
414412
bool isStructorDecl(const NamedDecl *ND) const {
415413
return ND == Structor || getStructor(ND) == Structor;
@@ -479,11 +477,6 @@ class MicrosoftCXXNameMangler {
479477
SourceRange Range);
480478
void mangleObjCKindOfType(const ObjCObjectType *T, Qualifiers Quals,
481479
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);
487480
};
488481
}
489482

@@ -2501,57 +2494,6 @@ void MicrosoftCXXNameMangler::mangleAddressSpaceType(QualType T,
25012494
mangleArtificialTagType(TagTypeKind::Struct, ASMangling, {"__clang"});
25022495
}
25032496

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-
25552497
void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
25562498
QualifierMangleMode QMM) {
25572499
// Don't use the canonical types. MSVC includes things like 'const' on
@@ -2965,52 +2907,17 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
29652907
// can differ by their calling convention and are typically deduced. So
29662908
// we make sure that this type gets mangled properly.
29672909
mangleType(ResultType, Range, QMM_Result);
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()) {
2910+
} else if (const auto *AT = dyn_cast_or_null<AutoType>(
2911+
ResultType->getContainedAutoType())) {
2912+
Out << '?';
2913+
mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
2914+
Out << '?';
29822915
assert(AT->getKeyword() != AutoTypeKeyword::GNUAutoType &&
29832916
"shouldn't need to mangle __auto_type!");
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-
mangleAutoReturnType(ResultType, QMM_Result);
3006-
}
3007-
} else {
3008-
Out << '?';
3009-
mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
3010-
Out << '?';
3011-
mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
3012-
Out << '@';
3013-
}
2917+
mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
2918+
Out << '@';
2919+
} else if (IsInLambda) {
2920+
Out << '@';
30142921
} else {
30152922
if (ResultType->isVoidType())
30162923
ResultType = ResultType.getUnqualifiedType();
@@ -4313,57 +4220,6 @@ void MicrosoftMangleContextImpl::mangleStringLiteral(const StringLiteral *SL,
43134220
Mangler.getStream() << '@';
43144221
}
43154222

4316-
void MicrosoftCXXNameMangler::mangleAutoReturnType(const MemberPointerType *T,
4317-
Qualifiers Quals) {
4318-
QualType PointeeType = T->getPointeeType();
4319-
manglePointerCVQualifiers(Quals);
4320-
manglePointerExtQualifiers(Quals, PointeeType);
4321-
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
4322-
Out << '8';
4323-
mangleName(T->getClass()->castAs<RecordType>()->getDecl());
4324-
mangleFunctionType(FPT, nullptr, true);
4325-
} else {
4326-
mangleQualifiers(PointeeType.getQualifiers(), true);
4327-
mangleName(T->getClass()->castAs<RecordType>()->getDecl());
4328-
mangleAutoReturnType(PointeeType, QMM_Drop);
4329-
}
4330-
}
4331-
4332-
void MicrosoftCXXNameMangler::mangleAutoReturnType(const PointerType *T,
4333-
Qualifiers Quals) {
4334-
QualType PointeeType = T->getPointeeType();
4335-
assert(!PointeeType.getQualifiers().hasAddressSpace() &&
4336-
"Unexpected address space mangling required");
4337-
4338-
manglePointerCVQualifiers(Quals);
4339-
manglePointerExtQualifiers(Quals, PointeeType);
4340-
4341-
if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
4342-
Out << '6';
4343-
mangleFunctionType(FPT);
4344-
} else {
4345-
mangleAutoReturnType(PointeeType, QMM_Mangle);
4346-
}
4347-
}
4348-
4349-
void MicrosoftCXXNameMangler::mangleAutoReturnType(const LValueReferenceType *T,
4350-
Qualifiers Quals) {
4351-
QualType PointeeType = T->getPointeeType();
4352-
assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
4353-
Out << 'A';
4354-
manglePointerExtQualifiers(Quals, PointeeType);
4355-
mangleAutoReturnType(PointeeType, QMM_Mangle);
4356-
}
4357-
4358-
void MicrosoftCXXNameMangler::mangleAutoReturnType(const RValueReferenceType *T,
4359-
Qualifiers Quals) {
4360-
QualType PointeeType = T->getPointeeType();
4361-
assert(!Quals.hasConst() && !Quals.hasVolatile() && "unexpected qualifier!");
4362-
Out << "$$Q";
4363-
manglePointerExtQualifiers(Quals, PointeeType);
4364-
mangleAutoReturnType(PointeeType, QMM_Mangle);
4365-
}
4366-
43674223
MicrosoftMangleContext *MicrosoftMangleContext::create(ASTContext &Context,
43684224
DiagnosticsEngine &Diags,
43694225
bool IsAux) {

0 commit comments

Comments
 (0)