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