@@ -610,6 +610,20 @@ GetExistentialSyntheticChildren(std::shared_ptr<TypeSystemSwiftTypeRef> ts,
610
610
assert (children.size ());
611
611
return children;
612
612
}
613
+
614
+ // / Log the fact that a type kind is not supported.
615
+ void LogUnimplementedTypeKind (const char *function, CompilerType type) {
616
+ // When running the test suite assert that all cases are covered.
617
+ LLDB_LOG (GetLog (LLDBLog::Types), " {0}: unimplemented type info in {1}" ,
618
+ type.GetMangledTypeName (), function);
619
+ #ifndef NDEBUG
620
+ llvm::dbgs () << function << " : unimplemented type info in"
621
+ << type.GetMangledTypeName () << " \n " ;
622
+ if (ModuleList::GetGlobalModuleListProperties ().GetSwiftValidateTypeSystem ())
623
+ assert (false && " not implemented" );
624
+ #endif
625
+ }
626
+
613
627
} // namespace
614
628
615
629
llvm::Optional<unsigned >
@@ -729,9 +743,7 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
729
743
return {};
730
744
}
731
745
732
- // FIXME: Implement more cases.
733
- LLDB_LOG (GetLog (LLDBLog::Types), " {0}: unimplemented type info" ,
734
- type.GetMangledTypeName ());
746
+ LogUnimplementedTypeKind (__FUNCTION__, type);
735
747
return {};
736
748
}
737
749
@@ -800,26 +812,34 @@ SwiftLanguageRuntimeImpl::GetNumFields(CompilerType type,
800
812
}
801
813
}
802
814
default :
803
- // FIXME: Implement more cases.
815
+ LogUnimplementedTypeKind (__FUNCTION__, type);
804
816
return {};
805
817
}
806
818
}
807
819
808
- static std::pair<bool , llvm::Optional<size_t >>
820
+ static std::pair<SwiftLanguageRuntime::LookupResult , llvm::Optional<size_t >>
809
821
findFieldWithName (const std::vector<swift::reflection::FieldInfo> &fields,
810
822
const swift::reflection::TypeRef *tr, llvm::StringRef name,
811
823
bool is_enum, std::vector<uint32_t > &child_indexes,
812
824
uint32_t offset = 0 ) {
813
825
uint32_t index = 0 ;
826
+ uint32_t name_as_index = 0 ;
827
+ bool name_is_index = false ;
828
+ auto *tuple_tr = llvm::dyn_cast<swift::reflection::TupleTypeRef>(tr);
829
+ if (tuple_tr)
830
+ name_is_index = !name.getAsInteger (10 , name_as_index);
814
831
bool is_nonpayload_enum_case = false ;
832
+
815
833
auto it = std::find_if (fields.begin (), fields.end (), [&](const auto &field) {
834
+ if (name_is_index && name_as_index == index)
835
+ return true ;
836
+
816
837
// In some situations the cached TI for a tuple type is missing the names,
817
838
// but the type_ref has them.
818
839
StringRef field_name = field.Name ;
819
840
if (!field.Name .size ())
820
- if (auto *tuple_tr = llvm::dyn_cast<swift::reflection::TupleTypeRef>(tr))
821
- if (tuple_tr->getLabels ().size () > index)
822
- field_name = tuple_tr->getLabels ().at (index);
841
+ if (tuple_tr && tuple_tr->getLabels ().size () > index)
842
+ field_name = tuple_tr->getLabels ().at (index);
823
843
if (name != field_name) {
824
844
// A nonnull TypeRef is required for enum cases, where it represents cases
825
845
// that have a payload. In other types it will be true anyway.
@@ -831,14 +851,15 @@ findFieldWithName(const std::vector<swift::reflection::FieldInfo> &fields,
831
851
is_nonpayload_enum_case = (field.TR == nullptr );
832
852
return true ;
833
853
});
854
+
834
855
// Not found.
835
856
if (it == fields.end ())
836
- return {false , {}};
857
+ return {SwiftLanguageRuntime::eNotFound , {}};
837
858
// Found, but no index to report.
838
859
if (is_nonpayload_enum_case)
839
- return {true , {}};
860
+ return {SwiftLanguageRuntime::eFound , {}};
840
861
child_indexes.push_back (offset + index);
841
- return {true , child_indexes.size ()};
862
+ return {SwiftLanguageRuntime::eFound , child_indexes.size ()};
842
863
}
843
864
844
865
llvm::Optional<std::string> SwiftLanguageRuntimeImpl::GetEnumCaseName (
@@ -859,24 +880,30 @@ llvm::Optional<std::string> SwiftLanguageRuntimeImpl::GetEnumCaseName(
859
880
if (eti->projectEnumValue (*GetMemoryReader (), addr, &case_index))
860
881
return eti->getCases ()[case_index].Name ;
861
882
883
+ // FIXME: Enabling this fails TestSwiftNestedCEnums.py: The test
884
+ // nests a C-style enum inside of a payload-carrying enum and most
885
+ // likely we're not stripping off the outer enum's discriminator
886
+ // before reading the value of the inner one.
887
+
888
+ // LogUnimplementedTypeKind(__FUNCTION__, type);
862
889
return {};
863
890
}
864
891
865
- std::pair<bool , llvm::Optional<size_t >>
892
+ std::pair<SwiftLanguageRuntime::LookupResult , llvm::Optional<size_t >>
866
893
SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName (
867
894
CompilerType type, llvm::StringRef name, ExecutionContext *exe_ctx,
868
895
bool omit_empty_base_classes, std::vector<uint32_t > &child_indexes) {
869
896
LLDB_SCOPED_TIMER ();
870
897
auto ts = type.GetTypeSystem ().dyn_cast_or_null <TypeSystemSwiftTypeRef>();
871
898
if (!ts)
872
- return {false , {}};
899
+ return {SwiftLanguageRuntime::eError , {}};
873
900
874
901
using namespace swift ::reflection;
875
902
// Try the static type metadata.
876
903
const TypeRef *tr = nullptr ;
877
904
auto *ti = GetSwiftRuntimeTypeInfo (type, exe_ctx->GetFramePtr (), &tr);
878
905
if (!ti)
879
- return {false , {}};
906
+ return {SwiftLanguageRuntime::eError , {}};
880
907
switch (ti->getKind ()) {
881
908
case TypeInfoKind::Record: {
882
909
// Structs and Tuples.
@@ -886,7 +913,7 @@ SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName(
886
913
case RecordKind::ThickFunction:
887
914
// There are two fields, `function` and `context`, but they're not exposed
888
915
// by lldb.
889
- return {true , {0 }};
916
+ return {SwiftLanguageRuntime::eFound , {0 }};
890
917
case RecordKind::OpaqueExistential:
891
918
// `OpaqueExistential` is documented as:
892
919
// An existential is a three-word buffer followed by value metadata...
@@ -896,7 +923,7 @@ SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName(
896
923
uint32_t index;
897
924
if (name.take_back ().getAsInteger (10 , index) && index < 3 ) {
898
925
child_indexes.push_back (index);
899
- return {true , child_indexes.size ()};
926
+ return {SwiftLanguageRuntime::eFound , child_indexes.size ()};
900
927
}
901
928
}
902
929
return findFieldWithName (rti->getFields (), tr, name, false , child_indexes,
@@ -916,19 +943,23 @@ SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName(
916
943
case ReferenceKind::Weak:
917
944
case ReferenceKind::Unowned:
918
945
case ReferenceKind::Unmanaged:
946
+ // Weak references are implicitly optional.
947
+ child_indexes.push_back (0 );
948
+ if (name == " some" )
949
+ return {SwiftLanguageRuntime::eFound, child_indexes.size ()};
919
950
return GetIndexOfChildMemberWithName (GetWeakReferent (*ts, type), name,
920
951
exe_ctx, omit_empty_base_classes,
921
952
child_indexes);
922
953
case ReferenceKind::Strong: {
923
954
ThreadSafeReflectionContext reflection_ctx = GetReflectionContext ();
924
955
if (!reflection_ctx)
925
- return {false , {}};
956
+ return {SwiftLanguageRuntime::eError , {}};
926
957
927
958
size_t idx = 0 ;
928
959
for (auto &protocol_child : GetExistentialSyntheticChildren (ts, tr, ti)) {
929
960
if (protocol_child.name == name) {
930
961
child_indexes.push_back (idx);
931
- return {true , child_indexes.size ()};
962
+ return {SwiftLanguageRuntime::eFound , child_indexes.size ()};
932
963
}
933
964
++idx;
934
965
}
@@ -941,26 +972,46 @@ SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName(
941
972
auto *record_ti = llvm::dyn_cast_or_null<RecordTypeInfo>(
942
973
reflection_ctx->GetClassInstanceTypeInfo (
943
974
current_tr, &tip, ts->GetDescriptorFinder ()));
944
- if (!record_ti)
945
- break ;
975
+ if (!record_ti) {
976
+ child_indexes.clear ();
977
+ return {SwiftLanguageRuntime::eError, {}};
978
+ }
946
979
auto *super_tr = reflection_ctx->LookupSuperclass (
947
980
current_tr, ts->GetDescriptorFinder ());
948
981
uint32_t offset = super_tr ? 1 : 0 ;
949
982
auto found_size = findFieldWithName (record_ti->getFields (), current_tr,
950
983
name, false , child_indexes, offset);
951
- if (found_size.first )
984
+ if (found_size.first == SwiftLanguageRuntime::eError ||
985
+ found_size.first == SwiftLanguageRuntime::eFound)
952
986
return found_size;
953
987
current_tr = super_tr;
954
988
child_indexes.push_back (0 );
955
989
}
956
990
child_indexes.clear ();
957
- return {false , {}};
991
+ return {SwiftLanguageRuntime::eNotFound , {}};
958
992
}
959
993
}
960
994
}
995
+ case TypeInfoKind::Builtin: {
996
+ // Clang enums have an artificial rawValue property.
997
+ CompilerType clang_type;
998
+ if (ts->IsImportedType (type.GetOpaqueQualType (), &clang_type)) {
999
+ bool is_signed;
1000
+ if (clang_type.IsEnumerationType (is_signed) && name == " rawValue" ) {
1001
+ child_indexes.push_back (0 );
1002
+ return {SwiftLanguageRuntime::eFound, {1 }};
1003
+ }
1004
+ }
1005
+ // SIMD types have an artificial _value.
1006
+ if (name == " _value" && TypeSystemSwiftTypeRef::IsSIMDType (type)) {
1007
+ child_indexes.push_back (0 );
1008
+ return {SwiftLanguageRuntime::eFound, {1 }};
1009
+ }
1010
+ return {SwiftLanguageRuntime::eNotFound, {0 }};
1011
+ }
961
1012
default :
962
- // FIXME: Implement more cases.
963
- return {false , {}};
1013
+ LogUnimplementedTypeKind (__FUNCTION__, type);
1014
+ return {SwiftLanguageRuntime::eError , {}};
964
1015
}
965
1016
}
966
1017
@@ -1267,8 +1318,14 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
1267
1318
i - 1 );
1268
1319
return {};
1269
1320
}
1270
- LLDB_LOG (GetLog (LLDBLog::Types), " Cannot retrieve type information for {0}" ,
1271
- type.GetTypeName ());
1321
+ if (llvm::dyn_cast_or_null<swift::reflection::BuiltinTypeInfo>(ti)) {
1322
+ // Clang enums have an artificial rawValue property. We could
1323
+ // consider handling them here, but
1324
+ // TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex can also
1325
+ // handle them and without a Process.
1326
+ return {};
1327
+ }
1328
+ LogUnimplementedTypeKind (__FUNCTION__, type);
1272
1329
return {};
1273
1330
}
1274
1331
0 commit comments