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