Skip to content

Commit 39f3a11

Browse files
Merge pull request llvm#8605 from augusto2112/abi-name-lldb
[lldb] Support reconstructing types compiled with a different abi name
2 parents d26f7ff + d19cadc commit 39f3a11

File tree

8 files changed

+146
-2
lines changed

8 files changed

+146
-2
lines changed

lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1953,8 +1953,14 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
19531953
auto var_info = MaterializeVariable(
19541954
variable, swift_expr, *materializer, *parsed_expr->code_manipulator,
19551955
m_stack_frame_wp, diagnostic_manager, log, repl);
1956-
if (!var_info)
1956+
if (!var_info) {
1957+
auto error_string = llvm::toString(var_info.takeError());
1958+
LLDB_LOG(log, "Variable info failzed to materialize with error: {0}",
1959+
error_string);
1960+
1961+
19571962
return ParseResult::unrecoverable_error;
1963+
}
19581964

19591965
const char *name = ConstString(variable.GetName().get()).GetCString();
19601966
variable_map[name] = *var_info;

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3775,6 +3775,29 @@ void SwiftASTContext::CacheModule(swift::ModuleDecl *module) {
37753775
m_swift_module_cache.insert({ID, module});
37763776
}
37773777

3778+
void SwiftASTContext::RegisterModuleABINameToRealName(
3779+
swift::ModuleDecl *module) {
3780+
if (module->getABIName() == module->getName())
3781+
return;
3782+
3783+
// Ignore _Concurrency, which is hardcoded in the compiler and should be
3784+
// looked up using its ABI name "Swift"
3785+
if (module->getName().str() == swift::SWIFT_CONCURRENCY_NAME)
3786+
return;
3787+
3788+
// Also ignore modules with the special "Compiler" prefix.
3789+
if (module->getABIName().str().starts_with(
3790+
swift::SWIFT_MODULE_ABI_NAME_PREFIX))
3791+
return;
3792+
3793+
LOG_PRINTF(GetLog(LLDBLog::Types),
3794+
"Mapping module ABI name \"%s\" to its regular name \"%s\"",
3795+
module->getABIName().str().str().c_str(),
3796+
module->getName().str().str().c_str());
3797+
m_module_abi_to_regular_name.insert({module->getABIName().str(),
3798+
module->getName().str()});
3799+
}
3800+
37783801
swift::ModuleDecl *SwiftASTContext::GetModule(const SourceModule &module,
37793802
Status &error, bool *cached) {
37803803
if (cached)
@@ -3884,6 +3907,7 @@ swift::ModuleDecl *SwiftASTContext::GetModule(const SourceModule &module,
38843907
module.path.front().GetCString(),
38853908
module_decl->getName().str().str().c_str());
38863909

3910+
RegisterModuleABINameToRealName(module_decl);
38873911
m_swift_module_cache[module.path.front().GetStringRef()] = module_decl;
38883912
return module_decl;
38893913
}
@@ -3938,6 +3962,7 @@ swift::ModuleDecl *SwiftASTContext::GetModule(const FileSpec &module_spec,
39383962
module_spec.GetPath().c_str(),
39393963
module->getName().str().str().c_str());
39403964

3965+
RegisterModuleABINameToRealName(module);
39413966
m_swift_module_cache[module_basename.GetCString()] = module;
39423967
return module;
39433968
} else {
@@ -4605,7 +4630,7 @@ SwiftASTContext::ReconstructTypeOrWarn(ConstString mangled_typename) {
46054630
}
46064631

46074632
llvm::Expected<swift::TypeBase *>
4608-
SwiftASTContext::ReconstructType(ConstString mangled_typename) {
4633+
SwiftASTContext::ReconstructTypeImpl(ConstString mangled_typename) {
46094634
VALID_OR_RETURN(nullptr);
46104635

46114636
const char *mangled_cstr = mangled_typename.AsCString();
@@ -4715,6 +4740,43 @@ SwiftASTContext::ReconstructType(ConstString mangled_typename) {
47154740
"\" was not found");
47164741
}
47174742

4743+
llvm::Expected<swift::TypeBase *>
4744+
SwiftASTContext::ReconstructType(ConstString mangled_typename) {
4745+
VALID_OR_RETURN(nullptr);
4746+
4747+
// Mangled names are encoded with the ABI module name in debug info, but with
4748+
// the regular module name in the swift module. When reconstructing these
4749+
// types, SwiftASTContext must first substitute the ABI module name with the
4750+
// regular one on the type's mangled name before attempting to reconstruct
4751+
// them.
4752+
auto mangling = TypeSystemSwiftTypeRef::TransformModuleName(
4753+
mangled_typename, m_module_abi_to_regular_name);
4754+
ConstString module_adjusted_mangled_typename;
4755+
if (mangling.isSuccess())
4756+
module_adjusted_mangled_typename = ConstString(mangling.result());
4757+
4758+
if (mangled_typename == module_adjusted_mangled_typename)
4759+
return ReconstructTypeImpl(mangled_typename);
4760+
4761+
// If the mangles names don't match, try the one with the module's regular
4762+
// name first.
4763+
auto result = ReconstructTypeImpl(module_adjusted_mangled_typename);
4764+
4765+
if (result)
4766+
return result;
4767+
4768+
auto error = llvm::toString(result.takeError());
4769+
LOG_PRINTF(
4770+
GetLog(LLDBLog::Types),
4771+
"Reconstruct type failed for adjusted type: \"%s\" with error: \"%s\"",
4772+
module_adjusted_mangled_typename.GetCString(), error.c_str());
4773+
4774+
// If the mangled name with the regular name fails, try the one with the ABI
4775+
// name. This could happen if a module's ABI name is the same as another
4776+
// module's regular name.
4777+
return ReconstructTypeImpl(mangled_typename);
4778+
}
4779+
47184780
CompilerType SwiftASTContext::GetAnyObjectType() {
47194781
VALID_OR_RETURN(CompilerType());
47204782
swift::ASTContext *ast = GetASTContext();

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,12 @@ class SwiftASTContext : public TypeSystemSwift {
423423
llvm::Expected<swift::Type> GetSwiftType(CompilerType compiler_type);
424424
/// Import compiler_type into this context and return the swift::CanType.
425425
swift::CanType GetCanonicalSwiftType(CompilerType compiler_type);
426+
private:
427+
/// Reconstruct a Swift AST type from a mangled name by looking its
428+
/// components up in Swift modules.
429+
llvm::Expected<swift::TypeBase *>
430+
ReconstructTypeImpl(ConstString mangled_typename);
431+
426432
protected:
427433
swift::Type GetSwiftType(lldb::opaque_compiler_type_t opaque_type);
428434
swift::Type GetSwiftTypeIgnoringErrors(CompilerType compiler_type);
@@ -892,6 +898,10 @@ class SwiftASTContext : public TypeSystemSwift {
892898

893899
CompilerType GetAsClangType(ConstString mangled_name);
894900

901+
/// Inserts the mapping from the module's ABI name to it's regular name into
902+
/// m_module_abi_to_regular_name if they're different.
903+
void RegisterModuleABINameToRealName(swift::ModuleDecl *module);
904+
895905
/// Data members.
896906
/// @{
897907
// Always non-null outside of unit tests.
@@ -953,6 +963,9 @@ class SwiftASTContext : public TypeSystemSwift {
953963
mutable bool m_reported_fatal_error = false;
954964
mutable bool m_logged_fatal_error = false;
955965

966+
/// Holds the source module name (value) for all modules with a custom ABI
967+
/// name (key).
968+
llvm::StringMap<llvm::StringRef> m_module_abi_to_regular_name;
956969
/// Whether this is a scratch or a module AST context.
957970
bool m_is_scratch_context = false;
958971

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,31 @@ TypeSystemSwiftTypeRef::CanonicalizeSugar(swift::Demangle::Demangler &dem,
147147
});
148148
}
149149

150+
swift::Demangle::ManglingErrorOr<std::string>
151+
TypeSystemSwiftTypeRef::TransformModuleName(
152+
llvm::StringRef mangled_name,
153+
const llvm::StringMap<llvm::StringRef> &module_name_map) {
154+
swift::Demangle::Demangler dem;
155+
auto *node = dem.demangleSymbol(mangled_name);
156+
auto *adjusted_node = TypeSystemSwiftTypeRef::Transform(
157+
dem, node, [&](swift::Demangle::NodePointer node) {
158+
if (node->getKind() == Node::Kind::Module) {
159+
auto module_name = node->getText();
160+
if (module_name_map.contains(module_name)) {
161+
auto real_name = module_name_map.lookup(module_name);
162+
auto *adjusted_module_node =
163+
dem.createNodeWithAllocatedText(Node::Kind::Module, real_name);
164+
return adjusted_module_node;
165+
}
166+
}
167+
168+
return node;
169+
});
170+
171+
auto mangling = mangleNode(adjusted_node);
172+
return mangling;
173+
}
174+
150175
llvm::StringRef
151176
TypeSystemSwiftTypeRef::GetBaseName(swift::Demangle::NodePointer node) {
152177
if (!node)

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ namespace Demangle {
2929
class Node;
3030
using NodePointer = Node *;
3131
class Demangler;
32+
template <typename T>
33+
class ManglingErrorOr;
3234
} // namespace Demangle
3335
namespace reflection {
3436
struct DescriptorFinder;
@@ -362,6 +364,12 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
362364
CanonicalizeSugar(swift::Demangle::Demangler &dem,
363365
swift::Demangle::NodePointer node);
364366

367+
/// Transforms the module name in the mangled type name using module_name_map
368+
/// as the mapping source.
369+
static swift::Demangle::ManglingErrorOr<std::string>
370+
TransformModuleName(llvm::StringRef mangled_name,
371+
const llvm::StringMap<llvm::StringRef> &module_name_map);
372+
365373
/// Return the canonicalized Demangle tree for a Swift mangled type name.
366374
swift::Demangle::NodePointer
367375
GetCanonicalDemangleTree(swift::Demangle::Demangler &dem,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFTFLAGS_EXTRAS := -module-abi-name OtherName
3+
4+
include Makefile.rules
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
import unittest2
6+
7+
8+
class TestSwiftDifferentABIName(TestBase):
9+
@swiftTest
10+
def test(self):
11+
self.build()
12+
13+
_, _, _, _ = lldbutil.run_to_source_breakpoint(
14+
self, "break here", lldb.SBFileSpec("main.swift")
15+
)
16+
17+
self.expect("frame variable s",
18+
substrs=["Struct", "s = ", "field = 42"])
19+
self.expect("expr s", substrs=["Struct", "field = 42"])
20+
self.expect("expr -O -- s", substrs=["Struct", "- field : 42"])
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
struct Struct {
2+
let field = 42
3+
}
4+
5+
let s = Struct()
6+
print(s) // break here

0 commit comments

Comments
 (0)