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.
This commit is contained in:
Slava Pestov
2019-01-29 18:06:29 -05:00
parent c7aede6ffe
commit c2029db223
4 changed files with 63 additions and 4 deletions

View File

@@ -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);

View File

@@ -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) {}

View File

@@ -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<FunctionType>()) {
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) {

View File

@@ -698,7 +698,8 @@ private:
Mangle::ASTMangler Mangler;
std::string Name = Mangler.mangleTypeForDebugger(
Ty, DbgTy.getDeclContext());
Ty, DbgTy.getDeclContext(),
!Opts.DisableRoundTripDebugTypes);
return BumpAllocatedString(Name);
}