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