Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1746,7 +1746,8 @@ def SwiftVersioned : Attr {
// This attribute has no spellings as it is only ever created implicitly
// from API notes.
let Spellings = [];
let Args = [VersionArgument<"Version">, AttrArgument<"AttrToAdd">];
let Args = [VersionArgument<"Version">, AttrArgument<"AttrToAdd">,
BoolArgument<"IsReplacedByActive">];
let SemaHandler = 0;
let Documentation = [Undocumented];
}
Expand All @@ -1755,7 +1756,8 @@ def SwiftVersionedRemoval : Attr {
// This attribute has no spellings as it is only ever created implicitly
// from API notes.
let Spellings = [];
let Args = [VersionArgument<"Version">, UnsignedArgument<"RawKind">];
let Args = [VersionArgument<"Version">, UnsignedArgument<"RawKind">,
BoolArgument<"IsReplacedByActive">];
let SemaHandler = 0;
let Documentation = [Undocumented];
let AdditionalMembers = [{
Expand Down
42 changes: 27 additions & 15 deletions lib/Sema/SemaAPINotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,21 @@ namespace {
IsNotActive,
IsActive
};
enum IsReplacement_t : bool {
IsNotReplacement,
IsReplacement
};

struct VersionedInfoMetadata {
/// An empty version refers to unversioned metadata.
VersionTuple Version;
bool IsActive;
unsigned IsActive: 1;
unsigned IsReplacement: 1;

VersionedInfoMetadata(VersionTuple version, IsActive_t active)
: Version(version), IsActive(active == IsActive_t::IsActive) {}
VersionedInfoMetadata(VersionTuple version, IsActive_t active,
IsReplacement_t replacement)
: Version(version), IsActive(active == IsActive_t::IsActive),
IsReplacement(replacement == IsReplacement_t::IsReplacement) {}
};
} // end anonymous namespace

Expand Down Expand Up @@ -148,9 +155,8 @@ namespace {
if (existing != end) {
// Remove the existing attribute, and treat it as a superseded
// non-versioned attribute.
auto *versioned =
SwiftVersionedAttr::CreateImplicit(S.Context, clang::VersionTuple(),
*existing);
auto *versioned = SwiftVersionedAttr::CreateImplicit(
S.Context, metadata.Version, *existing, /*IsReplacedByActive*/true);

D->getAttrs().erase(existing.getCurrent());
D->addAttr(versioned);
Expand All @@ -166,19 +172,18 @@ namespace {
} else {
if (shouldAddAttribute) {
if (auto attr = createAttr()) {
auto *versioned =
SwiftVersionedAttr::CreateImplicit(S.Context, metadata.Version,
attr);
auto *versioned = SwiftVersionedAttr::CreateImplicit(
S.Context, metadata.Version, attr,
/*IsReplacedByActive*/metadata.IsReplacement);
D->addAttr(versioned);
}
} else {
// FIXME: This isn't preserving enough information for things like
// availability, where we're trying to remove a /specific/ kind of
// attribute.
auto *versioned =
SwiftVersionedRemovalAttr::CreateImplicit(S.Context,
metadata.Version,
AttrKindFor<A>::value);
auto *versioned = SwiftVersionedRemovalAttr::CreateImplicit(
S.Context, metadata.Version, AttrKindFor<A>::value,
/*IsReplacedByActive*/metadata.IsReplacement);
D->addAttr(versioned);
}
}
Expand Down Expand Up @@ -684,7 +689,8 @@ static void maybeAttachUnversionedSwiftName(
}

// Then explicitly call that out with a removal attribute.
VersionedInfoMetadata DummyFutureMetadata(VersionTuple(), IsNotActive);
VersionedInfoMetadata DummyFutureMetadata(SelectedVersion, IsNotActive,
IsReplacement);
handleAPINotedAttribute<SwiftNameAttr>(S, D, /*add*/false,
DummyFutureMetadata,
[]() -> SwiftNameAttr * {
Expand All @@ -709,7 +715,13 @@ static void ProcessVersionedAPINotes(
for (unsigned i = 0, e = Info.size(); i != e; ++i) {
std::tie(Version, InfoSlice) = Info[i];
auto Active = (i == Selected) ? IsActive : IsNotActive;
ProcessAPINotes(S, D, InfoSlice, VersionedInfoMetadata(Version, Active));
auto Replacement = IsNotReplacement;
if (Active == IsNotActive && Version.empty()) {
Replacement = IsReplacement;
Version = Info[Selected].first;
}
ProcessAPINotes(S, D, InfoSlice, VersionedInfoMetadata(Version, Active,
Replacement));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Classes:
- Name: accessorsOnlyForClassExceptInVersion3
PropertyKind: Class
SwiftImportAsAccessors: true
Functions:
- Name: unversionedRenameDUMP
SwiftName: 'unversionedRename_NOTES()'
Tags:
- Name: APINotedFlagEnum
FlagEnum: true
Expand Down Expand Up @@ -123,6 +126,9 @@ SwiftVersions:
- Name: MultiVersionedTypedef45Notes
SwiftName: MultiVersionedTypedef45Notes_5
- Version: 4 # Versions are deliberately ordered as "3, 5, 4" to catch bugs.
Classes:
- Name: Swift4RenamedDUMP
SwiftName: SpecialSwift4Name
Typedefs:
- Name: MultiVersionedTypedef34
SwiftName: MultiVersionedTypedef34_4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(x:y:)")));

void unversionedRenameDUMP(void) __attribute__((swift_name("unversionedRename_HEADER()")));

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

void privateFunc(void) __attribute__((swift_private));
Expand Down Expand Up @@ -43,6 +45,10 @@ __attribute__((swift_bridge("MyValueType")))
__attribute__((swift_name("Swift4Name")))
@interface Swift3RenamedAlsoDUMP
@end

@interface Swift4RenamedDUMP
@end

#endif


Expand Down
8 changes: 4 additions & 4 deletions test/APINotes/properties.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyInVersion3 'id'
// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
// CHECK-4-NEXT: SwiftVersionedAttr {{.+}} 3.0
// CHECK-4-NEXT: SwiftVersionedAttr {{.+}} 3.0{{$}}
// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
// CHECK-NOT: Attr

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClassInVersion3 'id'
// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
// CHECK-4-NEXT: SwiftVersionedAttr {{.+}} 3.0
// CHECK-4-NEXT: SwiftVersionedAttr {{.+}} 3.0{{$}}
// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
// CHECK-NOT: Attr

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyExceptInVersion3 'id'
// CHECK-3-NEXT: SwiftVersionedAttr {{.+}} 0{{$}}
// CHECK-3-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
// CHECK-4-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 3.0 {{[0-9]+}}
// CHECK-NOT: Attr

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClassExceptInVersion3 'id'
// CHECK-3-NEXT: SwiftVersionedAttr {{.+}} 0{{$}}
// CHECK-3-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
// CHECK-4-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 3.0 {{[0-9]+}}
Expand Down
29 changes: 22 additions & 7 deletions test/APINotes/versioned.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,53 @@
// CHECK-VERSIONED: void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(a:b:)")));

// CHECK-DUMP-LABEL: Dumping moveToPointDUMP
// CHECK-VERSIONED-DUMP: SwiftVersionedAttr {{.+}} Implicit 0
// CHECK-VERSIONED-DUMP: SwiftVersionedAttr {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} "moveTo(x:y:)"
// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "moveTo(a:b:)"
// CHECK-UNVERSIONED-DUMP: SwiftNameAttr {{.+}} "moveTo(x:y:)"
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0{{$}}
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "moveTo(a:b:)"
// CHECK-DUMP-NOT: Attr

// CHECK-DUMP-LABEL: Dumping unversionedRenameDUMP
// CHECK-DUMP: in VersionedKit unversionedRenameDUMP
// CHECK-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 0 IsReplacedByActive{{$}}
// CHECK-DUMP-NEXT: SwiftNameAttr {{.+}} "unversionedRename_HEADER()"
// CHECK-DUMP-NEXT: SwiftNameAttr {{.+}} "unversionedRename_NOTES()"
// CHECK-DUMP-NOT: Attr

// CHECK-DUMP-LABEL: Dumping TestGenericDUMP
// CHECK-VERSIONED-DUMP: SwiftImportAsNonGenericAttr {{.+}} Implicit
// CHECK-UNVERSIONED-DUMP: SwiftVersionedAttr {{.+}} Implicit 3.0
// CHECK-UNVERSIONED-DUMP: SwiftVersionedAttr {{.+}} Implicit 3.0{{$}}
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftImportAsNonGenericAttr {{.+}} Implicit
// CHECK-DUMP-NOT: Attr

// CHECK-DUMP-LABEL: Dumping Swift3RenamedOnlyDUMP
// CHECK-DUMP: in VersionedKit Swift3RenamedOnlyDUMP
// CHECK-VERSIONED-DUMP-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 0 {{[0-9]+}}
// CHECK-VERSIONED-DUMP-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 3.0 {{[0-9]+}} IsReplacedByActive{{$}}
// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} "SpecialSwift3Name"
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0{{$}}
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "SpecialSwift3Name"
// CHECK-DUMP-NOT: Attr

// CHECK-DUMP-LABEL: Dumping Swift3RenamedAlsoDUMP
// CHECK-DUMP: in VersionedKit Swift3RenamedAlsoDUMP
// CHECK-VERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 0
// CHECK-VERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} <line:{{.+}}, col:{{.+}}> "Swift4Name"
// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} "SpecialSwift3Also"
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} <line:{{.+}}, col:{{.+}}> "Swift4Name"
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0{{$}}
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "SpecialSwift3Also"
// CHECK-DUMP-NOT: Attr

// CHECK-DUMP-LABEL: Dumping Swift4RenamedDUMP
// CHECK-DUMP: in VersionedKit Swift4RenamedDUMP
// CHECK-VERSIONED-DUMP-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 4 {{[0-9]+}} IsReplacedByActive{{$}}
// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} "SpecialSwift4Name"
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 4{{$}}
// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "SpecialSwift4Name"
// CHECK-DUMP-NOT: Attr

// CHECK-DUMP-NOT: Dumping

// CHECK-UNVERSIONED: void acceptClosure(void (^block)(void) __attribute__((noescape)));
Expand Down