22
22
#include " lldb/Symbol/Variable.h"
23
23
#include " lldb/Symbol/VariableList.h"
24
24
#include " lldb/Target/ProcessStructReader.h"
25
+ #include " lldb/Target/SectionLoadList.h"
25
26
#include " lldb/Target/Target.h"
26
27
#include " lldb/Utility/LLDBLog.h"
27
28
#include " lldb/Utility/Log.h"
@@ -2217,6 +2218,80 @@ SwiftLanguageRuntimeImpl::GetValueType(ValueObject &in_value,
2217
2218
return Value::ValueType::Scalar;
2218
2219
}
2219
2220
2221
+ namespace {
2222
+ struct SwiftNominalType {
2223
+ std::string module ;
2224
+ std::string identifier;
2225
+ };
2226
+
2227
+ // Find the Swift class that backs an ObjC type.
2228
+ //
2229
+ // A Swift class that uses the @objc(<ClassName>) attribute will emit ObjC
2230
+ // metadata into the binary. Typically, ObjC classes have a symbol in the form
2231
+ // of OBJC_CLASS_$_<ClassName>, however for Swift classes, there are two symbols
2232
+ // that both point to the ObjC class metadata, where the second symbol is a
2233
+ // Swift mangled name.
2234
+ std::optional<SwiftNominalType> GetSwiftClass (ValueObject &valobj,
2235
+ AppleObjCRuntime &objc_runtime) {
2236
+ // To find the Swift symbol, the following preparation steps are taken:
2237
+ // 1. Get the value's ISA pointer
2238
+ // 2. Resolve the ISA load address into an Address instance
2239
+ // 3. Get the Module that contains the Address
2240
+ auto descriptor_sp = objc_runtime.GetClassDescriptor (valobj);
2241
+ if (!descriptor_sp)
2242
+ return {};
2243
+
2244
+ auto isa_load_addr = descriptor_sp->GetISA ();
2245
+ Address isa;
2246
+ const auto §ions = objc_runtime.GetTargetRef ().GetSectionLoadList ();
2247
+ if (!sections.ResolveLoadAddress (isa_load_addr, isa))
2248
+ return {};
2249
+
2250
+ // Next, iterate over the Module's symbol table, looking for a symbol with
2251
+ // following criteria:
2252
+ // 1. The symbol address is the ISA address
2253
+ // 2. The symbol name is a Swift mangled name
2254
+ std::optional<StringRef> swift_symbol;
2255
+ auto find_swift_symbol_for_isa = [&](Symbol *symbol) {
2256
+ if (symbol->GetAddress () == isa) {
2257
+ StringRef symbol_name =
2258
+ symbol->GetMangled ().GetMangledName ().GetStringRef ();
2259
+ if (SwiftLanguageRuntime::IsSwiftMangledName (symbol_name)) {
2260
+ swift_symbol = symbol_name;
2261
+ return false ;
2262
+ }
2263
+ }
2264
+ return true ;
2265
+ };
2266
+
2267
+ isa.GetModule ()->GetSymtab ()->ForEachSymbolContainingFileAddress (
2268
+ isa.GetFileAddress (), find_swift_symbol_for_isa);
2269
+ if (!swift_symbol)
2270
+ return {};
2271
+
2272
+ // Once the Swift symbol is found, demangle it into a node tree. The node tree
2273
+ // provides the final data, the name of the class and the name of its module.
2274
+ swift::Demangle::Context ctx;
2275
+ auto *global = ctx.demangleSymbolAsNode (*swift_symbol);
2276
+ using Kind = Node::Kind;
2277
+ auto *class_node = swift_demangle::nodeAtPath (
2278
+ global, {Kind::TypeMetadata, Kind::Type, Kind::Class});
2279
+ if (class_node && class_node->getNumChildren () == 2 ) {
2280
+ auto module_node = class_node->getFirstChild ();
2281
+ auto ident_node = class_node->getLastChild ();
2282
+ if (module_node->getKind () == Kind::Module && module_node->hasText () &&
2283
+ ident_node->getKind () == Kind::Identifier && ident_node->hasText ()) {
2284
+ auto module_name = module_node->getText ();
2285
+ auto class_name = ident_node->getText ();
2286
+ return SwiftNominalType{module_name.str (), class_name.str ()};
2287
+ }
2288
+ }
2289
+
2290
+ return {};
2291
+ }
2292
+
2293
+ } // namespace
2294
+
2220
2295
bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType (
2221
2296
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
2222
2297
TypeAndOrName &class_type_or_name, Address &address,
@@ -2243,9 +2318,22 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
2243
2318
dyn_name.startswith (" __NS" ))
2244
2319
return false ;
2245
2320
2321
+ SwiftNominalType swift_class;
2322
+
2323
+ if (auto maybe_swift_class = GetSwiftClass (in_value, *objc_runtime)) {
2324
+ swift_class = *maybe_swift_class;
2325
+ std::string type_name =
2326
+ (llvm::Twine (swift_class.module ) + " ." + swift_class.identifier ).str ();
2327
+ dyn_class_type_or_name.SetName (type_name.data ());
2328
+ address.SetRawAddress (in_value.GetPointerValue ());
2329
+ } else {
2330
+ swift_class.module = swift::MANGLING_MODULE_OBJC;
2331
+ swift_class.identifier = dyn_name;
2332
+ }
2333
+
2246
2334
std::string remangled;
2247
2335
{
2248
- // Create a mangle tree for __C.dyn_name?.
2336
+ // Create a mangle tree for Swift.Optional<$module.$class>
2249
2337
using namespace swift ::Demangle;
2250
2338
NodeFactory factory;
2251
2339
NodePointer global = factory.createNode (Node::Kind::Global);
@@ -2256,7 +2344,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
2256
2344
NodePointer ety = factory.createNode (Node::Kind::Type);
2257
2345
bge->addChild (ety, factory);
2258
2346
NodePointer e = factory.createNode (Node::Kind::Enum);
2259
- e->addChild (factory.createNode (Node::Kind::Module, " Swift" ), factory);
2347
+ e->addChild (factory.createNode (Node::Kind::Module, swift::STDLIB_NAME),
2348
+ factory);
2260
2349
e->addChild (factory.createNode (Node::Kind::Identifier, " Optional" ),
2261
2350
factory);
2262
2351
ety->addChild (e, factory);
@@ -2265,10 +2354,11 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
2265
2354
NodePointer cty = factory.createNode (Node::Kind::Type);
2266
2355
list->addChild (cty, factory);
2267
2356
NodePointer c = factory.createNode (Node::Kind::Class);
2357
+ c->addChild (factory.createNode (Node::Kind::Module, swift_class.module ),
2358
+ factory);
2268
2359
c->addChild (
2269
- factory.createNode (Node::Kind::Module, swift::MANGLING_MODULE_OBJC ),
2360
+ factory.createNode (Node::Kind::Identifier, swift_class. identifier ),
2270
2361
factory);
2271
- c->addChild (factory.createNode (Node::Kind::Identifier, dyn_name), factory);
2272
2362
cty->addChild (c, factory);
2273
2363
2274
2364
auto mangling = mangleNode (global);
0 commit comments