forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request swiftlang#31813 from gribozavr/add-tests
Added tests for edge cases in importing and mangling C structs
- Loading branch information
Showing
4 changed files
with
290 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
module StructDeclContext { | ||
header "struct-decl-context.h" | ||
export * | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#ifndef TEST_INTEROP_C_STRUCT_INPUTS_STRUCT_DECL_CONTEXT_H | ||
#define TEST_INTEROP_C_STRUCT_INPUTS_STRUCT_DECL_CONTEXT_H | ||
|
||
// This header contains C structs that are declared and nested in various ways. | ||
// Some of these patterns are special-cased by ClangImporter (for example, the | ||
// names of typedefs become names of imported structs). Nested structs have been | ||
// historically imported in Swift according to C rules, that is, structs | ||
// lexically declared nested in other structs are imported into the global | ||
// namespace anyway. | ||
|
||
struct StructRegular { | ||
struct StructNestedComplete1 { | ||
struct StructNestedNestedComplete1 {} complete_immediately_nested; | ||
struct StructNestedNestedCompletedLater1 *completed_later_nested; | ||
} complete_immediately; | ||
struct StructNestedCompletedLater1 *completed_later; | ||
}; | ||
|
||
struct StructNestedNestedCompletedLater1 {}; | ||
struct StructNestedCompletedLater1 {}; | ||
|
||
typedef struct StructTypedefTag2 { | ||
struct StructNestedComplete2 {} complete_immediately; | ||
struct StructNestedCompletedLater2 *completed_later; | ||
} StructTypedefName2; | ||
|
||
struct StructNestedCompletedLater2 {}; | ||
|
||
typedef struct { | ||
struct StructNestedComplete3 {} complete_immediately; | ||
struct StructNestedCompletedLater3 *completed_later; | ||
} StructTypedefName3; | ||
|
||
struct StructNestedCompletedLater3 {}; | ||
|
||
typedef struct StructTypedefTag4 { | ||
struct StructNestedComplete4 {} complete_immediately; | ||
struct StructNestedCompletedLater4 *completed_later; | ||
} *StructTypedefName4; | ||
|
||
struct StructNestedCompletedLater4 {}; | ||
|
||
typedef struct { | ||
struct StructNestedComplete5 {} complete_immediately; | ||
struct StructNestedCompletedLater5 *completed_later; | ||
} *StructTypedefName5; | ||
|
||
struct StructNestedCompletedLater5 {}; | ||
|
||
typedef struct { | ||
struct StructNestedComplete6 {} complete_immediately; | ||
struct StructNestedCompletedLater6 *completed_later; | ||
} StructTypedefName6, *StructTypedefName6Ptr; | ||
|
||
struct StructNestedCompletedLater6 {}; | ||
|
||
typedef struct { | ||
struct StructNestedComplete7 {} complete_immediately; | ||
struct StructNestedCompletedLater7 *completed_later; | ||
} *StructTypedefName7Ptr, StructTypedefName7; | ||
|
||
struct StructNestedCompletedLater7 {}; | ||
|
||
typedef struct { | ||
struct StructNestedComplete8 {} complete_immediately; | ||
struct StructNestedCompletedLater8 *completed_later; | ||
} StructTypedefName8, *StructTypedefName8Ptr, **StructTypedefName8PtrPtr; | ||
|
||
struct StructNestedCompletedLater8 {}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// RUN: %target-swift-emit-ir -I %S/Inputs %s | %FileCheck %s | ||
|
||
// This test checks that structs that are imported from a C module are mangled | ||
// in Swift names as if they are declared in the global namespace, even when | ||
// they are lexically declared nested in other C structs. | ||
|
||
import StructDeclContext | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo13StructRegularVF"({{.*}}) | ||
public func take(_ x: StructRegular) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo21StructNestedComplete1VF"({{.*}}) | ||
public func take(_: StructNestedComplete1) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo012StructNestedD9Complete1VF"({{.*}}) | ||
public func take(_: StructNestedNestedComplete1) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo012StructNestedD15CompletedLater1VF"({{.*}}) | ||
public func take(_: StructNestedNestedCompletedLater1) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo27StructNestedCompletedLater1VF"({{.*}}) | ||
public func take(_: StructNestedCompletedLater1) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo17StructTypedefTag2VF"({{.*}}) | ||
public func take(_: StructTypedefTag2) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo21StructNestedComplete2VF"({{.*}}) | ||
public func take(_: StructNestedComplete2) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main5take2yySo17StructTypedefTag2VF"({{.*}}) | ||
public func take2(_: StructTypedefName2) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo27StructNestedCompletedLater2VF"({{.*}}) | ||
public func take(_: StructNestedCompletedLater2) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo18StructTypedefName3aF"({{.*}}) | ||
public func take(_: StructTypedefName3) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo21StructNestedComplete3VF"({{.*}}) | ||
public func take(_: StructNestedComplete3) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo27StructNestedCompletedLater3VF"({{.*}}) | ||
public func take(_: StructNestedCompletedLater3) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo17StructTypedefTag4VF"({{.*}}) | ||
public func take(_: StructTypedefTag4) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo21StructNestedComplete4VF"({{.*}}) | ||
public func take(_: StructNestedComplete4) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySpySo17StructTypedefTag4VGF"(i8* %0) | ||
public func take(_: StructTypedefName4) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo27StructNestedCompletedLater4VF"({{.*}}) | ||
public func take(_: StructNestedCompletedLater4) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo21StructNestedComplete5VF"({{.*}}) | ||
public func take(_: StructNestedComplete5) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyys13OpaquePointerVF"(i8* %0) | ||
public func take(_: StructTypedefName5) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo27StructNestedCompletedLater5VF"({{.*}}) | ||
public func take(_: StructNestedCompletedLater5) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo18StructTypedefName6aF"({{.*}}) | ||
public func take(_: StructTypedefName6) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo21StructNestedComplete6VF"({{.*}}) | ||
public func take(_: StructNestedComplete6) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySpySo18StructTypedefName6aGF"(i8* %0) | ||
public func take(_: StructTypedefName6Ptr) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo27StructNestedCompletedLater6VF"({{.*}}) | ||
public func take(_: StructNestedCompletedLater6) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo18StructTypedefName7aF"({{.*}}) | ||
public func take(_: StructTypedefName7) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo21StructNestedComplete7VF"({{.*}}) | ||
public func take(_: StructNestedComplete7) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySpySo18StructTypedefName7aGF"(i8* %0) | ||
public func take(_: StructTypedefName7Ptr) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo27StructNestedCompletedLater7VF"({{.*}}) | ||
public func take(_: StructNestedCompletedLater7) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo18StructTypedefName8aF"({{.*}}) | ||
public func take(_: StructTypedefName8) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo21StructNestedComplete8VF"({{.*}}) | ||
public func take(_: StructNestedComplete8) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySpySo18StructTypedefName8aGF"(i8* %0) | ||
public func take(_: StructTypedefName8Ptr) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySpySpySo18StructTypedefName8aGSgGF"(i8* %0) | ||
public func take(_: StructTypedefName8PtrPtr) {} | ||
|
||
// CHECK-LABEL: define {{.*}} void @"$s4main4takeyySo27StructNestedCompletedLater8VF"({{.*}}) | ||
public func take(_: StructNestedCompletedLater8) {} |
112 changes: 112 additions & 0 deletions
112
test/Interop/C/struct/struct-decl-context-module-interface.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// RUN: %target-swift-ide-test -print-module -module-to-print=StructDeclContext -I %S/Inputs -source-filename=x | %FileCheck %s | ||
|
||
// This test checks that structs that are imported from a C module are imported | ||
// into the top-level scope in Swift, even when they are lexically declared | ||
// nested in other C structs. | ||
|
||
// CHECK: struct StructRegular { | ||
// CHECK-NEXT: var complete_immediately: StructNestedComplete1 | ||
// CHECK-NEXT: var completed_later: UnsafeMutablePointer<StructNestedCompletedLater1>! | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: init(complete_immediately: StructNestedComplete1, completed_later: UnsafeMutablePointer<StructNestedCompletedLater1>!) | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedComplete1 { | ||
// CHECK-NEXT: var complete_immediately_nested: StructNestedNestedComplete1 | ||
// CHECK-NEXT: var completed_later_nested: UnsafeMutablePointer<StructNestedNestedCompletedLater1>! | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: init(complete_immediately_nested: StructNestedNestedComplete1, completed_later_nested: UnsafeMutablePointer<StructNestedNestedCompletedLater1>!) | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedNestedComplete1 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedNestedCompletedLater1 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedCompletedLater1 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructTypedefTag2 { | ||
// CHECK-NEXT: var complete_immediately: StructNestedComplete2 | ||
// CHECK-NEXT: var completed_later: UnsafeMutablePointer<StructNestedCompletedLater2>! | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: init(complete_immediately: StructNestedComplete2, completed_later: UnsafeMutablePointer<StructNestedCompletedLater2>!) | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedComplete2 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: typealias StructTypedefName2 = StructTypedefTag2 | ||
// CHECK-NEXT: struct StructNestedCompletedLater2 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructTypedefName3 { | ||
// CHECK-NEXT: var complete_immediately: StructNestedComplete3 | ||
// CHECK-NEXT: var completed_later: UnsafeMutablePointer<StructNestedCompletedLater3>! | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: init(complete_immediately: StructNestedComplete3, completed_later: UnsafeMutablePointer<StructNestedCompletedLater3>!) | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedComplete3 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedCompletedLater3 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructTypedefTag4 { | ||
// CHECK-NEXT: var complete_immediately: StructNestedComplete4 | ||
// CHECK-NEXT: var completed_later: UnsafeMutablePointer<StructNestedCompletedLater4>! | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: init(complete_immediately: StructNestedComplete4, completed_later: UnsafeMutablePointer<StructNestedCompletedLater4>!) | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedComplete4 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: typealias StructTypedefName4 = UnsafeMutablePointer<StructTypedefTag4> | ||
// CHECK-NEXT: struct StructNestedCompletedLater4 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedComplete5 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: typealias StructTypedefName5 = OpaquePointer | ||
// CHECK-NEXT: struct StructNestedCompletedLater5 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructTypedefName6 { | ||
// CHECK-NEXT: var complete_immediately: StructNestedComplete6 | ||
// CHECK-NEXT: var completed_later: UnsafeMutablePointer<StructNestedCompletedLater6>! | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: init(complete_immediately: StructNestedComplete6, completed_later: UnsafeMutablePointer<StructNestedCompletedLater6>!) | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedComplete6 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: typealias StructTypedefName6Ptr = UnsafeMutablePointer<StructTypedefName6> | ||
// CHECK-NEXT: struct StructNestedCompletedLater6 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructTypedefName7 { | ||
// CHECK-NEXT: var complete_immediately: StructNestedComplete7 | ||
// CHECK-NEXT: var completed_later: UnsafeMutablePointer<StructNestedCompletedLater7>! | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: init(complete_immediately: StructNestedComplete7, completed_later: UnsafeMutablePointer<StructNestedCompletedLater7>!) | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedComplete7 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: typealias StructTypedefName7Ptr = UnsafeMutablePointer<StructTypedefName7> | ||
// CHECK-NEXT: struct StructNestedCompletedLater7 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructTypedefName8 { | ||
// CHECK-NEXT: var complete_immediately: StructNestedComplete8 | ||
// CHECK-NEXT: var completed_later: UnsafeMutablePointer<StructNestedCompletedLater8>! | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: init(complete_immediately: StructNestedComplete8, completed_later: UnsafeMutablePointer<StructNestedCompletedLater8>!) | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: struct StructNestedComplete8 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } | ||
// CHECK-NEXT: typealias StructTypedefName8Ptr = UnsafeMutablePointer<StructTypedefName8> | ||
// CHECK-NEXT: typealias StructTypedefName8PtrPtr = UnsafeMutablePointer<UnsafeMutablePointer<StructTypedefName8>?> | ||
// CHECK-NEXT: struct StructNestedCompletedLater8 { | ||
// CHECK-NEXT: init() | ||
// CHECK-NEXT: } |