Skip to content

Commit f296aff

Browse files
authored
Merge pull request #6509 from augusto2112/autodetect-cxx-interop
[lldb] Enable auto-detection of Swift/C++ interop
2 parents d41f263 + c113ef8 commit f296aff

30 files changed

+204
-50
lines changed

lldb/include/lldb/Core/Module.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,8 @@ class Module : public std::enable_shared_from_this<Module>,
849849
void
850850
ReportWarningToolchainMismatch(CompileUnit &comp_unit,
851851
llvm::Optional<lldb::user_id_t> debugger_id);
852+
853+
bool IsSwiftCxxInteropEnabled();
852854
#endif
853855

854856
// Return true if the file backing this module has changed since the module
@@ -1174,6 +1176,10 @@ class Module : public std::enable_shared_from_this<Module>,
11741176

11751177
Module(const Module &) = delete;
11761178
const Module &operator=(const Module &) = delete;
1179+
1180+
#ifdef LLDB_ENABLE_SWIFT
1181+
LazyBool m_is_swift_cxx_interop_enabled = eLazyBoolCalculate;
1182+
#endif
11771183
};
11781184

11791185
} // namespace lldb_private

lldb/include/lldb/Symbol/SymbolFile.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <mutex>
3232
#include <vector>
33+
#include <unordered_map>
3334

3435
#if defined(LLDB_CONFIGURATION_DEBUG)
3536
#define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock())
@@ -471,9 +472,20 @@ class SymbolFile : public PluginInterface {
471472

472473
virtual lldb::TypeSP CopyType(const lldb::TypeSP &other_type) = 0;
473474

475+
/// Returns a map of compilation unit to the compile option arguments
476+
/// associated with that compilation unit.
477+
std::unordered_map<lldb::CompUnitSP, Args> GetCompileOptions() {
478+
std::unordered_map<lldb::CompUnitSP, Args> args;
479+
GetCompileOptions(args);
480+
return args;
481+
}
482+
474483
protected:
475484
void AssertModuleLock();
476485

486+
virtual void GetCompileOptions(
487+
std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {}
488+
477489
private:
478490
SymbolFile(const SymbolFile &) = delete;
479491
const SymbolFile &operator=(const SymbolFile &) = delete;

lldb/include/lldb/Target/Target.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class TargetProperties : public Properties {
182182

183183
bool GetSwiftEnableBareSlashRegex() const;
184184

185-
bool GetSwiftEnableCxxInterop() const;
185+
EnableSwiftCxxInterop GetEnableSwiftCxxInterop() const;
186186

187187
bool GetSwiftAutoImportFrameworks() const;
188188

@@ -1260,6 +1260,7 @@ class Target : public std::enable_shared_from_this<Target>,
12601260
/// Return whether this is the Swift REPL.
12611261
bool IsSwiftREPL();
12621262

1263+
bool IsSwiftCxxInteropEnabled();
12631264
private:
12641265
void DisplayFallbackSwiftContextErrors(
12651266
SwiftASTContextForExpressions *swift_ast_ctx);
@@ -1736,6 +1737,11 @@ class Target : public std::enable_shared_from_this<Target>,
17361737

17371738
Target(const Target &) = delete;
17381739
const Target &operator=(const Target &) = delete;
1740+
1741+
#ifdef LLDB_ENABLE_SWIFT
1742+
LazyBool m_is_swift_cxx_interop_enabled = eLazyBoolCalculate;
1743+
#endif // LLDB_ENABLE_SWIFT
1744+
17391745
};
17401746

17411747
} // namespace lldb_private

lldb/include/lldb/lldb-private-enumerations.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,14 @@ typedef enum SwiftModuleLoadingMode {
170170
eSwiftModuleLoadingModeOnlyInterface, // Load via .swiftinterface only
171171
} SwiftModuleLoadingMode;
172172

173+
// BEGIN SWIFT
174+
enum EnableSwiftCxxInterop {
175+
eAutoDetectSwiftCxxInterop,
176+
eEnableSwiftCxxInterop,
177+
eDisableSwiftCxxInterop
178+
};
179+
// END SWIFT
180+
173181
// Loading modules from memory
174182
enum MemoryModuleLoadLevel {
175183
eMemoryModuleLoadLevelMinimal, // Load sections only

lldb/source/Core/Module.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,6 +1202,48 @@ void Module::ReportWarningToolchainMismatch(
12021202
}
12031203
}
12041204
}
1205+
1206+
bool Module::IsSwiftCxxInteropEnabled() {
1207+
switch (m_is_swift_cxx_interop_enabled) {
1208+
case eLazyBoolYes:
1209+
return true;
1210+
case eLazyBoolNo:
1211+
return false;
1212+
case eLazyBoolCalculate:
1213+
break;
1214+
}
1215+
EnableSwiftCxxInterop interop_enabled =
1216+
Target::GetGlobalProperties().GetEnableSwiftCxxInterop();
1217+
switch (interop_enabled) {
1218+
case eEnableSwiftCxxInterop:
1219+
m_is_swift_cxx_interop_enabled = eLazyBoolYes;
1220+
break;
1221+
case eDisableSwiftCxxInterop:
1222+
m_is_swift_cxx_interop_enabled = eLazyBoolNo;
1223+
break;
1224+
case eAutoDetectSwiftCxxInterop: {
1225+
// Look for the "-enable-experimental-cxx-interop" compile flag in the args
1226+
// of the compile units this module is composed of.
1227+
auto *sym_file = GetSymbolFile();
1228+
if (sym_file) {
1229+
auto options = sym_file->GetCompileOptions();
1230+
for (auto &[_, args] : options) {
1231+
for (const char *arg : args.GetArgumentArrayRef()) {
1232+
if (strcmp(arg, "-enable-experimental-cxx-interop") == 0) {
1233+
m_is_swift_cxx_interop_enabled = eLazyBoolYes;
1234+
break;
1235+
}
1236+
}
1237+
if (m_is_swift_cxx_interop_enabled == eLazyBoolYes)
1238+
break;
1239+
}
1240+
}
1241+
if (m_is_swift_cxx_interop_enabled == eLazyBoolCalculate)
1242+
m_is_swift_cxx_interop_enabled = eLazyBoolNo;
1243+
}
1244+
}
1245+
return m_is_swift_cxx_interop_enabled == eLazyBoolYes;
1246+
}
12051247
#endif
12061248

12071249
void Module::ReportErrorIfModifyDetected(const char *format, ...) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,7 @@ SwiftLanguage::GetHardcodedSynthetics() {
10901090

10911091
Log *log(GetLog(LLDBLog::DataFormatters));
10921092

1093-
if (!valobj.GetTargetSP()->GetSwiftEnableCxxInterop())
1093+
if (!valobj.GetTargetSP()->IsSwiftCxxInteropEnabled())
10941094
return nullptr;
10951095

10961096
CompilerType type(valobj.GetCompilerType());

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4282,3 +4282,30 @@ Status SymbolFileDWARF::CalculateFrameVariableError(StackFrame &frame) {
42824282
return Status("no variable information is available in debug info for this "
42834283
"compile unit");
42844284
}
4285+
4286+
void SymbolFileDWARF::GetCompileOptions(
4287+
std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {
4288+
4289+
const uint32_t num_compile_units = GetNumCompileUnits();
4290+
4291+
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
4292+
lldb::CompUnitSP comp_unit = GetCompileUnitAtIndex(cu_idx);
4293+
if (!comp_unit)
4294+
continue;
4295+
4296+
DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit.get());
4297+
if (!dwarf_cu)
4298+
continue;
4299+
4300+
const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly();
4301+
if (!die)
4302+
continue;
4303+
4304+
const char *flags = die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL);
4305+
4306+
if (!flags)
4307+
continue;
4308+
args.insert({comp_unit, Args(flags)});
4309+
}
4310+
}
4311+

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,9 @@ class SymbolFileDWARF : public lldb_private::SymbolFileCommon,
545545

546546
void InitializeFirstCodeAddress();
547547

548+
void GetCompileOptions(
549+
std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) override;
550+
548551
lldb::ModuleWP m_debug_map_module_wp;
549552
SymbolFileDWARFDebugMap *m_debug_map_symfile;
550553

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,3 +1642,12 @@ Status SymbolFileDWARFDebugMap::CalculateFrameVariableError(StackFrame &frame) {
16421642
}
16431643
return Status();
16441644
}
1645+
1646+
void SymbolFileDWARFDebugMap::GetCompileOptions(
1647+
std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) {
1648+
1649+
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
1650+
oso_dwarf->GetCompileOptions(args);
1651+
return false;
1652+
});
1653+
}

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ class SymbolFileDWARFDebugMap : public lldb_private::SymbolFileCommon {
160160
// Statistics overrides.
161161
lldb_private::ModuleList GetDebugInfoModules() override;
162162

163+
void GetCompileOptions(
164+
std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) override;
165+
163166
protected:
164167
enum { kHaveInitializedOSOs = (1 << 0), kNumFlags };
165168

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,7 +1564,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
15641564
swift_ast_sp->m_module = &module;
15651565
swift_ast_sp->GetLanguageOptions().EnableAccessControl = false;
15661566
swift_ast_sp->GetLanguageOptions().EnableCXXInterop =
1567-
Target::GetGlobalProperties().GetSwiftEnableCxxInterop();
1567+
module.IsSwiftCxxInteropEnabled();
1568+
15681569
bool found_swift_modules = false;
15691570
SymbolFile *sym_file = module.GetSymbolFile();
15701571

@@ -1950,7 +1951,7 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
19501951
swift_ast_sp->m_is_scratch_context = true;
19511952

19521953
swift_ast_sp->GetLanguageOptions().EnableCXXInterop =
1953-
target.GetSwiftEnableCxxInterop();
1954+
target.IsSwiftCxxInteropEnabled();
19541955
bool handled_sdk_path = false;
19551956
const size_t num_images = target.GetImages().GetSize();
19561957

@@ -4825,6 +4826,8 @@ void SwiftASTContext::LogConfiguration() {
48254826
for (std::string &extra_arg : clang_importer_options.ExtraArgs) {
48264827
HEALTH_LOG_PRINTF(" %s", extra_arg.c_str());
48274828
}
4829+
HEALTH_LOG_PRINTF(" Swift/C++ interop mode: %s",
4830+
m_ast_context_ap->LangOpts.EnableCXXInterop ? "on" : "off");
48284831
}
48294832

48304833
bool SwiftASTContext::HasTarget() {

lldb/source/Target/Target.cpp

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,6 +2860,37 @@ bool Target::IsSwiftREPL() {
28602860
GetProcessLaunchInfo().GetArg0().endswith("repl_swift");
28612861
}
28622862

2863+
bool Target::IsSwiftCxxInteropEnabled() {
2864+
switch (m_is_swift_cxx_interop_enabled) {
2865+
case eLazyBoolYes:
2866+
return true;
2867+
case eLazyBoolNo:
2868+
return false;
2869+
case eLazyBoolCalculate:
2870+
break;
2871+
}
2872+
2873+
EnableSwiftCxxInterop interop_enabled = GetEnableSwiftCxxInterop();
2874+
switch (interop_enabled) {
2875+
case eEnableSwiftCxxInterop:
2876+
m_is_swift_cxx_interop_enabled = eLazyBoolYes;
2877+
break;
2878+
case eDisableSwiftCxxInterop:
2879+
m_is_swift_cxx_interop_enabled = eLazyBoolNo;
2880+
break;
2881+
case eAutoDetectSwiftCxxInterop: {
2882+
if (GetImages().IsEmpty())
2883+
m_is_swift_cxx_interop_enabled = eLazyBoolNo;
2884+
else
2885+
m_is_swift_cxx_interop_enabled =
2886+
GetImages().GetModuleAtIndex(0)->IsSwiftCxxInteropEnabled()
2887+
? eLazyBoolYes
2888+
: eLazyBoolNo;
2889+
}
2890+
}
2891+
return m_is_swift_cxx_interop_enabled == eLazyBoolYes;
2892+
}
2893+
28632894
#endif // LLDB_ENABLE_SWIFT
28642895

28652896
void Target::SettingsInitialize() { Process::SettingsInitialize(); }
@@ -4385,6 +4416,13 @@ static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = {
43854416
},
43864417
};
43874418

4419+
static constexpr OptionEnumValueElement g_enable_swift_cxx_interop_values[] = {
4420+
{eAutoDetectSwiftCxxInterop, "auto",
4421+
"Automatically detect if C++ interop mode should be enabled."},
4422+
{eEnableSwiftCxxInterop, "true", "Enable C++ interop."},
4423+
{eDisableSwiftCxxInterop, "false", "Disable C++ interop."},
4424+
};
4425+
43884426
#define LLDB_PROPERTIES_target
43894427
#include "TargetProperties.inc"
43904428

@@ -4605,16 +4643,14 @@ bool TargetProperties::GetSwiftEnableBareSlashRegex() const {
46054643
return true;
46064644
}
46074645

4608-
bool TargetProperties::GetSwiftEnableCxxInterop() const {
4609-
const Property *exp_property = m_collection_sp->GetPropertyAtIndex(
4610-
nullptr, false, ePropertyExperimental);
4611-
OptionValueProperties *exp_values =
4612-
exp_property->GetValue()->GetAsProperties();
4613-
if (exp_values)
4614-
return exp_values->GetPropertyAtIndexAsBoolean(
4615-
nullptr, ePropertySwiftEnableCxxInterop, false);
4646+
EnableSwiftCxxInterop TargetProperties::GetEnableSwiftCxxInterop() const {
4647+
const uint32_t idx = ePropertySwiftEnableCxxInterop;
46164648

4617-
return false;
4649+
EnableSwiftCxxInterop enable_interop =
4650+
(EnableSwiftCxxInterop)m_experimental_properties_up->GetValueProperties()
4651+
->GetPropertyAtIndexAsEnumeration(
4652+
nullptr, idx, g_target_properties[idx].default_uint_value);
4653+
return enable_interop;
46184654
}
46194655

46204656
bool TargetProperties::GetSwiftAutoImportFrameworks() const {

lldb/source/Target/TargetProperties.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ let Definition = "target_experimental" in {
1919
def SwiftEnableBareSlashRegex: Property<"swift-enable-bare-slash-regex", "Boolean">,
2020
DefaultFalse,
2121
Desc<"Passes the -enable-bare-slash-regex compiler flag to the swift compiler.">;
22-
def SwiftEnableCxxInterop: Property<"swift-enable-cxx-interop", "Boolean">,
23-
DefaultFalse,
22+
def SwiftEnableCxxInterop: Property<"swift-enable-cxx-interop", "Enum">,
23+
DefaultEnumValue<"eAutoDetectSwiftCxxInterop">,
24+
EnumValues<"OptionEnumValues(g_enable_swift_cxx_interop_values)">,
2425
Desc<"Passes the -enable-cxx-interop flag to the swift compiler.">;
2526
}
2627

lldb/test/API/lang/swift/cxx_interop/backward/format-actors/TestSwiftBackwardInteropFormatActors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class TestSwiftBackwardInteropFormatActors(TestBase):
1111
@swiftTest
1212
def test_class(self):
1313
self.build()
14-
self.runCmd('setting set target.experimental.swift-enable-cxx-interop true')
14+
1515
_, _, _, _= lldbutil.run_to_source_breakpoint(
1616
self, 'Set breakpoint here', lldb.SBFileSpec('main.cpp'))
1717

lldb/test/API/lang/swift/cxx_interop/backward/format-swift-stdlib-types/TestSwiftBackwardInteropFormatSwiftStdlibTypes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class TestSwiftBackwardInteropFormatSwiftStdlibTypes(TestBase):
1010
def setup(self, bkpt_str):
1111
self.build()
12-
self.runCmd('setting set target.experimental.swift-enable-cxx-interop true')
12+
1313
_, _, _, _= lldbutil.run_to_source_breakpoint(
1414
self, bkpt_str, lldb.SBFileSpec('main.cpp'))
1515

lldb/test/API/lang/swift/cxx_interop/backward/format-swift-types-in-cxx/TestSwiftBackwardInteropFormatSwiftTypesInCxx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class TestSwiftBackwardInteropFormatSwiftTypesInCxx(TestBase):
1010

1111
def setup(self, bkpt_str):
1212
self.build()
13-
self.runCmd('setting set target.experimental.swift-enable-cxx-interop true')
13+
1414
_, _, _, _= lldbutil.run_to_source_breakpoint(
1515
self, bkpt_str, lldb.SBFileSpec('main.cpp'))
1616

lldb/test/API/lang/swift/cxx_interop/backward/stepping/TestSwiftBackwardInteropStepping.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class TestSwiftBackwardInteropStepping(TestBase):
1010

1111
def setup(self, bkpt_str):
1212
self.build()
13-
self.runCmd('setting set target.experimental.swift-enable-cxx-interop true')
13+
1414
_, _, thread, _ = lldbutil.run_to_source_breakpoint(
1515
self, bkpt_str, lldb.SBFileSpec('main.cpp'))
1616
return thread

lldb/test/API/lang/swift/cxx_interop/forward/class-in-namespace/TestSwiftForwardInteropClassInNamespace.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ class TestSwiftForwardInteropClassInNamespace(TestBase):
1212
@swiftTest
1313
def test_class(self):
1414
self.build()
15-
self.runCmd('settings set target.experimental.swift-enable-cxx-interop true')
1615
_, _, _, _= lldbutil.run_to_source_breakpoint(
1716
self, 'Set breakpoint here', lldb.SBFileSpec('main.swift'))
1817

lldb/test/API/lang/swift/cxx_interop/forward/cxx-class-as-existential/TestSwiftForwardInteropCxxClassAsExistential.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class TestSwiftForwardInteropCxxClassAsExistential(TestBase):
1111
@swiftTest
1212
def test(self):
1313
self.build()
14-
self.runCmd('setting set target.experimental.swift-enable-cxx-interop true')
14+
1515
_, _, _, _= lldbutil.run_to_source_breakpoint(
1616
self, 'Set breakpoint here', lldb.SBFileSpec('main.swift'))
1717

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ class TestSwiftForwardInteropCxxClass(TestBase):
1111
@swiftTest
1212
def test_class(self):
1313
self.build()
14-
self.runCmd('setting set target.experimental.swift-enable-cxx-interop true')
1514
_, _, _, _= lldbutil.run_to_source_breakpoint(
1615
self, 'Set breakpoint here', lldb.SBFileSpec('main.swift'))
1716

0 commit comments

Comments
 (0)