Add "nonswift" availability mapping to Swift
unavailability.
The new "nonswift" availability maps to
__attribute__((swift,unavailable)). Part of rdar://problem/24447420.
diff --git a/include/clang/APINotes/Types.h b/include/clang/APINotes/Types.h
index 8173bf4..3cf1493 100644
--- a/include/clang/APINotes/Types.h
+++ b/include/clang/APINotes/Types.h
@@ -67,12 +67,16 @@
/// Whether this entity is marked unavailable.
unsigned Unavailable : 1;
- CommonEntityInfo() : Unavailable(0) { }
+ /// Whether this entity is marked unavailable in Swift.
+ unsigned UnavailableInSwift : 1;
+
+ CommonEntityInfo() : Unavailable(0), UnavailableInSwift(0) { }
friend bool operator==(const CommonEntityInfo &lhs,
const CommonEntityInfo &rhs) {
return lhs.UnavailableMsg == rhs.UnavailableMsg &&
- lhs.Unavailable == rhs.Unavailable;
+ lhs.Unavailable == rhs.Unavailable &&
+ lhs.UnavailableInSwift == rhs.UnavailableInSwift;
}
friend bool operator!=(const CommonEntityInfo &lhs,
@@ -91,6 +95,14 @@
}
}
+ if (rhs.UnavailableInSwift) {
+ lhs.UnavailableInSwift = true;
+ if (rhs.UnavailableMsg.length() != 0 &&
+ lhs.UnavailableMsg.length() == 0) {
+ lhs.UnavailableMsg = rhs.UnavailableMsg;
+ }
+ }
+
return lhs;
}
diff --git a/lib/APINotes/APINotesFormat.h b/lib/APINotes/APINotesFormat.h
index 5462e5a..0801d2c 100644
--- a/lib/APINotes/APINotesFormat.h
+++ b/lib/APINotes/APINotesFormat.h
@@ -35,7 +35,7 @@
/// API notes file minor version number.
///
/// When the format changes IN ANY WAY, this number should be incremented.
-const uint16_t VERSION_MINOR = 6;
+const uint16_t VERSION_MINOR = 7;
using IdentifierID = Fixnum<31>;
using IdentifierIDField = BCVBR<16>;
diff --git a/lib/APINotes/APINotesReader.cpp b/lib/APINotes/APINotesReader.cpp
index a84f2d7..c768f3a 100644
--- a/lib/APINotes/APINotesReader.cpp
+++ b/lib/APINotes/APINotesReader.cpp
@@ -30,7 +30,9 @@
namespace {
/// Read serialized CommonEntityInfo.
void readCommonEntityInfo(const uint8_t *&data, CommonEntityInfo &info) {
- info.Unavailable = *data++;
+ uint8_t unavailableBits = *data++;
+ info.Unavailable = (unavailableBits >> 1) & 0x01;
+ info.UnavailableInSwift = unavailableBits & 0x01;
unsigned msgLength = endian::readNext<uint16_t, little, unaligned>(data);
info.UnavailableMsg
diff --git a/lib/APINotes/APINotesWriter.cpp b/lib/APINotes/APINotesWriter.cpp
index 400bd08..0e498a7 100644
--- a/lib/APINotes/APINotesWriter.cpp
+++ b/lib/APINotes/APINotesWriter.cpp
@@ -272,7 +272,7 @@
static void emitCommonEntityInfo(raw_ostream &out,
const CommonEntityInfo &info) {
endian::Writer<little> writer(out);
- writer.write<uint8_t>(info.Unavailable);
+ writer.write<uint8_t>(info.Unavailable << 1 | info.UnavailableInSwift);
writer.write<uint16_t>(info.UnavailableMsg.size());
out.write(info.UnavailableMsg.c_str(), info.UnavailableMsg.size());
}
diff --git a/lib/APINotes/APINotesYAMLCompiler.cpp b/lib/APINotes/APINotesYAMLCompiler.cpp
index 1f29987..8c27a01 100644
--- a/lib/APINotes/APINotesYAMLCompiler.cpp
+++ b/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -44,7 +44,7 @@
Availability: OSX # Optional: Specifies which platform the API is
# available on. [OSX / iOS / none/
- # available]
+ # available / nonswift]
AvailabilityMsg: "" # Optional: Custom availability message to display to
# the user, when API is not available.
@@ -143,6 +143,7 @@
OSX,
IOS,
None,
+ NonSwift,
};
enum class MethodKind {
@@ -264,6 +265,7 @@
io.enumCase(value, "OSX", APIAvailability::OSX);
io.enumCase(value, "iOS", APIAvailability::IOS);
io.enumCase(value, "none", APIAvailability::None);
+ io.enumCase(value, "nonswift", APIAvailability::NonSwift);
io.enumCase(value, "available", APIAvailability::Available);
}
};
@@ -410,9 +412,10 @@
bool convertAvailability(const AvailabilityItem &in,
CommonEntityInfo &outInfo,
llvm::StringRef apiName) {
- // Populate the 'Unavailable' information.
+ // Populate the unavailability information.
outInfo.Unavailable = (in.Mode == APIAvailability::None);
- if (outInfo.Unavailable) {
+ outInfo.UnavailableInSwift = (in.Mode == APIAvailability::NonSwift);
+ if (outInfo.Unavailable || outInfo.UnavailableInSwift) {
outInfo.UnavailableMsg = in.Msg;
} else {
if (!in.Msg.empty()) {
@@ -716,6 +719,11 @@
availability.Mode = APIAvailability::None;
availability.Msg = copyString(info.UnavailableMsg);
}
+
+ if (info.UnavailableInSwift) {
+ availability.Mode = APIAvailability::NonSwift;
+ availability.Msg = copyString(info.UnavailableMsg);
+ }
}
/// Map nullability information for a function.
diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp
index 8ca364e..6f08fd4 100644
--- a/lib/Sema/SemaAPINotes.cpp
+++ b/lib/Sema/SemaAPINotes.cpp
@@ -99,6 +99,16 @@
if (Info.Unavailable && !D->hasAttr<UnavailableAttr>()) {
D->addAttr(UnavailableAttr::CreateImplicit(S.Context, Info.UnavailableMsg));
}
+
+ if (Info.UnavailableInSwift) {
+ D->addAttr(AvailabilityAttr::CreateImplicit(S.Context,
+ &S.Context.Idents.get("swift"),
+ VersionTuple(),
+ VersionTuple(),
+ VersionTuple(),
+ /*Unavailable=*/true,
+ Info.UnavailableMsg));
+ }
}
/// Process API notes for a variable or property.