@@ -1422,7 +1422,26 @@ static bool ContainsSugaredParen(swift::Demangle::NodePointer node) {
1422
1422
1423
1423
return false ;
1424
1424
}
1425
-
1425
+
1426
+ swift::Demangle::NodePointer
1427
+ StripPrivateIDs (swift::Demangle::Demangler &dem,
1428
+ swift::Demangle::NodePointer node) {
1429
+ using namespace swift ::Demangle;
1430
+ return TypeSystemSwiftTypeRef::Transform (dem, node, [&](NodePointer node) {
1431
+ if (node->getKind () != Node::Kind::PrivateDeclName ||
1432
+ node->getNumChildren () != 2 )
1433
+ return node;
1434
+
1435
+ assert (node->getFirstChild ()->getKind () == Node::Kind::Identifier);
1436
+ assert (node->getLastChild ()->getKind () == Node::Kind::Identifier);
1437
+ auto *new_node = dem.createNode (Node::Kind::PrivateDeclName);
1438
+ auto *ident = dem.createNodeWithAllocatedText (
1439
+ Node::Kind::Identifier, node->getLastChild ()->getText ());
1440
+ new_node->addChild (ident, dem);
1441
+ return new_node;
1442
+ });
1443
+ }
1444
+
1426
1445
// / Compare two swift types from different type systems by comparing their
1427
1446
// / (canonicalized) mangled name.
1428
1447
template <> bool Equivalent<CompilerType>(CompilerType l, CompilerType r) {
@@ -1443,10 +1462,10 @@ template <> bool Equivalent<CompilerType>(CompilerType l, CompilerType r) {
1443
1462
if (ContainsUnresolvedTypeAlias (r_node) ||
1444
1463
ContainsGenericTypeParameter (r_node) || ContainsSugaredParen (r_node))
1445
1464
return true ;
1446
- if (swift::Demangle::mangleNode (
1447
- TypeSystemSwiftTypeRef::CanonicalizeSugar (dem, l_node)) ==
1448
- swift::Demangle::mangleNode (
1449
- TypeSystemSwiftTypeRef::CanonicalizeSugar (dem, r_node)))
1465
+ if (swift::Demangle::mangleNode (StripPrivateIDs (
1466
+ dem, TypeSystemSwiftTypeRef::CanonicalizeSugar (dem, l_node) )) ==
1467
+ swift::Demangle::mangleNode (StripPrivateIDs (
1468
+ dem, TypeSystemSwiftTypeRef::CanonicalizeSugar (dem, r_node) )))
1450
1469
return true ;
1451
1470
1452
1471
// SwiftASTContext hardcodes some less-precise types.
@@ -2296,6 +2315,8 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
2296
2315
child_bitfield_bit_offset, child_is_base_class,
2297
2316
child_is_deref_of_parent, valobj, language_flags);
2298
2317
};
2318
+ auto ast_num_children = m_swift_ast_context->GetNumChildren (
2319
+ ReconstructType (type), omit_empty_base_classes, exe_ctx);
2299
2320
auto impl = [&]() -> CompilerType {
2300
2321
ExecutionContextScope *exe_scope = nullptr ;
2301
2322
if (exe_ctx)
@@ -2315,9 +2336,15 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
2315
2336
if (llvm::StringRef (AsMangledName (type))
2316
2337
.endswith (" sSo18NSNotificationNameaD" ))
2317
2338
return GetTypeFromMangledTypename (ConstString (" $sSo8NSStringCD" ));
2318
- // FIXME: Private discriminators come out in a different format.
2319
- if (result.GetMangledTypeName ().GetStringRef ().count (' $' ) > 1 )
2320
- return fallback ();
2339
+ if (result.GetMangledTypeName ().GetStringRef ().count (' $' ) > 1 &&
2340
+ ast_num_children == runtime->GetNumChildren ({this , type}, valobj))
2341
+ // If available, prefer the AST for private types. Private
2342
+ // identifiers are not ABI; the runtime returns anonymous private
2343
+ // identifiers (using a '$' prefix) which cannot match identifiers
2344
+ // in the AST. Because these private types can't be used in an AST
2345
+ // context, prefer the AST type if available.
2346
+ if (auto ast_type = fallback ())
2347
+ return ast_type;
2321
2348
return result;
2322
2349
}
2323
2350
}
@@ -2416,8 +2443,7 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
2416
2443
// Because the API deals out an index into a list of children we
2417
2444
// can't mix&match between the two typesystems if there is such a
2418
2445
// divergence. We'll need to replace all calls at once.
2419
- if (m_swift_ast_context->GetNumChildren (ReconstructType (type),
2420
- omit_empty_base_classes, exe_ctx) <
2446
+ if (ast_num_children <
2421
2447
runtime->GetNumChildren ({this , type}, valobj).getValueOr (0 ))
2422
2448
return impl ();
2423
2449
@@ -2436,9 +2462,9 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
2436
2462
ast_child_name = suffix.str ();
2437
2463
assert ((llvm::StringRef (child_name).contains (' .' ) ||
2438
2464
Equivalent (child_name, ast_child_name)));
2439
- assert (( Equivalent (llvm::Optional< uint64_t >(child_byte_size),
2440
- llvm::Optional<uint64_t >(ast_child_byte_size)) ||
2441
- ast_language_flags ));
2465
+ assert (ast_language_flags ||
2466
+ ( Equivalent ( llvm::Optional<uint64_t >(child_byte_size),
2467
+ llvm::Optional< uint64_t >(ast_child_byte_size)) ));
2442
2468
assert (Equivalent (llvm::Optional<uint64_t >(child_byte_offset),
2443
2469
llvm::Optional<uint64_t >(ast_child_byte_offset)));
2444
2470
assert (
@@ -2778,37 +2804,14 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
2778
2804
size_t data_byte_size, uint32_t bitfield_bit_size,
2779
2805
uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope,
2780
2806
bool is_base_class) {
2781
- if (!type)
2782
- return false ;
2783
-
2784
- using namespace swift ::Demangle;
2785
- Demangler dem;
2786
- auto *node = DemangleCanonicalType (dem, type);
2787
- auto kind = node->getKind ();
2788
-
2789
- switch (kind) {
2790
- case Node::Kind::Structure: {
2791
- // TODO: Handle ObjC enums masquerading as structs.
2792
- // In rare instances, a Swift `Structure` wraps an ObjC enum. An example is
2793
- // `$sSo16ComparisonResultVD`. For now, use `SwiftASTContext` to handle
2794
- // these enum structs.
2795
- auto resolved = ResolveTypeAlias (m_swift_ast_context, dem, node, true );
2796
- auto clang_type = std::get<CompilerType>(resolved);
2797
- bool is_signed;
2798
- if (!clang_type.IsEnumerationType (is_signed))
2799
- break ;
2800
- LLVM_FALLTHROUGH;
2801
- }
2802
- case Node::Kind::Enum:
2803
- case Node::Kind::BoundGenericEnum:
2804
- // TODO: Add support for Enums.
2805
- return m_swift_ast_context->DumpTypeValue (
2806
- ReconstructType (type), s, format, data, data_offset, data_byte_size,
2807
- bitfield_bit_size, bitfield_bit_offset, exe_scope, is_base_class);
2808
- }
2809
-
2810
2807
auto impl = [&]() -> bool {
2811
- switch (kind) {
2808
+ if (!type)
2809
+ return false ;
2810
+
2811
+ using namespace swift ::Demangle;
2812
+ Demangler dem;
2813
+ auto *node = DemangleCanonicalType (dem, type);
2814
+ switch (node->getKind ()) {
2812
2815
case Node::Kind::Class:
2813
2816
case Node::Kind::BoundGenericClass:
2814
2817
if (is_base_class)
@@ -2868,9 +2871,47 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
2868
2871
s, format, data, data_offset, data_byte_size, bitfield_bit_size,
2869
2872
bitfield_bit_offset, exe_scope, is_base_class);
2870
2873
}
2871
- case Node::Kind::Structure:
2872
2874
case Node::Kind::BoundGenericStructure:
2873
2875
return false ;
2876
+ case Node::Kind::Structure: {
2877
+ // In some instances, a swift `structure` wraps an objc enum. The enum
2878
+ // case needs to be handled, but structs are no-ops.
2879
+ auto resolved = ResolveTypeAlias (m_swift_ast_context, dem, node, true );
2880
+ auto clang_type = std::get<CompilerType>(resolved);
2881
+ if (!clang_type)
2882
+ return false ;
2883
+
2884
+ bool is_signed;
2885
+ if (!clang_type.IsEnumerationType (is_signed))
2886
+ // The type is a clang struct, not an enum.
2887
+ return false ;
2888
+
2889
+ // The type is an enum imported from clang. Try Swift type metadata first,
2890
+ // and failing that fallback to the AST.
2891
+ LLVM_FALLTHROUGH;
2892
+ }
2893
+ case Node::Kind::Enum:
2894
+ case Node::Kind::BoundGenericEnum: {
2895
+ if (exe_scope)
2896
+ if (auto runtime =
2897
+ SwiftLanguageRuntime::Get (exe_scope->CalculateProcess ())) {
2898
+ ExecutionContext exe_ctx;
2899
+ exe_scope->CalculateExecutionContext (exe_ctx);
2900
+ if (auto case_name =
2901
+ runtime->GetEnumCaseName ({this , type}, data, &exe_ctx)) {
2902
+ s->PutCString (*case_name);
2903
+ return true ;
2904
+ }
2905
+ }
2906
+
2907
+ // No result available from the runtime, fallback to the AST.
2908
+ // This can happen in two cases:
2909
+ // 1. MultiPayloadEnums not currently supported by Swift reflection
2910
+ // 2. Some clang imported enums
2911
+ return m_swift_ast_context->DumpTypeValue (
2912
+ ReconstructType (type), s, format, data, data_offset, data_byte_size,
2913
+ bitfield_bit_size, bitfield_bit_offset, exe_scope, is_base_class);
2914
+ }
2874
2915
default :
2875
2916
assert (false && " Unhandled node kind" );
2876
2917
LLDB_LOGF (GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES),
0 commit comments