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