Skip to content

[lldb] Allow SwiftASTContext fallbacks for types from expressions #10059

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
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
19 changes: 19 additions & 0 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftDemangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ NodeAtPath(swift::Demangle::NodePointer root,
return ChildAtPath(root, kind_path.drop_front());
}

/// Find the first child node of root that satisfies cond.
inline swift::Demangle::NodePointer
FindIf(swift::Demangle::NodePointer root,
std::function<bool(swift::Demangle::NodePointer)> cond) {
if (!root)
return nullptr;

auto *node = root;
if (cond(node))
return node;
for (auto *child : *node) {
assert(child && "swift::Demangle::Node has null child");
if (auto *found = FindIf(child, cond))
return found;
}

return nullptr;
}

/// \return the child of the TypeMangling node.
static swift::Demangle::NodePointer
GetTypeMangling(swift::Demangle::NodePointer n) {
Expand Down
59 changes: 31 additions & 28 deletions lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1653,29 +1653,6 @@ swift::Demangle::NodePointer TypeSystemSwiftTypeRef::GetDemangleTreeForPrinting(
return GetNodeForPrintingImpl(dem, node, flavor, resolve_objc_module);
}

/// Determine wether this demangle tree contains a node of kind \c kind and with
/// text \c text (if provided).
static bool Contains(swift::Demangle::NodePointer node,
swift::Demangle::Node::Kind kind,
llvm::StringRef text = "") {
if (!node)
return false;

if (node->getKind() == kind) {
if (text.empty())
return true;
if (!node->hasText())
return false;
return node->getText() == text;
}

for (swift::Demangle::NodePointer child : *node)
if (Contains(child, kind, text))
return true;

return false;
}

static bool ProtocolCompositionContainsSingleObjcProtocol(
swift::Demangle::NodePointer node) {
// Kind=ProtocolList
Expand All @@ -1691,12 +1668,18 @@ static bool ProtocolCompositionContainsSingleObjcProtocol(
type_list->getNumChildren() != 1)
return false;
NodePointer type = type_list->getFirstChild();
return Contains(type, Node::Kind::Module, swift::MANGLING_MODULE_OBJC);
return swift_demangle::FindIf(type, [](NodePointer node) {
return node->getKind() == Node::Kind::Module && node->hasText() &&
node->getText() == swift::MANGLING_MODULE_OBJC;
});
}

/// Determine wether this demangle tree contains a generic type parameter.
static bool ContainsGenericTypeParameter(swift::Demangle::NodePointer node) {
return Contains(node, swift::Demangle::Node::Kind::DependentGenericParamType);
return swift_demangle::FindIf(node, [](NodePointer node) {
return node->getKind() ==
swift::Demangle::Node::Kind::DependentGenericParamType;
});
}

/// Collect TypeInfo flags from a demangle tree. For most attributes
Expand Down Expand Up @@ -1929,7 +1912,9 @@ uint32_t TypeSystemSwiftTypeRef::CollectTypeInfo(
if (swift_flags != eTypeIsSwift) {
if (ContainsGenericTypeParameter(node))
swift_flags |= eTypeHasUnboundGeneric;
if (Contains(node, Node::Kind::DynamicSelf))
if (swift_demangle::FindIf(node, [](NodePointer node) {
return node->getKind() == swift::Demangle::Node::Kind::DynamicSelf;
}))
swift_flags |= eTypeHasDynamicSelf;
return swift_flags;
}
Expand Down Expand Up @@ -2817,6 +2802,8 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;

bool TypeSystemSwiftTypeRef::UseSwiftASTContextFallback(
const char *func_name, lldb::opaque_compiler_type_t type) {
if (IsExpressionEvaluatorDefined(type))
return true;
if (!ModuleList::GetGlobalModuleListProperties().GetSwiftTypeSystemFallback())
return false;

Expand All @@ -2827,8 +2814,11 @@ bool TypeSystemSwiftTypeRef::UseSwiftASTContextFallback(
return true;
}

bool TypeSystemSwiftTypeRef::DiagnoseSwiftASTContextFallback(
void TypeSystemSwiftTypeRef::DiagnoseSwiftASTContextFallback(
const char *func_name, lldb::opaque_compiler_type_t type) {
if (IsExpressionEvaluatorDefined(type))
return;

const char *type_name = AsMangledName(type);

std::optional<lldb::user_id_t> debugger_id;
Expand All @@ -2842,7 +2832,6 @@ bool TypeSystemSwiftTypeRef::DiagnoseSwiftASTContextFallback(
Debugger::ReportWarning(msg, debugger_id, &m_fallback_warning);

LLDB_LOGF(GetLog(LLDBLog::Types), "%s", msg.c_str());
return true;
}

CompilerType
Expand Down Expand Up @@ -2900,6 +2889,20 @@ TypeSystemSwiftTypeRef::DemangleCanonicalOutermostType(
return canonical;
}

bool TypeSystemSwiftTypeRef::IsExpressionEvaluatorDefined(
lldb::opaque_compiler_type_t type) {
using namespace swift::Demangle;
const auto *mangled_name = AsMangledName(type);
Demangler dem;
NodePointer node = GetDemangledType(dem, mangled_name);
return swift_demangle::FindIf(node, [](NodePointer node) -> NodePointer {
if (node->getKind() == Node::Kind::Module &&
node->getText().starts_with("__lldb_expr"))
return node;
return nullptr;
});
}

CompilerType TypeSystemSwiftTypeRef::CreateGenericTypeParamType(
unsigned int depth, unsigned int index,
swift::Mangle::ManglingFlavor flavor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
bool UseSwiftASTContextFallback(const char *func_name,
lldb::opaque_compiler_type_t type);
/// Print a warning that a fallback was necessary.
bool DiagnoseSwiftASTContextFallback(const char *func_name,
void DiagnoseSwiftASTContextFallback(const char *func_name,
lldb::opaque_compiler_type_t type);

/// Helper that creates an AST type from \p type.
Expand Down Expand Up @@ -544,6 +544,11 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
swift::Demangle::NodePointer
GetClangTypeTypeNode(swift::Demangle::Demangler &dem,
CompilerType clang_type);

/// Determine if this type contains a type from a module that looks
/// like it was JIT-compiled by LLDB.
bool IsExpressionEvaluatorDefined(lldb::opaque_compiler_type_t type);

#ifndef NDEBUG
/// Check whether the type being dealt with is tricky to validate due to
/// discrepancies between TypeSystemSwiftTypeRef and SwiftASTContext.
Expand Down
3 changes: 0 additions & 3 deletions lldb/test/API/lang/swift/expression/self/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
SWIFT_SOURCES := main.swift
include Makefile.rules

cleanup:
rm -f Makefile *.d