Merge remote-tracking branch 'origin/swift-3.1-branch' into stable
diff --git a/include/clang/APINotes/APINotesReader.h b/include/clang/APINotes/APINotesReader.h
index a09bcc7..f96c7b6 100644
--- a/include/clang/APINotes/APINotesReader.h
+++ b/include/clang/APINotes/APINotesReader.h
@@ -25,6 +25,20 @@
 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 {
@@ -80,6 +94,9 @@
     /// 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) { }
@@ -105,6 +122,11 @@
       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 9761510..4620bfd 100644
--- a/include/clang/APINotes/Types.h
+++ b/include/clang/APINotes/Types.h
@@ -127,26 +127,48 @@
   /// The Swift type to which a given type is bridged.
   ///
   /// Reflects the swift_bridge attribute.
-  std::string SwiftBridge;
+  Optional<std::string> SwiftBridge;
 
   /// The NS error domain for this type.
-  std::string NSErrorDomain;
+  Optional<std::string> NSErrorDomain;
 
 public:
   CommonTypeInfo() : CommonEntityInfo() { }
 
-  const std::string &getSwiftBridge() const { return SwiftBridge; }
-  void setSwiftBridge(const std::string &swiftType) { SwiftBridge = swiftType; }
+  const Optional<std::string> &getSwiftBridge() const { return SwiftBridge; }
 
-  const std::string &getNSErrorDomain() const { return NSErrorDomain; }
-  void setNSErrorDomain(const std::string &domain) { NSErrorDomain = domain; }
+  void setSwiftBridge(const Optional<std::string> &swiftType) {
+    SwiftBridge = swiftType;
+  }
+
+  void setSwiftBridge(const Optional<StringRef> &swiftType) {
+    if (swiftType)
+      SwiftBridge = *swiftType;
+    else
+      SwiftBridge = None;
+  }
+
+  const Optional<std::string> &getNSErrorDomain() const {
+    return NSErrorDomain;
+  }
+
+  void setNSErrorDomain(const Optional<std::string> &domain) {
+    NSErrorDomain = domain;
+  }
+
+  void setNSErrorDomain(const Optional<StringRef> &domain) {
+    if (domain)
+      NSErrorDomain = *domain;
+    else
+      NSErrorDomain = None;
+  }
 
   friend CommonTypeInfo &operator|=(CommonTypeInfo &lhs,
                                     const CommonTypeInfo &rhs) {
     static_cast<CommonEntityInfo &>(lhs) |= rhs;
-    if (lhs.SwiftBridge.empty() && !rhs.SwiftBridge.empty())
+    if (!lhs.SwiftBridge && rhs.SwiftBridge)
       lhs.SwiftBridge = rhs.SwiftBridge;
-    if (lhs.NSErrorDomain.empty() && !rhs.NSErrorDomain.empty())
+    if (!lhs.NSErrorDomain && rhs.NSErrorDomain)
       lhs.NSErrorDomain = rhs.NSErrorDomain;
     return lhs;
   }
@@ -308,24 +330,41 @@
 
 /// Describes a function or method parameter.
 class ParamInfo : public VariableInfo {
+  /// Whether noescape was specified.
+  unsigned NoEscapeSpecified : 1;
+
   /// Whether the this parameter has the 'noescape' attribute.
   unsigned NoEscape : 1;
 
 public:
-  ParamInfo() : VariableInfo(), NoEscape(false) { }
+  ParamInfo() : VariableInfo(), NoEscapeSpecified(false), NoEscape(false) { }
 
-  bool isNoEscape() const { return NoEscape; }
-  void setNoEscape(bool noescape) { NoEscape = noescape; }
+  Optional<bool> isNoEscape() const {
+    if (!NoEscapeSpecified) return None;
+    return NoEscape;
+  }
+  void setNoEscape(Optional<bool> noescape) {
+    if (noescape) {
+      NoEscapeSpecified = true;
+      NoEscape = *noescape;
+    } else {
+      NoEscapeSpecified = false;
+      NoEscape = false;
+    }
+  }
 
   friend ParamInfo &operator|=(ParamInfo &lhs, const ParamInfo &rhs) {
     static_cast<VariableInfo &>(lhs) |= rhs;
-    if (!lhs.NoEscape && rhs.NoEscape)
-      lhs.NoEscape = true;
+    if (!lhs.NoEscapeSpecified && rhs.NoEscapeSpecified) {
+      lhs.NoEscapeSpecified = true;
+      lhs.NoEscape = rhs.NoEscape;
+    }
     return lhs;
   }
 
   friend bool operator==(const ParamInfo &lhs, const ParamInfo &rhs) {
     return static_cast<const VariableInfo &>(lhs) == rhs &&
+           lhs.NoEscapeSpecified == rhs.NoEscapeSpecified &&
            lhs.NoEscape == rhs.NoEscape;
   }
 
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index fb9b049..5ef250c 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -108,6 +108,8 @@
                          specific_attr_iterator Right) {
     return !(Left == Right);
   }
+
+  Iterator getCurrent() const { return Current; }
 };
 
 template <typename SpecificAttr, typename Container>
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index bb6029d..980602d 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -3097,11 +3097,15 @@
   /// method) or an Objective-C property attribute, rather than as an
   /// underscored type specifier.
   ///
+  /// \param overrideExisting Whether to override an existing, locally-specified
+  /// nullability specifier rather than complaining about the conflict.
+  ///
   /// \returns true if nullability cannot be applied, false otherwise.
   bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability,
                                      SourceLocation nullabilityLoc,
                                      bool isContextSensitive,
-                                     bool implicit);
+                                     bool implicit,
+                                     bool overrideExisting = false);
 
   /// \brief Stmt attributes - this routine is the top level dispatcher.
   StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
diff --git a/lib/APINotes/APINotesFormat.h b/lib/APINotes/APINotesFormat.h
index 9b68cf2..6f7734b 100644
--- a/lib/APINotes/APINotesFormat.h
+++ b/lib/APINotes/APINotesFormat.h
@@ -36,7 +36,7 @@
 /// API notes file minor version number.
 ///
 /// When the format changes IN ANY WAY, this number should be incremented.
-const uint16_t VERSION_MINOR = 16;  // versioned API notes.
+const uint16_t VERSION_MINOR = 17;  // optional NSErrorDomain
 
 using IdentifierID = PointerEmbeddedInt<unsigned, 31>;
 using IdentifierIDField = BCVBR<16>;
diff --git a/lib/APINotes/APINotesReader.cpp b/lib/APINotes/APINotesReader.cpp
index dda721e..0e25409 100644
--- a/lib/APINotes/APINotesReader.cpp
+++ b/lib/APINotes/APINotesReader.cpp
@@ -126,15 +126,19 @@
 
     unsigned swiftBridgeLength =
         endian::readNext<uint16_t, little, unaligned>(data);
-    info.setSwiftBridge(
-        StringRef(reinterpret_cast<const char *>(data), swiftBridgeLength));
-    data += swiftBridgeLength;
+    if (swiftBridgeLength > 0) {
+      info.setSwiftBridge(
+        std::string(reinterpret_cast<const char *>(data), swiftBridgeLength-1));
+      data += swiftBridgeLength-1;
+    }
 
     unsigned errorDomainLength =
       endian::readNext<uint16_t, little, unaligned>(data);
-    info.setNSErrorDomain(
-        StringRef(reinterpret_cast<const char *>(data), errorDomainLength));
-    data += errorDomainLength;
+    if (errorDomainLength > 0) {
+      info.setNSErrorDomain(
+        std::string(reinterpret_cast<const char *>(data), errorDomainLength-1));
+      data += errorDomainLength-1;
+    }
   }
 
   /// Used to deserialize the on-disk identifier table.
@@ -303,8 +307,10 @@
       if (payload & 0x01)
         pi.setNullabilityAudited(static_cast<NullabilityKind>(nullabilityValue));
       payload >>= 1;
-      pi.setNoEscape(payload & 0x01);
-      payload >>= 1; assert(payload == 0 && "Bad API notes");
+      if (payload & 0x01) {
+        pi.setNoEscape(payload & 0x02);
+      }
+      payload >>= 2; assert(payload == 0 && "Bad API notes");
 
       info.Params.push_back(pi);
       --numParams;
@@ -1451,9 +1457,14 @@
   // 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;
     }
 
@@ -1465,9 +1476,11 @@
 
   // If we didn't find a match but we have an unversioned result, use the
   // unversioned result.
-  if (Selected == Results.size() && unversioned)
+  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 6debe99..2cd5776 100644
--- a/lib/APINotes/APINotesWriter.cpp
+++ b/lib/APINotes/APINotesWriter.cpp
@@ -343,8 +343,8 @@
   // Retrieve the serialized size of the given CommonTypeInfo, for use
   // in on-disk hash tables.
   static unsigned getCommonTypeInfoSize(const CommonTypeInfo &info) {
-    return 2 + info.getSwiftBridge().size() +
-           2 + info.getNSErrorDomain().size() +
+    return 2 + (info.getSwiftBridge() ? info.getSwiftBridge()->size() : 0) +
+           2 + (info.getNSErrorDomain() ? info.getNSErrorDomain()->size() : 0) +
            getCommonEntityInfoSize(info);
   }
 
@@ -352,10 +352,18 @@
   static void emitCommonTypeInfo(raw_ostream &out, const CommonTypeInfo &info) {
     emitCommonEntityInfo(out, info);
     endian::Writer<little> writer(out);
-    writer.write<uint16_t>(info.getSwiftBridge().size());
-    out.write(info.getSwiftBridge().c_str(), info.getSwiftBridge().size());
-    writer.write<uint16_t>(info.getNSErrorDomain().size());
-    out.write(info.getNSErrorDomain().c_str(), info.getNSErrorDomain().size());
+    if (auto swiftBridge = info.getSwiftBridge()) {
+      writer.write<uint16_t>(swiftBridge->size() + 1);
+      out.write(swiftBridge->c_str(), swiftBridge->size());
+    } else {
+      writer.write<uint16_t>(0);
+    }
+    if (auto nsErrorDomain = info.getNSErrorDomain()) {
+      writer.write<uint16_t>(nsErrorDomain->size() + 1);
+      out.write(nsErrorDomain->c_str(), info.getNSErrorDomain()->size());
+    } else {
+      writer.write<uint16_t>(0);
+    }
   }
 
   /// Used to serialize the on-disk Objective-C context table.
@@ -687,7 +695,12 @@
     // Parameters.
     writer.write<uint16_t>(info.Params.size());
     for (const auto &pi : info.Params) {
-      uint8_t payload = pi.isNoEscape();
+      uint8_t payload = 0;
+      if (auto noescape = pi.isNoEscape()) {
+        payload |= 0x01;
+        if (*noescape)
+          payload |= 0x02;
+      }
 
       auto nullability = pi.getNullability();
       payload = (payload << 1) | nullability.hasValue();
diff --git a/lib/APINotes/APINotesYAMLCompiler.cpp b/lib/APINotes/APINotesYAMLCompiler.cpp
index 8f1e5a2..69ed542 100644
--- a/lib/APINotes/APINotesYAMLCompiler.cpp
+++ b/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -171,7 +171,7 @@
 
   struct Param {
     unsigned Position;
-    bool NoEscape = false;
+    Optional<bool> NoEscape = false;
     llvm::Optional<NullabilityKind> Nullability;
   };
   typedef std::vector<Param> ParamsSeq;
@@ -208,8 +208,8 @@
     AvailabilityItem Availability;
     bool SwiftPrivate = false;
     StringRef SwiftName;
-    StringRef SwiftBridge;
-    StringRef NSErrorDomain;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
     MethodsSeq Methods;
     PropertiesSeq Properties;
   };
@@ -248,8 +248,8 @@
     AvailabilityItem Availability;
     StringRef SwiftName;
     bool SwiftPrivate = false;
-    StringRef SwiftBridge;
-    StringRef NSErrorDomain;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
   };
   typedef std::vector<Tag> TagsSeq;
 
@@ -258,8 +258,8 @@
     AvailabilityItem Availability;
     StringRef SwiftName;
     bool SwiftPrivate = false;
-    StringRef SwiftBridge;
-    StringRef NSErrorDomain;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
   };
   typedef std::vector<Typedef> TypedefsSeq;
 
@@ -929,7 +929,6 @@
       // Convert the versioned information.
       for (const auto &versioned : TheModule.SwiftVersions) {
         convertTopLevelItems(versioned.Items, versioned.Version);
-
       }
 
       if (!ErrorOccured)
@@ -1034,6 +1033,20 @@
       return StringRef(reinterpret_cast<const char *>(ptr), string.size());
     }
 
+    /// Copy an optional string into allocated memory so it does disappear on us.
+    Optional<StringRef> maybeCopyString(Optional<StringRef> string) {
+      if (!string) return None;
+
+      return copyString(*string);
+    }
+
+    /// Copy an optional string into allocated memory so it does disappear on us.
+    Optional<StringRef> maybeCopyString(Optional<std::string> string) {
+      if (!string) return None;
+
+      return copyString(*string);
+    }
+
     template<typename T>
     void handleCommon(T &record, const CommonEntityInfo &info) {
       handleAvailability(record.Availability, info);
@@ -1044,8 +1057,8 @@
     template<typename T>
     void handleCommonType(T &record, const CommonTypeInfo &info) {
       handleCommon(record, info);
-      record.SwiftBridge = copyString(info.getSwiftBridge());      
-      record.NSErrorDomain = copyString(info.getNSErrorDomain());
+      record.SwiftBridge = maybeCopyString(info.getSwiftBridge());
+      record.NSErrorDomain = maybeCopyString(info.getNSErrorDomain());
     }
 
     /// Map Objective-C context info.
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index d270121..d1c77bb 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -897,9 +897,13 @@
         return MD;
   }
 
-  if (isRedeclaration())
-    return cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
-                                                    isInstanceMethod());
+  if (isRedeclaration()) {
+    // It is possible that we have not done deserializing the ObjCMethod yet.
+    ObjCMethodDecl *MD =
+        cast<ObjCContainerDecl>(CtxD)->getMethod(getSelector(),
+                                                 isInstanceMethod());
+    return MD ? MD : this;
+  }
 
   return this;
 }
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 7e78699..e599840 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -1137,6 +1137,9 @@
     return;
   }
   bool eolnOut = false;
+  prettyPrintAttributes(OID);
+  if (OID->hasAttrs()) Out << "\n";
+
   Out << "@interface " << I;
 
   if (auto TypeParams = OID->getTypeParamListAsWritten()) {
@@ -1346,6 +1349,17 @@
   if (D->hasTypename())
     Out << "typename ";
   D->getQualifier()->print(Out, Policy);
+
+  // Use the correct record name when the using declaration is used for
+  // inheriting constructors.
+  for (const auto *Shadow : D->shadows()) {
+    if (const auto *ConstructorShadow =
+            dyn_cast<ConstructorUsingShadowDecl>(Shadow)) {
+      assert(Shadow->getDeclContext() == ConstructorShadow->getDeclContext());
+      Out << *ConstructorShadow->getNominatedBaseClass();
+      return;
+    }
+  }
   Out << *D;
 }
 
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 0cb09f1..8d1a817 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -5364,6 +5364,8 @@
     const char Arg[] = "-fapinotes-cache-path=";
     APINotesCachePath.insert(APINotesCachePath.begin(), Arg, Arg + strlen(Arg));
     CmdArgs.push_back(Args.MakeArgString(APINotesCachePath));
+
+    Args.AddLastArg(CmdArgs, options::OPT_fapinotes_swift_version);
   }
 
   // -fblocks=0 is default.
diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp
index 4a666cc..89cf5b6 100644
--- a/lib/Sema/SemaAPINotes.cpp
+++ b/lib/Sema/SemaAPINotes.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/APINotes/APINotesReader.h"
 using namespace clang;
+using clang::api_notes::VersionedInfoRole;
 
 /// Determine whether this is a multi-level pointer type.
 static bool isMultiLevelPointerType(QualType type) {
@@ -27,7 +28,23 @@
 }
 
 // Apply nullability to the given declaration.
-static void applyNullability(Sema &S, Decl *decl, NullabilityKind nullability) {
+static void applyNullability(Sema &S, Decl *decl, NullabilityKind nullability,
+                             VersionedInfoRole role) {
+  bool overrideExisting;
+  switch (role) {
+  case VersionedInfoRole::AugmentSource:
+    overrideExisting = false;
+    break;
+
+  case VersionedInfoRole::ReplaceSource:
+    overrideExisting = true;
+    break;
+
+  case VersionedInfoRole::Versioned:
+    // FIXME: Record versioned info?
+    return;
+  }
+
   QualType type;
 
   // Nullability for a function/method appertains to the retain type.
@@ -47,7 +64,8 @@
   QualType origType = type;
   S.checkNullabilityTypeSpecifier(type, nullability, decl->getLocation(),
                                   /*isContextSensitive=*/false,
-                                  /*implicit=*/true);
+                                  /*implicit=*/true,
+                                  overrideExisting);
   if (type.getTypePtr() == origType.getTypePtr())
     return;
 
@@ -100,104 +118,198 @@
   return StringRef(static_cast<char *>(mem), string.size());
 }
 
-static void ProcessAPINotes(Sema &S, Decl *D,
-                            const api_notes::CommonEntityInfo &Info) {
-  // Availability
-  if (Info.Unavailable && !D->hasAttr<UnavailableAttr>()) {
-    D->addAttr(UnavailableAttr::CreateImplicit(S.Context,
-					       CopyString(S.Context,
-							  Info.UnavailableMsg)));
-  }
+namespace {
+  /// Handle an attribute introduced by API notes.
+  ///
+  /// \param shouldAddAttribute Whether we should add a new attribute
+  /// (otherwise, we might remove an existing attribute).
+  /// \param createAttr Create the new attribute to be added.
+  /// \param getExistingAttr Get an existing, matching attribute on the given
+  /// declaration.
+  template<typename A>
+  void handleAPINotedAttribute(
+         Sema &S, Decl *D, bool shouldAddAttribute,
+         VersionedInfoRole role,
+         llvm::function_ref<A *()> createAttr,
+         llvm::function_ref<specific_attr_iterator<A>(Decl *)> getExistingAttr =
+           [](Decl *decl) { return decl->specific_attr_begin<A>(); }) {
+    switch (role) {
+    case VersionedInfoRole::AugmentSource:
+      // If we're not adding an attribute, there's nothing to do.
+      if (!shouldAddAttribute) return;
 
-  if (Info.UnavailableInSwift) {
-    D->addAttr(AvailabilityAttr::CreateImplicit(
-		             S.Context,
-                 &S.Context.Idents.get("swift"),
-                 VersionTuple(),
-                 VersionTuple(),
-                 VersionTuple(),
-                 /*Unavailable=*/true,
-                 CopyString(S.Context, Info.UnavailableMsg),
-                 /*Strict=*/false,
-                 /*Replacement=*/StringRef()));
-  }
+      // If the attribute is already present, we're done.
+      if (getExistingAttr(D) != D->specific_attr_end<A>()) return;
 
-  // swift_private
-  if (Info.SwiftPrivate && !D->hasAttr<SwiftPrivateAttr>()) {
-    D->addAttr(SwiftPrivateAttr::CreateImplicit(S.Context));
-  }
+      // Add the attribute.
+      if (auto attr = createAttr())
+        D->addAttr(attr);
+      break;
 
-  // swift_name
-  if (!Info.SwiftName.empty() && !D->hasAttr<SwiftNameAttr>()) {
-    auto &APINoteName = S.getASTContext().Idents.get("SwiftName API Note");
-    
-    if (!S.DiagnoseSwiftName(D, Info.SwiftName, D->getLocation(),
-                             &APINoteName)) {
-      return;
+    case VersionedInfoRole::ReplaceSource: {
+      auto end = D->specific_attr_end<A>();
+      auto existing = getExistingAttr(D);
+      if (existing != end) {
+        // Remove the existing attribute.
+        D->getAttrs().erase(existing.getCurrent());
+      }
+
+      // If we're supposed to add a new attribute, do so.
+      if (shouldAddAttribute) {
+        if (auto attr = createAttr()) {
+          D->addAttr(attr);
+        }
+      }
+      break;
     }
-    D->addAttr(SwiftNameAttr::CreateImplicit(S.Context,
-                                       CopyString(S.Context, Info.SwiftName)));
+
+    case VersionedInfoRole::Versioned:
+      // FIXME: Retain versioned attributes separately.
+      break;
+    }
   }
 }
 
 static void ProcessAPINotes(Sema &S, Decl *D,
-                            const api_notes::CommonTypeInfo &Info) {
+                            const api_notes::CommonEntityInfo &info,
+                            VersionedInfoRole role) {
+  // Availability
+  if (info.Unavailable) {
+    handleAPINotedAttribute<UnavailableAttr>(S, D, true, role,
+      [&] {
+        return UnavailableAttr::CreateImplicit(S.Context,
+                                               CopyString(S.Context,
+                                                          info.UnavailableMsg));
+    });
+  }
+
+  if (info.UnavailableInSwift) {
+    handleAPINotedAttribute<AvailabilityAttr>(S, D, true, role, [&] {
+      return AvailabilityAttr::CreateImplicit(
+                   S.Context,
+                   &S.Context.Idents.get("swift"),
+                   VersionTuple(),
+                   VersionTuple(),
+                   VersionTuple(),
+                   /*Unavailable=*/true,
+                   CopyString(S.Context, info.UnavailableMsg),
+                   /*Strict=*/false,
+                   /*Replacement=*/StringRef());
+    },
+    [](Decl *decl) {
+      auto existing = decl->specific_attr_begin<AvailabilityAttr>(),
+        end = decl->specific_attr_end<AvailabilityAttr>();
+      while (existing != end) {
+        if (auto platform = (*existing)->getPlatform()) {
+          if (platform->isStr("swift"))
+            break;
+        }
+
+        ++existing;
+      }
+
+      return existing;
+    });
+  }
+
+  // swift_private
+  if (info.SwiftPrivate) {
+    handleAPINotedAttribute<SwiftPrivateAttr>(S, D, true, role, [&] {
+      return SwiftPrivateAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // swift_name
+  if (!info.SwiftName.empty()) {
+    handleAPINotedAttribute<SwiftNameAttr>(S, D, true, role,
+                                           [&]() -> SwiftNameAttr * {
+      auto &APINoteName = S.getASTContext().Idents.get("SwiftName API Note");
+      
+      if (!S.DiagnoseSwiftName(D, info.SwiftName, D->getLocation(),
+                               &APINoteName)) {
+        return nullptr;
+      }
+
+      return SwiftNameAttr::CreateImplicit(S.Context,
+                                           CopyString(S.Context,
+                                                      info.SwiftName));
+    });
+  }
+}
+
+static void ProcessAPINotes(Sema &S, Decl *D,
+                            const api_notes::CommonTypeInfo &info,
+                            VersionedInfoRole role) {
   // swift_bridge
-  if (!Info.getSwiftBridge().empty() &&
-      !D->getAttr<SwiftBridgeAttr>()) {
-    D->addAttr(
-      SwiftBridgeAttr::CreateImplicit(S.Context,
-                                      CopyString(S.Context,
-                                                 Info.getSwiftBridge())));
+  if (auto swiftBridge = info.getSwiftBridge()) {
+    handleAPINotedAttribute<SwiftBridgeAttr>(S, D, !swiftBridge->empty(), role,
+                                             [&] {
+      return SwiftBridgeAttr::CreateImplicit(S.Context,
+                                             CopyString(S.Context,
+                                                        *swiftBridge));
+    });
   }
 
   // ns_error_domain
-  if (!Info.getNSErrorDomain().empty() &&
-      !D->getAttr<NSErrorDomainAttr>()) {
-    D->addAttr(
-      NSErrorDomainAttr::CreateImplicit(
-        S.Context,
-        &S.Context.Idents.get(Info.getNSErrorDomain())));
+  if (auto nsErrorDomain = info.getNSErrorDomain()) {
+    handleAPINotedAttribute<NSErrorDomainAttr>(S, D, !nsErrorDomain->empty(),
+                                               role, [&] {
+      return NSErrorDomainAttr::CreateImplicit(
+               S.Context,
+               &S.Context.Idents.get(*nsErrorDomain));
+    });
   }
 
-  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  role);
 }
 
 /// Process API notes for a variable or property.
 static void ProcessAPINotes(Sema &S, Decl *D,
-                            const api_notes::VariableInfo &Info) {
+                            const api_notes::VariableInfo &info,
+                            VersionedInfoRole role) {
   // Nullability.
-  if (auto Nullability = Info.getNullability()) {
-    applyNullability(S, D, *Nullability);
+  if (auto Nullability = info.getNullability()) {
+    applyNullability(S, D, *Nullability, role);
   }
 
   // Handle common entity information.
-  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  role);
 }
 
 /// Process API notes for a parameter.
 static void ProcessAPINotes(Sema &S, ParmVarDecl *D,
-                            const api_notes::ParamInfo &Info) {
+                            const api_notes::ParamInfo &info,
+                            VersionedInfoRole role) {
   // noescape
-  if (Info.isNoEscape() && !D->getAttr<NoEscapeAttr>())
-    D->addAttr(NoEscapeAttr::CreateImplicit(S.Context));
+  if (auto noescape = info.isNoEscape()) {
+    handleAPINotedAttribute<NoEscapeAttr>(S, D, *noescape, role, [&] {
+      return NoEscapeAttr::CreateImplicit(S.Context);
+    });
+  }
 
   // Handle common entity information.
-  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  role);
 }
 
 /// Process API notes for a global variable.
 static void ProcessAPINotes(Sema &S, VarDecl *D,
-                            const api_notes::GlobalVariableInfo &Info) {
+                            const api_notes::GlobalVariableInfo &info,
+                            VersionedInfoRole role) {
   // Handle common entity information.
-  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  role);
 }
 
 /// Process API notes for an Objective-C property.
 static void ProcessAPINotes(Sema &S, ObjCPropertyDecl *D,
-                            const api_notes::ObjCPropertyInfo &Info) {
+                            const api_notes::ObjCPropertyInfo &info,
+                            VersionedInfoRole role) {
   // Handle common entity information.
-  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  role);
 }
 
 namespace {
@@ -206,7 +318,8 @@
 
 /// Process API notes for a function or method.
 static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc,
-                            const api_notes::FunctionInfo &Info) {
+                            const api_notes::FunctionInfo &info,
+                            VersionedInfoRole role) {
   // Find the declaration itself.
   FunctionDecl *FD = AnyFunc.dyn_cast<FunctionDecl *>();
   Decl *D = FD;
@@ -217,8 +330,8 @@
   }
 
   // Nullability of return type.
-  if (Info.NullabilityAudited) {
-    applyNullability(S, D, Info.getReturnTypeInfo());
+  if (info.NullabilityAudited) {
+    applyNullability(S, D, info.getReturnTypeInfo(), role);
   }
 
   // Parameters.
@@ -236,48 +349,57 @@
       Param = MD->param_begin()[I];
     
     // Nullability.
-    if (Info.NullabilityAudited)
-      applyNullability(S, Param, Info.getParamTypeInfo(I));
+    if (info.NullabilityAudited)
+      applyNullability(S, Param, info.getParamTypeInfo(I), role);
 
-    if (I < Info.Params.size()) {
-      ProcessAPINotes(S, Param, Info.Params[I]);
+    if (I < info.Params.size()) {
+      ProcessAPINotes(S, Param, info.Params[I], role);
     }
   }
 
   // Handle common entity information.
-  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  role);
 }
 
 /// Process API notes for a global function.
 static void ProcessAPINotes(Sema &S, FunctionDecl *D,
-                            const api_notes::GlobalFunctionInfo &Info) {
+                            const api_notes::GlobalFunctionInfo &info,
+                            VersionedInfoRole role) {
 
   // Handle common function information.
   ProcessAPINotes(S, FunctionOrMethod(D),
-                  static_cast<const api_notes::FunctionInfo &>(Info));
+                  static_cast<const api_notes::FunctionInfo &>(info), role);
 }
 
 /// Process API notes for an enumerator.
 static void ProcessAPINotes(Sema &S, EnumConstantDecl *D,
-                            const api_notes::EnumConstantInfo &Info) {
+                            const api_notes::EnumConstantInfo &info,
+                            VersionedInfoRole role) {
 
   // Handle common information.
   ProcessAPINotes(S, D,
-                  static_cast<const api_notes::CommonEntityInfo &>(Info));
+                  static_cast<const api_notes::CommonEntityInfo &>(info),
+                  role);
 }
 
 /// Process API notes for an Objective-C method.
 static void ProcessAPINotes(Sema &S, ObjCMethodDecl *D,
-                            const api_notes::ObjCMethodInfo &Info) {
+                            const api_notes::ObjCMethodInfo &info,
+                            VersionedInfoRole role) {
   // Designated initializers.
-  if (Info.DesignatedInit && !D->getAttr<ObjCDesignatedInitializerAttr>()) {
-    if (ObjCInterfaceDecl *IFace = D->getClassInterface()) {
-      D->addAttr(ObjCDesignatedInitializerAttr::CreateImplicit(S.Context));
-      IFace->setHasDesignatedInitializers();
-    }
+  if (info.DesignatedInit) {
+    handleAPINotedAttribute<ObjCDesignatedInitializerAttr>(S, D, true, role, [&] {
+      if (ObjCInterfaceDecl *IFace = D->getClassInterface()) {
+        IFace->setHasDesignatedInitializers();
+      }
+      return ObjCDesignatedInitializerAttr::CreateImplicit(S.Context);
+    });
   }
 
-  if (Info.getFactoryAsInitKind()
+  // FIXME: This doesn't work well with versioned API notes.
+  if (role == VersionedInfoRole::AugmentSource &&
+      info.getFactoryAsInitKind()
         == api_notes::FactoryAsInitKind::AsClassMethod &&
       !D->getAttr<SwiftNameAttr>()) {
     D->addAttr(SwiftSuppressFactoryAsInitAttr::CreateImplicit(S.Context));
@@ -285,36 +407,43 @@
 
   // Handle common function information.
   ProcessAPINotes(S, FunctionOrMethod(D),
-                  static_cast<const api_notes::FunctionInfo &>(Info));
+                  static_cast<const api_notes::FunctionInfo &>(info), role);
 }
 
 /// Process API notes for a tag.
 static void ProcessAPINotes(Sema &S, TagDecl *D,
-                            const api_notes::TagInfo &Info) {
+                            const api_notes::TagInfo &info,
+                            VersionedInfoRole role) {
   // Handle common type information.
-  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  role);
 }
 
 /// Process API notes for a typedef.
 static void ProcessAPINotes(Sema &S, TypedefNameDecl *D,
-                            const api_notes::TypedefInfo &Info) {
+                            const api_notes::TypedefInfo &info,
+                            VersionedInfoRole role) {
   // Handle common type information.
-  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  role);
 }
 
 /// Process API notes for an Objective-C class or protocol.
 static void ProcessAPINotes(Sema &S, ObjCContainerDecl *D,
-                            const api_notes::ObjCContextInfo &Info) {
+                            const api_notes::ObjCContextInfo &info,
+                            VersionedInfoRole role) {
 
   // Handle common type information.
-  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(Info));
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  role);
 }
 
 /// Process API notes for an Objective-C class.
 static void ProcessAPINotes(Sema &S, ObjCInterfaceDecl *D,
-                            const api_notes::ObjCContextInfo &Info) {
+                            const api_notes::ObjCContextInfo &info,
+                            VersionedInfoRole role) {
   // Handle information common to Objective-C classes and protocols.
-  ProcessAPINotes(S, static_cast<clang::ObjCContainerDecl *>(D), Info);
+  ProcessAPINotes(S, static_cast<clang::ObjCContainerDecl *>(D), info, role);
 }
 
 /// Process API notes that are associated with this declaration, mapping them
@@ -329,7 +458,7 @@
     if (auto VD = dyn_cast<VarDecl>(D)) {
       for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
         if (auto Info = Reader->lookupGlobalVariable(VD->getName())) {
-          ::ProcessAPINotes(*this, VD, *Info);
+          ::ProcessAPINotes(*this, VD, *Info, Info.getSelectedRole());
         }
       }
 
@@ -341,7 +470,7 @@
       if (FD->getDeclName().isIdentifier()) {
         for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
           if (auto Info = Reader->lookupGlobalFunction(FD->getName())) {
-            ::ProcessAPINotes(*this, FD, *Info);
+            ::ProcessAPINotes(*this, FD, *Info, Info.getSelectedRole());
           }
         }
       }
@@ -353,7 +482,7 @@
     if (auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
       for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
         if (auto Info = Reader->lookupObjCClassInfo(Class->getName())) {
-          ::ProcessAPINotes(*this, Class, *Info);
+          ::ProcessAPINotes(*this, Class, *Info, Info.getSelectedRole());
         }
       }
 
@@ -364,7 +493,7 @@
     if (auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
       for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
         if (auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName())) {
-          ::ProcessAPINotes(*this, Protocol, *Info);
+          ::ProcessAPINotes(*this, Protocol, *Info, Info.getSelectedRole());
         }
       }
 
@@ -375,7 +504,7 @@
     if (auto Tag = dyn_cast<TagDecl>(D)) {
       for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
         if (auto Info = Reader->lookupTag(Tag->getName())) {
-          ::ProcessAPINotes(*this, Tag, *Info);
+          ::ProcessAPINotes(*this, Tag, *Info, Info.getSelectedRole());
         }
       }
 
@@ -386,7 +515,7 @@
     if (auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
       for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
         if (auto Info = Reader->lookupTypedef(Typedef->getName())) {
-          ::ProcessAPINotes(*this, Typedef, *Info);
+          ::ProcessAPINotes(*this, Typedef, *Info, Info.getSelectedRole());
         }
       }
 
@@ -401,7 +530,7 @@
     if (auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
       for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
         if (auto Info = Reader->lookupEnumConstant(EnumConstant->getName())) {
-          ::ProcessAPINotes(*this, EnumConstant, *Info);
+          ::ProcessAPINotes(*this, EnumConstant, *Info, Info.getSelectedRole());
         }
       }
 
@@ -472,7 +601,7 @@
 
           if (auto Info = Reader->lookupObjCMethod(*Context, SelectorRef,
                                                    Method->isInstanceMethod())){
-            ::ProcessAPINotes(*this, Method, *Info);
+            ::ProcessAPINotes(*this, Method, *Info, Info.getSelectedRole());
           }
         }
       }
@@ -488,7 +617,7 @@
           if (auto Info = Reader->lookupObjCProperty(*Context,
                                                      Property->getName(),
                                                      isInstanceProperty)) {
-            ::ProcessAPINotes(*this, Property, *Info);
+            ::ProcessAPINotes(*this, Property, *Info, Info.getSelectedRole());
           }
         }
       }
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index edfea14..e170b7e 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -5797,11 +5797,31 @@
   return false;
 }
 
+/// Rebuild an attributed type without the nullability attribute on it.
+static QualType rebuildAttributedTypeWithoutNullability(ASTContext &ctx,
+                                                        QualType type) {
+  auto attributed = dyn_cast<AttributedType>(type.getTypePtr());
+  if (!attributed) return type;
+
+  // Skip the nullability attribute; we're done.
+  if (attributed->getImmediateNullability()) {
+    return attributed->getModifiedType();
+  }
+
+  // Build the modified type.
+  auto modified = rebuildAttributedTypeWithoutNullability(
+                    ctx, attributed->getModifiedType());
+  assert(modified.getTypePtr() != attributed->getModifiedType().getTypePtr());
+  return ctx.getAttributedType(attributed->getAttrKind(), modified,
+                                   attributed->getEquivalentType());
+}
+
 bool Sema::checkNullabilityTypeSpecifier(QualType &type,
                                          NullabilityKind nullability,
                                          SourceLocation nullabilityLoc,
                                          bool isContextSensitive,
-                                         bool implicit) {
+                                         bool implicit,
+                                         bool overrideExisting) {
   if (!implicit) {
     // We saw a nullability type specifier. If this is the first one for
     // this file, note that.
@@ -5838,11 +5858,16 @@
         break;
       } 
 
-      // Conflicting nullability.
-      Diag(nullabilityLoc, diag::err_nullability_conflicting)
-        << DiagNullabilityKind(nullability, isContextSensitive)
-        << DiagNullabilityKind(*existingNullability, false);
-      return true;
+      if (!overrideExisting) {
+        // Conflicting nullability.
+        Diag(nullabilityLoc, diag::err_nullability_conflicting)
+          << DiagNullabilityKind(nullability, isContextSensitive)
+          << DiagNullabilityKind(*existingNullability, false);
+        return true;
+      }
+
+      // Rebuild the attributed type, dropping the existing nullability.
+      type  = rebuildAttributedTypeWithoutNullability(Context, type);
     }
 
     desugared = attributed->getModifiedType();
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes
index 9c855c6..aa43d84 100644
--- a/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes
@@ -40,3 +40,10 @@
             MethodKind:      Instance
             NullabilityOfRet: O
             Nullability:      [ O, S ]
+        Properties:
+          - Name: explicitNonnullInstance
+            PropertyKind:    Instance
+            Nullability:     O
+          - Name: explicitNullableInstance
+            PropertyKind:    Instance
+            Nullability:     N
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
index 9c855c6..aa43d84 100644
--- a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
@@ -40,3 +40,10 @@
             MethodKind:      Instance
             NullabilityOfRet: O
             Nullability:      [ O, S ]
+        Properties:
+          - Name: explicitNonnullInstance
+            PropertyKind:    Instance
+            Nullability:     O
+          - Name: explicitNullableInstance
+            PropertyKind:    Instance
+            Nullability:     N
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
index eb25cc0..60d9afa 100644
--- a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
@@ -35,4 +35,6 @@
 @property (class, nonatomic, readwrite, retain) A *nonnullABoth;
 @end
 
+#import <SomeKit/SomeKitExplicitNullability.h>
+
 #endif
diff --git a/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes
new file mode 100644
index 0000000..1fc6aa4
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes
@@ -0,0 +1,18 @@
+Name: SomeKit
+SwiftVersions:
+  - Version: 3.0
+    Classes:
+      - Name: MyReferenceType
+        SwiftBridge: ''
+    Functions:
+      - Name: moveToPoint
+        SwiftName: 'moveTo(a:b:)'
+      - Name: acceptClosure
+        Parameters:      
+          - Position:        0
+            NoEscape:        false
+    Tags:
+      - Name: MyErrorCode
+        NSErrorDomain: ''
+
+  
\ No newline at end of file
diff --git a/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h
new file mode 100644
index 0000000..741bdaa
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h
@@ -0,0 +1,15 @@
+void moveToPoint(double x, double y) __attribute__((swift_name("moveTo(x:y:)")));
+
+void acceptClosure(void (^ __attribute__((noescape)) block)(void));
+
+@class NSString;
+
+extern NSString *MyErrorDomain;
+
+enum __attribute__((ns_error_domain(MyErrorDomain))) MyErrorCode {
+  MyErrorCodeFailed = 1
+};
+
+__attribute__((swift_bridge("MyValueType")))
+@interface MyReferenceType
+@end
diff --git a/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Modules/module.modulemap b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..6d957fd
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module VersionedKit {
+  umbrella header "VersionedKit.h"
+  export *
+  module * { export * }
+}
diff --git a/test/APINotes/Inputs/roundtrip.apinotes b/test/APINotes/Inputs/roundtrip.apinotes
index 13e08a1..7e2e68a 100644
--- a/test/APINotes/Inputs/roundtrip.apinotes
+++ b/test/APINotes/Inputs/roundtrip.apinotes
@@ -9,8 +9,6 @@
     AvailabilityMsg: ''
     SwiftPrivate:    false
     SwiftName:       ''
-    SwiftBridge:     ''
-    NSErrorDomain:   ''
     Methods:         
       - Selector:        'cellWithImage:'
         MethodKind:      Class
@@ -62,7 +60,6 @@
     SwiftPrivate:    false
     SwiftName:       ''
     SwiftBridge:     View
-    NSErrorDomain:   ''
     Methods:         
       - Selector:        'addSubview:'
         MethodKind:      Instance
@@ -78,7 +75,6 @@
           - Position:        0
             NoEscape:        false
           - Position:        1
-            NoEscape:        false
           - Position:        2
             NoEscape:        true
         Nullability:     [ N, N, O ]
@@ -136,14 +132,12 @@
     AvailabilityMsg: ''
     SwiftPrivate:    false
     SwiftName:       SomeEnum
-    SwiftBridge:     ''
     NSErrorDomain:   some_error_domain
   - Name:            NSSomeStruct
     Availability:    available
     AvailabilityMsg: ''
     SwiftPrivate:    false
     SwiftName:       SomeStruct
-    SwiftBridge:     ''
     NSErrorDomain:   ''
 Typedefs:        
   - Name:            NSTypedef
@@ -152,7 +146,6 @@
     SwiftPrivate:    false
     SwiftName:       Typedef
     SwiftBridge:     ''
-    NSErrorDomain:   ''
 SwiftVersions:   
   - Version:         3.0
     Classes:         
@@ -162,7 +155,6 @@
         SwiftPrivate:    false
         SwiftName:       NSBox
         SwiftBridge:     ''
-        NSErrorDomain:   ''
         Methods:         
           - Selector:        init
             MethodKind:      Instance
diff --git a/test/APINotes/nullability.m b/test/APINotes/nullability.m
index c11cea5..f70c363 100644
--- a/test/APINotes/nullability.m
+++ b/test/APINotes/nullability.m
@@ -3,7 +3,7 @@
 
 // Test with Swift version 3.0. This should only affect the few APIs that have an entry in the 3.0 tables.
 
-// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fapinotes-swift-version=3.0 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify -DSWIFT_VERSION_3_0
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fapinotes-swift-version=3.0 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify -DSWIFT_VERSION_3_0 -fmodules-ignore-macro=SWIFT_VERSION_3_0
 
 #import <SomeKit/SomeKit.h>
 
@@ -29,6 +29,16 @@
 
   [a setInternalProperty: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
 
+#if SWIFT_VERSION_3_0
+  // Version 3 information overrides header information.
+  [a setExplicitNonnullInstance: 0]; //  okay
+  [a setExplicitNullableInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+#else
+  // Header information overrides unversioned information.
+  [a setExplicitNonnullInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+  [a setExplicitNullableInstance: 0]; // okay
+#endif
+
   return 0;
 }
 
diff --git a/test/APINotes/versioned.m b/test/APINotes/versioned.m
new file mode 100644
index 0000000..53af333
--- /dev/null
+++ b/test/APINotes/versioned.m
@@ -0,0 +1,31 @@
+// RUN: rm -rf %t && mkdir -p %t
+
+// Build and check the unversioned module file.
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Unversioned -fdisable-module-hash -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/Unversioned/VersionedKit.pcm | FileCheck -check-prefix=CHECK-UNVERSIONED %s
+
+// Build and check the versioned module file.
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned -fdisable-module-hash -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fapinotes-swift-version=3.0 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/Versioned/VersionedKit.pcm | FileCheck -check-prefix=CHECK-VERSIONED %s
+
+#import <VersionedKit/VersionedKit.h>
+
+// CHECK-UNVERSIONED: void moveToPoint(double x, double y) __attribute__((swift_name("moveTo(x:y:)")));
+// CHECK-VERSIONED: void moveToPoint(double x, double y) __attribute__((swift_name("moveTo(a:b:)")));
+
+// CHECK-UNVERSIONED: void acceptClosure(void (^block)(void) __attribute__((noescape)));
+// CHECK-VERSIONED: void acceptClosure(void (^block)(void));
+
+// CHECK-UNVERSIONED:      enum MyErrorCode {
+// CHECK-UNVERSIONED-NEXT:     MyErrorCodeFailed = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((ns_error_domain(MyErrorDomain)));
+
+// CHECK-UNVERSIONED: __attribute__((swift_bridge("MyValueType")))
+// CHECK-UNVERSIONED: @interface MyReferenceType
+
+// CHECK-VERSIONED:      enum MyErrorCode {
+// CHECK-VERSIONED-NEXT:     MyErrorCodeFailed = 1
+// CHECK-VERSIONED-NEXT: };
+
+// CHECK-VERSIONED-NOT: __attribute__((swift_bridge("MyValueType")))
+// CHECK-VERSIONED: @interface MyReferenceType
diff --git a/test/Modules/Inputs/objc-method-redecl.h b/test/Modules/Inputs/objc-method-redecl.h
new file mode 100644
index 0000000..95c6533
--- /dev/null
+++ b/test/Modules/Inputs/objc-method-redecl.h
@@ -0,0 +1,4 @@
+@interface T
+- (void)test;
+- (void)test;
+@end
diff --git a/test/Modules/objc-method-redecl.m b/test/Modules/objc-method-redecl.m
new file mode 100644
index 0000000..f7acda5
--- /dev/null
+++ b/test/Modules/objc-method-redecl.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c-header -emit-pch %S/Inputs/objc-method-redecl.h -o %t.pch -Wno-objc-root-class
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -x objective-c -include-pch %t.pch %s -verify -Wno-objc-root-class
+// expected-no-diagnostics
+
+@implementation T
+- (void)test {
+}
+@end
diff --git a/test/SemaCXX/cxx11-ast-print.cpp b/test/SemaCXX/cxx11-ast-print.cpp
index 1eeb67a..9c617af 100644
--- a/test/SemaCXX/cxx11-ast-print.cpp
+++ b/test/SemaCXX/cxx11-ast-print.cpp
@@ -43,6 +43,14 @@
 // CHECK: const char *PR23120 = operator""_suffix<char32_t, 66615>();
 const char *PR23120 = U"𐐷"_suffix;
 
+// PR28885
+struct A {
+  A();
+};
+struct B : A {
+  using A::A; // CHECK:      using A::A;
+};            // CHECK-NEXT: };
+
 // CHECK: ;
 ;
 // CHECK-NOT: ;