1111// ===----------------------------------------------------------------------===//
1212
1313#include " LLDBMemoryReader.h"
14+ #include " Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
1415#include " Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h"
1516#include " ReflectionContextInterface.h"
1617#include " SwiftLanguageRuntime.h"
3334#include " lldb/ValueObject/ValueObjectMemory.h"
3435#include " llvm/ADT/STLExtras.h"
3536#include " llvm/Support/Casting.h"
37+ #include " llvm/Support/Error.h"
3638
39+ #include " lldb/lldb-enumerations.h"
3740#include " swift/AST/ASTContext.h"
3841#include " swift/AST/ASTMangler.h"
3942#include " swift/AST/ASTWalker.h"
@@ -728,7 +731,7 @@ class SwiftRuntimeTypeVisitor {
728731 CompilerType m_type;
729732 ValueObject *m_valobj = nullptr ;
730733 bool m_hide_superclass = false ;
731- bool m_include_clang_types = false ;
734+ bool m_omit_empty_base_classes = true ;
732735 bool m_visit_superclass = false ;
733736
734737 void SetFlavor () {
@@ -757,26 +760,27 @@ class SwiftRuntimeTypeVisitor {
757760 using VisitCallback = std::function<llvm::Error(
758761 CompilerType, unsigned , GetChildNameClosure, GetChildInfoClosure)>;
759762 SwiftRuntimeTypeVisitor (SwiftLanguageRuntime &runtime, CompilerType type,
760- ValueObject *valobj)
761- : m_runtime(runtime), m_type(type), m_valobj(valobj) {
763+ ValueObject *valobj, bool omit_empty_base_classes)
764+ : m_runtime(runtime), m_type(type), m_valobj(valobj),
765+ m_omit_empty_base_classes(omit_empty_base_classes) {
762766 if (valobj)
763767 m_exe_ctx = valobj->GetExecutionContextRef ();
764768 SetFlavor ();
765769 }
766770 SwiftRuntimeTypeVisitor (SwiftLanguageRuntime &runtime, CompilerType type,
767771 ExecutionContextScope *exe_scope,
768- bool hide_superclass, bool include_clang_types )
772+ bool hide_superclass, bool omit_empty_base_classes )
769773 : m_runtime(runtime), m_type(type), m_hide_superclass(hide_superclass),
770- m_include_clang_types(include_clang_types ) {
774+ m_omit_empty_base_classes(omit_empty_base_classes ) {
771775 if (exe_scope)
772776 exe_scope->CalculateExecutionContext (m_exe_ctx);
773777 SetFlavor ();
774778 }
775779 SwiftRuntimeTypeVisitor (SwiftLanguageRuntime &runtime, CompilerType type,
776780 ExecutionContext *exe_ctx, bool hide_superclass,
777- bool include_clang_types , bool visit_superclass)
781+ bool omit_empty_base_classes , bool visit_superclass)
778782 : m_runtime(runtime), m_type(type), m_hide_superclass(hide_superclass),
779- m_include_clang_types(include_clang_types ),
783+ m_omit_empty_base_classes(omit_empty_base_classes ),
780784 m_visit_superclass(visit_superclass) {
781785 if (exe_ctx)
782786 m_exe_ctx = *exe_ctx;
@@ -800,9 +804,7 @@ class SwiftRuntimeTypeVisitor {
800804
801805llvm::Expected<unsigned >
802806SwiftRuntimeTypeVisitor::VisitImpl (std::optional<unsigned > visit_only,
803- VisitCallback visit_callback)
804-
805- {
807+ VisitCallback visit_callback) {
806808 if (!m_type)
807809 return llvm::createStringError (" invalid type" );
808810
@@ -854,19 +856,91 @@ SwiftRuntimeTypeVisitor::VisitImpl(std::optional<unsigned> visit_only,
854856 return success;
855857 }
856858
857- // FIXME: Remove this entire mode.
858- assert (!m_include_clang_types || (m_include_clang_types && count_only));
859- if (m_include_clang_types && count_only) {
859+ auto visit_clang_type =
860+ [&](CompilerType clang_type) -> llvm::Expected<unsigned > {
861+ auto swiftify = [&](CompilerType type) {
862+ if (!type.GetTypeSystem ().isa_and_nonnull <TypeSystemClang>())
863+ return type;
864+ CompilerType swift_type = ts.ConvertClangTypeToSwiftType (type);
865+ return swift_type ?: type;
866+ };
867+ unsigned depth = 0 ;
868+ auto n_or_err =
869+ clang_type.GetNumChildren (m_omit_empty_base_classes, &m_exe_ctx);
870+ if (!n_or_err)
871+ return n_or_err.takeError ();
872+ unsigned n = *n_or_err;
873+ bool is_signed, is_enum = clang_type.IsEnumerationType (is_signed);
874+ if (count_only)
875+ return is_enum ? 1 : n;
876+ if (is_enum) {
877+ auto get_name = [&]() -> std::string { return " rawValue" ; };
878+ auto get_info = [&]() -> llvm::Expected<ChildInfo> {
879+ auto ts =
880+ clang_type.GetTypeSystem ().dyn_cast_or_null <TypeSystemClang>();
881+
882+ if (!ts)
883+ return llvm::createStringError (" no clang type system" );
884+ clang::EnumDecl *enum_decl = ts->GetAsEnumDecl (clang_type);
885+ if (!enum_decl)
886+ return llvm::createStringError (" no enum decl" );
887+ swift::Demangle::Demangler dem;
888+ CompilerType raw_value =
889+ CompilerType (ts, enum_decl->getIntegerType ().getAsOpaquePtr ());
890+
891+ auto bit_size =
892+ raw_value.GetBitSize (m_exe_ctx.GetBestExecutionContextScope ());
893+ if (!bit_size)
894+ return bit_size.takeError ();
895+ ChildInfo child;
896+ child.byte_size = *bit_size / 8 ;
897+ child.byte_offset = 0 ;
898+ child.bitfield_bit_size = 0 ;
899+ child.bitfield_bit_offset = 0 ;
900+ child.is_base_class = false ;
901+ child.is_deref_of_parent = false ;
902+ child.language_flags = 0 ;
903+ return child;
904+ };
905+ return visit_callback (clang_type, depth, get_name, get_info);
906+ }
907+ for (unsigned i = 0 ; i < n; ++i)
908+ if (!visit_only || *visit_only == i) {
909+ bool transparent_pointers = false ;
910+ bool ignore_array_bounds = false ;
911+ std::string child_name;
912+ ChildInfo child;
913+ auto child_type_or_err = clang_type.GetChildCompilerTypeAtIndex (
914+ &m_exe_ctx, i, transparent_pointers, m_omit_empty_base_classes,
915+ ignore_array_bounds, child_name, child.byte_size , child.byte_offset ,
916+ child.bitfield_bit_size , child.bitfield_bit_offset ,
917+ child.is_base_class , child.is_deref_of_parent , nullptr ,
918+ child.language_flags );
919+ if (!child_type_or_err)
920+ return child_type_or_err.takeError ();
921+ CompilerType type = swiftify (*child_type_or_err);
922+ auto get_name = [&]() -> std::string { return child_name; };
923+ auto get_info = [&]() -> llvm::Expected<ChildInfo> { return child; };
924+ if (auto err = visit_callback (type, depth, get_name, get_info))
925+ return err;
926+ }
927+ return success;
928+ };
929+
930+ {
860931 CompilerType clang_type = m_runtime.LookupAnonymousClangType (
861932 m_type.GetMangledTypeName ().AsCString ());
862933 if (!clang_type)
863934 ts.IsImportedType (m_type.GetOpaqueQualType (), &clang_type);
864935 if (clang_type) {
865936 clang_type = GetTypedefedTypeRecursive (clang_type);
866- bool is_signed;
867- if (clang_type.IsEnumerationType (is_signed))
868- return 1 ;
869- return clang_type.GetNumChildren (true , &m_exe_ctx);
937+ auto result = visit_clang_type (clang_type);
938+ if (result)
939+ return result;
940+ // FIXME: It would be nice not to fall through here. CFStringRef
941+ // needs this path right now.
942+ LLDB_LOG_ERRORV (GetLog (LLDBLog::Types), result.takeError (),
943+ " could not resolve as clang type: {0}" );
870944 }
871945 }
872946
@@ -1113,6 +1187,57 @@ SwiftRuntimeTypeVisitor::VisitImpl(std::optional<unsigned> visit_only,
11131187 if (ts.IsBuiltinType (m_type))
11141188 return 0 ;
11151189
1190+ // Resolve ObjC references via the ObjC runtime.
1191+ auto visit_objcclass = [&](const swift::reflection::ObjCClassTypeRef &tr)
1192+ -> llvm::Expected<unsigned > {
1193+ const std::string &name = tr.getName ();
1194+ auto *process = m_exe_ctx.GetProcessPtr ();
1195+ if (!process)
1196+ return llvm::createStringError (
1197+ " cannot resolve objc type without process" );
1198+ auto objc_runtime = SwiftLanguageRuntime::GetObjCRuntime (*process);
1199+ if (!process)
1200+ return llvm::createStringError (" no Objective-C runtime" );
1201+ AppleObjCRuntime::ObjCISA isa = objc_runtime->GetISA (ConstString (name));
1202+ if (!isa)
1203+ return llvm::createStringError (" no Objective-C class " + name);
1204+ AppleObjCRuntime::ClassDescriptorSP desc_sp =
1205+ objc_runtime->GetClassDescriptorFromISA (isa);
1206+ if (!desc_sp)
1207+ return llvm::createStringError (" no class descriptor for " + name);
1208+ bool has_super = !m_hide_superclass && desc_sp->GetSuperclass ();
1209+ unsigned n = 0 ;
1210+ if (count_only)
1211+ return has_super ? n + 1 : n;
1212+
1213+ unsigned depth = 0 ;
1214+ if (has_super)
1215+ if (!visit_only || *visit_only == i) {
1216+ if (AppleObjCRuntime::ClassDescriptorSP superclass_desc_sp =
1217+ desc_sp->GetSuperclass ()) {
1218+ auto get_name = [&]() -> std::string {
1219+ return superclass_desc_sp->GetClassName ().GetString ();
1220+ };
1221+ auto get_info = [&]() -> llvm::Expected<ChildInfo> {
1222+ return ChildInfo ();
1223+ };
1224+ CompilerType type;
1225+ if (TypeSP type_sp = superclass_desc_sp->GetType ())
1226+ type = type_sp->GetForwardCompilerType ();
1227+ if (auto err = visit_callback (type, depth, get_name, get_info))
1228+ return err;
1229+ if (visit_only)
1230+ return success;
1231+ }
1232+ }
1233+ // We could query the runtime for the children here but that
1234+ // would be inconsistent with SwiftASTContext.
1235+ return success;
1236+ };
1237+ if (auto *obj_tr =
1238+ llvm::dyn_cast_or_null<swift::reflection::ObjCClassTypeRef>(tr))
1239+ return visit_objcclass (*obj_tr);
1240+
11161241 LLDBTypeInfoProvider tip (m_runtime, ts);
11171242 auto cti_or_err = reflection_ctx->GetClassInstanceTypeInfo (
11181243 *tr, &tip, ts.GetDescriptorFinder ());
@@ -1452,9 +1577,9 @@ SwiftLanguageRuntime::GetNumFields(CompilerType type,
14521577
14531578llvm::Expected<uint32_t > SwiftLanguageRuntime::GetNumChildren (
14541579 CompilerType type, ExecutionContextScope *exe_scope,
1455- bool include_superclass, bool include_clang_types ) {
1580+ bool include_superclass, bool omit_empty_base_classes ) {
14561581 SwiftRuntimeTypeVisitor visitor (*this , type, exe_scope, !include_superclass,
1457- include_clang_types );
1582+ omit_empty_base_classes );
14581583 return visitor.CountChildren ();
14591584}
14601585
@@ -1622,8 +1747,10 @@ SwiftLanguageRuntime::ProjectEnum(ValueObject &valobj) {
16221747std::pair<SwiftLanguageRuntime::LookupResult, std::optional<size_t >>
16231748SwiftLanguageRuntime::GetIndexOfChildMemberWithName (
16241749 CompilerType type, llvm::StringRef name, ExecutionContext *exe_ctx,
1625- bool omit_empty_base_classes, std::vector<uint32_t > &child_indexes) {
1626- SwiftRuntimeTypeVisitor visitor (*this , type, exe_ctx, false , false , true );
1750+ bool omit_empty_base_classes, bool include_clang_types,
1751+ std::vector<uint32_t > &child_indexes) {
1752+ SwiftRuntimeTypeVisitor visitor (*this , type, exe_ctx, false ,
1753+ include_clang_types, true );
16271754 bool found = false ;
16281755 unsigned i = 0 , last_depth = 0 ;
16291756 llvm::Error error = visitor.VisitAllChildren (
@@ -1640,7 +1767,7 @@ SwiftLanguageRuntime::GetIndexOfChildMemberWithName(
16401767 return info_or_err.takeError ();
16411768 // All enum children are index 0.
16421769 if (info_or_err->is_enum || name == get_child_name ()) {
1643- // The only access paths supperted are into base classes,
1770+ // The only access paths supported are into base classes,
16441771 // which are always at index 0.
16451772 for (unsigned j = 0 ; j < depth; ++j)
16461773 child_indexes.push_back (0 );
@@ -1670,7 +1797,7 @@ llvm::Expected<CompilerType> SwiftLanguageRuntime::GetChildCompilerTypeAtIndex(
16701797 uint64_t &language_flags) {
16711798 CompilerType child_type;
16721799 bool found = false ;
1673- SwiftRuntimeTypeVisitor visitor (*this , type, valobj);
1800+ SwiftRuntimeTypeVisitor visitor (*this , type, valobj, omit_empty_base_classes );
16741801 llvm::Error error = visitor.VisitChildAtIndex (
16751802 idx,
16761803 [&](CompilerType type, unsigned depth, auto get_child_name,
0 commit comments