@@ -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.
@@ -2293,6 +2312,8 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
2293
2312
child_bitfield_bit_offset, child_is_base_class,
2294
2313
child_is_deref_of_parent, valobj, language_flags);
2295
2314
};
2315
+ auto ast_num_children = m_swift_ast_context->GetNumChildren (
2316
+ ReconstructType (type), omit_empty_base_classes, exe_ctx);
2296
2317
auto impl = [&]() -> CompilerType {
2297
2318
ExecutionContextScope *exe_scope = nullptr ;
2298
2319
if (exe_ctx)
@@ -2312,9 +2333,15 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
2312
2333
if (llvm::StringRef (AsMangledName (type))
2313
2334
.endswith (" sSo18NSNotificationNameaD" ))
2314
2335
return GetTypeFromMangledTypename (ConstString (" $sSo8NSStringCD" ));
2315
- // FIXME: Private discriminators come out in a different format.
2316
- if (result.GetMangledTypeName ().GetStringRef ().count (' $' ) > 1 )
2317
- return fallback ();
2336
+ if (result.GetMangledTypeName ().GetStringRef ().count (' $' ) > 1 &&
2337
+ ast_num_children == runtime->GetNumChildren ({this , type}, valobj))
2338
+ // If available, prefer the AST for private types. Private
2339
+ // identifiers are not ABI; the runtime returns anonymous private
2340
+ // identifiers (using a '$' prefix) which cannot match identifiers
2341
+ // in the AST. Because these private types can't be used in an AST
2342
+ // context, prefer the AST type if available.
2343
+ if (auto ast_type = fallback ())
2344
+ return ast_type;
2318
2345
return result;
2319
2346
}
2320
2347
}
@@ -2413,8 +2440,7 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
2413
2440
// Because the API deals out an index into a list of children we
2414
2441
// can't mix&match between the two typesystems if there is such a
2415
2442
// divergence. We'll need to replace all calls at once.
2416
- if (m_swift_ast_context->GetNumChildren (ReconstructType (type),
2417
- omit_empty_base_classes, exe_ctx) <
2443
+ if (ast_num_children <
2418
2444
runtime->GetNumChildren ({this , type}, valobj).getValueOr (0 ))
2419
2445
return impl ();
2420
2446
@@ -2433,9 +2459,9 @@ CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
2433
2459
ast_child_name = suffix.str ();
2434
2460
assert ((llvm::StringRef (child_name).contains (' .' ) ||
2435
2461
Equivalent (child_name, ast_child_name)));
2436
- assert (( Equivalent (llvm::Optional< uint64_t >(child_byte_size),
2437
- llvm::Optional<uint64_t >(ast_child_byte_size)) ||
2438
- ast_language_flags ));
2462
+ assert (ast_language_flags ||
2463
+ ( Equivalent ( llvm::Optional<uint64_t >(child_byte_size),
2464
+ llvm::Optional< uint64_t >(ast_child_byte_size)) ));
2439
2465
assert (Equivalent (llvm::Optional<uint64_t >(child_byte_offset),
2440
2466
llvm::Optional<uint64_t >(ast_child_byte_offset)));
2441
2467
assert (
@@ -2787,37 +2813,14 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
2787
2813
size_t data_byte_size, uint32_t bitfield_bit_size,
2788
2814
uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope,
2789
2815
bool is_base_class) {
2790
- if (!type)
2791
- return false ;
2792
-
2793
- using namespace swift ::Demangle;
2794
- Demangler dem;
2795
- auto *node = DemangleCanonicalType (dem, type);
2796
- auto kind = node->getKind ();
2797
-
2798
- switch (kind) {
2799
- case Node::Kind::Structure: {
2800
- // TODO: Handle ObjC enums masquerading as structs.
2801
- // In rare instances, a Swift `Structure` wraps an ObjC enum. An example is
2802
- // `$sSo16ComparisonResultVD`. For now, use `SwiftASTContext` to handle
2803
- // these enum structs.
2804
- auto resolved = ResolveTypeAlias (m_swift_ast_context, dem, node, true );
2805
- auto clang_type = std::get<CompilerType>(resolved);
2806
- bool is_signed;
2807
- if (!clang_type.IsEnumerationType (is_signed))
2808
- break ;
2809
- LLVM_FALLTHROUGH;
2810
- }
2811
- case Node::Kind::Enum:
2812
- case Node::Kind::BoundGenericEnum:
2813
- // TODO: Add support for Enums.
2814
- return m_swift_ast_context->DumpTypeValue (
2815
- ReconstructType (type), s, format, data, data_offset, data_byte_size,
2816
- bitfield_bit_size, bitfield_bit_offset, exe_scope, is_base_class);
2817
- }
2818
-
2819
2816
auto impl = [&]() -> bool {
2820
- switch (kind) {
2817
+ if (!type)
2818
+ return false ;
2819
+
2820
+ using namespace swift ::Demangle;
2821
+ Demangler dem;
2822
+ auto *node = DemangleCanonicalType (dem, type);
2823
+ switch (node->getKind ()) {
2821
2824
case Node::Kind::Class:
2822
2825
case Node::Kind::BoundGenericClass:
2823
2826
if (is_base_class)
@@ -2877,9 +2880,47 @@ bool TypeSystemSwiftTypeRef::DumpTypeValue(
2877
2880
s, format, data, data_offset, data_byte_size, bitfield_bit_size,
2878
2881
bitfield_bit_offset, exe_scope, is_base_class);
2879
2882
}
2880
- case Node::Kind::Structure:
2881
2883
case Node::Kind::BoundGenericStructure:
2882
2884
return false ;
2885
+ case Node::Kind::Structure: {
2886
+ // In some instances, a swift `structure` wraps an objc enum. The enum
2887
+ // case needs to be handled, but structs are no-ops.
2888
+ auto resolved = ResolveTypeAlias (m_swift_ast_context, dem, node, true );
2889
+ auto clang_type = std::get<CompilerType>(resolved);
2890
+ if (!clang_type)
2891
+ return false ;
2892
+
2893
+ bool is_signed;
2894
+ if (!clang_type.IsEnumerationType (is_signed))
2895
+ // The type is a clang struct, not an enum.
2896
+ return false ;
2897
+
2898
+ // The type is an enum imported from clang. Try Swift type metadata first,
2899
+ // and failing that fallback to the AST.
2900
+ LLVM_FALLTHROUGH;
2901
+ }
2902
+ case Node::Kind::Enum:
2903
+ case Node::Kind::BoundGenericEnum: {
2904
+ if (exe_scope)
2905
+ if (auto runtime =
2906
+ SwiftLanguageRuntime::Get (exe_scope->CalculateProcess ())) {
2907
+ ExecutionContext exe_ctx;
2908
+ exe_scope->CalculateExecutionContext (exe_ctx);
2909
+ if (auto case_name =
2910
+ runtime->GetEnumCaseName ({this , type}, data, &exe_ctx)) {
2911
+ s->PutCString (*case_name);
2912
+ return true ;
2913
+ }
2914
+ }
2915
+
2916
+ // No result available from the runtime, fallback to the AST.
2917
+ // This can happen in two cases:
2918
+ // 1. MultiPayloadEnums not currently supported by Swift reflection
2919
+ // 2. Some clang imported enums
2920
+ return m_swift_ast_context->DumpTypeValue (
2921
+ ReconstructType (type), s, format, data, data_offset, data_byte_size,
2922
+ bitfield_bit_size, bitfield_bit_offset, exe_scope, is_base_class);
2923
+ }
2883
2924
default :
2884
2925
assert (false && " Unhandled node kind" );
2885
2926
LLDB_LOGF (GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES),
0 commit comments