Skip to content

Commit b55f833

Browse files
committed
[lldb] When Swift/C++ is enabled, let Clang imported types format as Clang types.
Instead of attempting to format Clang types as Swift types, let existing engine to format Clang types do the job. rdar://100285267
1 parent 6b44bcc commit b55f833

File tree

7 files changed

+120
-92
lines changed

7 files changed

+120
-92
lines changed

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

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,59 @@ ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
811811
return {};
812812
}
813813

814+
815+
/// Synthetic child that wraps a value object.
816+
class ValueObjectWrapperSyntheticChildren : public SyntheticChildren {
817+
class ValueObjectWrapperFrontEndProvider : public SyntheticChildrenFrontEnd {
818+
public:
819+
ValueObjectWrapperFrontEndProvider(ValueObject &backend)
820+
: SyntheticChildrenFrontEnd(backend) {}
821+
822+
size_t CalculateNumChildren() override {
823+
return 1;
824+
}
825+
826+
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
827+
return idx == 0 ? m_backend.GetSP() : nullptr;
828+
}
829+
830+
size_t GetIndexOfChildWithName(ConstString name) override {
831+
return m_backend.GetName() == name ? 0 : UINT32_MAX;
832+
}
833+
834+
bool Update() override { return false; }
835+
836+
bool MightHaveChildren() override { return true; }
837+
838+
ConstString GetSyntheticTypeName() override {
839+
return m_backend.GetCompilerType().GetTypeName();
840+
}
841+
};
842+
843+
public:
844+
ValueObjectWrapperSyntheticChildren(ValueObjectSP valobj, const Flags &flags)
845+
: SyntheticChildren(flags), m_valobj(valobj) {}
846+
847+
SyntheticChildrenFrontEnd::AutoPointer
848+
GetFrontEnd(ValueObject &backend) override {
849+
if (!m_valobj)
850+
return nullptr;
851+
// We ignore the backend parameter here, as we have a more specific one
852+
// available.
853+
return std::make_unique<ValueObjectWrapperFrontEndProvider>(*m_valobj);
854+
}
855+
856+
bool IsScripted() override { return false; }
857+
858+
std::string GetDescription() override {
859+
return "C++ bridged synthetic children";
860+
}
861+
862+
private:
863+
ValueObjectSP m_valobj;
864+
};
865+
866+
814867
HardcodedFormatters::HardcodedSyntheticFinder
815868
SwiftLanguage::GetHardcodedSynthetics() {
816869
static std::once_flag g_initialize;
@@ -1007,11 +1060,68 @@ SwiftLanguage::GetHardcodedSynthetics() {
10071060
swift_type = type_or_name.GetCompilerType();
10081061
// Cast it to the more specific type.
10091062
casted_to_swift = casted_to_swift->Cast(swift_type);
1063+
if (!casted_to_swift) {
1064+
LLDB_LOGF(log,
1065+
"[Matching CxxBridgedSyntheticChildProvider] - "
1066+
"Could not cast value object to dynamic swift type.");
1067+
return nullptr;
1068+
}
10101069
}
10111070
}
10121071

1013-
return swift_runtime->GetCxxBridgedSyntheticChildProvider(
1014-
casted_to_swift);
1072+
casted_to_swift->SetName(ConstString("Swift_Type"));
1073+
1074+
SyntheticChildrenSP synth_sp =
1075+
SyntheticChildrenSP(new ValueObjectWrapperSyntheticChildren(
1076+
casted_to_swift, SyntheticChildren::Flags()));
1077+
return synth_sp;
1078+
});
1079+
g_formatters.push_back([](lldb_private::ValueObject &valobj,
1080+
lldb::DynamicValueType,
1081+
FormatManager &) -> lldb::SyntheticChildrenSP {
1082+
// If C++ interop is enabled, format imported clang types as clang types,
1083+
// instead of attempting to disguise them as Swift types.
1084+
1085+
Log *log(GetLog(LLDBLog::DataFormatters));
1086+
1087+
if (!valobj.GetTargetSP()->GetSwiftEnableCxxInterop())
1088+
return nullptr;
1089+
1090+
CompilerType type(valobj.GetCompilerType());
1091+
auto swift_type_system =
1092+
type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
1093+
if (!swift_type_system)
1094+
return nullptr;
1095+
1096+
CompilerType original_type;
1097+
if (!swift_type_system->IsImportedType(type.GetOpaqueQualType(),
1098+
&original_type))
1099+
return nullptr;
1100+
1101+
if (!original_type.GetTypeSystem().isa_and_nonnull<TypeSystemClang>())
1102+
return nullptr;
1103+
1104+
auto qual_type =
1105+
TypeSystemClang::GetQualType(original_type.GetOpaqueQualType());
1106+
auto *decl = qual_type->getAsCXXRecordDecl();
1107+
if (!decl) {
1108+
LLDB_LOGV(log, "[Matching Clang imported type] - "
1109+
"Could not get decl from clang type");
1110+
return nullptr;
1111+
}
1112+
auto casted = valobj.Cast(original_type);
1113+
if (!casted) {
1114+
LLDB_LOGV(log, "[Matching Clang imported type] - "
1115+
"Could not cast value object to clang type");
1116+
return nullptr;
1117+
}
1118+
1119+
casted->SetName(ConstString("Clang_Type"));
1120+
1121+
SyntheticChildrenSP synth_sp =
1122+
SyntheticChildrenSP(new ValueObjectWrapperSyntheticChildren(
1123+
casted, SyntheticChildren::Flags()));
1124+
return synth_sp;
10151125
});
10161126
});
10171127

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

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -387,12 +387,6 @@ class SwiftLanguageRuntimeStub {
387387
return {};
388388
}
389389

390-
lldb::SyntheticChildrenSP
391-
GetCxxBridgedSyntheticChildProvider(ValueObjectSP valobj) {
392-
STUB_LOG();
393-
return {};
394-
}
395-
396390
void WillStartExecutingUserExpression(bool runs_in_playground_or_repl) {
397391
if (!runs_in_playground_or_repl)
398392
STUB_LOG();
@@ -1849,77 +1843,6 @@ lldb::ValueObjectSP SwiftLanguageRuntime::ExtractSwiftValueObjectFromCxxWrapper(
18491843
}
18501844
return swift_valobj;
18511845
}
1852-
/// Synthetic child for Swift types wrapped in C++ interop wrapper classes.
1853-
class CxxBridgedSyntheticChildren : public SyntheticChildren {
1854-
class CxxBridgedFrontEndProvider : public SyntheticChildrenFrontEnd {
1855-
public:
1856-
CxxBridgedFrontEndProvider(ValueObject &backend)
1857-
: SyntheticChildrenFrontEnd(backend) {}
1858-
1859-
size_t CalculateNumChildren() override {
1860-
return 1;
1861-
}
1862-
1863-
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
1864-
return idx == 0 ? m_backend.GetSP() : nullptr;
1865-
}
1866-
1867-
size_t GetIndexOfChildWithName(ConstString name) override {
1868-
return m_backend.GetName() == name ? 0 : UINT32_MAX;
1869-
}
1870-
1871-
bool Update() override { return false; }
1872-
1873-
bool MightHaveChildren() override { return true; }
1874-
1875-
ConstString GetSyntheticTypeName() override {
1876-
return m_backend.GetCompilerType().GetTypeName();
1877-
}
1878-
};
1879-
1880-
public:
1881-
CxxBridgedSyntheticChildren(ValueObjectSP valobj, const Flags &flags)
1882-
: SyntheticChildren(flags), m_valobj(valobj) {}
1883-
1884-
SyntheticChildrenFrontEnd::AutoPointer
1885-
GetFrontEnd(ValueObject &backend) override {
1886-
if (!m_valobj)
1887-
return nullptr;
1888-
// We ignore the backend parameter here, as we have a more specific one
1889-
// available.
1890-
return std::make_unique<CxxBridgedFrontEndProvider>(*m_valobj);
1891-
}
1892-
1893-
bool IsScripted() override { return false; }
1894-
1895-
std::string GetDescription() override {
1896-
return "C++ bridged synthetic children";
1897-
}
1898-
1899-
private:
1900-
ValueObjectSP m_valobj;
1901-
};
1902-
1903-
lldb::SyntheticChildrenSP
1904-
SwiftLanguageRuntimeImpl::GetCxxBridgedSyntheticChildProvider(
1905-
ValueObjectSP valobj) {
1906-
auto swift_type = valobj->GetCompilerType();
1907-
if (!swift_type)
1908-
return nullptr;
1909-
ConstString type_name = swift_type.GetDisplayTypeName();
1910-
1911-
if (!type_name.IsEmpty()) {
1912-
auto iter = m_bridged_synthetics_map.find(type_name.AsCString()),
1913-
end = m_bridged_synthetics_map.end();
1914-
if (iter != end)
1915-
return iter->second;
1916-
}
1917-
1918-
SyntheticChildrenSP synth_sp = SyntheticChildrenSP(
1919-
new CxxBridgedSyntheticChildren(valobj, SyntheticChildren::Flags()));
1920-
m_bridged_synthetics_map.insert({type_name.AsCString(), synth_sp});
1921-
return synth_sp;
1922-
}
19231846

19241847
void SwiftLanguageRuntimeImpl::WillStartExecutingUserExpression(
19251848
bool runs_in_playground_or_repl) {
@@ -2548,12 +2471,6 @@ SwiftLanguageRuntime::GetBridgedSyntheticChildProvider(ValueObject &valobj) {
25482471
FORWARD(GetBridgedSyntheticChildProvider, valobj);
25492472
}
25502473

2551-
lldb::SyntheticChildrenSP
2552-
SwiftLanguageRuntime::GetCxxBridgedSyntheticChildProvider(
2553-
ValueObjectSP valobj) {
2554-
FORWARD(GetCxxBridgedSyntheticChildProvider, valobj);
2555-
}
2556-
25572474
void SwiftLanguageRuntime::WillStartExecutingUserExpression(
25582475
bool runs_in_playground_or_repl) {
25592476
FORWARD(WillStartExecutingUserExpression, runs_in_playground_or_repl);

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,9 +413,6 @@ class SwiftLanguageRuntime : public LanguageRuntime {
413413
lldb::SyntheticChildrenSP
414414
GetBridgedSyntheticChildProvider(ValueObject &valobj);
415415

416-
/// Get the synthethic child provider that displays Swift in C++ frames.
417-
lldb::SyntheticChildrenSP
418-
GetCxxBridgedSyntheticChildProvider(lldb::ValueObjectSP valobj);
419416

420417
/// Expression Callbacks.
421418
/// \{

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,6 @@ class SwiftLanguageRuntimeImpl {
183183
lldb::SyntheticChildrenSP
184184
GetBridgedSyntheticChildProvider(ValueObject &valobj);
185185

186-
/// Get the synthethic child provider that displays Swift in C++ frames.
187-
lldb::SyntheticChildrenSP
188-
GetCxxBridgedSyntheticChildProvider(lldb::ValueObjectSP valobj);
189-
190186
bool IsABIStable();
191187

192188
void DumpTyperef(CompilerType type, TypeSystemSwiftTypeRef *module_holder,

lldb/test/API/lang/swift/cxx_interop/forward/test-cxx-class/TestCxxClass.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ def test_class(self):
1717

1818
self.expect('v x', substrs=['CxxClass', 'a1', '10', 'a2', '20', 'a3', '30'])
1919
self.expect('po x', substrs=['CxxClass', 'a1', '10', 'a2', '20', 'a3', '30'])
20+
21+
self.expect('v y', substrs=['InheritedCxxClass', 'a1', '10', 'a2', '20', 'a3', '30', 'a4', '40'])
22+
# FIXME: rdar://106216567
23+
self.expect('po y', substrs=['InheritedCxxClass', 'a4', '40'])

lldb/test/API/lang/swift/cxx_interop/forward/test-cxx-class/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import ReturnsClass
22

33
func main() {
44
let x = CxxClass()
5+
let y = InheritedCxxClass()
56
print(x) // Set breakpoint here
67
}
78
main()

lldb/test/API/lang/swift/cxx_interop/forward/test-cxx-class/returns-class.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ struct CxxClass {
55
long long a3 = 30;
66
};
77

8+
struct InheritedCxxClass: CxxClass {
9+
long long a4 = 40;
10+
};

0 commit comments

Comments
 (0)