Skip to content

Commit 363e47b

Browse files
authored
Merge pull request swiftlang#22260 from slavapestov/round-trip-type-reconstruction
ASTMangler: Verify that debug manglings round-trip
2 parents de2b75c + c2029db commit 363e47b

File tree

4 files changed

+63
-4
lines changed

4 files changed

+63
-4
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ class ASTMangler : public Mangler {
158158
GenericSignature *signature,
159159
ResilienceExpansion expansion);
160160

161-
std::string mangleTypeForDebugger(Type decl, const DeclContext *DC);
161+
std::string mangleTypeForDebugger(Type decl, const DeclContext *DC,
162+
bool verify=false);
162163

163164
std::string mangleDeclType(const ValueDecl *decl);
164165

include/swift/AST/IRGenOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ class IRGenOptions {
197197
/// Enable chaining of dynamic replacements.
198198
unsigned EnableDynamicReplacementChaining : 1;
199199

200+
/// Disable round-trip verification of mangled debug types.
201+
unsigned DisableRoundTripDebugTypes : 1;
202+
200203
/// Path to the profdata file to be used for PGO, or the empty string.
201204
std::string UseProfile = "";
202205

@@ -232,6 +235,7 @@ class IRGenOptions {
232235
EnableResilienceBypass(false), LazyInitializeClassMetadata(false),
233236
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),
234237
GenerateProfile(false), EnableDynamicReplacementChaining(false),
238+
DisableRoundTripDebugTypes(false),
235239
CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()),
236240
TypeInfoFilter(TypeInfoDumpFilter::All) {}
237241

lib/AST/ASTMangler.cpp

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
#include "llvm/Support/raw_ostream.h"
4343
#include "llvm/Support/CommandLine.h"
4444

45+
#ifndef NDEBUG
46+
#include "swift/AST/ASTDemangler.h"
47+
#endif
48+
4549
using namespace swift;
4650
using namespace swift::Mangle;
4751

@@ -360,7 +364,30 @@ std::string ASTMangler::mangleReabstractionThunkHelper(
360364
return finalize();
361365
}
362366

363-
std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
367+
#ifndef NDEBUG
368+
static bool areTypesReallyEqual(Type lhs, Type rhs) {
369+
// Due to an oversight, escaping and non-escaping @convention(block)
370+
// are mangled identically.
371+
auto eraseEscapingBlock = [](Type t) -> Type {
372+
return t.transform([](Type t) -> Type {
373+
if (auto *fnType = t->getAs<FunctionType>()) {
374+
if (fnType->getExtInfo().getRepresentation()
375+
== FunctionTypeRepresentation::Block) {
376+
return FunctionType::get(fnType->getParams(),
377+
fnType->getResult(),
378+
fnType->getExtInfo().withNoEscape(true));
379+
}
380+
}
381+
return t;
382+
});
383+
};
384+
385+
return eraseEscapingBlock(lhs)->isEqual(eraseEscapingBlock(rhs));
386+
}
387+
#endif
388+
389+
std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC,
390+
bool verify) {
364391
PrettyStackTraceType prettyStackTrace(Ty->getASTContext(),
365392
"mangling type for debugger", Ty);
366393

@@ -373,7 +400,33 @@ std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
373400

374401
appendType(Ty);
375402
appendOperator("D");
376-
return finalize();
403+
std::string result = finalize();
404+
405+
if (!verify)
406+
return result;
407+
408+
// Make sure we can reconstruct mangled types for the debugger.
409+
#ifndef NDEBUG
410+
auto &Ctx = Ty->getASTContext();
411+
Type Reconstructed = Demangle::getTypeForMangling(Ctx, result);
412+
if (!Reconstructed) {
413+
llvm::errs() << "Failed to reconstruct type for " << result << "\n";
414+
llvm::errs() << "Original type:\n";
415+
Ty->dump();
416+
abort();
417+
} else if (!Reconstructed->isEqual(Ty)) {
418+
if (!areTypesReallyEqual(Reconstructed, Ty)) {
419+
llvm::errs() << "Incorrect reconstructed type for " << result << "\n";
420+
llvm::errs() << "Original type:\n";
421+
Ty->dump();
422+
llvm::errs() << "Reconstructed type:\n";
423+
Reconstructed->dump();
424+
abort();
425+
}
426+
}
427+
#endif
428+
429+
return result;
377430
}
378431

379432
std::string ASTMangler::mangleDeclType(const ValueDecl *decl) {

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,8 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
698698

699699
Mangle::ASTMangler Mangler;
700700
std::string Name = Mangler.mangleTypeForDebugger(
701-
Ty, DbgTy.getDeclContext());
701+
Ty, DbgTy.getDeclContext(),
702+
!Opts.DisableRoundTripDebugTypes);
702703
return BumpAllocatedString(Name);
703704
}
704705

0 commit comments

Comments
 (0)