Skip to content

Commit

Permalink
Merge pull request swiftlang#31813 from gribozavr/add-tests
Browse files Browse the repository at this point in the history
Added tests for edge cases in importing and mangling C structs
  • Loading branch information
gribozavr authored May 15, 2020
2 parents 82728d3 + 61d4793 commit e85b658
Show file tree
Hide file tree
Showing 4 changed files with 290 additions and 0 deletions.
4 changes: 4 additions & 0 deletions test/Interop/C/struct/Inputs/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module StructDeclContext {
header "struct-decl-context.h"
export *
}
71 changes: 71 additions & 0 deletions test/Interop/C/struct/Inputs/struct-decl-context.h
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
103 changes: 103 additions & 0 deletions test/Interop/C/struct/struct-decl-context-irgen.swift
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 test/Interop/C/struct/struct-decl-context-module-interface.swift
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: }

0 comments on commit e85b658

Please sign in to comment.