Skip to content

Commit 4a1abae

Browse files
authored
[lldb] Support plain ObjC names in LLDBTypeInfoProvider (#9320)
Extend `LLDBTypeInfoProvider` to support ObjC class names (such as "NSObject", "NSView") in addition to mangled Swift names. This is to support `ObjCClassTypeRefs`, which contain the class name, but not the mangled name. Note that `ObjCClassTypeRefs` are typerefs for classes in the ObjC (`__C`) module. Depends on swiftlang/swift#76678
1 parent 2459b45 commit 4a1abae

File tree

5 files changed

+81
-6
lines changed

5 files changed

+81
-6
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,12 +317,26 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
317317
std::string wrapped;
318318
// The mangled name passed in is bare. Add global prefix ($s) and type (D).
319319
llvm::raw_string_ostream(wrapped) << "$s" << mangledName << 'D';
320+
swift::Demangle::Demangler dem;
321+
auto *node = dem.demangleSymbol(wrapped);
322+
if (!node) {
323+
// Try `mangledName` as plain ObjC class name. Ex: NSObject, NSView, etc.
324+
auto maybeMangled = swift_demangle::mangleClass(
325+
dem, swift::MANGLING_MODULE_OBJC, mangledName);
326+
if (!maybeMangled.isSuccess()) {
327+
LLDB_LOG(GetLog(LLDBLog::Types),
328+
"[LLDBTypeInfoProvider] invalid mangled name: {0}",
329+
mangledName);
330+
return nullptr;
331+
}
332+
wrapped = maybeMangled.result();
333+
LLDB_LOG(GetLog(LLDBLog::Types),
334+
"[LLDBTypeInfoProvider] using mangled ObjC class name: {0}",
335+
wrapped);
336+
} else {
320337
#ifndef NDEBUG
321-
{
322338
// Check that our hardcoded mangling wrapper is still up-to-date.
323-
swift::Demangle::Context dem;
324-
auto node = dem.demangleSymbolAsNode(wrapped);
325-
assert(node && node->getKind() == swift::Demangle::Node::Kind::Global);
339+
assert(node->getKind() == swift::Demangle::Node::Kind::Global);
326340
assert(node->getNumChildren() == 1);
327341
node = node->getChild(0);
328342
assert(node->getKind() == swift::Demangle::Node::Kind::TypeMangling);
@@ -332,8 +346,9 @@ class LLDBTypeInfoProvider : public swift::remote::TypeInfoProvider {
332346
assert(node->getNumChildren() == 1);
333347
node = node->getChild(0);
334348
assert(node->getKind() != swift::Demangle::Node::Kind::Type);
335-
}
336349
#endif
350+
}
351+
337352
ConstString mangled(wrapped);
338353
CompilerType swift_type = typesystem.GetTypeFromMangledTypename(mangled);
339354
auto ts = swift_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,34 @@ static swift::Demangle::NodePointer
7070
GetDemangledType(swift::Demangle::Demangler &dem, llvm::StringRef name) {
7171
return GetType(dem.demangleSymbol(name));
7272
}
73-
73+
74+
/// Wrap node in Global/TypeMangling/Type.
75+
static swift::Demangle::NodePointer
76+
mangleType(swift::Demangle::Demangler &dem,
77+
swift::Demangle::NodePointer typeNode) {
78+
auto *global = dem.createNode(Node::Kind::Global);
79+
auto *typeMangling = dem.createNode(Node::Kind::TypeMangling);
80+
global->addChild(typeMangling, dem);
81+
auto *type = dem.createNode(Node::Kind::Type);
82+
typeMangling->addChild(type, dem);
83+
type->addChild(typeNode, dem);
84+
return global;
85+
}
86+
87+
/// Produce a type mangling for a class.
88+
inline ManglingErrorOr<std::string> mangleClass(swift::Demangle::Demangler &dem,
89+
llvm::StringRef moduleName,
90+
llvm::StringRef className) {
91+
auto *classNode = dem.createNode(Node::Kind::Class);
92+
auto *module =
93+
dem.createNodeWithAllocatedText(Node::Kind::Module, moduleName);
94+
auto *identifier =
95+
dem.createNodeWithAllocatedText(Node::Kind::Identifier, className);
96+
classNode->addChild(module, dem);
97+
classNode->addChild(identifier, dem);
98+
return mangleNode(mangleType(dem, classNode));
99+
}
100+
74101
} // namespace swift_demangle
75102
} // namespace lldb_private
76103

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES := main.swift
2+
3+
include Makefile.rules
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
6+
7+
class TestCase(TestBase):
8+
@swiftTest
9+
@skipUnlessFoundation
10+
def test(self):
11+
"""Print an ObjC derived object without using the AST context."""
12+
self.build()
13+
lldbutil.run_to_source_breakpoint(
14+
self, "// break here", lldb.SBFileSpec("main.swift")
15+
)
16+
self.runCmd("settings set symbols.swift-enable-ast-context false")
17+
self.expect("v", substrs=["num = 15"])
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Foundation
2+
3+
class C: NSObject {
4+
var num: Int = 15
5+
}
6+
7+
func main() {
8+
let c = C()
9+
// break here
10+
print(c)
11+
}
12+
13+
main()

0 commit comments

Comments
 (0)