mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
@@ -158,7 +158,8 @@ public:
|
|||||||
GenericSignature *signature,
|
GenericSignature *signature,
|
||||||
ResilienceExpansion expansion);
|
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);
|
std::string mangleDeclType(const ValueDecl *decl);
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,9 @@ public:
|
|||||||
/// Enable chaining of dynamic replacements.
|
/// Enable chaining of dynamic replacements.
|
||||||
unsigned EnableDynamicReplacementChaining : 1;
|
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.
|
/// Path to the profdata file to be used for PGO, or the empty string.
|
||||||
std::string UseProfile = "";
|
std::string UseProfile = "";
|
||||||
|
|
||||||
@@ -232,6 +235,7 @@ public:
|
|||||||
EnableResilienceBypass(false), LazyInitializeClassMetadata(false),
|
EnableResilienceBypass(false), LazyInitializeClassMetadata(false),
|
||||||
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),
|
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),
|
||||||
GenerateProfile(false), EnableDynamicReplacementChaining(false),
|
GenerateProfile(false), EnableDynamicReplacementChaining(false),
|
||||||
|
DisableRoundTripDebugTypes(false),
|
||||||
CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()),
|
||||||
TypeInfoFilter(TypeInfoDumpFilter::All) {}
|
TypeInfoFilter(TypeInfoDumpFilter::All) {}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,10 @@
|
|||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#include "swift/AST/ASTDemangler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
using namespace swift::Mangle;
|
using namespace swift::Mangle;
|
||||||
|
|
||||||
@@ -360,7 +364,30 @@ std::string ASTMangler::mangleReabstractionThunkHelper(
|
|||||||
return finalize();
|
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(),
|
PrettyStackTraceType prettyStackTrace(Ty->getASTContext(),
|
||||||
"mangling type for debugger", Ty);
|
"mangling type for debugger", Ty);
|
||||||
|
|
||||||
@@ -373,7 +400,33 @@ std::string ASTMangler::mangleTypeForDebugger(Type Ty, const DeclContext *DC) {
|
|||||||
|
|
||||||
appendType(Ty);
|
appendType(Ty);
|
||||||
appendOperator("D");
|
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) {
|
std::string ASTMangler::mangleDeclType(const ValueDecl *decl) {
|
||||||
|
|||||||
@@ -698,7 +698,8 @@ private:
|
|||||||
|
|
||||||
Mangle::ASTMangler Mangler;
|
Mangle::ASTMangler Mangler;
|
||||||
std::string Name = Mangler.mangleTypeForDebugger(
|
std::string Name = Mangler.mangleTypeForDebugger(
|
||||||
Ty, DbgTy.getDeclContext());
|
Ty, DbgTy.getDeclContext(),
|
||||||
|
!Opts.DisableRoundTripDebugTypes);
|
||||||
return BumpAllocatedString(Name);
|
return BumpAllocatedString(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user