Skip to content

Commit 0852543

Browse files
committed
Merge commit '5977e120d6e6' from swift/release/5.9 into stable/20221013
Conflicts: lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp
2 parents 9b562f5 + 5977e12 commit 0852543

File tree

14 files changed

+245
-5
lines changed

14 files changed

+245
-5
lines changed

lldb/include/lldb/Target/LanguageRuntime.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ class LanguageRuntime : public Runtime, public PluginInterface {
6767

6868
virtual lldb::LanguageType GetLanguageType() const = 0;
6969

70+
/// Return the preferred language runtime instance, which in most cases will
71+
/// be the current instance.
72+
virtual LanguageRuntime *GetPreferredLanguageRuntime(ValueObject &in_value) {
73+
return nullptr;
74+
}
75+
7076
virtual bool GetObjectDescription(Stream &str, ValueObject &object) = 0;
7177

7278
virtual bool GetObjectDescription(Stream &str, Value &value,

lldb/source/Core/ValueObjectDynamicValue.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,18 @@ bool ValueObjectDynamicValue::UpdateValue() {
181181
known_type != lldb::eLanguageTypeUnknown &&
182182
known_type != lldb::eLanguageTypeC) {
183183
runtime = process->GetLanguageRuntime(known_type);
184-
if (runtime)
184+
if (auto *preferred_runtime =
185+
runtime->GetPreferredLanguageRuntime(*m_parent)) {
186+
// Try the preferred runtime first.
187+
found_dynamic_type = preferred_runtime->GetDynamicTypeAndAddress(
188+
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
189+
value_type);
190+
if (found_dynamic_type)
191+
// Set the operative `runtime` for later use in this function.
192+
runtime = preferred_runtime;
193+
}
194+
if (!found_dynamic_type)
195+
// Fallback to the runtime for `known_type`.
185196
found_dynamic_type = runtime->GetDynamicTypeAndAddress(
186197
*m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
187198
value_type);

lldb/source/Plugins/Language/ObjC/Cocoa.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,20 @@ bool lldb_private::formatters::NSTimeZoneSummaryProvider(
132132
stream.Printf("%s", summary_stream.GetData());
133133
return true;
134134
}
135+
} else if (class_name == "_NSSwiftTimeZone") {
136+
llvm::ArrayRef<ConstString> identifier_path = {
137+
ConstString("timeZone"),
138+
ConstString("_timeZone"),
139+
ConstString("some"),
140+
ConstString("identifier"),
141+
};
142+
if (auto identifier_sp = valobj.GetChildAtNamePath(identifier_path)) {
143+
std::string desc;
144+
if (identifier_sp->GetSummaryAsCString(desc, options)) {
145+
stream.PutCString(desc);
146+
return true;
147+
}
148+
}
135149
}
136150

137151
return false;

lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,11 @@ LoadFoundationValueTypesFormatters(lldb::TypeCategoryImplSP swift_category_sp) {
636636
"Decimal summary provider", ConstString("Foundation.Decimal"),
637637
TypeSummaryImpl::Flags(summary_flags).SetDontShowChildren(true));
638638

639+
lldb_private::formatters::AddCXXSummary(
640+
swift_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider,
641+
"NSTimeZone summary provider", ConstString("Foundation._NSSwiftTimeZone"),
642+
TypeSummaryImpl::Flags(summary_flags).SetDontShowChildren(true));
643+
639644
lldb_private::formatters::AddCXXSynthetic(
640645
swift_category_sp,
641646
lldb_private::formatters::swift::URLComponentsSyntheticFrontEndCreator,

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010

1111
#include "lldb/Expression/FunctionCaller.h"
1212
#include "lldb/Target/ABI.h"
13+
#include "lldb/Target/Language.h"
1314
#include "lldb/Utility/LLDBLog.h"
1415
#include "lldb/Utility/Log.h"
16+
#include "lldb/lldb-enumerations.h"
1517

1618
using namespace lldb;
1719
using namespace lldb_private;
@@ -668,6 +670,19 @@ uint64_t ClassDescriptorV2::GetInstanceSize() {
668670
return 0;
669671
}
670672

673+
// From the ObjC runtime.
674+
static uint8_t IS_SWIFT_STABLE = 1U << 1;
675+
676+
LanguageType ClassDescriptorV2::GetImplementationLanguage() const {
677+
std::unique_ptr<objc_class_t> objc_class;
678+
if (auto *process = m_runtime.GetProcess())
679+
if (Read_objc_class(process, objc_class))
680+
if (objc_class->m_flags & IS_SWIFT_STABLE)
681+
return lldb::eLanguageTypeSwift;
682+
683+
return lldb::eLanguageTypeObjC;
684+
}
685+
671686
ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_ivars(), m_mutex() {}
672687

673688
size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); }

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <mutex>
1313

1414
#include "AppleObjCRuntimeV2.h"
15+
#include "lldb/lldb-enumerations.h"
1516
#include "lldb/lldb-private.h"
1617

1718
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
@@ -34,6 +35,8 @@ class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor {
3435
return true; // any Objective-C v2 runtime class descriptor we vend is valid
3536
}
3637

38+
lldb::LanguageType GetImplementationLanguage() const override;
39+
3740
// a custom descriptor is used for tagged pointers
3841
bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr,
3942
uint64_t *value_bits = nullptr,

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "lldb/Target/ABI.h"
3434
#include "lldb/Target/DynamicLoader.h"
3535
#include "lldb/Target/ExecutionContext.h"
36+
#include "lldb/Target/LanguageRuntime.h"
3637
#include "lldb/Target/Platform.h"
3738
#include "lldb/Target/Process.h"
3839
#include "lldb/Target/RegisterContext.h"
@@ -758,6 +759,19 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process,
758759
RegisterObjCExceptionRecognizer(process);
759760
}
760761

762+
LanguageRuntime *
763+
AppleObjCRuntimeV2::GetPreferredLanguageRuntime(ValueObject &in_value) {
764+
if (auto process_sp = in_value.GetProcessSP()) {
765+
assert(process_sp.get() == m_process);
766+
if (auto descriptor_sp = GetNonKVOClassDescriptor(in_value)) {
767+
LanguageType impl_lang = descriptor_sp->GetImplementationLanguage();
768+
if (impl_lang != eLanguageTypeUnknown)
769+
return process_sp->GetLanguageRuntime(impl_lang);
770+
}
771+
}
772+
return nullptr;
773+
}
774+
761775
bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress(
762776
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
763777
TypeAndOrName &class_type_or_name, Address &address,

lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class AppleObjCRuntimeV2 : public AppleObjCRuntime {
3737

3838
static llvm::StringRef GetPluginNameStatic() { return "apple-objc-v2"; }
3939

40+
LanguageRuntime *GetPreferredLanguageRuntime(ValueObject &in_value) override;
41+
4042
static char ID;
4143

4244
bool isA(const void *ClassID) const override {

lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "lldb/Symbol/Type.h"
2424
#include "lldb/Target/LanguageRuntime.h"
2525
#include "lldb/Utility/ConstString.h"
26+
#include "lldb/lldb-enumerations.h"
2627
#include "lldb/lldb-private.h"
2728

2829
class CommandObjectObjC_ClassTable_Dump;
@@ -84,6 +85,11 @@ class ObjCLanguageRuntime : public LanguageRuntime {
8485
return (m_is_cf == eLazyBoolYes);
8586
}
8687

88+
/// Determine whether this class is implemented in Swift.
89+
virtual lldb::LanguageType GetImplementationLanguage() const {
90+
return lldb::eLanguageTypeObjC;
91+
}
92+
8793
virtual bool IsValid() = 0;
8894

8995
/// There are two routines in the ObjC runtime that tagged pointer clients

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lldb/Symbol/Variable.h"
2323
#include "lldb/Symbol/VariableList.h"
2424
#include "lldb/Target/ProcessStructReader.h"
25+
#include "lldb/Target/SectionLoadList.h"
2526
#include "lldb/Target/Target.h"
2627
#include "lldb/Utility/LLDBLog.h"
2728
#include "lldb/Utility/Log.h"
@@ -2924,6 +2925,80 @@ SwiftLanguageRuntimeImpl::GetValueType(ValueObject &in_value,
29242925
return Value::ValueType::Scalar;
29252926
}
29262927

2928+
namespace {
2929+
struct SwiftNominalType {
2930+
std::string module;
2931+
std::string identifier;
2932+
};
2933+
2934+
// Find the Swift class that backs an ObjC type.
2935+
//
2936+
// A Swift class that uses the @objc(<ClassName>) attribute will emit ObjC
2937+
// metadata into the binary. Typically, ObjC classes have a symbol in the form
2938+
// of OBJC_CLASS_$_<ClassName>, however for Swift classes, there are two symbols
2939+
// that both point to the ObjC class metadata, where the second symbol is a
2940+
// Swift mangled name.
2941+
std::optional<SwiftNominalType> GetSwiftClass(ValueObject &valobj,
2942+
AppleObjCRuntime &objc_runtime) {
2943+
// To find the Swift symbol, the following preparation steps are taken:
2944+
// 1. Get the value's ISA pointer
2945+
// 2. Resolve the ISA load address into an Address instance
2946+
// 3. Get the Module that contains the Address
2947+
auto descriptor_sp = objc_runtime.GetClassDescriptor(valobj);
2948+
if (!descriptor_sp)
2949+
return {};
2950+
2951+
auto isa_load_addr = descriptor_sp->GetISA();
2952+
Address isa;
2953+
const auto &sections = objc_runtime.GetTargetRef().GetSectionLoadList();
2954+
if (!sections.ResolveLoadAddress(isa_load_addr, isa))
2955+
return {};
2956+
2957+
// Next, iterate over the Module's symbol table, looking for a symbol with
2958+
// following criteria:
2959+
// 1. The symbol address is the ISA address
2960+
// 2. The symbol name is a Swift mangled name
2961+
std::optional<StringRef> swift_symbol;
2962+
auto find_swift_symbol_for_isa = [&](Symbol *symbol) {
2963+
if (symbol->GetAddress() == isa) {
2964+
StringRef symbol_name =
2965+
symbol->GetMangled().GetMangledName().GetStringRef();
2966+
if (SwiftLanguageRuntime::IsSwiftMangledName(symbol_name)) {
2967+
swift_symbol = symbol_name;
2968+
return false;
2969+
}
2970+
}
2971+
return true;
2972+
};
2973+
2974+
isa.GetModule()->GetSymtab()->ForEachSymbolContainingFileAddress(
2975+
isa.GetFileAddress(), find_swift_symbol_for_isa);
2976+
if (!swift_symbol)
2977+
return {};
2978+
2979+
// Once the Swift symbol is found, demangle it into a node tree. The node tree
2980+
// provides the final data, the name of the class and the name of its module.
2981+
swift::Demangle::Context ctx;
2982+
auto *global = ctx.demangleSymbolAsNode(*swift_symbol);
2983+
using Kind = Node::Kind;
2984+
auto *class_node = swift_demangle::nodeAtPath(
2985+
global, {Kind::TypeMetadata, Kind::Type, Kind::Class});
2986+
if (class_node && class_node->getNumChildren() == 2) {
2987+
auto module_node = class_node->getFirstChild();
2988+
auto ident_node = class_node->getLastChild();
2989+
if (module_node->getKind() == Kind::Module && module_node->hasText() &&
2990+
ident_node->getKind() == Kind::Identifier && ident_node->hasText()) {
2991+
auto module_name = module_node->getText();
2992+
auto class_name = ident_node->getText();
2993+
return SwiftNominalType{module_name.str(), class_name.str()};
2994+
}
2995+
}
2996+
2997+
return {};
2998+
}
2999+
3000+
} // namespace
3001+
29273002
bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
29283003
ValueObject &in_value, lldb::DynamicValueType use_dynamic,
29293004
TypeAndOrName &class_type_or_name, Address &address,
@@ -2950,9 +3025,22 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
29503025
dyn_name.startswith("__NS"))
29513026
return false;
29523027

3028+
SwiftNominalType swift_class;
3029+
3030+
if (auto maybe_swift_class = GetSwiftClass(in_value, *objc_runtime)) {
3031+
swift_class = *maybe_swift_class;
3032+
std::string type_name =
3033+
(llvm::Twine(swift_class.module) + "." + swift_class.identifier).str();
3034+
dyn_class_type_or_name.SetName(type_name.data());
3035+
address.SetRawAddress(in_value.GetPointerValue());
3036+
} else {
3037+
swift_class.module = swift::MANGLING_MODULE_OBJC;
3038+
swift_class.identifier = dyn_name;
3039+
}
3040+
29533041
std::string remangled;
29543042
{
2955-
// Create a mangle tree for __C.dyn_name?.
3043+
// Create a mangle tree for Swift.Optional<$module.$class>
29563044
using namespace swift::Demangle;
29573045
NodeFactory factory;
29583046
NodePointer global = factory.createNode(Node::Kind::Global);
@@ -2963,7 +3051,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
29633051
NodePointer ety = factory.createNode(Node::Kind::Type);
29643052
bge->addChild(ety, factory);
29653053
NodePointer e = factory.createNode(Node::Kind::Enum);
2966-
e->addChild(factory.createNode(Node::Kind::Module, "Swift"), factory);
3054+
e->addChild(factory.createNode(Node::Kind::Module, swift::STDLIB_NAME),
3055+
factory);
29673056
e->addChild(factory.createNode(Node::Kind::Identifier, "Optional"),
29683057
factory);
29693058
ety->addChild(e, factory);
@@ -2972,10 +3061,11 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
29723061
NodePointer cty = factory.createNode(Node::Kind::Type);
29733062
list->addChild(cty, factory);
29743063
NodePointer c = factory.createNode(Node::Kind::Class);
3064+
c->addChild(factory.createNode(Node::Kind::Module, swift_class.module),
3065+
factory);
29753066
c->addChild(
2976-
factory.createNode(Node::Kind::Module, swift::MANGLING_MODULE_OBJC),
3067+
factory.createNode(Node::Kind::Identifier, swift_class.identifier),
29773068
factory);
2978-
c->addChild(factory.createNode(Node::Kind::Identifier, dyn_name), factory);
29793069
cty->addChild(c, factory);
29803070

29813071
auto mangling = mangleNode(global);

0 commit comments

Comments
 (0)