Skip to content

Commit 45f4398

Browse files
authored
[lldb] Support plain ObjC names in LLDBTypeInfoProvider (#9320) (#9357)
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 (cherry picked from commit 4a1abae)
1 parent 27f7e57 commit 45f4398

File tree

5 files changed

+80
-5
lines changed

5 files changed

+80
-5
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: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,33 @@ GetDemangledType(swift::Demangle::Demangler &dem, llvm::StringRef name) {
8080
return GetType(dem.demangleSymbol(name));
8181
}
8282

83+
/// Wrap node in Global/TypeMangling/Type.
84+
static swift::Demangle::NodePointer
85+
mangleType(swift::Demangle::Demangler &dem,
86+
swift::Demangle::NodePointer typeNode) {
87+
auto *global = dem.createNode(Node::Kind::Global);
88+
auto *typeMangling = dem.createNode(Node::Kind::TypeMangling);
89+
global->addChild(typeMangling, dem);
90+
auto *type = dem.createNode(Node::Kind::Type);
91+
typeMangling->addChild(type, dem);
92+
type->addChild(typeNode, dem);
93+
return global;
94+
}
95+
96+
/// Produce a type mangling for a class.
97+
inline ManglingErrorOr<std::string> mangleClass(swift::Demangle::Demangler &dem,
98+
llvm::StringRef moduleName,
99+
llvm::StringRef className) {
100+
auto *classNode = dem.createNode(Node::Kind::Class);
101+
auto *module =
102+
dem.createNodeWithAllocatedText(Node::Kind::Module, moduleName);
103+
auto *identifier =
104+
dem.createNodeWithAllocatedText(Node::Kind::Identifier, className);
105+
classNode->addChild(module, dem);
106+
classNode->addChild(identifier, dem);
107+
return mangleNode(mangleType(dem, classNode));
108+
}
109+
83110
} // namespace swift_demangle
84111
} // namespace lldb_private
85112

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)