Skip to content

Commit 11017a3

Browse files
authored
Merge pull request #6448 from augusto2112/test-swift-stdlib-in-cxx
[lldb] Support primitive C++ types as Swift type parameters
2 parents ce735b3 + 54fecf3 commit 11017a3

File tree

11 files changed

+186
-5
lines changed

11 files changed

+186
-5
lines changed

lldb/packages/Python/lldbsuite/test/make/Makefile.rules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ $(SWIFT_CXX_HEADER): $(SWIFT_SOURCES) $(SWIFT_BRIDGING_PCH)
730730
@echo "### Building C++ header from Swift" $<
731731
$(SWIFT_FE) -typecheck $(VPATHSOURCES) \
732732
$(SWIFT_FEFLAGS) $(SWIFT_HFLAGS) -module-name $(MODULENAME) \
733-
-clang-header-expose-decls=all-public -emit-clang-header-path $(SWIFT_CXX_HEADER)
733+
-emit-clang-header-path $(SWIFT_CXX_HEADER)
734734
endif
735735

736736
else # USESWIFTDRIVER = 0

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,6 @@ ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
747747
// static inline constexpr $sClassMangledNameHere __swift_mangled_name = 0;
748748
// }
749749

750-
751750
Log *log(GetLog(LLDBLog::DataFormatters));
752751
// This only makes sense for Clang types.
753752
auto tsc = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
@@ -803,15 +802,22 @@ ExtractSwiftTypeFromCxxInteropType(CompilerType type, TypeSystemSwift &ts,
803802
return {};
804803

805804
auto templated_type = type.GetTypeTemplateArgument(index);
806-
return ExtractSwiftTypeFromCxxInteropType(templated_type, ts,
807-
runtime);
805+
auto substituted_type =
806+
ExtractSwiftTypeFromCxxInteropType(templated_type, ts, runtime);
807+
808+
// The generic type might also not be a user defined type which
809+
// ExtractSwiftTypeFromCxxInteropType can find, but which is still
810+
// convertible to Swift (for example, int -> Int32). Attempt to
811+
// convert it to a Swift type.
812+
if (!substituted_type)
813+
substituted_type = ts.ConvertClangTypeToSwiftType(templated_type);
814+
return substituted_type;
808815
});
809816
return bound_type;
810817
}
811818
return {};
812819
}
813820

814-
815821
/// Synthetic child that wraps a value object.
816822
class ValueObjectWrapperSyntheticChildren : public SyntheticChildren {
817823
class ValueObjectWrapperFrontEndProvider : public SyntheticChildrenFrontEnd {

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7656,6 +7656,27 @@ CompilerType SwiftASTContext::GetBuiltinRawPointerType() {
76567656
return GetTypeFromMangledTypename(ConstString("$sBpD"));
76577657
}
76587658

7659+
CompilerType
7660+
SwiftASTContext::ConvertClangTypeToSwiftType(CompilerType clang_type) {
7661+
auto typeref_type =
7662+
GetTypeSystemSwiftTypeRef().ConvertClangTypeToSwiftType(clang_type);
7663+
7664+
if (!typeref_type)
7665+
return {};
7666+
7667+
Status error;
7668+
auto *ast_type = ReconstructType(typeref_type.GetMangledTypeName(), error);
7669+
if (error.Fail()) {
7670+
LLDB_LOGF(GetLog(LLDBLog::Types),
7671+
"[SwiftASTContext::ConvertClangTypeToSwiftType] Could not "
7672+
"reconstruct type. Error: %s",
7673+
error.AsCString());
7674+
return {};
7675+
}
7676+
7677+
return {this->weak_from_this(), ast_type};
7678+
}
7679+
76597680
bool SwiftASTContext::TypeHasArchetype(CompilerType type) {
76607681
auto swift_type = GetSwiftType(type);
76617682
if (swift_type)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,10 @@ class SwiftASTContext : public TypeSystemSwift {
364364

365365
CompilerType GetBuiltinRawPointerType() override;
366366

367+
/// Attempts to convert a Clang type into a Swift type.
368+
/// For example, int is converted to Int32.
369+
CompilerType ConvertClangTypeToSwiftType(CompilerType clang_type) override;
370+
367371
bool TypeHasArchetype(CompilerType type);
368372

369373
/// Use \p ClangImporter to swiftify the decl's name.

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwift.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ class TypeSystemSwift : public TypeSystem {
176176

177177
virtual CompilerType GetBuiltinRawPointerType() = 0;
178178

179+
/// Attempts to convert a Clang type into a Swift type.
180+
/// For example, int is converted to Int32.
181+
virtual CompilerType ConvertClangTypeToSwiftType(CompilerType clang_type) = 0;
182+
179183
void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
180184
Stream *s, lldb::Format format, const DataExtractor &data,
181185
lldb::offset_t data_offset, size_t data_byte_size,

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2860,6 +2860,19 @@ TypeSystemSwiftTypeRef::GetClangTypeTypeNode(swift::Demangle::Demangler &dem,
28602860
return type;
28612861
}
28622862

2863+
CompilerType
2864+
TypeSystemSwiftTypeRef::ConvertClangTypeToSwiftType(CompilerType clang_type) {
2865+
assert(clang_type.GetTypeSystem().isa_and_nonnull<TypeSystemClang>() &&
2866+
"Unexpected type system!");
2867+
2868+
if (!clang_type.GetTypeSystem().isa_and_nonnull<TypeSystemClang>())
2869+
return {};
2870+
2871+
swift::Demangle::Demangler dem;
2872+
swift::Demangle::NodePointer node = GetClangTypeTypeNode(dem, clang_type);
2873+
return RemangleAsType(dem, node);
2874+
}
2875+
28632876
CompilerType TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
28642877
opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
28652878
bool transparent_pointers, bool omit_empty_base_classes,

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
349349
lldb::TypeSP LookupClangType(llvm::StringRef name_ref,
350350
llvm::ArrayRef<CompilerContext> decl_context);
351351

352+
/// Attempts to convert a Clang type into a Swift type.
353+
/// For example, int is converted to Int32.
354+
CompilerType ConvertClangTypeToSwiftType(CompilerType clang_type) override;
355+
352356
protected:
353357
/// Helper that creates an AST type from \p type.
354358
void *ReconstructType(lldb::opaque_compiler_type_t type);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
SWIFT_CXX_HEADER := swift-types.h
2+
SWIFT_SOURCES := swift-types.swift
3+
CXX_SOURCES := main.cpp
4+
SWIFT_CXX_INTEROP := 1
5+
SWIFTFLAGS_EXTRAS = -Xcc -I$(SRCDIR) -parse-as-library
6+
CFLAGS = -I. -g
7+
include Makefile.rules
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
"""
3+
Test that Swift types are displayed correctly in C++
4+
"""
5+
from lldbsuite.test.lldbtest import *
6+
from lldbsuite.test.decorators import *
7+
8+
9+
class TestFormatSwiftStdlibTypes(TestBase):
10+
def setup(self, bkpt_str):
11+
self.build()
12+
self.runCmd('setting set target.experimental.swift-enable-cxx-interop true')
13+
_, _, _, _= lldbutil.run_to_source_breakpoint(
14+
self, bkpt_str, lldb.SBFileSpec('main.cpp'))
15+
16+
17+
@swiftTest
18+
def test_array(self):
19+
self.setup('break here for array')
20+
self.expect('v array', substrs=['Swift.Array<a.SwiftClass>',
21+
'[0]', 'str = "Hello from the Swift class!"',
22+
'[1]', 'str = "Hello from the Swift class!"',])
23+
24+
@swiftTest
25+
def test_array_of_ints(self):
26+
self.setup('break here for array of ints')
27+
28+
self.expect('v array', substrs=['Swift.Array<Swift.Int32>', '1', '2', '3', '4'])
29+
30+
@swiftTest
31+
def test_optional(self):
32+
self.setup('break here for optional')
33+
34+
self.expect('v optional', substrs=['Swift.Optional<a.SwiftClass>',
35+
'str = "Hello from the Swift class!"'])
36+
37+
@swiftTest
38+
def test_optional_primitive(self):
39+
self.setup('break here for optional primitive')
40+
41+
self.expect('v optional', substrs=['Swift.Optional<Swift.Double>',
42+
'4.2'])
43+
44+
@swiftTest
45+
def test_string(self):
46+
self.setup('break here for string')
47+
48+
self.expect('v string', substrs=['"Hello from Swift!"'])
49+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "swift-types.h"
2+
3+
4+
using namespace swift;
5+
using namespace a;
6+
7+
int testArray() {
8+
auto array = createArray();
9+
return 0; // break here for array
10+
}
11+
12+
int testArrayOfInts() {
13+
auto array = createArrayOfInts();
14+
return 0; // break here for array of ints
15+
}
16+
17+
18+
int testOptional() {
19+
auto optional = createOptional();
20+
return 0; // break here for optional
21+
}
22+
23+
int testOptionalPrimitive() {
24+
auto optional = createOptionalPrimitive();
25+
return 0; // break here for optional primitive
26+
}
27+
28+
int testString() {
29+
auto string = createString();
30+
return 0; // break here for string
31+
}
32+
33+
int main() {
34+
testArray();
35+
testArrayOfInts();
36+
testOptional();
37+
testOptionalPrimitive();
38+
testString();
39+
}

0 commit comments

Comments
 (0)