Skip to content

Commit 2c365f1

Browse files
Merge pull request #8592 from adrian-prantl/125182583
Precise compiler invocations: Set C++ interoperability per SymbolContext
2 parents 092327f + 90e1467 commit 2c365f1

File tree

7 files changed

+109
-2
lines changed

7 files changed

+109
-2
lines changed

lldb/source/Core/Module.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,9 @@ bool Module::IsSwiftCxxInteropEnabled() {
11881188
auto *sym_file = GetSymbolFile();
11891189
if (sym_file) {
11901190
auto options = sym_file->GetCompileOptions();
1191-
for (auto &[_, args] : options) {
1191+
for (auto &[cu, args] : options) {
1192+
if (cu->GetLanguage() != eLanguageTypeSwift)
1193+
continue;
11921194
for (const char *arg : args.GetArgumentArrayRef()) {
11931195
if (strcmp(arg, "-enable-experimental-cxx-interop") == 0) {
11941196
m_is_swift_cxx_interop_enabled = eLazyBoolYes;

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2199,6 +2199,41 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
21992199
return swift_ast_sp;
22002200
}
22012201

2202+
/// Determine whether this CU was compiled with C++ interop enabled.
2203+
static bool ShouldEnableCXXInterop(CompileUnit *cu) {
2204+
AutoBool interop_enabled =
2205+
ModuleList::GetGlobalModuleListProperties().GetSwiftEnableCxxInterop();
2206+
switch (interop_enabled) {
2207+
case AutoBool::True:
2208+
return true;
2209+
case AutoBool::False:
2210+
return false;
2211+
case AutoBool::Auto: {
2212+
if (!cu)
2213+
return false;
2214+
lldb::ModuleSP module = cu->CalculateSymbolContextModule();
2215+
if (!module)
2216+
return false;
2217+
// Look for the "-enable-experimental-cxx-interop" compile flag in the
2218+
// args of the compile units this module is composed of.
2219+
auto *sym_file = module->GetSymbolFile();
2220+
if (!sym_file)
2221+
return false;
2222+
auto options = sym_file->GetCompileOptions();
2223+
for (auto &[unit, args] : options) {
2224+
if (unit.get() == cu) {
2225+
if (cu->GetLanguage() == eLanguageTypeSwift)
2226+
for (const char *arg : args.GetArgumentArrayRef())
2227+
if (strcmp(arg, "-enable-experimental-cxx-interop") == 0)
2228+
return true;
2229+
return false;
2230+
}
2231+
}
2232+
}
2233+
}
2234+
return false;
2235+
}
2236+
22022237
static bool IsUnitTestExecutable(lldb_private::Module &module) {
22032238
static ConstString s_xctest("xctest");
22042239
static ConstString s_XCTRunner("XCTRunner");
@@ -2755,7 +2790,7 @@ lldb::TypeSystemSP SwiftASTContext::CreateInstance(
27552790
swift_ast_sp->m_is_scratch_context = true;
27562791

27572792
swift_ast_sp->GetLanguageOptions().EnableCXXInterop =
2758-
target.IsSwiftCxxInteropEnabled();
2793+
ShouldEnableCXXInterop(cu);
27592794

27602795
if (target.IsEmbeddedSwift())
27612796
swift_ast_sp->GetLanguageOptions().enableFeature(swift::Feature::Embedded);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public func f() {
2+
print("break here")
3+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFT_CXX_INTEROP := 1
3+
SWIFTFLAGS_EXTRAS = -I.
4+
LD_EXTRAS = -L$(BUILDDIR) -lDylib
5+
6+
all: libDylib.dylib a.out
7+
8+
include Makefile.rules
9+
10+
libDylib.dylib: Dylib.swift
11+
$(MAKE) MAKE_DSYM=$(MAKE_DSYM) CC=$(CC) SWIFTC=$(SWIFTC) \
12+
ARCH=$(ARCH) DSYMUTIL=$(DSYMUTIL) \
13+
VPATH=$(SRCDIR) -I $(SRCDIR) \
14+
-f $(THIS_FILE_DIR)/Makefile.rules \
15+
DYLIB_SWIFT_SOURCES=Dylib.swift \
16+
DYLIB_NAME=Dylib \
17+
DYLIB_ONLY=YES \
18+
SWIFT_SOURCES= \
19+
SWIFT_CXX_INTEROP=0 \
20+
SWIFT_BRIDGING_HEADER= \
21+
all
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
"""
3+
Test that a C++ class is visible in Swift.
4+
"""
5+
from lldbsuite.test.lldbtest import *
6+
from lldbsuite.test.decorators import *
7+
8+
9+
class TestSwiftForwardInteropCxxLangOpt(TestBase):
10+
11+
@swiftTest
12+
@expectedFailureAll(setting=('symbols.swift-precise-compiler-invocation', 'false'))
13+
def test_class(self):
14+
"""
15+
Test that C++ interoperability is enabled on a per-CU basis.
16+
"""
17+
self.build()
18+
log = self.getBuildArtifact("types.log")
19+
self.runCmd('log enable lldb types -f "%s"' % log)
20+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
21+
self, 'break here', lldb.SBFileSpec('main.swift'),
22+
extra_images=['Dylib'])
23+
dylib_bkpt = target.BreakpointCreateBySourceRegex(
24+
'break here', lldb.SBFileSpec('Dylib.swift'))
25+
self.assertGreater(dylib_bkpt.GetNumLocations(), 0, VALID_BREAKPOINT)
26+
self.expect('expr 0')
27+
lldbutil.continue_to_breakpoint(process, dylib_bkpt)
28+
self.expect('expr 1')
29+
self.filecheck('platform shell cat ""%s"' % log, __file__)
30+
# CHECK: SwiftASTContextForExpressions(module: "a", cu: "main.swift")::LogConfiguration(){{.*}}Swift/C++ interop : on
31+
# CHECK: SwiftASTContextForExpressions(module: "Dylib", cu: "Dylib.swift")::LogConfiguration(){{.*}}Swift/C++ interop : off
32+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
struct CxxClass {
3+
long long a1 = 10;
4+
long long a2 = 20;
5+
long long a3 = 30;
6+
};
7+
8+
struct InheritedCxxClass: CxxClass {
9+
long long a4 = 40;
10+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import Dylib
2+
3+
print("break here")
4+
f()

0 commit comments

Comments
 (0)