Skip to content

Commit 772e04d

Browse files
authored
Merge pull request apple#122 from jrose-apple/apinotes-less-than-or-equal
[APINotes] Honor Swift 4 API notes in Swift 3 mode.
2 parents af014b9 + 202145d commit 772e04d

File tree

6 files changed

+183
-28
lines changed

6 files changed

+183
-28
lines changed

lib/APINotes/APINotesReader.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,27 +1487,30 @@ APINotesReader::VersionedInfo<T>::VersionedInfo(
14871487
SmallVector<std::pair<VersionTuple, T>, 1> results)
14881488
: Results(std::move(results)) {
14891489

1490-
// Look for an exact version match.
1491-
Optional<unsigned> unversioned;
1492-
Selected = Results.size();
1490+
assert(!Results.empty());
1491+
assert(std::is_sorted(Results.begin(), Results.end(),
1492+
[](const std::pair<VersionTuple, T> &left,
1493+
const std::pair<VersionTuple, T> &right) -> bool {
1494+
assert(left.first != right.first && "two entries for the same version");
1495+
return left.first < right.first;
1496+
}));
14931497

1498+
Selected = Results.size();
14941499
for (unsigned i = 0, n = Results.size(); i != n; ++i) {
1495-
if (Results[i].first == version) {
1500+
if (version && Results[i].first >= version) {
1501+
// If the current version is "4", then entries for 4 are better than
1502+
// entries for 5, but both are valid. Because entries are sorted, we get
1503+
// that behavior by picking the first match.
14961504
Selected = i;
14971505
break;
14981506
}
1499-
1500-
if (!Results[i].first) {
1501-
assert(!unversioned && "Two unversioned entries?");
1502-
unversioned = i;
1503-
}
15041507
}
15051508

15061509
// If we didn't find a match but we have an unversioned result, use the
1507-
// unversioned result.
1508-
if (Selected == Results.size() && unversioned) {
1509-
Selected = *unversioned;
1510-
}
1510+
// unversioned result. This will always be the first entry because we encode
1511+
// it as version 0.
1512+
if (Selected == Results.size() && Results[0].first.empty())
1513+
Selected = 0;
15111514
}
15121515

15131516
auto APINotesReader::lookupObjCClassID(StringRef name) -> Optional<ContextID> {

lib/APINotes/APINotesWriter.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,10 +475,16 @@ namespace {
475475
template<typename T>
476476
void emitVersionedInfo(
477477
raw_ostream &out,
478-
const SmallVectorImpl<std::pair<VersionTuple, T>> &infoArray,
478+
SmallVectorImpl<std::pair<VersionTuple, T>> &infoArray,
479479
llvm::function_ref<void(raw_ostream &out,
480480
const typename MakeDependent<T>::Type& info)>
481481
emitInfo) {
482+
std::sort(infoArray.begin(), infoArray.end(),
483+
[](const std::pair<VersionTuple, T> &left,
484+
const std::pair<VersionTuple, T> &right) -> bool {
485+
assert(left.first != right.first && "two entries for the same version");
486+
return left.first < right.first;
487+
});
482488
endian::Writer<little> writer(out);
483489
writer.write<uint16_t>(infoArray.size());
484490
for (const auto &element : infoArray) {
@@ -528,7 +534,7 @@ namespace {
528534
using key_type_ref = key_type;
529535
using data_type =
530536
SmallVector<std::pair<VersionTuple, UnversionedDataType>, 1>;
531-
using data_type_ref = const data_type &;
537+
using data_type_ref = data_type &;
532538
using hash_value_type = size_t;
533539
using offset_type = unsigned;
534540

test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ Tags:
3636
EnumKind: NSClosedEnum
3737
- Name: UndoAllThatHasBeenDoneToMe
3838
EnumKind: none
39+
Typedefs:
40+
- Name: MultiVersionedTypedef34Notes
41+
SwiftName: MultiVersionedTypedef34Notes_NEW
42+
- Name: MultiVersionedTypedef345Notes
43+
SwiftName: MultiVersionedTypedef345Notes_NEW
44+
- Name: MultiVersionedTypedef4Notes
45+
SwiftName: MultiVersionedTypedef4Notes_NEW
46+
- Name: MultiVersionedTypedef45Notes
47+
SwiftName: MultiVersionedTypedef45Notes_NEW
3948
SwiftVersions:
4049
- Version: 3.0
4150
Classes:
@@ -87,6 +96,55 @@ SwiftVersions:
8796
Typedefs:
8897
- Name: MyDoubleWrapper
8998
SwiftWrapper: none
90-
91-
92-
99+
- Name: MultiVersionedTypedef34
100+
SwiftName: MultiVersionedTypedef34_3
101+
- Name: MultiVersionedTypedef34Header
102+
SwiftName: MultiVersionedTypedef34Header_3
103+
- Name: MultiVersionedTypedef34Notes
104+
SwiftName: MultiVersionedTypedef34Notes_3
105+
- Name: MultiVersionedTypedef345
106+
SwiftName: MultiVersionedTypedef345_3
107+
- Name: MultiVersionedTypedef345Header
108+
SwiftName: MultiVersionedTypedef345Header_3
109+
- Name: MultiVersionedTypedef345Notes
110+
SwiftName: MultiVersionedTypedef345Notes_3
111+
- Version: 5
112+
Typedefs:
113+
- Name: MultiVersionedTypedef345
114+
SwiftName: MultiVersionedTypedef345_5
115+
- Name: MultiVersionedTypedef345Header
116+
SwiftName: MultiVersionedTypedef345Header_5
117+
- Name: MultiVersionedTypedef345Notes
118+
SwiftName: MultiVersionedTypedef345Notes_5
119+
- Name: MultiVersionedTypedef45
120+
SwiftName: MultiVersionedTypedef45_5
121+
- Name: MultiVersionedTypedef45Header
122+
SwiftName: MultiVersionedTypedef45Header_5
123+
- Name: MultiVersionedTypedef45Notes
124+
SwiftName: MultiVersionedTypedef45Notes_5
125+
- Version: 4 # Versions are deliberately ordered as "3, 5, 4" to catch bugs.
126+
Typedefs:
127+
- Name: MultiVersionedTypedef34
128+
SwiftName: MultiVersionedTypedef34_4
129+
- Name: MultiVersionedTypedef34Header
130+
SwiftName: MultiVersionedTypedef34Header_4
131+
- Name: MultiVersionedTypedef34Notes
132+
SwiftName: MultiVersionedTypedef34Notes_4
133+
- Name: MultiVersionedTypedef345
134+
SwiftName: MultiVersionedTypedef345_4
135+
- Name: MultiVersionedTypedef345Header
136+
SwiftName: MultiVersionedTypedef345Header_4
137+
- Name: MultiVersionedTypedef345Notes
138+
SwiftName: MultiVersionedTypedef345Notes_4
139+
- Name: MultiVersionedTypedef4
140+
SwiftName: MultiVersionedTypedef4_4
141+
- Name: MultiVersionedTypedef4Header
142+
SwiftName: MultiVersionedTypedef4Header_4
143+
- Name: MultiVersionedTypedef4Notes
144+
SwiftName: MultiVersionedTypedef4Notes_4
145+
- Name: MultiVersionedTypedef45
146+
SwiftName: MultiVersionedTypedef45_4
147+
- Name: MultiVersionedTypedef45Header
148+
SwiftName: MultiVersionedTypedef45Header_4
149+
- Name: MultiVersionedTypedef45Notes
150+
SwiftName: MultiVersionedTypedef45Notes_4

test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(x:y:)
22

33
void acceptClosure(void (^ __attribute__((noescape)) block)(void));
44

5+
void privateFunc(void) __attribute__((swift_private));
6+
7+
typedef double MyDoubleWrapper __attribute__((swift_wrapper(struct)));
8+
9+
#if __OBJC__
510
@class NSString;
611

712
extern NSString *MyErrorDomain;
@@ -14,10 +19,6 @@ __attribute__((swift_bridge("MyValueType")))
1419
@interface MyReferenceType
1520
@end
1621

17-
void privateFunc(void) __attribute__((swift_private));
18-
19-
typedef double MyDoubleWrapper __attribute__((swift_wrapper(struct)));
20-
2122
@interface TestProperties
2223
@property (nonatomic, readwrite, retain) id accessorsOnly;
2324
@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClass;
@@ -42,6 +43,7 @@ typedef double MyDoubleWrapper __attribute__((swift_wrapper(struct)));
4243
__attribute__((swift_name("Swift4Name")))
4344
@interface Swift3RenamedAlsoDUMP
4445
@end
46+
#endif
4547

4648

4749
enum __attribute__((flag_enum)) FlagEnum {
@@ -110,3 +112,20 @@ enum SoonToBeNSClosedEnum {
110112
enum UndoAllThatHasBeenDoneToMe {
111113
UndoAllThatHasBeenDoneToMeA = 1
112114
} __attribute__((flag_enum)) __attribute__((enum_extensibility(closed)));
115+
116+
117+
typedef int MultiVersionedTypedef4;
118+
typedef int MultiVersionedTypedef4Notes;
119+
typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_NEW")));
120+
121+
typedef int MultiVersionedTypedef34;
122+
typedef int MultiVersionedTypedef34Notes;
123+
typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_NEW")));
124+
125+
typedef int MultiVersionedTypedef45;
126+
typedef int MultiVersionedTypedef45Notes;
127+
typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_NEW")));
128+
129+
typedef int MultiVersionedTypedef345;
130+
typedef int MultiVersionedTypedef345Notes;
131+
typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_NEW")));

test/APINotes/versioned-multi.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// RUN: rm -rf %t && mkdir -p %t
2+
3+
// Build and check the unversioned module file.
4+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Unversioned -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
5+
// RUN: %clang_cc1 -ast-print %t/ModulesCache/Unversioned/VersionedKit.pcm | FileCheck -check-prefix=CHECK-UNVERSIONED %s
6+
7+
// Build and check the various versions.
8+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned3 -fdisable-module-hash -fapinotes-modules -fapinotes-swift-version=3 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
9+
// RUN: %clang_cc1 -ast-print %t/ModulesCache/Versioned3/VersionedKit.pcm | FileCheck -check-prefix=CHECK-VERSIONED-3 %s
10+
11+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned4 -fdisable-module-hash -fapinotes-modules -fapinotes-swift-version=4 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
12+
// RUN: %clang_cc1 -ast-print %t/ModulesCache/Versioned4/VersionedKit.pcm | FileCheck -check-prefix=CHECK-VERSIONED-4 %s
13+
14+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned5 -fdisable-module-hash -fapinotes-modules -fapinotes-swift-version=5 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
15+
// RUN: %clang_cc1 -ast-print %t/ModulesCache/Versioned5/VersionedKit.pcm | FileCheck -check-prefix=CHECK-VERSIONED-5 %s
16+
17+
#import <VersionedKit/VersionedKit.h>
18+
19+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef4;
20+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef4Notes __attribute__((swift_name("MultiVersionedTypedef4Notes_NEW")));
21+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_NEW")));
22+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef34;
23+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef34Notes __attribute__((swift_name("MultiVersionedTypedef34Notes_NEW")));
24+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_NEW")));
25+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef45;
26+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef45Notes __attribute__((swift_name("MultiVersionedTypedef45Notes_NEW")));
27+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_NEW")));
28+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef345;
29+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef345Notes __attribute__((swift_name("MultiVersionedTypedef345Notes_NEW")));
30+
// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_NEW")));
31+
32+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef4 __attribute__((swift_name("MultiVersionedTypedef4_4")));
33+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef4Notes __attribute__((swift_name("MultiVersionedTypedef4Notes_4")));
34+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_4")));
35+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef34 __attribute__((swift_name("MultiVersionedTypedef34_3")));
36+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef34Notes __attribute__((swift_name("MultiVersionedTypedef34Notes_3")));
37+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_3")));
38+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef45 __attribute__((swift_name("MultiVersionedTypedef45_4")));
39+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef45Notes __attribute__((swift_name("MultiVersionedTypedef45Notes_4")));
40+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_4")));
41+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef345 __attribute__((swift_name("MultiVersionedTypedef345_3")));
42+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef345Notes __attribute__((swift_name("MultiVersionedTypedef345Notes_3")));
43+
// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_3")));
44+
45+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef4 __attribute__((swift_name("MultiVersionedTypedef4_4")));
46+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef4Notes __attribute__((swift_name("MultiVersionedTypedef4Notes_4")));
47+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_4")));
48+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef34 __attribute__((swift_name("MultiVersionedTypedef34_4")));
49+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef34Notes __attribute__((swift_name("MultiVersionedTypedef34Notes_4")));
50+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_4")));
51+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef45 __attribute__((swift_name("MultiVersionedTypedef45_4")));
52+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef45Notes __attribute__((swift_name("MultiVersionedTypedef45Notes_4")));
53+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_4")));
54+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef345 __attribute__((swift_name("MultiVersionedTypedef345_4")));
55+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef345Notes __attribute__((swift_name("MultiVersionedTypedef345Notes_4")));
56+
// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_4")));
57+
58+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef4;
59+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef4Notes __attribute__((swift_name("MultiVersionedTypedef4Notes_NEW")));
60+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_NEW")));
61+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef34;
62+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef34Notes __attribute__((swift_name("MultiVersionedTypedef34Notes_NEW")));
63+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_NEW")));
64+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef45 __attribute__((swift_name("MultiVersionedTypedef45_5")));
65+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef45Notes __attribute__((swift_name("MultiVersionedTypedef45Notes_5")));
66+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_5")));
67+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef345 __attribute__((swift_name("MultiVersionedTypedef345_5")));
68+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef345Notes __attribute__((swift_name("MultiVersionedTypedef345Notes_5")));
69+
// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_5")));

test/APINotes/versioned.m

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,20 @@
5353
// CHECK-UNVERSIONED: void acceptClosure(void (^block)(void) __attribute__((noescape)));
5454
// CHECK-VERSIONED: void acceptClosure(void (^block)(void));
5555

56+
// CHECK-UNVERSIONED: void privateFunc() __attribute__((swift_private));
57+
58+
// CHECK-UNVERSIONED: typedef double MyDoubleWrapper __attribute__((swift_wrapper("struct")));
59+
5660
// CHECK-UNVERSIONED: enum MyErrorCode {
5761
// CHECK-UNVERSIONED-NEXT: MyErrorCodeFailed = 1
5862
// CHECK-UNVERSIONED-NEXT: } __attribute__((ns_error_domain(MyErrorDomain)));
5963

6064
// CHECK-UNVERSIONED: __attribute__((swift_bridge("MyValueType")))
6165
// CHECK-UNVERSIONED: @interface MyReferenceType
6266

63-
// CHECK-UNVERSIONED: void privateFunc() __attribute__((swift_private));
67+
// CHECK-VERSIONED: void privateFunc();
6468

65-
// CHECK-UNVERSIONED: typedef double MyDoubleWrapper __attribute__((swift_wrapper("struct")));
69+
// CHECK-VERSIONED: typedef double MyDoubleWrapper;
6670

6771
// CHECK-VERSIONED: enum MyErrorCode {
6872
// CHECK-VERSIONED-NEXT: MyErrorCodeFailed = 1
@@ -71,10 +75,6 @@
7175
// CHECK-VERSIONED-NOT: __attribute__((swift_bridge("MyValueType")))
7276
// CHECK-VERSIONED: @interface MyReferenceType
7377

74-
// CHECK-VERSIONED: void privateFunc();
75-
76-
// CHECK-VERSIONED: typedef double MyDoubleWrapper;
77-
7878
// CHECK-UNVERSIONED: __attribute__((swift_objc_members)
7979
// CHECK-UNVERSIONED-NEXT: @interface TestProperties
8080
// CHECK-VERSIONED-NOT: __attribute__((swift_objc_members)

0 commit comments

Comments
 (0)