Merge remote-tracking branch 'origin/swift-4.0-branch' into stable
diff --git a/include/clang/APINotes/APINotesReader.h b/include/clang/APINotes/APINotesReader.h
index 2b985c6..a71c74d 100644
--- a/include/clang/APINotes/APINotesReader.h
+++ b/include/clang/APINotes/APINotesReader.h
@@ -25,20 +25,6 @@
namespace clang {
namespace api_notes {
-/// Describes the role of a specific bit of versioned information.
-enum class VersionedInfoRole : unsigned {
- /// Augment the AST, but do not override information explicitly specified
- /// in the source code.
- AugmentSource,
-
- /// Replace information that may have been explicitly specified in the source
- /// code.
- ReplaceSource,
-
- /// Describes an alternate version of this information.
- Versioned,
-};
-
/// A class that reads API notes data from a binary file that was written by
/// the \c APINotesWriter.
class APINotesReader {
@@ -94,9 +80,6 @@
/// Swift version, or \c Results.size() if nothing matched.
unsigned Selected;
- /// The role of the selected index.
- VersionedInfoRole SelectedRole;
-
public:
/// Form an empty set of versioned information.
VersionedInfo(llvm::NoneType) : Selected(0) { }
@@ -122,11 +105,6 @@
return Selected;
}
- /// Describes the role of the selected entity.
- VersionedInfoRole getSelectedRole() const {
- return SelectedRole;
- }
-
/// Return the number of versioned results we know about.
unsigned size() const { return Results.size(); }
diff --git a/include/clang/APINotes/Types.h b/include/clang/APINotes/Types.h
index 6fbd5d8..3f7ab86 100644
--- a/include/clang/APINotes/Types.h
+++ b/include/clang/APINotes/Types.h
@@ -38,16 +38,6 @@
using llvm::Optional;
using llvm::None;
-/// Describes whether to classify a factory method as an initializer.
-enum class FactoryAsInitKind {
- /// Infer based on name and type (the default).
- Infer,
- /// Treat as a class method.
- AsClassMethod,
- /// Treat as an initializer.
- AsInitializer
-};
-
/// Opaque context ID used to refer to an Objective-C class or protocol.
class ContextID {
public:
@@ -556,30 +546,17 @@
/// Whether this is a designated initializer of its class.
unsigned DesignatedInit : 1;
- /// Whether to treat this method as a factory or initializer.
- unsigned FactoryAsInit : 2;
-
/// Whether this is a required initializer.
unsigned Required : 1;
ObjCMethodInfo()
: FunctionInfo(),
DesignatedInit(false),
- FactoryAsInit(static_cast<unsigned>(FactoryAsInitKind::Infer)),
Required(false) { }
- FactoryAsInitKind getFactoryAsInitKind() const {
- return static_cast<FactoryAsInitKind>(FactoryAsInit);
- }
-
- void setFactoryAsInitKind(FactoryAsInitKind kind) {
- FactoryAsInit = static_cast<unsigned>(kind);
- }
-
friend bool operator==(const ObjCMethodInfo &lhs, const ObjCMethodInfo &rhs) {
return static_cast<const FunctionInfo &>(lhs) == rhs &&
lhs.DesignatedInit == rhs.DesignatedInit &&
- lhs.FactoryAsInit == rhs.FactoryAsInit &&
lhs.Required == rhs.Required;
}
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 3ff6f25..835f3c2 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -1498,14 +1498,6 @@
let Documentation = [Undocumented];
}
-def SwiftSuppressFactoryAsInit : InheritableAttr {
- // This attribute has no spellings as it is only ever created implicitly
- // from API notes.
- let Spellings = [];
- let SemaHandler = 0;
- let Documentation = [Undocumented];
-}
-
def SwiftImportPropertyAsAccessors : InheritableAttr {
// This attribute has no spellings as it is only ever created implicitly
// from API notes.
diff --git a/lib/APINotes/APINotesReader.cpp b/lib/APINotes/APINotesReader.cpp
index 8fbe2a1..295e501 100644
--- a/lib/APINotes/APINotesReader.cpp
+++ b/lib/APINotes/APINotesReader.cpp
@@ -353,8 +353,6 @@
payload >>= 1;
info.DesignatedInit = payload & 0x01;
payload >>= 1;
- info.FactoryAsInit = payload & 0x03;
- payload >>= 2;
readFunctionInfo(data, info);
return info;
@@ -1473,14 +1471,10 @@
// Look for an exact version match.
Optional<unsigned> unversioned;
Selected = Results.size();
- SelectedRole = VersionedInfoRole::Versioned;
for (unsigned i = 0, n = Results.size(); i != n; ++i) {
if (Results[i].first == version) {
Selected = i;
-
- if (version) SelectedRole = VersionedInfoRole::ReplaceSource;
- else SelectedRole = VersionedInfoRole::AugmentSource;
break;
}
@@ -1494,9 +1488,8 @@
// unversioned result.
if (Selected == Results.size() && unversioned) {
Selected = *unversioned;
- SelectedRole = VersionedInfoRole::AugmentSource;
}
- }
+}
auto APINotesReader::lookupObjCClassID(StringRef name) -> Optional<ContextID> {
if (!Impl.ObjCContextIDTable)
diff --git a/lib/APINotes/APINotesWriter.cpp b/lib/APINotes/APINotesWriter.cpp
index 86b6abd..116d23d 100644
--- a/lib/APINotes/APINotesWriter.cpp
+++ b/lib/APINotes/APINotesWriter.cpp
@@ -766,7 +766,7 @@
}
void emitUnversionedInfo(raw_ostream &out, const ObjCMethodInfo &info) {
- uint8_t payload = info.FactoryAsInit;
+ uint8_t payload = 0;
payload = (payload << 1) | info.DesignatedInit;
payload = (payload << 1) | info.Required;
endian::Writer<little> writer(out);
diff --git a/lib/APINotes/APINotesYAMLCompiler.cpp b/lib/APINotes/APINotesYAMLCompiler.cpp
index 0ac0b6d..3621b72 100644
--- a/lib/APINotes/APINotesYAMLCompiler.cpp
+++ b/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -35,11 +35,6 @@
parameter has a nullability value. For 'audited' APIs, we assume the default
nullability for any underspecified type.
- FactoryAsInit can have the following values:
- C - Treat as class method.
- I - Treat as initializer.
- A - Automatically infer based on the name and type (default).
-
---
Name: AppKit # The name of the framework
@@ -98,8 +93,6 @@
AvailabilityMsg: ""
- FactoryAsInit: C # Optional: Specifies if this method is a
- # factory initializer (false/true)
DesignatedInit: false # Optional: Specifies if this method is a
# designated initializer (false/true)
@@ -158,6 +151,16 @@
Instance,
};
+ /// Old attribute deprecated in favor of SwiftName.
+ enum class FactoryAsInitKind {
+ /// Infer based on name and type (the default).
+ Infer,
+ /// Treat as a class method.
+ AsClassMethod,
+ /// Treat as an initializer.
+ AsInitializer
+ };
+
struct AvailabilityItem {
APIAvailability Mode = APIAvailability::Available;
StringRef Msg;
@@ -186,8 +189,7 @@
AvailabilityItem Availability;
Optional<bool> SwiftPrivate;
StringRef SwiftName;
- api_notes::FactoryAsInitKind FactoryAsInit
- = api_notes::FactoryAsInitKind::Infer;
+ FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
bool DesignatedInit = false;
bool Required = false;
StringRef ResultType;
@@ -330,11 +332,11 @@
};
template <>
- struct ScalarEnumerationTraits<api_notes::FactoryAsInitKind > {
- static void enumeration(IO &io, api_notes::FactoryAsInitKind &value) {
- io.enumCase(value, "A", api_notes::FactoryAsInitKind::Infer);
- io.enumCase(value, "C", api_notes::FactoryAsInitKind::AsClassMethod);
- io.enumCase(value, "I", api_notes::FactoryAsInitKind::AsInitializer);
+ struct ScalarEnumerationTraits<FactoryAsInitKind> {
+ static void enumeration(IO &io, FactoryAsInitKind &value) {
+ io.enumCase(value, "A", FactoryAsInitKind::Infer);
+ io.enumCase(value, "C", FactoryAsInitKind::AsClassMethod);
+ io.enumCase(value, "I", FactoryAsInitKind::AsInitializer);
}
};
@@ -425,7 +427,7 @@
io.mapOptional("SwiftPrivate", m.SwiftPrivate);
io.mapOptional("SwiftName", m.SwiftName);
io.mapOptional("FactoryAsInit", m.FactoryAsInit,
- api_notes::FactoryAsInitKind::Infer);
+ FactoryAsInitKind::Infer);
io.mapOptional("DesignatedInit", m.DesignatedInit, false);
io.mapOptional("Required", m.Required, false);
io.mapOptional("ResultType", m.ResultType, StringRef(""));
@@ -721,8 +723,10 @@
// Translate the initializer info.
mInfo.DesignatedInit = meth.DesignatedInit;
mInfo.Required = meth.Required;
- if (meth.FactoryAsInit != FactoryAsInitKind::Infer)
- mInfo.setFactoryAsInitKind(meth.FactoryAsInit);
+ if (meth.FactoryAsInit != FactoryAsInitKind::Infer) {
+ emitError("'FactoryAsInit' is no longer valid; "
+ "use 'SwiftName' instead");
+ }
mInfo.ResultType = meth.ResultType;
// Translate parameter information.
@@ -1193,7 +1197,6 @@
handleParameters(method.Params, info);
handleNullability(method.Nullability, method.NullabilityOfRet, info,
selector.count(':'));
- method.FactoryAsInit = info.getFactoryAsInitKind();
method.DesignatedInit = info.DesignatedInit;
method.Required = info.Required;
method.ResultType = copyString(info.ResultType);
diff --git a/lib/APINotes/Types.cpp b/lib/APINotes/Types.cpp
index 963780f..4bbb4a8 100644
--- a/lib/APINotes/Types.cpp
+++ b/lib/APINotes/Types.cpp
@@ -14,7 +14,7 @@
#include "llvm/Support/raw_ostream.h"
void clang::api_notes::ObjCMethodInfo::dump(llvm::raw_ostream &os) {
- os << DesignatedInit << " " << FactoryAsInit << " " << Unavailable << " "
+ os << DesignatedInit << " " << Unavailable << " "
<< NullabilityAudited << " " << NumAdjustedNullable << " "
<< NullabilityPayload << " " << UnavailableMsg << "\n";
}
diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp
index 078445e..f11f803 100644
--- a/lib/Sema/SemaAPINotes.cpp
+++ b/lib/Sema/SemaAPINotes.cpp
@@ -15,20 +15,20 @@
#include "clang/AST/DeclObjC.h"
#include "clang/APINotes/APINotesReader.h"
using namespace clang;
-using clang::api_notes::VersionedInfoRole;
namespace {
+ enum IsActive_t : bool {
+ IsNotActive,
+ IsActive
+ };
+
struct VersionedInfoMetadata {
+ /// An empty version refers to unversioned metadata.
VersionTuple Version;
- VersionedInfoRole Role;
+ bool IsActive;
- /*implicit*/ VersionedInfoMetadata(VersionedInfoRole role) : Role(role) {
- assert(role != VersionedInfoRole::Versioned &&
- "explicit version required");
- }
-
- /*implicit*/ VersionedInfoMetadata(VersionTuple version)
- : Version(version), Role(VersionedInfoRole::Versioned) {}
+ VersionedInfoMetadata(VersionTuple version, IsActive_t active)
+ : Version(version), IsActive(active == IsActive_t::IsActive) {}
};
} // end anonymous namespace
@@ -45,20 +45,8 @@
// Apply nullability to the given declaration.
static void applyNullability(Sema &S, Decl *decl, NullabilityKind nullability,
VersionedInfoMetadata metadata) {
- bool overrideExisting;
- switch (metadata.Role) {
- case VersionedInfoRole::AugmentSource:
- overrideExisting = false;
- break;
-
- case VersionedInfoRole::ReplaceSource:
- overrideExisting = true;
- break;
-
- case VersionedInfoRole::Versioned:
- // FIXME: Record versioned info?
+ if (!metadata.IsActive)
return;
- }
QualType type;
@@ -80,7 +68,7 @@
S.checkNullabilityTypeSpecifier(type, nullability, decl->getLocation(),
/*isContextSensitive=*/false,
isa<ParmVarDecl>(decl), /*implicit=*/true,
- overrideExisting);
+ /*overrideExisting=*/true);
if (type.getTypePtr() == origType.getTypePtr())
return;
@@ -154,20 +142,7 @@
VersionedInfoMetadata metadata,
llvm::function_ref<A *()> createAttr,
llvm::function_ref<specific_attr_iterator<A>(Decl*)> getExistingAttr) {
- switch (metadata.Role) {
- case VersionedInfoRole::AugmentSource:
- // If we're not adding an attribute, there's nothing to do.
- if (!shouldAddAttribute) return;
-
- // If the attribute is already present, we're done.
- if (getExistingAttr(D) != D->specific_attr_end<A>()) return;
-
- // Add the attribute.
- if (auto attr = createAttr())
- D->addAttr(attr);
- break;
-
- case VersionedInfoRole::ReplaceSource: {
+ if (metadata.IsActive) {
auto end = D->specific_attr_end<A>();
auto existing = getExistingAttr(D);
if (existing != end) {
@@ -187,11 +162,8 @@
D->addAttr(attr);
}
}
- break;
- }
- case VersionedInfoRole::Versioned:
- // FIXME: Include the actual version instead of making one up.
+ } else {
if (shouldAddAttribute) {
if (auto attr = createAttr()) {
auto *versioned =
@@ -209,7 +181,6 @@
AttrKindFor<A>::value);
D->addAttr(versioned);
}
- break;
}
}
@@ -341,8 +312,8 @@
const api_notes::VariableInfo &info,
VersionedInfoMetadata metadata) {
// Type override.
- if (metadata.Role != VersionedInfoRole::Versioned &&
- !info.getType().empty() && S.ParseTypeFromStringCallback) {
+ if (metadata.IsActive && !info.getType().empty() &&
+ S.ParseTypeFromStringCallback) {
auto parsedType = S.ParseTypeFromStringCallback(info.getType(),
"<API Notes>",
D->getLocation());
@@ -480,8 +451,8 @@
// Result type override.
QualType overriddenResultType;
- if (metadata.Role != VersionedInfoRole::Versioned &&
- !info.ResultType.empty() && S.ParseTypeFromStringCallback) {
+ if (metadata.IsActive && !info.ResultType.empty() &&
+ S.ParseTypeFromStringCallback) {
auto parsedType = S.ParseTypeFromStringCallback(info.ResultType,
"<API Notes>",
D->getLocation());
@@ -568,14 +539,6 @@
});
}
- // FIXME: This doesn't work well with versioned API notes.
- if (metadata.Role == VersionedInfoRole::AugmentSource &&
- info.getFactoryAsInitKind()
- == api_notes::FactoryAsInitKind::AsClassMethod &&
- !D->getAttr<SwiftNameAttr>()) {
- D->addAttr(SwiftSuppressFactoryAsInitAttr::CreateImplicit(S.Context));
- }
-
// Handle common function information.
ProcessAPINotes(S, FunctionOrMethod(D),
static_cast<const api_notes::FunctionInfo &>(info), metadata);
@@ -658,11 +621,8 @@
SpecificInfo InfoSlice;
for (unsigned i = 0, e = Info.size(); i != e; ++i) {
std::tie(Version, InfoSlice) = Info[i];
- if (i != Selected) {
- ProcessAPINotes(S, D, InfoSlice, Version);
- } else {
- ProcessAPINotes(S, D, InfoSlice, Info.getSelectedRole());
- }
+ auto Active = (i == Selected) ? IsActive : IsNotActive;
+ ProcessAPINotes(S, D, InfoSlice, VersionedInfoMetadata(Version, Active));
}
}
diff --git a/test/APINotes/Inputs/roundtrip.apinotes b/test/APINotes/Inputs/roundtrip.apinotes
index 05599a7..2937fa6 100644
--- a/test/APINotes/Inputs/roundtrip.apinotes
+++ b/test/APINotes/Inputs/roundtrip.apinotes
@@ -16,7 +16,6 @@
AvailabilityMsg: ''
SwiftPrivate: false
SwiftName: ''
- FactoryAsInit: C
ResultType: id
- Selector: init
MethodKind: Instance