Skip to content

Downgrade the TypeSystemSwiftTypeRef string validation errors #1331

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lldb/include/lldb/Target/SwiftLanguageRuntime.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,9 @@ class SwiftLanguageRuntime : public LanguageRuntime {
/// since some day we may want to support more than one swift variant.
static bool IsSwiftMangledName(const char *name);

enum DemangleMode { eSimplified, eTypeName, eDisplayTypeName };
static std::string DemangleSymbolAsString(llvm::StringRef symbol,
bool simplified = false,
DemangleMode mode,
const SymbolContext *sc = nullptr);

class MethodName {
Expand Down
5 changes: 3 additions & 2 deletions lldb/source/Core/Mangled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ ConstString Mangled::GetDemangledName(lldb::LanguageType language,
if (log)
log->Printf("demangle swift: %s", mangled_name);
std::string demangled(SwiftLanguageRuntime::DemangleSymbolAsString(
mangled_name, false, sc));
mangled_name, SwiftLanguageRuntime::eTypeName, sc));
// Don't cache the demangled name the function isn't available yet.
if (!sc || !sc->function)
return ConstString(demangled);
Expand Down Expand Up @@ -429,7 +429,8 @@ ConstString Mangled::GetDisplayDemangledName(lldb::LanguageType language,

std::string demangled_std =
SwiftLanguageRuntime::DemangleSymbolAsString(
m_mangled.GetStringRef(), true, sc);
m_mangled.GetStringRef(), SwiftLanguageRuntime::eSimplified,
sc);
if (!demangled_std.empty()) {
demangled.SetCString(demangled_std.c_str());
display_cache->Insert(mangled, demangled);
Expand Down
86 changes: 69 additions & 17 deletions lldb/source/Symbol/TypeSystemSwiftTypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "lldb/Symbol/SwiftASTContext.h"

#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/SwiftLanguageRuntime.h"
Expand Down Expand Up @@ -385,13 +386,15 @@ GetNodeForPrinting(const std::string &m_description, lldb_private::Module &M,
GetClangImporterFn get_clangimporter,
swift::Demangle::Demangler &Dem,
swift::Demangle::NodePointer node,
bool resolve_objc_module,
bool desugar = true) {
if (!node)
return node;
using namespace swift::Demangle;
auto getNodeForPrinting = [&](NodePointer node) -> NodePointer {
return GetNodeForPrinting(m_description, M, get_apinotes_manager,
get_clangimporter, Dem, node, desugar);
get_clangimporter, Dem, node, resolve_objc_module,
desugar);
};

NodePointer canonical = nullptr;
Expand All @@ -415,13 +418,17 @@ GetNodeForPrinting(const std::string &m_description, lldb_private::Module &M,
llvm::SmallVector<CompilerContext, 4> DeclCtx;
clang_type->GetDeclContext(DeclCtx);
StringRef toplevel_module;
for (auto &Context : DeclCtx)
if (Context.kind == CompilerContextKind::Module) {
toplevel_module = Context.name.GetStringRef();
if (resolve_objc_module) {
for (auto &Context : DeclCtx)
if (Context.kind == CompilerContextKind::Module) {
toplevel_module = Context.name.GetStringRef();
break;
}
if (toplevel_module.empty())
break;
}
if (toplevel_module.empty())
break;
} else {
toplevel_module = swift::MANGLING_MODULE_OBJC;
}

// Create a new node with the Clang module instead of "__C".
NodePointer renamed = Dem.createNode(kind);
Expand Down Expand Up @@ -630,13 +637,13 @@ static swift::Demangle::NodePointer GetDemangleTreeForPrinting(
const std::string &m_description, lldb_private::Module *Module,
GetAPINotesManagerFn get_apinotes_manager,
GetClangImporterFn get_clangimporter, swift::Demangle::Demangler &Dem,
const char *mangled_name) {
const char *mangled_name, bool resolve_objc_module) {
NodePointer node = Dem.demangleSymbol(mangled_name);
if (!Module)
return node;
NodePointer canonical =
GetNodeForPrinting(m_description, *Module, get_apinotes_manager,
get_clangimporter, Dem, node);
get_clangimporter, Dem, node, resolve_objc_module);
return canonical;
}

Expand Down Expand Up @@ -742,9 +749,19 @@ template <typename T> bool Equivalent(T l, T r) { return l == r; }
template <> bool Equivalent<CompilerType>(CompilerType l, CompilerType r) {
return l.GetMangledTypeName() == r.GetMangledTypeName();
} // namespace
// This one is particularly taylored for GetName().
/// This one is particularly taylored for GetTypeName() and
/// GetDisplayTypeName().
///
/// String divergences are mostly cosmetic in nature and usually
/// TypeSystemSwiftTypeRef is returning more accurate results. They only really
/// matter for GetTypeName() and there only if there is a data formatter
/// matching that name.
template <> bool Equivalent<ConstString>(ConstString l, ConstString r) {
if (l != r) {
// Failure. Dump it for easier debugging.
llvm::dbgs() << "TypeSystemSwiftTypeRef diverges from SwiftASTContext: "
<< l.GetStringRef() << " != " << r.GetStringRef() << "\n";

// For some reason the Swift type dumper doesn't attach a module
// name to the AnyObject protocol, and only that one.
std::string l_prime = std::regex_replace(
Expand All @@ -757,8 +774,29 @@ template <> bool Equivalent<ConstString>(ConstString l, ConstString r) {
r.GetStringRef().contains("__ObjC.") || r.GetStringRef().contains(" -> ()"))
return true;

// Failure. Dump it for easier debugging.
llvm::dbgs() << l.GetStringRef() << " != " << r.GetStringRef() << "\n";
std::string r_prime =
std::regex_replace(r.GetStringRef().str(), std::regex("NS"), "");
if (l.GetStringRef() == llvm::StringRef(r_prime))
return true;

// The way it is currently configured, ASTPrinter's always-qualify
// mode is turned off. In this mode,
// TypePrinter::shouldPrintFullyQualified() insists on never
// printing qualifiers for types that come from Clang modules, but
// the way this is implemented this rule also fires for types from
// SDK overlays, which are technically Swift modules. Detecting
// this in TypeSystemSwiftTypeRef is so complicated that it just
// isn't worth the effort and we accept over-qualified types
// instead. It would be best to just always qualify types not from
// the current module.
l_prime = std::regex_replace(
l.GetStringRef().str(), std::regex("(CoreGraphics|Foundation|)\\."), "");
if (llvm::StringRef(l_prime) == r.GetStringRef())
return true;

#ifndef STRICT_VALIDATION
return true;
#endif
}
return l == r;
}
Expand Down Expand Up @@ -1040,19 +1078,33 @@ ConstString TypeSystemSwiftTypeRef::GetTypeName(opaque_compiler_type_t type) {
return GetAPINotesManager(source, id);
},
[&]() { return m_swift_ast_context->GetClangImporter(); }, Dem,
AsMangledName(type));
AsMangledName(type), true);
std::string remangled = mangleNode(print_node);
bool simplified = false;
return ConstString(
SwiftLanguageRuntime::DemangleSymbolAsString(remangled, simplified));
return ConstString(SwiftLanguageRuntime::DemangleSymbolAsString(
remangled, SwiftLanguageRuntime::eTypeName));
};
VALIDATE_AND_RETURN(impl,
m_swift_ast_context->GetTypeName(ReconstructType(type)));
}
ConstString
TypeSystemSwiftTypeRef::GetDisplayTypeName(opaque_compiler_type_t type,
const SymbolContext *sc) {
return m_swift_ast_context->GetDisplayTypeName(ReconstructType(type), sc);
auto impl = [&]() {
using namespace swift::Demangle;
Demangler Dem;
NodePointer print_node = GetDemangleTreeForPrinting(
m_description, GetModule(),
[&](ClangExternalASTSourceCallbacks *source, unsigned id) {
return GetAPINotesManager(source, id);
},
[&]() { return m_swift_ast_context->GetClangImporter(); }, Dem,
AsMangledName(type), false);
std::string remangled = mangleNode(print_node);
return ConstString(SwiftLanguageRuntime::DemangleSymbolAsString(
remangled, SwiftLanguageRuntime::eDisplayTypeName, sc));
};
VALIDATE_AND_RETURN(
impl, m_swift_ast_context->GetDisplayTypeName(ReconstructType(type), sc));
}
uint32_t TypeSystemSwiftTypeRef::GetTypeInfo(
opaque_compiler_type_t type, CompilerType *pointee_or_element_clang_type) {
Expand Down
17 changes: 14 additions & 3 deletions lldb/source/Target/SwiftLanguageRuntimeNames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "swift/Demangling/Demangle.h"
#include "swift/Demangling/Demangler.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
Expand Down Expand Up @@ -379,17 +380,27 @@ void SwiftLanguageRuntime::GetGenericParameterNamesForFunction(
}

std::string
SwiftLanguageRuntime::DemangleSymbolAsString(StringRef symbol, bool simplified,
SwiftLanguageRuntime::DemangleSymbolAsString(StringRef symbol, DemangleMode mode,
const SymbolContext *sc) {
bool did_init = false;
llvm::DenseMap<ArchetypePath, StringRef> dict;
swift::Demangle::DemangleOptions options;
if (simplified)
switch (mode) {
case eSimplified:
options = swift::Demangle::DemangleOptions::SimplifiedUIDemangleOptions();
else {
break;
case eTypeName:
options.DisplayModuleNames = true;
options.ShowPrivateDiscriminators = false;
options.DisplayExtensionContexts = false;
break;
case eDisplayTypeName:
options = swift::Demangle::DemangleOptions::SimplifiedUIDemangleOptions();
options.DisplayStdlibModule = false;
options.DisplayObjCModule = false;
options.QualifyEntities = true;
options.DisplayModuleNames = true;
break;
}

if (sc) {
Expand Down