From c2029db223cff93055d2aad06135f62937e1683c Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 29 Jan 2019 18:06:29 -0500 Subject: [PATCH] ASTMangler: Verify that debug manglings round-trip Add an IRGen flag to disable this verification, since it doesn't work from within lldb itself for some reason, and I don't want to investigate it right now. --- include/swift/AST/ASTMangler.h | 3 +- include/swift/AST/IRGenOptions.h | 4 +++ lib/AST/ASTMangler.cpp | 57 ++++++++++++++++++++++++++++++-- lib/IRGen/IRGenDebugInfo.cpp | 3 +- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/include/swift/AST/ASTMangler.h b/include/swift/AST/ASTMangler.h index ffe35873a19..c1c5299904f 100644 --- a/include/swift/AST/ASTMangler.h +++ b/include/swift/AST/ASTMangler.h @@ -158,7 +158,8 @@ public: GenericSignature *signature, ResilienceExpansion expansion); - std::string mangleTypeForDebugger(Type decl, const DeclContext *DC); + std::string mangleTypeForDebugger(Type decl, const DeclContext *DC, + bool verify=false); std::string mangleDeclType(const ValueDecl *decl); diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 6178d2fb6e2..37b9210f2e0 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -197,6 +197,9 @@ public: /// Enable chaining of dynamic replacements. unsigned EnableDynamicReplacementChaining : 1; + /// Disable round-trip verification of mangled debug types. + unsigned DisableRoundTripDebugTypes : 1; + /// Path to the profdata file to be used for PGO, or the empty string. std::string UseProfile = ""; @@ -232,6 +235,7 @@ public: EnableResilienceBypass(false), LazyInitializeClassMetadata(false), UseIncrementalLLVMCodeGen(true), UseSwiftCall(false), GenerateProfile(false), EnableDynamicReplacementChaining(false), + DisableRoundTripDebugTypes(false), CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()), TypeInfoFilter(TypeInfoDumpFilter::All) {} diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 4ec64196b09..218943b08d2 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -42,6 +42,10 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/CommandLine.h" +#ifndef NDEBUG +#include "swift/AST/ASTDemangler.h" +#endif + using namespace swift; using namespace swift::Mangle; @@ -360,7 +364,30 @@ std::string ASTMangler::mangleReabstractionThunkHelper( return finalize(); } -std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) { +#ifndef NDEBUG +static bool areTypesReallyEqual(Type lhs, Type rhs) { + // Due to an oversight, escaping and non-escaping @convention(block) + // are mangled identically. + auto eraseEscapingBlock = [](Type t) -> Type { + return t.transform([](Type t) -> Type { + if (auto *fnType = t->getAs()) { + if (fnType->getExtInfo().getRepresentation() + == FunctionTypeRepresentation::Block) { + return FunctionType::get(fnType->getParams(), + fnType->getResult(), + fnType->getExtInfo().withNoEscape(true)); + } + } + return t; + }); + }; + + return eraseEscapingBlock(lhs)->isEqual(eraseEscapingBlock(rhs)); +} +#endif + +std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC, + bool verify) { PrettyStackTraceType prettyStackTrace(Ty->getASTContext(), "mangling type for debugger", Ty); @@ -373,7 +400,33 @@ std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) { appendType(Ty); appendOperator("D"); - return finalize(); + std::string result = finalize(); + + if (!verify) + return result; + + // Make sure we can reconstruct mangled types for the debugger. +#ifndef NDEBUG + auto &Ctx = Ty->getASTContext(); + Type Reconstructed = Demangle::getTypeForMangling(Ctx, result); + if (!Reconstructed) { + llvm::errs() << "Failed to reconstruct type for " << result << "\n"; + llvm::errs() << "Original type:\n"; + Ty->dump(); + abort(); + } else if (!Reconstructed->isEqual(Ty)) { + if (!areTypesReallyEqual(Reconstructed, Ty)) { + llvm::errs() << "Incorrect reconstructed type for " << result << "\n"; + llvm::errs() << "Original type:\n"; + Ty->dump(); + llvm::errs() << "Reconstructed type:\n"; + Reconstructed->dump(); + abort(); + } + } +#endif + + return result; } std::string ASTMangler::mangleDeclType(const ValueDecl *decl) { diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index b8c35492d97..ea146dd9f2b 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -698,7 +698,8 @@ private: Mangle::ASTMangler Mangler; std::string Name = Mangler.mangleTypeForDebugger( - Ty, DbgTy.getDeclContext()); + Ty, DbgTy.getDeclContext(), + !Opts.DisableRoundTripDebugTypes); return BumpAllocatedString(Name); }