Propagating prior merge from 'llvm.org/release_40'.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..a0c1644
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,14 @@
+By submitting a pull request, you represent that you have the right to license
+your contribution to Apple and the community, and agree by submitting the patch
+that your contributions are licensed under the [Swift
+license](https://swift.org/LICENSE.txt).
+
+---
+
+Changes to this repository follow special considerations as described on
+Swift.org under "[LLVM and Swift](https://swift.org/contributing/#llvm-and-swift)".
+Please make sure your change is appropriate for this repository.
+
+Before submitting a pull request, please make sure you have tested your
+changes and that they follow the Swift project [guidelines for contributing
+code](https://swift.org/contributing/#contributing-code).
diff --git a/include/clang/APINotes/APINotesManager.h b/include/clang/APINotes/APINotesManager.h
new file mode 100644
index 0000000..2adc29c
--- /dev/null
+++ b/include/clang/APINotes/APINotesManager.h
@@ -0,0 +1,147 @@
+//===--- APINotesManager.h - Manage API Notes Files -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the APINotesManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_APINOTES_APINOTESMANAGER_H
+#define LLVM_CLANG_APINOTES_APINOTESMANAGER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+#include <string>
+
+namespace clang {
+
+class DirectoryEntry;
+class FileEntry;
+class LangOptions;
+class SourceManager;
+
+namespace api_notes {
+
+class APINotesReader;
+
+/// The API notes manager helps find API notes associated with declarations.
+///
+/// API notes are externally-provided annotations for declarations that can
+/// introduce new attributes (covering availability, nullability of
+/// parameters/results, and so on) for specific declarations without directly
+/// modifying the headers that contain those declarations.
+///
+/// The API notes manager is responsible for finding and loading the
+/// external API notes files that correspond to a given header. Its primary
+/// operation is \c findAPINotes(), which finds the API notes reader that
+/// provides information about the declarations at that location.
+class APINotesManager {
+  typedef llvm::PointerUnion<const DirectoryEntry *, APINotesReader *>
+    ReaderEntry;
+
+  SourceManager &SourceMgr;
+
+  /// Whether to implicitly search for API notes files based on the
+  /// source file from which an entity was declared.
+  bool ImplicitAPINotes;
+
+  /// The Swift version to use when interpreting versioned API notes.
+  VersionTuple SwiftVersion;
+
+  /// API notes readers for the current module.
+  ///
+  /// There can be up to two of these, one for public headers and one
+  /// for private headers.
+  APINotesReader *CurrentModuleReaders[2] = { nullptr, nullptr };
+
+  /// Whether we have already pruned the API notes cache.
+  bool PrunedCache;
+
+  /// A mapping from header file directories to the API notes reader for
+  /// that directory, or a redirection to another directory entry that may
+  /// have more information, or NULL to indicate that there is no API notes
+  /// reader for this directory.
+  llvm::DenseMap<const DirectoryEntry *, ReaderEntry> Readers;
+
+  /// Load the API notes associated with the given file, whether it is
+  /// the binary or source form of API notes.
+  ///
+  /// \returns the API notes reader for this file, or null if there is
+  /// a failure.
+  std::unique_ptr<APINotesReader> loadAPINotes(const FileEntry *apiNotesFile);
+
+  /// Load the given API notes file for the given header directory.
+  ///
+  /// \param HeaderDir The directory at which we
+  ///
+  /// \returns true if an error occurred.
+  bool loadAPINotes(const DirectoryEntry *HeaderDir,
+                    const FileEntry *APINotesFile);
+
+  /// Look for API notes in the given directory.
+  ///
+  /// This might find either a binary or source API notes.
+  const FileEntry *findAPINotesFile(const DirectoryEntry *directory,
+                                    StringRef filename,
+                                    bool wantPublic = true);
+
+  /// Attempt to load API notes for the given framework.
+  ///
+  /// \param FrameworkPath The path to the framework.
+  /// \param Public Whether to load the public API notes. Otherwise, attempt
+  /// to load the private API notes.
+  ///
+  /// \returns the header directory entry (e.g., for Headers or PrivateHeaders)
+  /// for which the API notes were successfully loaded, or NULL if API notes
+  /// could not be loaded for any reason.
+  const DirectoryEntry *loadFrameworkAPINotes(llvm::StringRef FrameworkPath,
+                                              llvm::StringRef FrameworkName,
+                                              bool Public);
+
+public:
+  APINotesManager(SourceManager &sourceMgr, const LangOptions &langOpts);
+  ~APINotesManager();
+
+  /// Set the Swift version to use when filtering API notes.
+  void setSwiftVersion(VersionTuple swiftVersion) {
+    SwiftVersion = swiftVersion;
+  }
+
+  /// Load the API notes for the current module.
+  ///
+  /// \param module The current module.
+  /// \param lookInModule Whether to look inside the module itself.
+  /// \param searchPaths The paths in which we should search for API notes
+  /// for the current module.
+  ///
+  /// \returns true if API notes were successfully loaded, \c false otherwise.
+  bool loadCurrentModuleAPINotes(const Module *module,
+                                 bool lookInModule,
+                                 ArrayRef<std::string> searchPaths);
+
+  /// Retrieve the set of API notes readers for the current module.
+  ArrayRef<APINotesReader *> getCurrentModuleReaders() const {
+    unsigned numReaders = static_cast<unsigned>(CurrentModuleReaders[0] != nullptr) +
+      static_cast<unsigned>(CurrentModuleReaders[1] != nullptr);
+    return llvm::makeArrayRef(CurrentModuleReaders).slice(0, numReaders);
+  }
+
+  /// Find the API notes readers that correspond to the given source location.
+  llvm::SmallVector<APINotesReader *, 2> findAPINotes(SourceLocation Loc);
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif
diff --git a/include/clang/APINotes/APINotesOptions.h b/include/clang/APINotes/APINotesOptions.h
new file mode 100644
index 0000000..24bb913
--- /dev/null
+++ b/include/clang/APINotes/APINotesOptions.h
@@ -0,0 +1,41 @@
+//===--- APINotesOptions.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the APINotesOptions class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_APINOTES_APINOTESOPTIONS_H
+#define LLVM_CLANG_APINOTES_APINOTESOPTIONS_H
+
+#include "clang/Basic/VersionTuple.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// APINotesOptions - Track various options which control how API
+/// notes are found and handled.
+class APINotesOptions {
+public:
+  /// The Swift version which should be used for API notes.
+  VersionTuple SwiftVersion;
+
+  /// The set of search paths where we API notes can be found for
+  /// particular modules.
+  ///
+  /// The API notes in this directory are stored as
+  /// <ModuleName>.apinotes or <ModuleName>.apinotesc, and are only
+  /// applied when building the module <ModuleName>.
+  std::vector<std::string> ModuleSearchPaths;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/APINotes/APINotesReader.h b/include/clang/APINotes/APINotesReader.h
new file mode 100644
index 0000000..2b985c6
--- /dev/null
+++ b/include/clang/APINotes/APINotesReader.h
@@ -0,0 +1,291 @@
+//===--- APINotesReader.h - API Notes Reader ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the \c APINotesReader class that reads source
+// API notes data providing additional information about source code as
+// a separate input, such as the non-nil/nilable annotations for
+// method parameters.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_API_NOTES_READER_H
+#define LLVM_CLANG_API_NOTES_READER_H
+
+#include "clang/APINotes/Types.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+
+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 {
+  class Implementation;
+
+  Implementation &Impl;
+
+  APINotesReader(llvm::MemoryBuffer *inputBuffer, bool ownsInputBuffer,
+                 VersionTuple swiftVersion, bool &failed);
+
+public:
+  /// Create a new API notes reader from the given member buffer, which
+  /// contains the contents of a binary API notes file.
+  ///
+  /// \returns the new API notes reader, or null if an error occurred.
+  static std::unique_ptr<APINotesReader>
+  get(std::unique_ptr<llvm::MemoryBuffer> inputBuffer,
+      VersionTuple swiftVersion);
+
+  /// Create a new API notes reader from the given member buffer, which
+  /// contains the contents of a binary API notes file.
+  ///
+  /// \returns the new API notes reader, or null if an error occurred.
+  static std::unique_ptr<APINotesReader>
+  getUnmanaged(llvm::MemoryBuffer *inputBuffer,
+               VersionTuple swiftVersion);
+
+  ~APINotesReader();
+
+  APINotesReader(const APINotesReader &) = delete;
+  APINotesReader &operator=(const APINotesReader &) = delete;
+
+  /// Retrieve the name of the module for which this reader is providing API
+  /// notes.
+  StringRef getModuleName() const;
+
+  /// Retrieve the size and modification time of the source file from
+  /// which this API notes file was created, if known.
+  Optional<std::pair<off_t, time_t>> getSourceFileSizeAndModTime() const;
+
+  /// Retrieve the module options
+  ModuleOptions getModuleOptions() const;
+
+  /// Captures the completed versioned information for a particular part of
+  /// API notes, including both unversioned API notes and each versioned API
+  /// note for that particular entity.
+  template<typename T>
+  class VersionedInfo {
+    /// The complete set of results.
+    SmallVector<std::pair<VersionTuple, T>, 1> Results;
+
+    /// The index of the result that is the "selected" set based on the desired
+    /// 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) { }
+    
+    /// Form a versioned info set given the desired version and a set of
+    /// results.
+    VersionedInfo(VersionTuple version,
+                  SmallVector<std::pair<VersionTuple, T>, 1> results);
+
+    /// Determine whether there is a result that should be applied directly
+    /// to the AST.
+    explicit operator bool() const { return Selected != size(); }
+
+    /// Retrieve the information to apply directly to the AST.
+    const T& operator*() const {
+      assert(*this && "No result to apply directly");
+      return (*this)[Selected].second;
+    }
+
+    /// Retrieve the selected index in the result set.
+    Optional<unsigned> getSelected() const {
+      if (Selected == Results.size()) return None;
+      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(); }
+
+    /// Access all versioned results.
+    const std::pair<VersionTuple, T> *begin() const { return Results.begin(); }
+    const std::pair<VersionTuple, T> *end() const { return Results.end(); }
+
+    /// Access a specific versioned result.
+    const std::pair<VersionTuple, T> &operator[](unsigned index) const {
+      return Results[index];
+    }
+  };
+
+  /// Look for the context ID of the given Objective-C class.
+  ///
+  /// \param name The name of the class we're looking for.
+  ///
+  /// \returns The ID, if known.
+  Optional<ContextID> lookupObjCClassID(StringRef name);
+
+  /// Look for information regarding the given Objective-C class.
+  ///
+  /// \param name The name of the class we're looking for.
+  ///
+  /// \returns The information about the class, if known.
+  VersionedInfo<ObjCContextInfo> lookupObjCClassInfo(StringRef name);
+
+  /// Look for the context ID of the given Objective-C protocol.
+  ///
+  /// \param name The name of the protocol we're looking for.
+  ///
+  /// \returns The ID of the protocol, if known.
+  Optional<ContextID> lookupObjCProtocolID(StringRef name);
+
+  /// Look for information regarding the given Objective-C protocol.
+  ///
+  /// \param name The name of the protocol we're looking for.
+  ///
+  /// \returns The information about the protocol, if known.
+  VersionedInfo<ObjCContextInfo> lookupObjCProtocolInfo(StringRef name);
+
+  /// Look for information regarding the given Objective-C property in
+  /// the given context.
+  ///
+  /// \param contextID The ID that references the context we are looking for.
+  /// \param name The name of the property we're looking for.
+  /// \param isInstance Whether we are looking for an instance property (vs.
+  /// a class property).
+  ///
+  /// \returns Information about the property, if known.
+  VersionedInfo<ObjCPropertyInfo> lookupObjCProperty(ContextID contextID,
+                                                     StringRef name,
+                                                     bool isInstance);
+
+  /// Look for information regarding the given Objective-C method in
+  /// the given context.
+  ///
+  /// \param contextID The ID that references the context we are looking for.
+  /// \param selector The selector naming the method we're looking for.
+  /// \param isInstanceMethod Whether we are looking for an instance method.
+  ///
+  /// \returns Information about the method, if known.
+  VersionedInfo<ObjCMethodInfo> lookupObjCMethod(ContextID contextID,
+                                                 ObjCSelectorRef selector,
+                                                 bool isInstanceMethod);
+
+  /// Look for information regarding the given global variable.
+  ///
+  /// \param name The name of the global variable.
+  ///
+  /// \returns information about the global variable, if known.
+  VersionedInfo<GlobalVariableInfo> lookupGlobalVariable(StringRef name);
+
+  /// Look for information regarding the given global function.
+  ///
+  /// \param name The name of the global function.
+  ///
+  /// \returns information about the global function, if known.
+  VersionedInfo<GlobalFunctionInfo> lookupGlobalFunction(StringRef name);
+
+  /// Look for information regarding the given enumerator.
+  ///
+  /// \param name The name of the enumerator.
+  ///
+  /// \returns information about the enumerator, if known.
+  VersionedInfo<EnumConstantInfo> lookupEnumConstant(StringRef name);
+
+  /// Look for information regarding the given tag
+  /// (struct/union/enum/C++ class).
+  ///
+  /// \param name The name of the tag.
+  ///
+  /// \returns information about the tag, if known.
+  VersionedInfo<TagInfo> lookupTag(StringRef name);
+
+  /// Look for information regarding the given typedef.
+  ///
+  /// \param name The name of the typedef.
+  ///
+  /// \returns information about the typedef, if known.
+  VersionedInfo<TypedefInfo> lookupTypedef(StringRef name);
+
+  /// Visitor used when walking the contents of the API notes file.
+  class Visitor {
+  public:
+    virtual ~Visitor();
+
+    /// Visit an Objective-C class.
+    virtual void visitObjCClass(ContextID contextID, StringRef name,
+                                const ObjCContextInfo &info,
+                                VersionTuple swiftVersion);
+
+    /// Visit an Objective-C protocol.
+    virtual void visitObjCProtocol(ContextID contextID, StringRef name,
+                                   const ObjCContextInfo &info,
+                                   VersionTuple swiftVersion);
+
+    /// Visit an Objective-C method.
+    virtual void visitObjCMethod(ContextID contextID, StringRef selector,
+                                 bool isInstanceMethod,
+                                 const ObjCMethodInfo &info,
+                                 VersionTuple swiftVersion);
+
+    /// Visit an Objective-C property.
+    virtual void visitObjCProperty(ContextID contextID, StringRef name,
+                                   bool isInstance,
+                                   const ObjCPropertyInfo &info,
+                                   VersionTuple swiftVersion);
+
+    /// Visit a global variable.
+    virtual void visitGlobalVariable(StringRef name,
+                                     const GlobalVariableInfo &info,
+                                     VersionTuple swiftVersion);
+
+    /// Visit a global function.
+    virtual void visitGlobalFunction(StringRef name,
+                                     const GlobalFunctionInfo &info,
+                                     VersionTuple swiftVersion);
+
+    /// Visit an enumerator.
+    virtual void visitEnumConstant(StringRef name,
+                                   const EnumConstantInfo &info,
+                                   VersionTuple swiftVersion);
+
+    /// Visit a tag.
+    virtual void visitTag(StringRef name, const TagInfo &info,
+                          VersionTuple swiftVersion);
+
+    /// Visit a typedef.
+    virtual void visitTypedef(StringRef name, const TypedefInfo &info,
+                              VersionTuple swiftVersion);
+  };
+
+  /// Visit the contents of the API notes file, passing each entity to the
+  /// given visitor.
+  void visit(Visitor &visitor);
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_API_NOTES_READER_H
diff --git a/include/clang/APINotes/APINotesWriter.h b/include/clang/APINotes/APINotesWriter.h
new file mode 100644
index 0000000..62defc1
--- /dev/null
+++ b/include/clang/APINotes/APINotesWriter.h
@@ -0,0 +1,126 @@
+//===--- APINotesWriter.h - API Notes Writer ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the \c APINotesWriter class that writes out source
+// API notes data providing additional information about source code as
+// a separate input, such as the non-nil/nilable annotations for
+// method parameters.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_API_NOTES_WRITER_H
+#define LLVM_CLANG_API_NOTES_WRITER_H
+
+#include "clang/Basic/VersionTuple.h"
+#include "clang/APINotes/Types.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+
+class FileEntry;
+
+namespace api_notes {
+
+/// A class that writes API notes data to a binary representation that can be
+/// read by the \c APINotesReader.
+class APINotesWriter {
+  class Implementation;
+  Implementation &Impl;
+
+public:
+  /// Create a new API notes writer with the given module name and
+  /// (optional) source file.
+  APINotesWriter(StringRef moduleName, const FileEntry *sourceFile);
+  ~APINotesWriter();
+
+  APINotesWriter(const APINotesWriter &) = delete;
+  APINotesWriter &operator=(const APINotesWriter &) = delete;
+
+  /// Write the API notes data to the given stream.
+  void writeToStream(llvm::raw_ostream &os);
+
+  /// Add information about a specific Objective-C class or protocol.
+  ///
+  /// \param name The name of this class/protocol.
+  /// \param isClass Whether this is a class (vs. a protocol).
+  /// \param info Information about this class/protocol.
+  ///
+  /// \returns the ID of the class or protocol, which can be used to add
+  /// properties and methods to the class/protocol.
+  ContextID addObjCContext(StringRef name, bool isClass,
+                           const ObjCContextInfo &info,
+                           VersionTuple swiftVersion);
+
+  /// Add information about a specific Objective-C property.
+  ///
+  /// \param contextID The context in which this property resides.
+  /// \param name The name of this property.
+  /// \param info Information about this property.
+  void addObjCProperty(ContextID contextID, StringRef name,
+                       bool isInstanceProperty,
+                       const ObjCPropertyInfo &info,
+                       VersionTuple swiftVersion);
+
+  /// Add information about a specific Objective-C method.
+  ///
+  /// \param contextID The context in which this method resides.
+  /// \param selector The selector that names this method.
+  /// \param isInstanceMethod Whether this method is an instance method
+  /// (vs. a class method).
+  /// \param info Information about this method.
+  void addObjCMethod(ContextID contextID, ObjCSelectorRef selector,
+                     bool isInstanceMethod, const ObjCMethodInfo &info,
+                     VersionTuple swiftVersion);
+
+  /// Add information about a global variable.
+  ///
+  /// \param name The name of this global variable.
+  /// \param info Information about this global variable.
+  void addGlobalVariable(StringRef name, const GlobalVariableInfo &info,
+                         VersionTuple swiftVersion);
+
+  /// Add information about a global function.
+  ///
+  /// \param name The name of this global function.
+  /// \param info Information about this global function.
+  void addGlobalFunction(StringRef name, const GlobalFunctionInfo &info,
+                         VersionTuple swiftVersion);
+
+  /// Add information about an enumerator.
+  ///
+  /// \param name The name of this enumerator.
+  /// \param info Information about this enumerator.
+  void addEnumConstant(StringRef name, const EnumConstantInfo &info,
+                       VersionTuple swiftVersion);
+
+  /// Add information about a tag (struct/union/enum/C++ class).
+  ///
+  /// \param name The name of this tag.
+  /// \param info Information about this tag.
+  void addTag(StringRef name, const TagInfo &info,
+              VersionTuple swiftVersion);
+
+  /// Add information about a typedef.
+  ///
+  /// \param name The name of this typedef.
+  /// \param info Information about this typedef.
+  void addTypedef(StringRef name, const TypedefInfo &info,
+                  VersionTuple swiftVersion);
+
+  /// Add module options
+  void addModuleOptions(ModuleOptions opts);
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_API_NOTES_WRITER_H
+
diff --git a/include/clang/APINotes/APINotesYAMLCompiler.h b/include/clang/APINotes/APINotesYAMLCompiler.h
new file mode 100644
index 0000000..508da65
--- /dev/null
+++ b/include/clang/APINotes/APINotesYAMLCompiler.h
@@ -0,0 +1,62 @@
+//=== APINotesYAMLCompiler.h - API Notes YAML to binary compiler *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file reads sidecar API notes specified in YAML format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_API_NOTES_YAML_COMPILER_H
+#define LLVM_CLANG_API_NOTES_YAML_COMPILER_H
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SourceMgr.h"
+#include <memory>
+
+namespace llvm {
+  class raw_ostream;
+  class MemoryBuffer;
+}
+
+namespace clang {
+
+class FileEntry;
+
+namespace api_notes {
+
+  enum class ActionType {
+    None,
+    YAMLToBinary,
+    BinaryToYAML,
+    Dump,
+  };
+
+  enum class OSType {
+    OSX,
+    IOS,
+    TvOS,
+    WatchOS,
+    Absent
+  };
+
+  /// Converts API notes from YAML format to binary format.
+  bool compileAPINotes(llvm::StringRef yamlInput,
+                       const FileEntry *sourceFile,
+                       llvm::raw_ostream &os,
+                       OSType targetOS,
+                       llvm::SourceMgr::DiagHandlerTy diagHandler = nullptr,
+                       void *diagHandlerCtxt = nullptr);
+
+  bool parseAndDumpAPINotes(llvm::StringRef yamlInput);
+
+  /// Converts API notes from the compiled binary format to the YAML format.
+  bool decompileAPINotes(std::unique_ptr<llvm::MemoryBuffer> input,
+                         llvm::raw_ostream &os);
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_API_NOTES_YAML_COMPILER_H
diff --git a/include/clang/APINotes/Types.h b/include/clang/APINotes/Types.h
new file mode 100644
index 0000000..6fbd5d8
--- /dev/null
+++ b/include/clang/APINotes/Types.h
@@ -0,0 +1,658 @@
+//===--- Types.h - API Notes Data Types --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines data types used in the representation of API notes data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_API_NOTES_TYPES_H
+#define LLVM_CLANG_API_NOTES_TYPES_H
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <climits>
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+namespace api_notes {
+
+/// The file extension used for the source representation of API notes.
+static const char SOURCE_APINOTES_EXTENSION[] = "apinotes";
+
+/// The file extension used for the binary representation of API notes.
+static const char BINARY_APINOTES_EXTENSION[] = "apinotesc";
+
+using llvm::ArrayRef;
+using llvm::StringRef;
+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:
+  unsigned Value;
+
+  explicit ContextID(unsigned value) : Value(value) { }
+};
+
+/// Describes API notes data for any entity.
+///
+/// This is used as the base of all API notes.
+class CommonEntityInfo {
+public:
+  /// Message to use when this entity is unavailable.
+  std::string UnavailableMsg;
+
+  /// Whether this entity is marked unavailable.
+  unsigned Unavailable : 1;
+
+  /// Whether this entity is marked unavailable in Swift.
+  unsigned UnavailableInSwift : 1;
+
+private:
+  /// Whether SwiftPrivate was specified.
+  unsigned SwiftPrivateSpecified : 1;
+
+  /// Whether this entity is considered "private" to a Swift overlay.
+  unsigned SwiftPrivate : 1;
+
+public:
+  /// Swift name of this entity.
+  std::string SwiftName;
+
+  CommonEntityInfo()
+    : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
+      SwiftPrivate(0) { }
+
+  Optional<bool> isSwiftPrivate() const {
+    if (!SwiftPrivateSpecified) return None;
+    return SwiftPrivate;
+  }
+
+  void setSwiftPrivate(Optional<bool> swiftPrivate) {
+    if (swiftPrivate) {
+      SwiftPrivateSpecified = 1;
+      SwiftPrivate = *swiftPrivate;
+    } else {
+      SwiftPrivateSpecified = 0;
+      SwiftPrivate = 0;
+    }
+  }
+
+  friend bool operator==(const CommonEntityInfo &lhs,
+                         const CommonEntityInfo &rhs) {
+    return lhs.UnavailableMsg == rhs.UnavailableMsg &&
+           lhs.Unavailable == rhs.Unavailable &&
+           lhs.UnavailableInSwift == rhs.UnavailableInSwift &&
+           lhs.SwiftPrivateSpecified == rhs.SwiftPrivateSpecified &&
+           lhs.SwiftPrivate == rhs.SwiftPrivate &&
+           lhs.SwiftName == rhs.SwiftName;
+  }
+
+  friend bool operator!=(const CommonEntityInfo &lhs,
+                         const CommonEntityInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+  friend CommonEntityInfo &operator|=(CommonEntityInfo &lhs,
+                                      const CommonEntityInfo &rhs) {
+    // Merge unavailability.
+    if (rhs.Unavailable) {
+      lhs.Unavailable = true;
+      if (rhs.UnavailableMsg.length() != 0 &&
+          lhs.UnavailableMsg.length() == 0) {
+        lhs.UnavailableMsg = rhs.UnavailableMsg;
+      }
+    }
+
+    if (rhs.UnavailableInSwift) {
+      lhs.UnavailableInSwift = true;
+      if (rhs.UnavailableMsg.length() != 0 &&
+          lhs.UnavailableMsg.length() == 0) {
+        lhs.UnavailableMsg = rhs.UnavailableMsg;
+      }
+    }
+
+    if (rhs.SwiftPrivateSpecified && !lhs.SwiftPrivateSpecified) {
+      lhs.SwiftPrivateSpecified = 1;
+      lhs.SwiftPrivate = rhs.SwiftPrivate;
+    }
+
+    if (rhs.SwiftName.length() != 0 &&
+        lhs.SwiftName.length() == 0)
+      lhs.SwiftName = rhs.SwiftName;
+
+    return lhs;
+  }
+};
+
+/// Describes API notes for types.
+class CommonTypeInfo : public CommonEntityInfo {
+  /// The Swift type to which a given type is bridged.
+  ///
+  /// Reflects the swift_bridge attribute.
+  Optional<std::string> SwiftBridge;
+
+  /// The NS error domain for this type.
+  Optional<std::string> NSErrorDomain;
+
+public:
+  CommonTypeInfo() : CommonEntityInfo() { }
+
+  const Optional<std::string> &getSwiftBridge() const { return SwiftBridge; }
+
+  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 && rhs.SwiftBridge)
+      lhs.SwiftBridge = rhs.SwiftBridge;
+    if (!lhs.NSErrorDomain && rhs.NSErrorDomain)
+      lhs.NSErrorDomain = rhs.NSErrorDomain;
+    return lhs;
+  }
+
+  friend bool operator==(const CommonTypeInfo &lhs,
+                         const CommonTypeInfo &rhs) {
+    return static_cast<const CommonEntityInfo &>(lhs) == rhs &&
+      lhs.SwiftBridge == rhs.SwiftBridge &&
+      lhs.NSErrorDomain == rhs.NSErrorDomain;
+  }
+
+  friend bool operator!=(const CommonTypeInfo &lhs,
+                         const CommonTypeInfo &rhs) {
+    return !(lhs == rhs);
+  }
+};
+
+/// Describes API notes data for an Objective-C class or protocol.
+class ObjCContextInfo : public CommonTypeInfo {
+  /// Whether this class has a default nullability.
+  unsigned HasDefaultNullability : 1;
+
+  /// The default nullability.
+  unsigned DefaultNullability : 2;
+
+  /// Whether this class has designated initializers recorded.
+  unsigned HasDesignatedInits : 1;
+
+public:
+  ObjCContextInfo()
+    : CommonTypeInfo(),
+      HasDefaultNullability(0),
+      DefaultNullability(0),
+      HasDesignatedInits(0)
+  { }
+
+  /// Determine the default nullability for properties and methods of this
+  /// class.
+  ///
+  /// \returns the default nullability, if implied, or None if there is no
+  Optional<NullabilityKind> getDefaultNullability() const {
+    if (HasDefaultNullability)
+      return static_cast<NullabilityKind>(DefaultNullability);
+
+    return None;
+  }
+
+  /// Set the default nullability for properties and methods of this class.
+  void setDefaultNullability(NullabilityKind kind) {
+    HasDefaultNullability = true;
+    DefaultNullability = static_cast<unsigned>(kind);
+  }
+
+  bool hasDesignatedInits() const { return HasDesignatedInits; }
+  void setHasDesignatedInits(bool value) { HasDesignatedInits = value; }
+
+  /// Strip off any information within the class information structure that is
+  /// module-local, such as 'audited' flags.
+  void stripModuleLocalInfo() {
+    HasDefaultNullability = false;
+    DefaultNullability = 0;
+  }
+
+  friend bool operator==(const ObjCContextInfo &lhs, const ObjCContextInfo &rhs) {
+    return static_cast<const CommonTypeInfo &>(lhs) == rhs &&
+           lhs.HasDefaultNullability == rhs.HasDefaultNullability &&
+           lhs.DefaultNullability == rhs.DefaultNullability &&
+           lhs.HasDesignatedInits == rhs.HasDesignatedInits;
+  }
+
+  friend bool operator!=(const ObjCContextInfo &lhs, const ObjCContextInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+  friend ObjCContextInfo &operator|=(ObjCContextInfo &lhs,
+                                     const ObjCContextInfo &rhs) {
+    // Merge inherited info.
+    static_cast<CommonTypeInfo &>(lhs) |= rhs;
+
+    // Merge nullability.
+    if (!lhs.getDefaultNullability()) {
+      if (auto nullable = rhs.getDefaultNullability()) {
+        lhs.setDefaultNullability(*nullable);
+      }
+    }
+
+    lhs.HasDesignatedInits |= rhs.HasDesignatedInits;
+
+    return lhs;
+  }
+  
+  void dump(llvm::raw_ostream &os);
+};
+
+/// API notes for a variable/property.
+class VariableInfo : public CommonEntityInfo {
+  /// Whether this property has been audited for nullability.
+  unsigned NullabilityAudited : 1;
+
+  /// The kind of nullability for this property. Only valid if the nullability
+  /// has been audited.
+  unsigned Nullable : 2;
+
+  /// The C type of the variable, as a string.
+  std::string Type;
+
+public:
+  VariableInfo()
+    : CommonEntityInfo(),
+      NullabilityAudited(false),
+      Nullable(0) { }
+
+  Optional<NullabilityKind> getNullability() const {
+    if (NullabilityAudited)
+      return static_cast<NullabilityKind>(Nullable);
+
+    return None;
+  }
+
+  void setNullabilityAudited(NullabilityKind kind) {
+    NullabilityAudited = true;
+    Nullable = static_cast<unsigned>(kind);
+  }
+
+  const std::string &getType() const { return Type; }
+  void setType(const std::string &type) { Type = type; }
+
+  friend bool operator==(const VariableInfo &lhs, const VariableInfo &rhs) {
+    return static_cast<const CommonEntityInfo &>(lhs) == rhs &&
+           lhs.NullabilityAudited == rhs.NullabilityAudited &&
+           lhs.Nullable == rhs.Nullable &&
+           lhs.Type == rhs.Type;
+  }
+
+  friend bool operator!=(const VariableInfo &lhs, const VariableInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+  friend VariableInfo &operator|=(VariableInfo &lhs,
+                                  const VariableInfo &rhs) {
+    static_cast<CommonEntityInfo &>(lhs) |= rhs;
+    if (!lhs.NullabilityAudited && rhs.NullabilityAudited)
+      lhs.setNullabilityAudited(*rhs.getNullability());
+    if (lhs.Type.empty() && !rhs.Type.empty())
+      lhs.Type = rhs.Type;
+    return lhs;
+  }
+};
+
+/// Describes API notes data for an Objective-C property.
+class ObjCPropertyInfo : public VariableInfo {
+  unsigned SwiftImportAsAccessorsSpecified : 1;
+  unsigned SwiftImportAsAccessors : 1;
+
+public:
+  ObjCPropertyInfo()
+      : VariableInfo(), SwiftImportAsAccessorsSpecified(false),
+        SwiftImportAsAccessors(false) {}
+
+  /// Merge class-wide information into the given property.
+  friend ObjCPropertyInfo &operator|=(ObjCPropertyInfo &lhs,
+                                      const ObjCContextInfo &rhs) {
+    static_cast<VariableInfo &>(lhs) |= rhs;
+
+    // Merge nullability.
+    if (!lhs.getNullability()) {
+      if (auto nullable = rhs.getDefaultNullability()) {
+        lhs.setNullabilityAudited(*nullable);
+      }
+    }
+
+    return lhs;
+  }
+
+  Optional<bool> getSwiftImportAsAccessors() const {
+    if (SwiftImportAsAccessorsSpecified)
+      return SwiftImportAsAccessors;
+    return None;
+  }
+  void setSwiftImportAsAccessors(Optional<bool> value) {
+    if (value.hasValue()) {
+      SwiftImportAsAccessorsSpecified = true;
+      SwiftImportAsAccessors = value.getValue();
+    } else {
+      SwiftImportAsAccessorsSpecified = false;
+      SwiftImportAsAccessors = false;
+    }
+  }
+
+  friend ObjCPropertyInfo &operator|=(ObjCPropertyInfo &lhs,
+                                      const ObjCPropertyInfo &rhs) {
+    lhs |= static_cast<const VariableInfo &>(rhs);
+    if (!lhs.SwiftImportAsAccessorsSpecified &&
+        rhs.SwiftImportAsAccessorsSpecified) {
+      lhs.SwiftImportAsAccessorsSpecified = true;
+      lhs.SwiftImportAsAccessors = rhs.SwiftImportAsAccessors;
+    }
+    return lhs;
+  }
+};
+
+/// 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(), NoEscapeSpecified(false), NoEscape(false) { }
+
+  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.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;
+  }
+
+  friend bool operator!=(const ParamInfo &lhs, const ParamInfo &rhs) {
+    return !(lhs == rhs);
+  }
+};
+
+/// A temporary reference to an Objective-C selector, suitable for
+/// referencing selector data on the stack.
+///
+/// Instances of this struct do not store references to any of the
+/// data they contain; it is up to the user to ensure that the data
+/// referenced by the identifier list persists.
+struct ObjCSelectorRef {
+  unsigned NumPieces;
+  ArrayRef<StringRef> Identifiers;
+};
+
+/// API notes for a function or method.
+class FunctionInfo : public CommonEntityInfo {
+private:
+  static unsigned const NullabilityKindMask = 0x3;
+  static unsigned const NullabilityKindSize = 2;
+
+public:
+  /// Whether the signature has been audited with respect to nullability.
+  /// If yes, we consider all types to be non-nullable unless otherwise noted.
+  /// If this flag is not set, the pointer types are considered to have
+  /// unknown nullability.
+  unsigned NullabilityAudited : 1;
+
+  /// Number of types whose nullability is encoded with the NullabilityPayload.
+  unsigned NumAdjustedNullable : 8;
+
+  /// Stores the nullability of the return type and the parameters.
+  //  NullabilityKindSize bits are used to encode the nullability. The info
+  //  about the return type is stored at position 0, followed by the nullability
+  //  of the parameters.
+  uint64_t NullabilityPayload = 0;
+
+  /// The result type of this function, as a C type.
+  std::string ResultType;
+
+  /// The function parameters.
+  std::vector<ParamInfo> Params;
+
+  FunctionInfo()
+    : CommonEntityInfo(),
+      NullabilityAudited(false),
+      NumAdjustedNullable(0) { }
+
+  static unsigned getMaxNullabilityIndex() {
+    return ((sizeof(NullabilityPayload) * CHAR_BIT)/NullabilityKindSize);
+  }
+
+  void addTypeInfo(unsigned index, NullabilityKind kind) {
+    assert(index <= getMaxNullabilityIndex());
+    assert(static_cast<unsigned>(kind) < NullabilityKindMask);
+    NullabilityAudited = true;
+    if (NumAdjustedNullable < index + 1)
+      NumAdjustedNullable = index + 1;
+
+    // Mask the bits.
+    NullabilityPayload &= ~(NullabilityKindMask << (index * NullabilityKindSize));
+
+    // Set the value.
+    unsigned kindValue =
+      (static_cast<unsigned>(kind)) << (index * NullabilityKindSize);
+    NullabilityPayload |= kindValue;
+  }
+
+  /// Adds the return type info.
+  void addReturnTypeInfo(NullabilityKind kind) {
+    addTypeInfo(0, kind);
+  }
+
+  /// Adds the parameter type info.
+  void addParamTypeInfo(unsigned index, NullabilityKind kind) {
+    addTypeInfo(index + 1, kind);
+  }
+
+private:
+  NullabilityKind getTypeInfo(unsigned index) const {
+    assert(NullabilityAudited &&
+           "Checking the type adjustment on non-audited method.");
+    // If we don't have info about this parameter, return the default.
+    if (index > NumAdjustedNullable)
+      return NullabilityKind::NonNull;
+    return static_cast<NullabilityKind>(( NullabilityPayload
+                                          >> (index * NullabilityKindSize) )
+                                         & NullabilityKindMask);
+  }
+
+public:
+  NullabilityKind getParamTypeInfo(unsigned index) const {
+    return getTypeInfo(index + 1);
+  }
+  
+  NullabilityKind getReturnTypeInfo() const {
+    return getTypeInfo(0);
+  }
+
+  friend bool operator==(const FunctionInfo &lhs, const FunctionInfo &rhs) {
+    return static_cast<const CommonEntityInfo &>(lhs) == rhs &&
+           lhs.NullabilityAudited == rhs.NullabilityAudited &&
+           lhs.NumAdjustedNullable == rhs.NumAdjustedNullable &&
+           lhs.NullabilityPayload == rhs.NullabilityPayload &&
+           lhs.ResultType == rhs.ResultType &&
+           lhs.Params == rhs.Params;
+  }
+
+  friend bool operator!=(const FunctionInfo &lhs, const FunctionInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+};
+
+/// Describes API notes data for an Objective-C method.
+class ObjCMethodInfo : public FunctionInfo {
+public:
+  /// 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;
+  }
+
+  friend bool operator!=(const ObjCMethodInfo &lhs, const ObjCMethodInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+  void mergePropInfoIntoSetter(const ObjCPropertyInfo &pInfo);
+
+  void mergePropInfoIntoGetter(const ObjCPropertyInfo &pInfo);
+
+  /// Merge class-wide information into the given method.
+  friend ObjCMethodInfo &operator|=(ObjCMethodInfo &lhs,
+                                    const ObjCContextInfo &rhs) {
+    // Merge nullability.
+    if (!lhs.NullabilityAudited) {
+      if (auto nullable = rhs.getDefaultNullability()) {
+        lhs.NullabilityAudited = true;
+        lhs.addTypeInfo(0, *nullable);
+      }
+    }
+
+    return lhs;
+  }
+
+  void dump(llvm::raw_ostream &os);
+};
+
+/// Describes API notes data for a global variable.
+class GlobalVariableInfo : public VariableInfo {
+public:
+  GlobalVariableInfo() : VariableInfo() { }
+};
+
+/// Describes API notes data for a global function.
+class GlobalFunctionInfo : public FunctionInfo {
+public:
+  GlobalFunctionInfo() : FunctionInfo() { }
+};
+
+/// Describes API notes data for an enumerator.
+class EnumConstantInfo : public CommonEntityInfo {
+public:
+  EnumConstantInfo() : CommonEntityInfo() { }
+};
+
+/// Describes API notes data for a tag.
+class TagInfo : public CommonTypeInfo {
+public:
+  TagInfo() : CommonTypeInfo() { }
+};
+
+/// The kind of a swift_wrapper/swift_newtype.
+enum class SwiftWrapperKind {
+  None,
+  Struct,
+  Enum
+};
+
+/// Describes API notes data for a typedef.
+class TypedefInfo : public CommonTypeInfo {
+public:
+  Optional<SwiftWrapperKind> SwiftWrapper;
+
+  TypedefInfo() : CommonTypeInfo() { }
+};
+
+/// Descripts a series of options for a module
+struct ModuleOptions {
+  bool SwiftInferImportAsMember = false;
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_API_NOTES_TYPES_H
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index bbe320c..58566db 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -24,6 +24,7 @@
 #include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/PointerEmbeddedInt.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
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/Basic/Attr.td b/include/clang/Basic/Attr.td
index fa60d51..a4a88d0 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -87,6 +87,9 @@
 def NonBitField : SubsetSubject<Field,
                                 [{!S->isBitField()}]>;
 
+def ObjCClassMethod : SubsetSubject<ObjCMethod,
+                                    [{!S->isInstanceMethod()}]>;
+
 def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
                                        [{S->isInstanceMethod()}]>;
 
@@ -192,6 +195,9 @@
   list<string> Enums = enums;
 }
 
+// Represents an attribute wrapped by another attribute.
+class AttrArgument<string name, bit opt = 0> : Argument<name, opt>;
+
 // This handles one spelling of an attribute.
 class Spelling<string name, string variety> {
   string Name = name;
@@ -505,6 +511,7 @@
              .Case("macos_app_extension", "macOS (App Extension)")
              .Case("tvos_app_extension", "tvOS (App Extension)")
              .Case("watchos_app_extension", "watchOS (App Extension)")
+             .Case("swift", "Swift")
              .Default(llvm::StringRef());
 } }];
   let HasCustomParsing = 1;
@@ -1171,6 +1178,12 @@
   let Documentation = [Undocumented];
 }
 
+def NoEscape : InheritableAttr {
+  let Spellings = [GCC<"noescape">];
+  let Subjects = SubjectList<[ParmVar], WarnDiag, "ExpectedParameter">;
+  let Documentation = [Undocumented];
+}
+
 def AssumeAligned : InheritableAttr {
   let Spellings = [GCC<"assume_aligned">];
   let Subjects = SubjectList<[ObjCMethod, Function]>;
@@ -1233,6 +1246,12 @@
   let Documentation = [Undocumented];
 }
 
+def NSErrorDomain : Attr {
+  let Spellings = [GNU<"ns_error_domain">];
+  let Args = [IdentifierArgument<"ErrorDomain">];
+  let Documentation = [NSErrorDomainDocs];
+}
+
 def NSReturnsRetained : InheritableAttr {
   let Spellings = [GNU<"ns_returns_retained">];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
@@ -1319,6 +1338,12 @@
   let Documentation = [ObjCSubclassingRestrictedDocs];
 }
 
+def ObjCCompleteDefinition : InheritableAttr {
+  let Spellings = [GNU<"objc_complete_definition">];
+  let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+  let Documentation = [Undocumented];
+}
+
 def ObjCExplicitProtocolImpl : InheritableAttr {
   let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">];
   let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
@@ -1421,6 +1446,86 @@
   let Documentation = [RegparmDocs];
 }
 
+def SwiftBridge : Attr {
+  let Spellings = [GNU<"swift_bridge">];
+  let Subjects = SubjectList<[Tag, TypedefName, ObjCInterface, ObjCProtocol],
+                             ErrorDiag, "ExpectedType">;
+  let Args = [StringArgument<"SwiftType">];
+  let Documentation = [SwiftBridgeDocs];
+}
+
+def SwiftError : InheritableAttr {
+  let Spellings = [GCC<"swift_error">];
+  let Args = [EnumArgument<"Convention", "ConventionKind",
+               ["none", "nonnull_error", "null_result", "zero_result", "nonzero_result"],
+               ["None", "NonNullError", "NullResult", "ZeroResult", "NonZeroResult"]>];
+  let Subjects = SubjectList<[ObjCMethod, Function], ErrorDiag>;
+  let Documentation = [SwiftErrorDocs];
+}
+
+def SwiftName : InheritableAttr {
+  let Spellings = [GCC<"swift_name">];
+  let Args = [StringArgument<"Name">];
+  // Proper subject list disabled because of the custom error needed.
+  // Let's avoid merge conflicts for now.
+//  let Subjects = SubjectList<[EnumConstant, ObjCProtocol, ObjCClassMethod],
+//                             ErrorDiag, "ExpectedSwiftNameSubjects">;
+  let Documentation = [Undocumented];
+}
+
+def SwiftNewtype : Attr {
+  let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">];
+  let Subjects = SubjectList<[TypedefName], ErrorDiag, "ExpectedType">;
+  let Args = [EnumArgument<"NewtypeKind", "NewtypeKind",
+               ["struct", "enum"],
+               ["NK_Struct", "NK_Enum"]>];
+  let Documentation = [SwiftNewtypeDocs];
+}
+
+def SwiftPrivate : InheritableAttr {
+  let Spellings = [GCC<"swift_private">];
+  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.
+  let Spellings = [];
+  let SemaHandler = 0;
+  let Documentation = [Undocumented];
+}
+
+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 SemaHandler = 0;
+  let Documentation = [Undocumented];
+}
+
+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 SemaHandler = 0;
+  let Documentation = [Undocumented];
+  let AdditionalMembers = [{
+    attr::Kind getAttrKindToRemove() const {
+      return static_cast<attr::Kind>(getRawKind());
+    }
+  }];
+}
+
 def ReqdWorkGroupSize : InheritableAttr {
   let Spellings = [GNU<"reqd_work_group_size">];
   let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 8f6a7ea..ccf4778 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -2322,6 +2322,58 @@
   }];
 }
 
+def SwiftDocs : DocumentationCategory<"Controlling Swift Import"> {
+  let Content = [{
+Clang supports additional attributes for controlling how APIs are imported into Swift.
+  }];
+}
+
+def NSErrorDomainDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``ns_error_domain`` attribute indicates a global constant representing the error domain.
+  }];
+}
+
+def SwiftBridgeDocs : Documentation {
+  let Category = SwiftDocs;
+  let Content = [{
+The ``swift_bridge`` attribute indicates that the type to which the attribute appertains is bridged to the named Swift type. 
+  }];
+}
+
+def SwiftErrorDocs : Documentation {
+  let Category = SwiftDocs;
+  let Heading = "swift_error";
+  let Content = [{
+The ``swift_error`` attribute controls whether a particular function (or Objective-C method) is imported into Swift as a throwing function, and if so, the dynamic convention it uses.
+
+All of these conventions except ``none`` require the function to have an error parameter.  Currently, the error parameter is always the last parameter of type ``NSError**`` or ``CFErrorRef*``.  Swift will remove the error parameter from the imported API, and dynamically will always pass a valid address initialized to a null pointer.
+
+* ``swift_error(none)`` means that the function should not be imported as throwing.  The error parameter and result type will be left alone.
+
+* ``swift_error(null_result)`` means that calls to the function should be considered to have thrown if they return a null value.  The return type must be a pointer type, and it will be imported into Swift with a non-optional type.  This is the default error convention for Objective-C methods that return pointers.
+
+* ``swift_error(zero_result)`` means that calls to the function should be considered to have thrown if they return a zero result.  The return type must be an integral type.  If the return type would have been imported as ``Bool``, it is instead imported as ``Void``.  This is the default error convention for Objective-C methods that return a type that would be imported as ``Bool``.
+
+* ``swift_error(nonzero_result)`` means that calls to the function should be considered to have thrown if they return a non-zero result.  The return type must be an integral type.  If the return type would have been imported as ``Bool``, it is instead imported as ``Void``.
+
+* ``swift_error(nonnull_error)`` means that calls to the function should be considered to have thrown if they leave a non-null error in the error parameter.  The return type is left unmodified.
+
+}];
+}
+
+def SwiftNewtypeDocs : Documentation {
+  let Category = SwiftDocs;
+  let Heading = "swift_newtype";
+  let Content = [{
+The ``swift_newtype`` attribute indicates that the typedef to which the attribute appertains is imported as a new Swift type of the typedef's name.
+* ``swift_newtype(struct)`` means that a Swift struct will be created for this typedef.
+* ``swift_newtype(enum)`` means that a Swift enum will be created for this typedef.
+  }];
+}
+
+
 def OMPDeclareTargetDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "#pragma omp declare target";
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index b83ef4d..ffce99b 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -29,6 +29,7 @@
 #include <cassert>
 #include <cstdint>
 #include <list>
+#include <map>
 #include <memory>
 #include <string>
 #include <type_traits>
@@ -232,59 +233,97 @@
   /// \brief Keeps and automatically disposes all DiagStates that we create.
   std::list<DiagState> DiagStates;
 
-  /// \brief Represents a point in source where the diagnostic state was
-  /// modified because of a pragma.
-  ///
-  /// 'Loc' can be null if the point represents the diagnostic state
-  /// modifications done through the command-line.
-  struct DiagStatePoint {
-    DiagState *State;
-    FullSourceLoc Loc;
-    DiagStatePoint(DiagState *State, FullSourceLoc Loc)
-      : State(State), Loc(Loc) { } 
-    
-    bool operator<(const DiagStatePoint &RHS) const {
-      // If Loc is invalid it means it came from <command-line>, in which case
-      // we regard it as coming before any valid source location.
-      if (RHS.Loc.isInvalid())
-        return false;
-      if (Loc.isInvalid())
-        return true;
-      return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
+  /// A mapping from files to the diagnostic states for those files. Lazily
+  /// built on demand for files in which the diagnostic state has not changed.
+  class DiagStateMap {
+  public:
+    /// Add an initial diagnostic state.
+    void appendFirst(DiagState *State);
+    /// Add a new latest state point.
+    void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
+    /// Look up the diagnostic state at a given source location.
+    DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
+    /// Determine whether this map is empty.
+    bool empty() const { return Files.empty(); }
+    /// Clear out this map.
+    void clear() {
+      Files.clear();
+      FirstDiagState = CurDiagState = nullptr;
+      CurDiagStateLoc = SourceLocation();
     }
+
+    /// Grab the most-recently-added state point.
+    DiagState *getCurDiagState() const { return CurDiagState; }
+    /// Get the location at which a diagnostic state was last added.
+    SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
+
+  private:
+    /// \brief Represents a point in source where the diagnostic state was
+    /// modified because of a pragma.
+    ///
+    /// 'Loc' can be null if the point represents the diagnostic state
+    /// modifications done through the command-line.
+    struct DiagStatePoint {
+      DiagState *State;
+      unsigned Offset;
+      DiagStatePoint(DiagState *State, unsigned Offset)
+        : State(State), Offset(Offset) { } 
+    };
+
+    /// Description of the diagnostic states and state transitions for a
+    /// particular FileID.
+    struct File {
+      /// The diagnostic state for the parent file. This is strictly redundant,
+      /// as looking up the DecomposedIncludedLoc for the FileID in the Files
+      /// map would give us this, but we cache it here for performance.
+      File *Parent = nullptr;
+      /// The offset of this file within its parent.
+      unsigned ParentOffset = 0;
+      /// Whether this file has any local (not imported from an AST file)
+      /// diagnostic state transitions.
+      bool HasLocalTransitions = false;
+      /// The points within the file where the state changes. There will always
+      /// be at least one of these (the state on entry to the file).
+      llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
+
+      DiagState *lookup(unsigned Offset) const;
+    };
+
+    /// The diagnostic states for each file.
+    mutable std::map<FileID, File> Files;
+
+    /// The initial diagnostic state.
+    DiagState *FirstDiagState;
+    /// The current diagnostic state.
+    DiagState *CurDiagState;
+    /// The location at which the current diagnostic state was established.
+    SourceLocation CurDiagStateLoc;
+
+    /// Get the diagnostic state information for a file.
+    File *getFile(SourceManager &SrcMgr, FileID ID) const;
+
+    friend class ASTReader;
+    friend class ASTWriter;
   };
 
-  /// \brief A sorted vector of all DiagStatePoints representing changes in
-  /// diagnostic state due to diagnostic pragmas.
-  ///
-  /// The vector is always sorted according to the SourceLocation of the
-  /// DiagStatePoint.
-  typedef std::vector<DiagStatePoint> DiagStatePointsTy;
-  mutable DiagStatePointsTy DiagStatePoints;
+  DiagStateMap DiagStatesByLoc;
 
   /// \brief Keeps the DiagState that was active during each diagnostic 'push'
   /// so we can get back at it when we 'pop'.
   std::vector<DiagState *> DiagStateOnPushStack;
 
   DiagState *GetCurDiagState() const {
-    assert(!DiagStatePoints.empty());
-    return DiagStatePoints.back().State;
+    return DiagStatesByLoc.getCurDiagState();
   }
 
-  void PushDiagStatePoint(DiagState *State, SourceLocation L) {
-    FullSourceLoc Loc(L, getSourceManager());
-    // Make sure that DiagStatePoints is always sorted according to Loc.
-    assert(Loc.isValid() && "Adding invalid loc point");
-    assert(!DiagStatePoints.empty() &&
-           (DiagStatePoints.back().Loc.isInvalid() ||
-            DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
-           "Previous point loc comes after or is the same as new one");
-    DiagStatePoints.push_back(DiagStatePoint(State, Loc));
-  }
+  void PushDiagStatePoint(DiagState *State, SourceLocation L);
 
   /// \brief Finds the DiagStatePoint that contains the diagnostic state of
   /// the given source location.
-  DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
+  DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
+    return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
+                     : DiagStatesByLoc.getCurDiagState();
+  }
 
   /// \brief Sticky flag set to \c true when an error is emitted.
   bool ErrorOccurred;
@@ -390,7 +429,11 @@
     assert(SourceMgr && "SourceManager not set!");
     return *SourceMgr;
   }
-  void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
+  void setSourceManager(SourceManager *SrcMgr) {
+    assert(DiagStatesByLoc.empty() &&
+           "Leftover diag state from a different SourceManager.");
+    SourceMgr = SrcMgr;
+  }
 
   //===--------------------------------------------------------------------===//
   //  DiagnosticsEngine characterization methods, used by a client to customize
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index af0612a..fe83b85 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -88,6 +88,8 @@
   "module '%0' %select{is incompatible with|requires}1 feature '%2'">;
 def err_module_header_missing : Error<
   "%select{|umbrella }0header '%1' not found">;
+def err_module_shadowed : Error<
+  "import of shadowed module '%0'">;
 def err_module_lock_failure : Error<
   "could not acquire lock file for module '%0': %1">, DefaultFatal;
 def err_module_lock_timeout : Error<
@@ -222,6 +224,11 @@
 def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
 def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
 
+// API notes
+def err_apinotes_message : Error<"%0">;
+def warn_apinotes_message : Warning<"%0">, InGroup<DiagGroup<"apinotes">>;
+def note_apinotes_message : Note<"%0">;
+
 // OpenMP
 def err_omp_more_one_clause : Error<
   "directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">;
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 1267f8d..257448e 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -222,6 +222,10 @@
 def err_invalid_vfs_overlay : Error<
   "invalid virtual filesystem overlay file '%0'">, DefaultFatal;
 
+def err_no_apinotes_cache_path : Error<
+  "-fapinotes was provided without -fapinotes-cache-path=<directory>">,
+  DefaultFatal;
+
 def warn_option_invalid_ocl_version : Warning<
   "OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
 }
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 4173d03..6129b54 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -219,7 +219,6 @@
 def DanglingElse: DiagGroup<"dangling-else">;
 def DanglingField : DiagGroup<"dangling-field">;
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
-def ExpansionToDefined : DiagGroup<"expansion-to-defined">;
 def FlagEnum : DiagGroup<"flag-enum">;
 def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>;
 def InfiniteRecursion : DiagGroup<"infinite-recursion">;
@@ -386,6 +385,9 @@
 def StringPlusInt : DiagGroup<"string-plus-int">;
 def StringPlusChar : DiagGroup<"string-plus-char">;
 def StrncatSize : DiagGroup<"strncat-size">;
+
+def SwiftNameAttribute : DiagGroup<"swift-name-attribute">;
+
 def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
 def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
 def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index fcd04a0..d13ae4c 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -36,7 +36,7 @@
       DIAG_START_AST           = DIAG_START_PARSE           +  500,
       DIAG_START_COMMENT       = DIAG_START_AST             +  110,
       DIAG_START_SEMA          = DIAG_START_COMMENT         +  100,
-      DIAG_START_ANALYSIS      = DIAG_START_SEMA            + 3500,
+      DIAG_START_ANALYSIS      = DIAG_START_SEMA            + 4000,
       DIAG_UPPER_LIMIT         = DIAG_START_ANALYSIS        +  100
     };
 
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 7f7022b..aaabe7f 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -679,13 +679,6 @@
 def note_header_guard : Note<
   "%0 is defined here; did you mean %1?">;
 
-def warn_defined_in_object_type_macro : Warning<
-  "macro expansion producing 'defined' has undefined behavior">,
-  InGroup<ExpansionToDefined>;
-def warn_defined_in_function_type_macro : Extension<
-  "macro expansion producing 'defined' has undefined behavior">,
-  InGroup<ExpansionToDefined>;
-
 let CategoryName = "Nullability Issue" in {
 
 def err_pp_assume_nonnull_syntax : Error<"expected 'begin' or 'end'">;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 0943fea..76e776c 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -1039,6 +1039,9 @@
 def err_pragma_invalid_keyword : Error<
   "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
 
+// API notes.
+def err_type_unparsed : Error<"unparsed tokens following type">;
+
 // Pragma unroll support.
 def warn_pragma_unroll_cuda_value_in_parens : Warning<
   "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index c934351..c28465a 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2735,6 +2735,9 @@
   InGroup<Availability>;
 def note_overridden_method : Note<
   "overridden method is here">;
+def warn_availability_swift_unavailable_deprecated_only : Warning<
+  "only 'unavailable' and 'deprecated' are supported for Swift availability">,
+  InGroup<Availability>;
 def note_protocol_method : Note<
   "protocol method is here">;
 
@@ -3103,6 +3106,9 @@
 def warn_attribute_nonnull_parm_no_args : Warning<
   "'nonnull' attribute when used on parameters takes no arguments">,
   InGroup<IgnoredAttributes>;
+def warn_attribute_noescape_non_pointer : Warning<
+  "'noescape' attribute ignored on parameter of non-pointer type %0">,
+  InGroup<IgnoredAttributes>;
 def note_declared_nonnull : Note<
   "declared %select{'returns_nonnull'|'nonnull'}0 here">;
 def warn_attribute_sentinel_named_arguments : Warning<
@@ -3225,6 +3231,68 @@
 def err_objc_attr_protocol_requires_definition : Error<
   "attribute %0 can only be applied to @protocol definitions, not forward declarations">;
 
+// Swift attributes
+def warn_attr_swift_name_decl_kind : Warning<
+  "%0 attribute cannot be applied to this declaration">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_function : Warning<
+  "parameter of %0 attribute must be a Swift function name string">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_function_no_prototype : Warning<
+  "%0 attribute can only be applied to function declarations with prototypes">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_context_name_invalid_identifier : Warning<
+  "%0 attribute has invalid identifier for context name">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_basename_invalid_identifier : Warning<
+  "%0 attribute has invalid identifier for base name">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_parameter_invalid_identifier : Warning<
+  "%0 attribute has invalid identifier for parameter name">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_missing_parameters : Warning<
+  "%0 attribute is missing parameter label clause">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_not_accessor : Warning<
+  "%0 attribute for 'subscript' must be a getter or setter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_no_parameter : Warning<
+  "%0 attribute for 'subscript' must take at least one parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_getter_newValue : Warning<
+  "%0 attribute for 'subscript' getter cannot take a 'newValue:' parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_setter_no_newValue : Warning<
+  "%0 attribute for 'subscript' setter must take a 'newValue:' parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_setter_multiple_newValues : Warning<
+  "%0 attribute for 'subscript' setter cannot take multiple 'newValue:' parameters">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_getter_parameters : Warning<
+  "%0 attribute for getter must not take any parameters besides 'self:'">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_setter_parameters : Warning<
+  "%0 attribute for setter must take one parameter for new value">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_multiple_selfs : Warning<
+  "%0 attribute cannot specify more than one 'self:' parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_static_subscript : Warning<
+  "%0 attribute for 'subscript' must take a 'self:' parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_num_params : Warning<
+  "too %select{few|many}0 parameters in %1 attribute (expected %2; got %3)">,
+  InGroup<SwiftNameAttribute>;
+def err_attr_swift_error_no_error_parameter : Error<
+  "%0 attribute can only be applied to a %select{function|method}1 "
+  "with an error parameter">;
+def err_attr_swift_error_return_type : Error<
+  "%0 attribute with '%1' convention can only be applied to a "
+  "%select{function|method}2 returning %select{an integral type|a pointer}3">;
+def warn_swift_newtype_attribute_non_typedef : Warning<
+  "'swift_newtype' attribute may be put on a typedef only; "
+  "attribute is ignored">, InGroup<DiagGroup<"swift-newtype-attribute">>;
+
 // Function Parameter Semantic Analysis.
 def err_param_with_void_type : Error<"argument may not have 'void' type">;
 def err_void_only_param : Error<
@@ -5164,7 +5232,7 @@
 def warn_block_capture_autoreleasing : Warning<
   "block captures an autoreleasing out-parameter, which may result in "
   "use-after-free bugs">,
-  InGroup<BlockCaptureAutoReleasing>, DefaultIgnore;
+  InGroup<BlockCaptureAutoReleasing>;
 def note_declare_parameter_autoreleasing : Note<
   "declare the parameter __autoreleasing explicitly to suppress this warning">;
 def note_declare_parameter_strong : Note<
@@ -7979,6 +8047,14 @@
 def err_nsreturns_retained_attribute_mismatch : Error<
   "overriding method has mismatched ns_returns_%select{not_retained|retained}0"
   " attributes">;
+
+def err_nserrordomain_not_tagdecl : Error<
+  "ns_error_domain attribute only valid on "
+  "%select{enums, structs, and unions|enums, structs, unions, and classes}0">;
+def err_nserrordomain_invalid_decl : Error<
+  "domain argument %0 does not refer to global constant">;
+def err_nserrordomain_requires_identifier : Error<
+  "domain argument must be an identifier">;
   
 def note_getter_unavailable : Note<
   "or because setter is declared here, but no getter method %0 is found">;
@@ -8237,6 +8313,13 @@
   InGroup<OpenCLUnsupportedRGBA>;
 } // end of sema category
 
+let CategoryName = "API Notes Issue" in {
+
+def err_incompatible_replacement_type : Error<
+  "API notes replacement type %0 has a different size from original type %1">;
+
+}
+
 let CategoryName = "OpenMP Issue" in {
 // OpenMP support.
 def err_omp_expected_var_arg : Error<
diff --git a/include/clang/Basic/FileSystemOptions.h b/include/clang/Basic/FileSystemOptions.h
index 38f1346..1beb2e2 100644
--- a/include/clang/Basic/FileSystemOptions.h
+++ b/include/clang/Basic/FileSystemOptions.h
@@ -25,6 +25,9 @@
   /// \brief If set, paths are resolved as if the working directory was
   /// set to the value of WorkingDir.
   std::string WorkingDir;
+
+  /// The path to the API notes cache.
+  std::string APINotesCachePath;
 };
 
 } // end namespace clang
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 3001d0b..52238f8 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -73,9 +73,6 @@
                                    // partially) from an AST file.
   bool ChangedAfterLoad       : 1; // True if identifier has changed from the
                                    // definition loaded from an AST file.
-  bool FEChangedAfterLoad     : 1; // True if identifier's frontend information
-                                   // has changed from the definition loaded
-                                   // from an AST file.
   bool RevertedTokenID        : 1; // True if revertTokenIDToIdentifier was
                                    // called.
   bool OutOfDate              : 1; // True if there may be additional
@@ -83,7 +80,7 @@
                                    // stored externally.
   bool IsModulesImport        : 1; // True if this is the 'import' contextual
                                    // keyword.
-  // 29 bit left in 64-bit word.
+  // 30 bit left in 64-bit word.
 
   void *FETokenInfo;               // Managed by the language front-end.
   llvm::StringMapEntry<IdentifierInfo*> *Entry;
@@ -313,18 +310,6 @@
     ChangedAfterLoad = true;
   }
 
-  /// \brief Determine whether the frontend token information for this
-  /// identifier has changed since it was loaded from an AST file.
-  bool hasFETokenInfoChangedSinceDeserialization() const {
-    return FEChangedAfterLoad;
-  }
-  
-  /// \brief Note that the frontend token information for this identifier has
-  /// changed since it was loaded from an AST file.
-  void setFETokenInfoChangedSinceDeserialization() {
-    FEChangedAfterLoad = true;
-  }
-
   /// \brief Determine whether the information for this identifier is out of
   /// date with respect to the external source.
   bool isOutOfDate() const { return OutOfDate; }
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index d944a9d..19a081c 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -256,6 +256,8 @@
 LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
 
 LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+LANGOPT(APINotes, 1, 0, "use external API notes")
+LANGOPT(APINotesModules, 1, 0, "use external API notes")
 
 LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
                                            "field padding (0: none, 1:least "
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 31c5c7e..ef50b5d 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -147,6 +147,9 @@
   /// will be false to indicate that this (sub)module is not available.
   SmallVector<Requirement, 2> Requirements;
 
+  /// \brief A module with the same name that shadows this module.
+  Module *ShadowingModule = nullptr;
+
   /// \brief Whether this module is missing a feature from \c Requirements.
   unsigned IsMissingRequirement : 1;
 
@@ -180,6 +183,9 @@
   /// \brief Whether this is an inferred submodule (module * { ... }).
   unsigned IsInferred : 1;
 
+  /// \brief Whether this is a module who has its swift_names inferred.
+  unsigned IsSwiftInferImportAsMember : 1;
+
   /// \brief Whether we should infer submodules for this module based on 
   /// the headers.
   ///
@@ -325,13 +331,20 @@
   ///
   /// \param Target The target options used for the current translation unit.
   ///
-  /// \param Req If this module is unavailable, this parameter
-  /// will be set to one of the requirements that is not met for use of
-  /// this module.
+  /// \param Req If this module is unavailable because of a missing requirement,
+  /// this parameter will be set to one of the requirements that is not met for
+  /// use of this module.
+  ///
+  /// \param MissingHeader If this module is unavailable because of a missing
+  /// header, this parameter will be set to one of the missing headers.
+  ///
+  /// \param ShadowingModule If this module is unavailable because it is
+  /// shadowed, this parameter will be set to the shadowing module.
   bool isAvailable(const LangOptions &LangOpts, 
                    const TargetInfo &Target,
                    Requirement &Req,
-                   UnresolvedHeaderDirective &MissingHeader) const;
+                   UnresolvedHeaderDirective &MissingHeader,
+                   Module *&ShadowingModule) const;
 
   /// \brief Determine whether this module is a submodule.
   bool isSubModule() const { return Parent != nullptr; }
diff --git a/include/clang/Basic/SourceMgrAdapter.h b/include/clang/Basic/SourceMgrAdapter.h
new file mode 100644
index 0000000..dd7b83f
--- /dev/null
+++ b/include/clang/Basic/SourceMgrAdapter.h
@@ -0,0 +1,85 @@
+//=== SourceMgrAdapter.h - SourceMgr to SourceManager Adapter ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an adapter that maps diagnostics from llvm::SourceMgr
+// to Clang's SourceManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMGRADAPTER_H
+#define LLVM_CLANG_SOURCEMGRADAPTER_H
+
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/SourceMgr.h"
+#include <string>
+#include <utility>
+
+namespace clang {
+
+class DiagnosticsEngine;
+class FileEntry;
+
+/// An adapter that can be used to translate diagnostics from one or more
+/// llvm::SourceMgr instances to a ,
+class SourceMgrAdapter {
+  /// Clang source manager.
+  SourceManager &SrcMgr;
+
+  /// Clang diagnostics engine.
+  DiagnosticsEngine &Diag;
+
+  /// Diagnostic IDs for errors, warnings, and notes.
+  unsigned ErrorDiagID, WarningDiagID, NoteDiagID;
+
+  /// The default file to use when mapping buffers.
+  const FileEntry *DefaultFile;
+
+  /// A mapping from (LLVM source manager, buffer ID) pairs to the
+  /// corresponding file ID within the Clang source manager.
+  llvm::DenseMap<std::pair<const llvm::SourceMgr *, unsigned>, FileID>
+    FileIDMapping;
+
+  /// Diagnostic handler.
+  static void handleDiag(const llvm::SMDiagnostic &diag, void *context);
+
+public:
+  /// Create a new \c SourceMgr adaptor that maps to the given source
+  /// manager and diagnostics engine.
+  SourceMgrAdapter(SourceManager &srcMgr, DiagnosticsEngine &diag,
+                   unsigned errorDiagID, unsigned warningDiagID,
+                   unsigned noteDiagID, const FileEntry *defaultFile = nullptr);
+
+  ~SourceMgrAdapter();
+
+  /// Map a source location in the given LLVM source manager to its
+  /// corresponding location in the Clang source manager.
+  SourceLocation mapLocation(const llvm::SourceMgr &llvmSrcMgr,llvm::SMLoc loc);
+
+  /// Map a source range in the given LLVM source manager to its corresponding
+  /// range in the Clang source manager.
+  SourceRange mapRange(const llvm::SourceMgr &llvmSrcMgr, llvm::SMRange range);
+
+  /// Handle the given diagnostic from an LLVM source manager.
+  void handleDiag(const llvm::SMDiagnostic &diag);
+
+  /// Retrieve the diagnostic handler to use with the underlying SourceMgr.
+  llvm::SourceMgr::DiagHandlerTy getDiagHandler() {
+    return &SourceMgrAdapter::handleDiag;
+  }
+
+  /// Retrieve the context to use with the diagnostic handler produced by
+  /// \c getDiagHandler().
+  void *getDiagContext() { return this; }
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
index da3b019..07315f0 100644
--- a/include/clang/Basic/VersionTuple.h
+++ b/include/clang/Basic/VersionTuple.h
@@ -17,6 +17,7 @@
 
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/DenseMapInfo.h"
 #include <string>
 #include <tuple>
 
@@ -70,6 +71,9 @@
     return Major == 0 && Minor == 0 && Subminor == 0 && Build == 0;
   }
 
+  /// Whether this is a non-empty version tuple.
+  explicit operator bool () const { return !empty(); }
+
   /// \brief Retrieve the major version number.
   unsigned getMajor() const { return Major; }
 
@@ -165,4 +169,35 @@
 raw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V);
 
 } // end namespace clang
+
+namespace llvm {
+  // Provide DenseMapInfo for version tuples.
+  template<>
+  struct DenseMapInfo<clang::VersionTuple> {
+    static inline clang::VersionTuple getEmptyKey() {
+      return clang::VersionTuple(0x7FFFFFFF);
+    }
+    static inline clang::VersionTuple getTombstoneKey() {
+      return clang::VersionTuple(0x7FFFFFFE);
+    }
+    static unsigned getHashValue(const clang::VersionTuple& value) {
+      unsigned result = value.getMajor();
+      if (auto minor = value.getMinor())
+        result = combineHashValue(result, *minor);
+      if (auto subminor = value.getSubminor())
+        result = combineHashValue(result, *subminor);
+      if (auto build = value.getBuild())
+        result = combineHashValue(result, *build);
+
+      return result;
+    }
+
+    static bool isEqual(const clang::VersionTuple &lhs,
+                        const clang::VersionTuple &rhs) {
+      return lhs == rhs;
+    }
+  };
+
+} // end namespace llvm
+
 #endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 0ce461c..d38e63b 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -304,13 +304,8 @@
   bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
 
   bool embedBitcodeEnabled() const { return BitcodeEmbed != EmbedNone; }
-  bool embedBitcodeInObject() const {
-    // LTO has no object file output so ignore embed bitcode option in LTO.
-    return (BitcodeEmbed == EmbedBitcode) && !isUsingLTO();
-  }
-  bool embedBitcodeMarkerOnly() const {
-    return (BitcodeEmbed == EmbedMarker) && !isUsingLTO();
-  }
+  bool embedBitcodeInObject() const { return (BitcodeEmbed == EmbedBitcode); }
+  bool embedBitcodeMarkerOnly() const { return (BitcodeEmbed == EmbedMarker); }
 
   /// Compute the desired OpenMP runtime from the flags provided.
   OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const;
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 6be159f..77e6cf3 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -556,6 +556,21 @@
 def fno_profile_use : Flag<["-"], "fno-profile-use">,
     Alias<fno_profile_instr_use>;
 
+def fapinotes : Flag<["-"], "fapinotes">, Group<f_clang_Group>,
+  Flags<[CC1Option]>, HelpText<"Enable external API notes support">;
+def fapinotes_modules : Flag<["-"], "fapinotes-modules">, Group<f_clang_Group>,
+  Flags<[CC1Option]>, HelpText<"Enable module-based external API notes support">;
+def fno_apinotes : Flag<["-"], "fno-apinotes">, Group<f_clang_Group>,
+  Flags<[CC1Option]>, HelpText<"Disable external API notes support">;
+def fno_apinotes_modules : Flag<["-"], "fno-apinotes-modules">, Group<f_clang_Group>,
+  Flags<[CC1Option]>, HelpText<"Disable module-based external API notes support">;
+def fapinotes_cache_path : Joined<["-"], "fapinotes-cache-path=">,
+  Group<i_Group>, Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
+  HelpText<"Specify the API notes cache path">;
+def fapinotes_swift_version : Joined<["-"], "fapinotes-swift-version=">,
+  Group<f_clang_Group>, Flags<[CC1Option]>, MetaVarName<"<version>">,
+  HelpText<"Specify the Swift version to use when filtering API notes">;
+
 def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable the 'blocks' language feature">;
 def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
@@ -1407,6 +1422,8 @@
   HelpText<"Display available options">;
 def index_header_map : Flag<["-"], "index-header-map">, Flags<[CC1Option]>,
   HelpText<"Make the next included directory (-I or -F) an indexer header map">;
+def iapinotes_modules : JoinedOrSeparate<["-"], "iapinotes-modules">, Group<clang_i_Group>, Flags<[CC1Option]>,
+  HelpText<"Add directory to the API notes search path referenced by module name">, MetaVarName<"<directory>">;
 def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Add directory to AFTER include search path">;
 def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>, Flags<[CC1Option]>,
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index b1cdb46..03961f1 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -519,6 +519,8 @@
 
   const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
 
+  IntrusiveRefCntPtr<ASTReader> getASTReader() const;
+
   StringRef getOriginalSourceFileName() {
     return OriginalSourceFile;
   }
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 3ebbc61..c549b08 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -292,6 +292,13 @@
     return Invocation->getHeaderSearchOptsPtr();
   }
 
+  APINotesOptions &getAPINotesOpts() {
+    return Invocation->getAPINotesOpts();
+  }
+  const APINotesOptions &getAPINotesOpts() const {
+    return Invocation->getAPINotesOpts();
+  }
+
   LangOptions &getLangOpts() {
     return *Invocation->getLangOpts();
   }
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index cef7f73..239991d 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
 #define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
 
+#include "clang/APINotes/APINotesOptions.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileSystemOptions.h"
 #include "clang/Basic/LangOptions.h"
@@ -113,6 +114,9 @@
 
   MigratorOptions MigratorOpts;
   
+  /// Options controlling API notes.
+  APINotesOptions APINotesOpts;
+
   /// Options controlling IRgen and the backend.
   CodeGenOptions CodeGenOpts;
 
@@ -184,6 +188,11 @@
   const MigratorOptions &getMigratorOpts() const {
     return MigratorOpts;
   }
+
+  APINotesOptions &getAPINotesOpts() { return APINotesOpts; }
+  const APINotesOptions &getAPINotesOpts() const {
+    return APINotesOpts;
+  }
   
   CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
   const CodeGenOptions &getCodeGenOpts() const {
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index d19e5eb..16c3026 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -57,6 +57,7 @@
   C,
   ObjC,
   CXX,
+  Swift,
 };
 
 /// Language specific sub-kinds.
@@ -66,6 +67,26 @@
   CXXMoveConstructor,
   AccessorGetter,
   AccessorSetter,
+
+  // Swift sub-kinds
+
+  SwiftAccessorWillSet,
+  SwiftAccessorDidSet,
+  SwiftAccessorAddressor,
+  SwiftAccessorMutableAddressor,
+
+  SwiftExtensionOfStruct,
+  SwiftExtensionOfClass,
+  SwiftExtensionOfEnum,
+  SwiftExtensionOfProtocol,
+
+  SwiftPrefixOperator,
+  SwiftPostfixOperator,
+  SwiftInfixOperator,
+
+  SwiftSubscript,
+  SwiftAssociatedType,
+  SwiftGenericTypeParam,
 };
 
 /// Set of properties that provide additional info about a symbol.
diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h
index e2e63dc..8eed33c 100644
--- a/include/clang/Index/IndexingAction.h
+++ b/include/clang/Index/IndexingAction.h
@@ -14,9 +14,14 @@
 #include <memory>
 
 namespace clang {
+  class ASTReader;
   class ASTUnit;
   class FrontendAction;
 
+namespace serialization {
+  class ModuleFile;
+}
+
 namespace index {
   class IndexDataConsumer;
 
@@ -42,6 +47,11 @@
                   std::shared_ptr<IndexDataConsumer> DataConsumer,
                   IndexingOptions Opts);
 
+void indexModuleFile(serialization::ModuleFile &Mod,
+                     ASTReader &Reader,
+                     std::shared_ptr<IndexDataConsumer> DataConsumer,
+                     IndexingOptions Opts);
+
 } // namespace index
 } // namespace clang
 
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
index be89068..61f2c9d 100644
--- a/include/clang/Index/USRGeneration.h
+++ b/include/clang/Index/USRGeneration.h
@@ -16,6 +16,7 @@
 namespace clang {
 class Decl;
 class MacroDefinitionRecord;
+class SourceLocation;
 class SourceManager;
 
 namespace index {
@@ -54,6 +55,8 @@
 /// \returns true on error, false on success.
 bool generateUSRForMacro(const MacroDefinitionRecord *MD,
                          const SourceManager &SM, SmallVectorImpl<char> &Buf);
+bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
+                         const SourceManager &SM, SmallVectorImpl<char> &Buf);
 
 } // namespace index
 } // namespace clang
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 830c25a..6f1f7c6 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -133,15 +133,17 @@
   /// from.  Currently this is only used by _Pragma handling.
   SourceLocation getFileLoc() const { return FileLoc; }
 
-private:
   /// Lex - Return the next token in the file.  If this is the end of file, it
   /// return the tok::eof token.  This implicitly involves the preprocessor.
   bool Lex(Token &Result);
 
-public:
   /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma.
   bool isPragmaLexer() const { return Is_PragmaLexer; }
 
+  /// Note that this Lexer is being used to lex a pragma, or something like it
+  /// that has simple end-of-file behavior.
+  void setIsPragmaLexer(bool value) { Is_PragmaLexer = value; }
+
 private:
   /// IndirectLex - An indirect call to 'Lex' that can be invoked via
   ///  the PreprocessorLexer interface.
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 4613672..61df51e 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -92,7 +92,7 @@
   // named LangOpts::CurrentModule, if we've loaded it).
   Module *SourceModule;
 
-  /// \brief The top-level modules that are known.
+  /// \brief The unshadowed top-level modules that are known.
   llvm::StringMap<Module *> Modules;
 
   /// \brief The number of modules we have created in total.
@@ -174,6 +174,15 @@
   /// header.
   llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
 
+  /// \brief A generation counter that is used to test whether modules of the
+  /// same name may shadow or are illegal redefintions.
+  ///
+  /// Modules from earlier scopes may shadow modules from later ones.
+  /// Modules from the same scope may not have the same name.
+  unsigned CurrentModuleScopeID = 0;
+
+  llvm::DenseMap<Module *, unsigned> ModuleScopeIDs;
+
   /// \brief The set of attributes that can be attached to a module.
   struct Attributes {
     Attributes()
@@ -188,6 +197,9 @@
     /// \brief Whether this is an exhaustive set of configuration macros.
     unsigned IsExhaustive : 1;
 
+    /// \brief Whether this is a module who has its swift_names inferred.
+    unsigned IsSwiftInferImportAsMember : 1;
+
     /// \brief Whether files in this module can only include non-modular headers
     /// and headers from used modules.
     unsigned NoUndeclaredIncludes : 1;
@@ -440,6 +452,24 @@
   Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir,
                                bool IsSystem, Module *Parent);
 
+  /// \brief Create a new top-level module that is shadowed by
+  /// \p ShadowingModule.
+  Module *createShadowedModule(StringRef Name, bool IsFramework,
+                               Module *ShadowingModule);
+
+  /// \brief Creates a new declaration scope for module names, allowing
+  /// previously defined modules to shadow definitions from the new scope.
+  ///
+  /// \note Module names from earlier scopes will shadow names from the new
+  /// scope, which is the opposite of how shadowing works for variables.
+  void finishModuleDeclarationScope() { CurrentModuleScopeID += 1; }
+
+  bool mayShadowNewModule(Module *ExistingModule) {
+    assert(!ExistingModule->Parent && "expected top-level module");
+    assert(ModuleScopeIDs.count(ExistingModule) && "unknown module");
+    return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID;
+  }
+
   /// \brief Retrieve the module map file containing the definition of the given
   /// module.
   ///
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index fe15902..2d31ba2 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -2282,6 +2282,14 @@
                                         SourceLocation ScopeLoc,
                                         AttributeList::Syntax Syntax);
 
+  void ParseSwiftNewtypeAttribute(IdentifierInfo &SwiftNewtype,
+                                  SourceLocation SwiftNewtypeLoc,
+                                  ParsedAttributes &attrs,
+                                  SourceLocation *endLoc,
+                                  IdentifierInfo *ScopeName,
+                                  SourceLocation ScopeLoc,
+                                  AttributeList::Syntax Syntax);
+
   void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
                                  SourceLocation AttrNameLoc,
                                  ParsedAttributes &Attrs,
@@ -2706,7 +2714,19 @@
   //===--------------------------------------------------------------------===//
   // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
   ExprResult ParseTypeTrait();
-  
+
+  /// Parse the given string as a type.
+  ///
+  /// This is a dangerous utility function currently employed only by API notes.
+  /// It is not a general entry-point for safely parsing types from strings.
+  ///
+  /// \param typeStr The string to be parsed as a type.
+  /// \param context The name of the context in which this string is being
+  /// parsed, which will be used in diagnostics.
+  /// \param includeLoc The location at which this parse was triggered.
+  TypeResult parseTypeFromString(StringRef typeStr, StringRef context,
+                                 SourceLocation includeLoc);
+
   //===--------------------------------------------------------------------===//
   // Embarcadero: Arary and Expression Traits
   ExprResult ParseArrayTypeTrait();
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 63d0784..ad4b934 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -27,6 +27,7 @@
 #include "clang/AST/NSAPI.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/APINotes/APINotesManager.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/ExpressionTraits.h"
 #include "clang/Basic/LangOptions.h"
@@ -54,6 +55,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include <deque>
+#include <functional>
 #include <memory>
 #include <string>
 #include <vector>
@@ -304,6 +306,7 @@
   ASTConsumer &Consumer;
   DiagnosticsEngine &Diags;
   SourceManager &SourceMgr;
+  api_notes::APINotesManager APINotes;
 
   /// \brief Flag indicating whether or not to collect detailed statistics.
   bool CollectStats;
@@ -573,6 +576,10 @@
     OpaqueParser = P;
   }
 
+  /// \brief Callback to the parser to parse a type expressed as a string.
+  std::function<TypeResult(StringRef, StringRef, SourceLocation)>
+    ParseTypeFromStringCallback;
+
   class DelayedDiagnostics;
 
   class DelayedDiagnosticsState {
@@ -1409,6 +1416,24 @@
     }
   };
 
+  /// Do a check to make sure \p Name looks like a legal swift_name
+  /// attribute for the decl \p D. Raise a diagnostic if the name is invalid
+  /// for the given declaration.
+  ///
+  /// For a function, this will validate a compound Swift name,
+  /// e.g. <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>,
+  /// and the function will output the number of parameter names, and whether
+  /// this is a single-arg initializer.
+  ///
+  /// For a type, enum constant, property, or variable declaration, this will
+  /// validate either a simple identifier, or a qualified
+  /// <code>context.identifier</code> name.
+  ///
+  /// \returns true if the name is a valid swift name for \p D, false otherwise.
+  bool DiagnoseSwiftName(Decl *D, StringRef Name,
+                         SourceLocation ArgLoc,
+                         IdentifierInfo *AttrName);
+
 private:
   bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
                                TypeDiagnoser *Diagnoser);
@@ -1777,6 +1802,8 @@
   ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
                                           SourceLocation Loc,
                                           QualType T);
+  QualType adjustParameterTypeForObjCAutoRefCount(QualType T,
+                                                  SourceLocation Loc);
   ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc,
                               SourceLocation NameLoc, IdentifierInfo *Name,
                               QualType T, TypeSourceInfo *TSInfo,
@@ -2263,6 +2290,9 @@
                                 unsigned AttrSpellingListIndex);
   OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
                                           unsigned AttrSpellingListIndex);
+  SwiftNameAttr *mergeSwiftNameAttr(Decl *D, SourceRange Range,
+                                    StringRef Name, bool Override,
+                                    unsigned AttrSpellingListIndex);
   InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, SourceRange Range,
                                                 IdentifierInfo *Ident,
                                                 unsigned AttrSpellingListIndex);
@@ -3105,6 +3135,12 @@
 
   void checkUnusedDeclAttributes(Declarator &D);
 
+  /// Map any API notes provided for this declaration to attributes on the
+  /// declaration.
+  ///
+  /// Triggered by declaration-attribute processing.
+  void ProcessAPINotes(Decl *D);
+
   /// Determine if type T is a valid subject for a nonnull and similar
   /// attributes. By default, we look through references (the behavior used by
   /// nonnull), but if the second parameter is true, then we treat a reference
@@ -3159,11 +3195,16 @@
   /// \param allowArrayTypes Whether to accept nullability specifiers on an
   /// array type (e.g., because it will decay to a pointer).
   ///
+  /// \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 allowArrayTypes);
+                                     bool allowArrayTypes,
+                                     bool implicit,
+                                     bool overrideExisting = false);
 
   /// \brief Stmt attributes - this routine is the top level dispatcher.
   StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
@@ -7928,6 +7969,12 @@
     RTC_Unknown
   };
 
+  /// Check whether the declared result type of the given Objective-C
+  /// method declaration is compatible with the method's class.
+  ResultTypeCompatibilityKind
+  checkRelatedResultTypeCompatibility(const ObjCMethodDecl *Method,
+                                      const ObjCInterfaceDecl *CurrentClass);
+
   void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
                                 ObjCInterfaceDecl *CurrentClass,
                                 ResultTypeCompatibilityKind RTC);
@@ -10107,6 +10154,7 @@
 
   /// The struct behind the CFErrorRef pointer.
   RecordDecl *CFError = nullptr;
+  bool isCFError(RecordDecl *D);
 
   /// Retrieve the identifier "NSError".
   IdentifierInfo *getNSErrorIdent();
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index 4b10c39..c26f3e0 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -26,6 +26,7 @@
 class MacroDefinitionRecord;
 class MacroInfo;
 class Module;
+class SourceLocation;
 
 class ASTDeserializationListener {
 public:
@@ -52,6 +53,9 @@
                                    MacroDefinitionRecord *MD) {}
   /// \brief A module definition was read from the AST file.
   virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {}
+  /// \brief A module import was read from the AST file.
+  virtual void ModuleImportRead(serialization::SubmoduleID ID,
+                                SourceLocation ImportLoc) {}
 };
 }
 
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 93994e2..3282eb0 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -1268,6 +1268,7 @@
   llvm::iterator_range<PreprocessingRecord::iterator>
   getModulePreprocessedEntities(ModuleFile &Mod) const;
 
+public:
   class ModuleDeclIterator
       : public llvm::iterator_adaptor_base<
             ModuleDeclIterator, const serialization::LocalDeclID *,
@@ -1298,6 +1299,7 @@
   llvm::iterator_range<ModuleDeclIterator>
   getModuleFileLevelDecls(ModuleFile &Mod);
 
+private:
   void PassInterestingDeclsToConsumer();
   void PassInterestingDeclToConsumer(Decl *D);
 
@@ -2189,6 +2191,12 @@
   /// \brief Loads comments ranges.
   void ReadComments() override;
 
+  /// Visit all the input files of the given module file.
+  void visitInputFiles(serialization::ModuleFile &MF,
+                       bool IncludeSystem, bool Complain,
+          llvm::function_ref<void(const serialization::InputFile &IF,
+                                  bool isSystem)> Visitor);
+
   bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
 };
 
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 58b3149..f0629ed 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -210,6 +210,10 @@
   /// \brief The input files that have been loaded from this AST file.
   std::vector<InputFile> InputFilesLoaded;
 
+  // All user input files reside at the index range [0, NumUserInputFiles), and
+  // system input files reside at [NumUserInputFiles, InputFilesLoaded.size()).
+  unsigned NumUserInputFiles = 0;
+
   /// \brief If non-zero, specifies the time when we last validated input
   /// files.  Zero means we never validated them.
   ///
diff --git a/lib/APINotes/APINotesFormat.h b/lib/APINotes/APINotesFormat.h
new file mode 100644
index 0000000..ef3ef73
--- /dev/null
+++ b/lib/APINotes/APINotesFormat.h
@@ -0,0 +1,308 @@
+//===--- APINotesFormat.h - The internals of API notes files ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Contains various constants and helper types to deal with API notes
+/// files.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_API_NOTES_FORMAT_H
+#define LLVM_CLANG_API_NOTES_FORMAT_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/PointerEmbeddedInt.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Bitcode/RecordLayout.h"
+
+namespace clang {
+namespace api_notes {
+
+using namespace llvm;
+
+/// Magic number for API notes files.
+const unsigned char API_NOTES_SIGNATURE[] = { 0xE2, 0x9C, 0xA8, 0x01 };
+
+/// API notes file major version number.
+///
+const uint16_t VERSION_MAJOR = 0;
+
+/// API notes file minor version number.
+///
+/// When the format changes IN ANY WAY, this number should be incremented.
+const uint16_t VERSION_MINOR = 21;  // Override types
+
+using IdentifierID = PointerEmbeddedInt<unsigned, 31>;
+using IdentifierIDField = BCVBR<16>;
+
+using SelectorID = PointerEmbeddedInt<unsigned, 31>;
+using SelectorIDField = BCVBR<16>;
+
+using StoredContextID = PointerEmbeddedInt<unsigned, 31>;
+
+/// The various types of blocks that can occur within a API notes file.
+///
+/// These IDs must \em not be renumbered or reordered without incrementing
+/// VERSION_MAJOR.
+enum BlockID {
+  /// The control block, which contains all of the information that needs to
+  /// be validated prior to committing to loading the API notes file.
+  ///
+  /// \sa control_block
+  CONTROL_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+
+  /// The identifier data block, which maps identifier strings to IDs.
+  IDENTIFIER_BLOCK_ID,
+
+  /// The Objective-C context data block, which contains information about
+  /// Objective-C classes and protocols.
+  OBJC_CONTEXT_BLOCK_ID,
+
+  /// The Objective-C property data block, which maps Objective-C
+  /// (class name, property name) pairs to information about the
+  /// property.
+  OBJC_PROPERTY_BLOCK_ID,
+
+  /// The Objective-C property data block, which maps Objective-C
+  /// (class name, selector, is_instance_method) tuples to information
+  /// about the method.
+  OBJC_METHOD_BLOCK_ID,
+
+  /// The Objective-C selector data block, which maps Objective-C
+  /// selector names (# of pieces, identifier IDs) to the selector ID
+  /// used in other tables.
+  OBJC_SELECTOR_BLOCK_ID,
+
+  /// The global variables data block, which maps global variable names to
+  /// information about the global variable.
+  GLOBAL_VARIABLE_BLOCK_ID,
+
+  /// The (global) functions data block, which maps global function names to
+  /// information about the global function.
+  GLOBAL_FUNCTION_BLOCK_ID,
+
+  /// The tag data block, which maps tag names to information about
+  /// the tags.
+  TAG_BLOCK_ID,
+
+  /// The typedef data block, which maps typedef names to information about
+  /// the typedefs.
+  TYPEDEF_BLOCK_ID,
+
+  /// The enum constant data block, which maps enumerator names to
+  /// information about the enumerators.
+  ENUM_CONSTANT_BLOCK_ID,
+};
+
+namespace control_block {
+  // These IDs must \em not be renumbered or reordered without incrementing
+  // VERSION_MAJOR.
+  enum {
+    METADATA = 1,
+    MODULE_NAME = 2,
+    MODULE_OPTIONS = 3,
+    SOURCE_FILE = 4,
+  };
+
+  using MetadataLayout = BCRecordLayout<
+    METADATA, // ID
+    BCFixed<16>, // Module format major version
+    BCFixed<16>  // Module format minor version
+  >;
+
+  using ModuleNameLayout = BCRecordLayout<
+    MODULE_NAME,
+    BCBlob       // Module name
+  >;
+
+  using ModuleOptionsLayout = BCRecordLayout<
+    MODULE_OPTIONS,
+    BCFixed<1> // SwiftInferImportAsMember
+  >;
+
+  using SourceFileLayout = BCRecordLayout<
+    SOURCE_FILE,
+    BCVBR<16>, // file size
+    BCVBR<16>  // creation time
+  >;
+}
+
+namespace identifier_block {
+  enum {
+    IDENTIFIER_DATA = 1,
+  };
+
+  using IdentifierDataLayout = BCRecordLayout<
+    IDENTIFIER_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from identifier strings to decl kinds / decl IDs
+  >;
+}
+
+namespace objc_context_block {
+  enum {
+    OBJC_CONTEXT_ID_DATA = 1,
+    OBJC_CONTEXT_INFO_DATA = 2,
+  };
+
+  using ObjCContextIDLayout = BCRecordLayout<
+    OBJC_CONTEXT_ID_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from ObjC class names/protocol (as IDs) to context IDs
+  >;
+
+  using ObjCContextInfoLayout = BCRecordLayout<
+    OBJC_CONTEXT_INFO_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob      // map from ObjC context IDs to context information.
+  >;
+}
+
+namespace objc_property_block {
+  enum {
+    OBJC_PROPERTY_DATA = 1,
+  };
+
+  using ObjCPropertyDataLayout = BCRecordLayout<
+    OBJC_PROPERTY_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from ObjC (class name, property name) pairs to ObjC
+            // property information
+  >;
+}
+
+namespace objc_method_block {
+  enum {
+    OBJC_METHOD_DATA = 1,
+  };
+
+  using ObjCMethodDataLayout = BCRecordLayout<
+    OBJC_METHOD_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from ObjC (class names, selector,
+            // is-instance-method) tuples to ObjC method information
+  >;
+}
+
+namespace objc_selector_block {
+  enum {
+    OBJC_SELECTOR_DATA = 1,
+  };
+
+  using ObjCSelectorDataLayout = BCRecordLayout<
+    OBJC_SELECTOR_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from (# pieces, identifier IDs) to Objective-C selector ID.
+  >;
+}
+
+namespace global_variable_block {
+  enum {
+    GLOBAL_VARIABLE_DATA = 1
+  };
+
+  using GlobalVariableDataLayout = BCRecordLayout<
+    GLOBAL_VARIABLE_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from name to global variable information
+  >;
+}
+
+namespace global_function_block {
+  enum {
+    GLOBAL_FUNCTION_DATA = 1
+  };
+
+  using GlobalFunctionDataLayout = BCRecordLayout<
+    GLOBAL_FUNCTION_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from name to global function information
+  >;
+}
+
+namespace tag_block {
+  enum {
+    TAG_DATA = 1
+  };
+
+  using TagDataLayout = BCRecordLayout<
+    TAG_DATA,   // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob      // map from name to tag information
+  >;
+};
+
+namespace typedef_block {
+  enum {
+    TYPEDEF_DATA = 1
+  };
+
+  using TypedefDataLayout = BCRecordLayout<
+    TYPEDEF_DATA,   // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob      // map from name to typedef information
+  >;
+};
+
+namespace enum_constant_block {
+  enum {
+    ENUM_CONSTANT_DATA = 1
+  };
+
+  using EnumConstantDataLayout = BCRecordLayout<
+    ENUM_CONSTANT_DATA,  // record ID
+    BCVBR<16>,           // table offset within the blob (see below)
+    BCBlob               // map from name to enumerator information
+  >;
+}
+
+/// A stored Objective-C selector.
+struct StoredObjCSelector {
+  unsigned NumPieces;
+  llvm::SmallVector<IdentifierID, 2> Identifiers;
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+namespace llvm {
+  template<>
+  struct DenseMapInfo<clang::api_notes::StoredObjCSelector> {
+    typedef DenseMapInfo<unsigned> UnsignedInfo;
+
+    static inline clang::api_notes::StoredObjCSelector getEmptyKey() {
+      return clang::api_notes::StoredObjCSelector{ 
+               UnsignedInfo::getEmptyKey(), { } };
+    }
+
+    static inline clang::api_notes::StoredObjCSelector getTombstoneKey() {
+      return clang::api_notes::StoredObjCSelector{ 
+               UnsignedInfo::getTombstoneKey(), { } };
+    }
+    
+    static unsigned getHashValue(
+                      const clang::api_notes::StoredObjCSelector& value) {
+      auto hash = llvm::hash_value(value.NumPieces);
+      hash = hash_combine(hash, value.Identifiers.size());
+      for (auto piece : value.Identifiers)
+        hash = hash_combine(hash, static_cast<unsigned>(piece));
+      // FIXME: Mix upper/lower 32-bit values together to produce
+      // unsigned rather than truncating.
+      return hash;
+    }
+
+    static bool isEqual(const clang::api_notes::StoredObjCSelector &lhs, 
+                        const clang::api_notes::StoredObjCSelector &rhs) {
+      return lhs.NumPieces == rhs.NumPieces && 
+             lhs.Identifiers == rhs.Identifiers;
+    }
+  };
+}
+
+#endif // LLVM_CLANG_API_NOTES_FORMAT_H
diff --git a/lib/APINotes/APINotesManager.cpp b/lib/APINotes/APINotesManager.cpp
new file mode 100644
index 0000000..832f454
--- /dev/null
+++ b/lib/APINotes/APINotesManager.cpp
@@ -0,0 +1,587 @@
+//===--- APINotesManager.cpp - Manage API Notes Files ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the APINotesManager class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/APINotes/APINotesManager.h"
+#include "clang/APINotes/APINotesOptions.h"
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/APINotes/APINotesYAMLCompiler.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceMgrAdapter.h"
+#include "clang/Basic/Version.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include <sys/stat.h>
+
+using namespace clang;
+using namespace api_notes;
+
+#define DEBUG_TYPE "API Notes"
+STATISTIC(NumHeaderAPINotes,
+          "non-framework API notes files loaded");
+STATISTIC(NumPublicFrameworkAPINotes,
+          "framework public API notes loaded");
+STATISTIC(NumPrivateFrameworkAPINotes,
+          "framework private API notes loaded");
+STATISTIC(NumFrameworksSearched,
+          "frameworks searched");
+STATISTIC(NumDirectoriesSearched,
+          "header directories searched");
+STATISTIC(NumDirectoryCacheHits,
+          "directory cache hits");
+STATISTIC(NumBinaryCacheHits,
+          "binary form cache hits");
+STATISTIC(NumBinaryCacheMisses,
+          "binary form cache misses");
+STATISTIC(NumBinaryCacheRebuilds,
+          "binary form cache rebuilds");
+
+namespace {
+  /// Prints two successive strings, which much be kept alive as long as the
+  /// PrettyStackTrace entry.
+  class PrettyStackTraceDoubleString : public llvm::PrettyStackTraceEntry {
+    StringRef First, Second;
+  public:
+    PrettyStackTraceDoubleString(StringRef first, StringRef second)
+        : First(first), Second(second) {}
+    void print(raw_ostream &OS) const override {
+      OS << First << Second;
+    }
+  };
+}
+
+APINotesManager::APINotesManager(SourceManager &sourceMgr,
+                                 const LangOptions &langOpts)
+  : SourceMgr(sourceMgr), ImplicitAPINotes(langOpts.APINotes),
+    PrunedCache(false) { }
+
+APINotesManager::~APINotesManager() {
+  // Free the API notes readers.
+  for (const auto &entry : Readers) {
+    if (auto reader = entry.second.dyn_cast<APINotesReader *>()) {
+      delete reader;
+    }
+  }
+
+  delete CurrentModuleReaders[0];
+  delete CurrentModuleReaders[1];
+}
+
+/// \brief Write a new timestamp file with the given path.
+static void writeTimestampFile(StringRef TimestampFile) {
+  std::error_code EC;
+  llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None);
+}
+
+/// \brief Prune the API notes cache of API notes that haven't been accessed in
+/// a long time.
+static void pruneAPINotesCache(StringRef APINotesCachePath) {
+  struct stat StatBuf;
+  llvm::SmallString<128> TimestampFile;
+  TimestampFile = APINotesCachePath;
+  llvm::sys::path::append(TimestampFile, "APINotes.timestamp");
+
+  // Try to stat() the timestamp file.
+  if (::stat(TimestampFile.c_str(), &StatBuf)) {
+    // If the timestamp file wasn't there, create one now.
+    if (errno == ENOENT) {
+      llvm::sys::fs::create_directories(APINotesCachePath);
+      writeTimestampFile(TimestampFile);
+    }
+    return;
+  }
+
+  const unsigned APINotesCachePruneInterval = 7 * 24 * 60 * 60;
+  const unsigned APINotesCachePruneAfter = 31 * 24 * 60 * 60;
+
+  // Check whether the time stamp is older than our pruning interval.
+  // If not, do nothing.
+  time_t TimeStampModTime = StatBuf.st_mtime;
+  time_t CurrentTime = time(nullptr);
+  if (CurrentTime - TimeStampModTime <= time_t(APINotesCachePruneInterval))
+    return;
+
+  // Write a new timestamp file so that nobody else attempts to prune.
+  // There is a benign race condition here, if two Clang instances happen to
+  // notice at the same time that the timestamp is out-of-date.
+  writeTimestampFile(TimestampFile);
+
+  // Walk the entire API notes cache, looking for unused compiled API notes.
+  std::error_code EC;
+  SmallString<128> APINotesCachePathNative;
+  llvm::sys::path::native(APINotesCachePath, APINotesCachePathNative);
+  for (llvm::sys::fs::directory_iterator
+         File(APINotesCachePathNative.str(), EC), DirEnd;
+       File != DirEnd && !EC; File.increment(EC)) {
+    StringRef Extension = llvm::sys::path::extension(File->path());
+    if (Extension.empty())
+      continue;
+
+    if (Extension.substr(1) != BINARY_APINOTES_EXTENSION)
+      continue;
+
+    // Look at this file. If we can't stat it, there's nothing interesting
+    // there.
+    if (::stat(File->path().c_str(), &StatBuf))
+      continue;
+
+    // If the file has been used recently enough, leave it there.
+    time_t FileAccessTime = StatBuf.st_atime;
+    if (CurrentTime - FileAccessTime <= time_t(APINotesCachePruneAfter)) {
+      continue;
+    }
+
+    // Remove the file.
+    llvm::sys::fs::remove(File->path());
+  }
+}
+
+std::unique_ptr<APINotesReader>
+APINotesManager::loadAPINotes(const FileEntry *apiNotesFile) {
+  FileManager &fileMgr = SourceMgr.getFileManager();
+  PrettyStackTraceDoubleString trace("Loading API notes from ",
+                                     apiNotesFile->getName());
+
+  // If the API notes file is already in the binary form, load it directly.
+  StringRef apiNotesFileName = apiNotesFile->getName();
+  StringRef apiNotesFileExt = llvm::sys::path::extension(apiNotesFileName);
+  if (!apiNotesFileExt.empty() &&
+      apiNotesFileExt.substr(1) == BINARY_APINOTES_EXTENSION) {
+    auto compiledFileID = SourceMgr.createFileID(apiNotesFile, SourceLocation(), SrcMgr::C_User);
+
+    // Load the file.
+    auto buffer = SourceMgr.getBuffer(compiledFileID, SourceLocation());
+    if (!buffer) return nullptr;
+
+    // Load the binary form.
+    return APINotesReader::getUnmanaged(buffer, SwiftVersion);
+  }
+
+  // If we haven't pruned the API notes cache yet during this execution, do
+  // so now.
+  if (!PrunedCache) {
+    pruneAPINotesCache(fileMgr.getFileSystemOpts().APINotesCachePath);
+    PrunedCache = true;
+  }
+
+  // Compute a hash of the API notes file's directory and the Clang version,
+  // to be used as part of the filename for the cached binary copy.
+  auto code = llvm::hash_value(StringRef(apiNotesFile->getDir()->getName()));
+  code = hash_combine(code, getClangFullRepositoryVersion());
+
+  // Determine the file name for the cached binary form.
+  SmallString<128> compiledFileName;
+  compiledFileName += fileMgr.getFileSystemOpts().APINotesCachePath;
+  assert(!compiledFileName.empty() && "No API notes cache path provided?");
+  llvm::sys::path::append(compiledFileName,
+    (llvm::Twine(llvm::sys::path::stem(apiNotesFileName)) + "-"
+     + llvm::APInt(64, code).toString(36, /*Signed=*/false) + "."
+     + BINARY_APINOTES_EXTENSION));
+
+  // Try to open the cached binary form.
+  if (const FileEntry *compiledFile = fileMgr.getFile(compiledFileName,
+                                                      /*openFile=*/true,
+                                                      /*cacheFailure=*/false)) {
+    // Load the file contents.
+    if (auto buffer = fileMgr.getBufferForFile(compiledFile)) {
+      // Load the file.
+      if (auto reader = APINotesReader::get(std::move(buffer.get()),
+                                            SwiftVersion)) {
+        bool outOfDate = false;
+        if (auto sizeAndModTime = reader->getSourceFileSizeAndModTime()) {
+          if (sizeAndModTime->first != apiNotesFile->getSize() ||
+              sizeAndModTime->second != apiNotesFile->getModificationTime())
+            outOfDate = true;
+        }
+
+        if (!outOfDate) {
+          // Success.
+          ++NumBinaryCacheHits;
+          return reader;
+        }
+      }
+    }
+
+    // The cache entry was somehow broken; delete this one so we can build a
+    // new one below.
+    llvm::sys::fs::remove(compiledFileName.str());
+    ++NumBinaryCacheRebuilds;
+  } else {
+    ++NumBinaryCacheMisses;
+  }
+
+  // Open the source file.
+  auto sourceFileID = SourceMgr.createFileID(apiNotesFile, SourceLocation(), SrcMgr::C_User);
+  auto sourceBuffer = SourceMgr.getBuffer(sourceFileID, SourceLocation());
+  if (!sourceBuffer) return nullptr;
+
+  // Compile the API notes source into a buffer.
+  // FIXME: Either propagate OSType through or, better yet, improve the binary
+  // APINotes format to maintain complete availability information.
+  llvm::SmallVector<char, 1024> apiNotesBuffer;
+  std::unique_ptr<llvm::MemoryBuffer> compiledBuffer;
+  {
+    SourceMgrAdapter srcMgrAdapter(SourceMgr, SourceMgr.getDiagnostics(),
+                                   diag::err_apinotes_message,
+                                   diag::warn_apinotes_message,
+                                   diag::note_apinotes_message,
+                                   apiNotesFile);
+    llvm::raw_svector_ostream OS(apiNotesBuffer);
+    if (api_notes::compileAPINotes(sourceBuffer->getBuffer(),
+                                   SourceMgr.getFileEntryForID(sourceFileID),
+                                   OS,
+                                   api_notes::OSType::Absent,
+                                   srcMgrAdapter.getDiagHandler(),
+                                   srcMgrAdapter.getDiagContext()))
+      return nullptr;
+
+    // Make a copy of the compiled form into the buffer.
+    compiledBuffer = llvm::MemoryBuffer::getMemBufferCopy(
+               StringRef(apiNotesBuffer.data(), apiNotesBuffer.size()));
+  }
+
+  // Save the binary form into the cache. Perform this operation
+  // atomically.
+  SmallString<64> temporaryBinaryFileName = compiledFileName.str();
+  temporaryBinaryFileName.erase(
+    temporaryBinaryFileName.end()
+      - llvm::sys::path::extension(temporaryBinaryFileName).size(),
+    temporaryBinaryFileName.end());
+  temporaryBinaryFileName += "-%%%%%%.";
+  temporaryBinaryFileName += BINARY_APINOTES_EXTENSION;
+
+  int temporaryFD;
+  llvm::sys::fs::create_directories(
+    fileMgr.getFileSystemOpts().APINotesCachePath);
+  if (!llvm::sys::fs::createUniqueFile(temporaryBinaryFileName.str(),
+                                       temporaryFD, temporaryBinaryFileName)) {
+    // Write the contents of the buffer.
+    bool hadError;
+    {
+      llvm::raw_fd_ostream out(temporaryFD, /*shouldClose=*/true);
+      out.write(compiledBuffer.get()->getBufferStart(),
+                compiledBuffer.get()->getBufferSize());
+      out.flush();
+
+      hadError = out.has_error();
+    }
+
+    if (!hadError) {
+      // Rename the temporary file to the actual compiled file.
+      llvm::sys::fs::rename(temporaryBinaryFileName.str(),
+                            compiledFileName.str());
+    }
+  }
+
+  // Load the binary form we just compiled.
+  auto reader = APINotesReader::get(std::move(compiledBuffer), SwiftVersion);
+  assert(reader && "Could not load the API notes we just generated?");
+  return reader;
+}
+
+bool APINotesManager::loadAPINotes(const DirectoryEntry *HeaderDir,
+                                   const FileEntry *APINotesFile) {
+  assert(Readers.find(HeaderDir) == Readers.end());
+  if (auto reader = loadAPINotes(APINotesFile)) {
+    Readers[HeaderDir] = reader.release();
+    return false;
+  }
+
+  Readers[HeaderDir] = nullptr;
+  return true;
+}
+
+const FileEntry *APINotesManager::findAPINotesFile(const DirectoryEntry *directory,
+                                                   StringRef basename,
+                                                   bool wantPublic) {
+  FileManager &fileMgr = SourceMgr.getFileManager();
+
+  llvm::SmallString<128> path;
+  path += directory->getName();
+
+  unsigned pathLen = path.size();
+
+  StringRef basenameSuffix = "";
+  if (!wantPublic) basenameSuffix = "_private";
+
+  // Look for a binary API notes file.
+  llvm::sys::path::append(path, 
+    llvm::Twine(basename) + basenameSuffix + "." + BINARY_APINOTES_EXTENSION);
+  if (const FileEntry *binaryFile = fileMgr.getFile(path))
+    return binaryFile;
+
+  // Go back to the original path.
+  path.resize(pathLen);
+
+  // Look for the source API notes file.
+  llvm::sys::path::append(path, 
+    llvm::Twine(basename) + basenameSuffix + "." + SOURCE_APINOTES_EXTENSION);
+  return fileMgr.getFile(path);
+}
+
+const DirectoryEntry *APINotesManager::loadFrameworkAPINotes(
+                        llvm::StringRef FrameworkPath,
+                        llvm::StringRef FrameworkName,
+                        bool Public) {
+  FileManager &FileMgr = SourceMgr.getFileManager();
+  
+  llvm::SmallString<128> Path;
+  Path += FrameworkPath;
+  unsigned FrameworkNameLength = Path.size();
+
+  // Form the path to the APINotes file.
+  llvm::sys::path::append(Path, "APINotes");
+  if (Public)
+    llvm::sys::path::append(Path,
+                            (llvm::Twine(FrameworkName) + "."
+                              + SOURCE_APINOTES_EXTENSION));
+  else
+    llvm::sys::path::append(Path,
+                            (llvm::Twine(FrameworkName) + "_private."
+                              + SOURCE_APINOTES_EXTENSION));
+
+  // Try to open the APINotes file.
+  const FileEntry *APINotesFile = FileMgr.getFile(Path);
+  if (!APINotesFile)
+    return nullptr;
+
+  // Form the path to the corresponding header directory.
+  Path.resize(FrameworkNameLength);
+  if (Public)
+    llvm::sys::path::append(Path, "Headers");
+  else
+    llvm::sys::path::append(Path, "PrivateHeaders");
+
+  // Try to access the header directory.
+  const DirectoryEntry *HeaderDir = FileMgr.getDirectory(Path);
+  if (!HeaderDir)
+    return nullptr;
+
+  // Try to load the API notes.
+  if (loadAPINotes(HeaderDir, APINotesFile))
+    return nullptr;
+
+  // Success: return the header directory.
+  if (Public)
+    ++NumPublicFrameworkAPINotes;
+  else
+    ++NumPrivateFrameworkAPINotes;
+  return HeaderDir;
+}
+
+bool APINotesManager::loadCurrentModuleAPINotes(
+                   const Module *module,
+                   bool lookInModule,
+                   ArrayRef<std::string> searchPaths) {
+  assert(!CurrentModuleReaders[0] &&
+         "Already loaded API notes for the current module?");
+
+  FileManager &fileMgr = SourceMgr.getFileManager();
+  auto moduleName = module->getTopLevelModuleName();
+
+  // First, look relative to the module itself.
+  if (lookInModule) {
+    bool foundAny = false;
+    unsigned numReaders = 0;
+
+    // Local function to try loading an API notes file in the given directory.
+    auto tryAPINotes = [&](const DirectoryEntry *dir, bool wantPublic) {
+      if (auto file = findAPINotesFile(dir, moduleName, wantPublic)) {
+        foundAny = true;
+
+        // Try to load the API notes file.
+        CurrentModuleReaders[numReaders] = loadAPINotes(file).release();
+        if (CurrentModuleReaders[numReaders])
+          ++numReaders;
+      }
+    };
+
+    if (module->IsFramework) {
+      // For frameworks, we search in the "Headers" or "PrivateHeaders"
+      // subdirectory.
+      llvm::SmallString<128> path;
+      path += module->Directory->getName();
+      unsigned pathLen = path.size();
+
+      llvm::sys::path::append(path, "Headers");
+      if (auto apinotesDir = fileMgr.getDirectory(path))
+        tryAPINotes(apinotesDir, /*wantPublic=*/true);
+
+      path.resize(pathLen);
+      llvm::sys::path::append(path, "PrivateHeaders");
+      if (auto privateAPINotesDir = fileMgr.getDirectory(path))
+        tryAPINotes(privateAPINotesDir, /*wantPublic=*/false);
+    } else {
+      tryAPINotes(module->Directory, /*wantPublic=*/true);
+      tryAPINotes(module->Directory, /*wantPublic=*/false);
+    }
+
+    if (foundAny)
+      return numReaders > 0;
+  }
+
+  // Second, look for API notes for this module in the module API
+  // notes search paths.
+  for (const auto &searchPath : searchPaths) {
+    if (auto searchDir = fileMgr.getDirectory(searchPath)) {
+      if (auto file = findAPINotesFile(searchDir, moduleName)) {
+        CurrentModuleReaders[0] = loadAPINotes(file).release();
+        return !getCurrentModuleReaders().empty();
+      }
+    }
+  }
+
+  // Didn't find any API notes.
+  return false;
+}
+
+llvm::SmallVector<APINotesReader *, 2> APINotesManager::findAPINotes(SourceLocation Loc) {
+  llvm::SmallVector<APINotesReader *, 2> Results;
+
+  // If there are readers for the current module, return them.
+  if (!getCurrentModuleReaders().empty()) {
+    Results.append(getCurrentModuleReaders().begin(), getCurrentModuleReaders().end());
+    return Results;
+  }
+
+  // If we're not allowed to implicitly load API notes files, we're done.
+  if (!ImplicitAPINotes) return Results;
+
+  // If we don't have source location information, we're done.
+  if (Loc.isInvalid()) return Results;
+
+  // API notes are associated with the expansion location. Retrieve the
+  // file for this location.
+  SourceLocation ExpansionLoc = SourceMgr.getExpansionLoc(Loc);
+  FileID ID = SourceMgr.getFileID(ExpansionLoc);
+  if (ID.isInvalid()) return Results;
+  const FileEntry *File = SourceMgr.getFileEntryForID(ID);
+  if (!File) return Results;
+
+  // Look for API notes in the directory corresponding to this file, or one of
+  // its its parent directories.
+  const DirectoryEntry *Dir = File->getDir();
+  FileManager &FileMgr = SourceMgr.getFileManager();
+  llvm::SetVector<const DirectoryEntry *,
+                  SmallVector<const DirectoryEntry *, 4>,
+                  llvm::SmallPtrSet<const DirectoryEntry *, 4>> DirsVisited;
+  do {
+    // Look for an API notes reader for this header search directory.
+    auto Known = Readers.find(Dir);
+
+    // If we already know the answer, chase it.
+    if (Known != Readers.end()) {
+      ++NumDirectoryCacheHits;
+
+      // We've been redirected to another directory for answers. Follow it.
+      if (auto OtherDir = Known->second.dyn_cast<const DirectoryEntry *>()) {
+        DirsVisited.insert(Dir);
+        Dir = OtherDir;
+        continue;
+      }
+
+      // We have the answer.
+      if (auto Reader = Known->second.dyn_cast<APINotesReader *>())
+        Results.push_back(Reader);
+      break;
+    }
+
+    // Look for API notes corresponding to this directory.
+    StringRef Path = Dir->getName();
+    if (llvm::sys::path::extension(Path) == ".framework") {
+      // If this is a framework directory, check whether there are API notes
+      // in the APINotes subdirectory.
+      auto FrameworkName = llvm::sys::path::stem(Path);
+      ++NumFrameworksSearched;
+
+      // Look for API notes for both the public and private headers.
+      const DirectoryEntry *PublicDir
+        = loadFrameworkAPINotes(Path, FrameworkName, /*Public=*/true);
+      const DirectoryEntry *PrivateDir
+        = loadFrameworkAPINotes(Path, FrameworkName, /*Public=*/false);
+
+      if (PublicDir || PrivateDir) {
+        // We found API notes: don't ever look past the framework directory.
+        Readers[Dir] = nullptr;
+
+        // Pretend we found the result in the public or private directory,
+        // as appropriate. All headers should be in one of those two places,
+        // but be defensive here.
+        if (!DirsVisited.empty()) {
+          if (DirsVisited.back() == PublicDir) {
+            DirsVisited.pop_back();
+            Dir = PublicDir;
+          } else if (DirsVisited.back() == PrivateDir) {
+            DirsVisited.pop_back();
+            Dir = PrivateDir;
+          }
+        }
+
+        // Grab the result.
+        if (auto Reader = Readers[Dir].dyn_cast<APINotesReader *>())
+          Results.push_back(Reader);
+        break;
+      }
+    } else {
+      // Look for an APINotes file in this directory.
+      llvm::SmallString<128> APINotesPath;
+      APINotesPath += Dir->getName();
+      llvm::sys::path::append(APINotesPath,
+                              (llvm::Twine("APINotes.")
+                                 + SOURCE_APINOTES_EXTENSION));
+
+      // If there is an API notes file here, try to load it.
+      ++NumDirectoriesSearched;
+      if (const FileEntry *APINotesFile = FileMgr.getFile(APINotesPath)) {
+        if (!loadAPINotes(Dir, APINotesFile)) {
+          ++NumHeaderAPINotes;
+          if (auto Reader = Readers[Dir].dyn_cast<APINotesReader *>())
+            Results.push_back(Reader);
+          break;
+        }
+      }
+    }
+
+    // We didn't find anything. Look at the parent directory.
+    if (!DirsVisited.insert(Dir)) {
+      Dir = 0;
+      break;
+    }
+
+    StringRef ParentPath = llvm::sys::path::parent_path(Path);
+    while (llvm::sys::path::stem(ParentPath) == "..") {
+      ParentPath = llvm::sys::path::parent_path(ParentPath);
+    }
+    if (ParentPath.empty()) {
+      Dir = nullptr;
+    } else {
+      Dir = FileMgr.getDirectory(ParentPath);
+    }
+  } while (Dir);
+
+  // Path compression for all of the directories we visited, redirecting
+  // them to the directory we ended on. If no API notes were found, the
+  // resulting directory will be NULL, indicating no API notes.
+  for (const auto Visited : DirsVisited) {
+    Readers[Visited] = Dir;
+  }
+
+  return Results;
+}
diff --git a/lib/APINotes/APINotesReader.cpp b/lib/APINotes/APINotesReader.cpp
new file mode 100644
index 0000000..8fbe2a1
--- /dev/null
+++ b/lib/APINotes/APINotesReader.cpp
@@ -0,0 +1,1864 @@
+//===--- APINotesReader.cpp - Side Car Reader --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the \c APINotesReader class that reads source
+// API notes data providing additional information about source code as
+// a separate input, such as the non-nil/nilable annotations for
+// method parameters.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/APINotesReader.h"
+#include "APINotesFormat.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/OnDiskHashTable.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace clang;
+using namespace api_notes;
+using namespace llvm::support;
+using namespace llvm;
+
+namespace {
+  /// Deserialize a version tuple.
+  VersionTuple readVersionTuple(const uint8_t *&data) {
+    uint8_t numVersions = (*data++) & 0x03;
+
+    unsigned major = endian::readNext<uint32_t, little, unaligned>(data);
+    if (numVersions == 0)
+      return VersionTuple(major);
+
+    unsigned minor = endian::readNext<uint32_t, little, unaligned>(data);
+    if (numVersions == 1)
+      return VersionTuple(major, minor);
+
+    unsigned subminor = endian::readNext<uint32_t, little, unaligned>(data);
+    if (numVersions == 2)
+      return VersionTuple(major, minor, subminor);
+
+    unsigned build = endian::readNext<uint32_t, little, unaligned>(data);
+    return VersionTuple(major, minor, subminor, build);
+  }
+
+  /// An on-disk hash table whose data is versioned based on the Swift version.
+  template<typename Derived, typename KeyType, typename UnversionedDataType>
+  class VersionedTableInfo {
+  public:
+    using internal_key_type = KeyType;
+    using external_key_type = KeyType;
+    using data_type = SmallVector<std::pair<VersionTuple, UnversionedDataType>, 1>;
+    using hash_value_type = size_t;
+    using offset_type = unsigned;
+
+    internal_key_type GetInternalKey(external_key_type key) {
+      return key;
+    }
+
+    external_key_type GetExternalKey(internal_key_type key) {
+      return key;
+    }
+
+    hash_value_type ComputeHash(internal_key_type key) {
+      return static_cast<size_t>(llvm::hash_value(key));
+    }
+
+    static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+      return lhs == rhs;
+    }
+
+    static std::pair<unsigned, unsigned>
+    ReadKeyDataLength(const uint8_t *&data) {
+      unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
+      return { keyLength, dataLength };
+    }
+
+    static data_type ReadData(internal_key_type key, const uint8_t *data,
+                              unsigned length) {
+      unsigned numElements = endian::readNext<uint16_t, little, unaligned>(data);
+      data_type result;
+      result.reserve(numElements);
+      for (unsigned i = 0; i != numElements; ++i) {
+        auto version = readVersionTuple(data);
+        auto dataBefore = data; (void)dataBefore;
+        auto unversionedData = Derived::readUnversioned(key, data);
+        assert(data != dataBefore
+               && "Unversioned data reader didn't move pointer");
+        result.push_back({version, unversionedData});
+      }
+      return result;
+    }
+  };
+
+
+  /// Read serialized CommonEntityInfo.
+  void readCommonEntityInfo(const uint8_t *&data, CommonEntityInfo &info) {
+    uint8_t unavailableBits = *data++;
+    info.Unavailable = (unavailableBits >> 1) & 0x01;
+    info.UnavailableInSwift = unavailableBits & 0x01;
+    if ((unavailableBits >> 2) & 0x01)
+      info.setSwiftPrivate(static_cast<bool>((unavailableBits >> 3) & 0x01));
+
+    unsigned msgLength = endian::readNext<uint16_t, little, unaligned>(data);
+    info.UnavailableMsg
+      = std::string(reinterpret_cast<const char *>(data),
+                    reinterpret_cast<const char *>(data) + msgLength);
+    data += msgLength;
+
+    unsigned swiftNameLength
+      = endian::readNext<uint16_t, little, unaligned>(data);
+    info.SwiftName
+      = std::string(reinterpret_cast<const char *>(data),
+                    reinterpret_cast<const char *>(data) + swiftNameLength);
+    data += swiftNameLength;
+  }
+
+  /// Read serialized CommonTypeInfo.
+  void readCommonTypeInfo(const uint8_t *&data, CommonTypeInfo &info) {
+    readCommonEntityInfo(data, info);
+
+    unsigned swiftBridgeLength =
+        endian::readNext<uint16_t, little, unaligned>(data);
+    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);
+    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.
+  class IdentifierTableInfo {
+  public:
+    using internal_key_type = StringRef;
+    using external_key_type = StringRef;
+    using data_type = IdentifierID;
+    using hash_value_type = uint32_t;
+    using offset_type = unsigned;
+
+    internal_key_type GetInternalKey(external_key_type key) {
+      return key;
+    }
+
+    external_key_type GetExternalKey(internal_key_type key) {
+      return key;
+    }
+
+    hash_value_type ComputeHash(internal_key_type key) {
+      return llvm::HashString(key);
+    }
+    
+    static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+      return lhs == rhs;
+    }
+    
+    static std::pair<unsigned, unsigned> 
+    ReadKeyDataLength(const uint8_t *&data) {
+      unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
+      return { keyLength, dataLength };
+    }
+    
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      return StringRef(reinterpret_cast<const char *>(data), length);
+    }
+    
+    static data_type ReadData(internal_key_type key, const uint8_t *data,
+                              unsigned length) {
+      return endian::readNext<uint32_t, little, unaligned>(data);
+    }
+  };
+
+  /// Used to deserialize the on-disk Objective-C class table.
+  class ObjCContextIDTableInfo {
+  public:
+    // identifier ID, is-protocol
+    using internal_key_type = std::pair<unsigned, char>;
+    using external_key_type = internal_key_type;
+    using data_type = unsigned;
+    using hash_value_type = size_t;
+    using offset_type = unsigned;
+
+    internal_key_type GetInternalKey(external_key_type key) {
+      return key;
+    }
+
+    external_key_type GetExternalKey(internal_key_type key) {
+      return key;
+    }
+
+    hash_value_type ComputeHash(internal_key_type key) {
+      return static_cast<size_t>(llvm::hash_value(key));
+    }
+    
+    static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+      return lhs == rhs;
+    }
+    
+    static std::pair<unsigned, unsigned> 
+    ReadKeyDataLength(const uint8_t *&data) {
+      unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
+      return { keyLength, dataLength };
+    }
+    
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID
+        = endian::readNext<uint32_t, little, unaligned>(data);
+      auto isProtocol = endian::readNext<uint8_t, little, unaligned>(data);
+      return { nameID, isProtocol };
+    }
+    
+    static data_type ReadData(internal_key_type key, const uint8_t *data,
+                              unsigned length) {
+      return endian::readNext<uint32_t, little, unaligned>(data);
+    }
+  };
+
+  /// Used to deserialize the on-disk Objective-C property table.
+  class ObjCContextInfoTableInfo
+    : public VersionedTableInfo<ObjCContextInfoTableInfo,
+                                unsigned,
+                                ObjCContextInfo>
+  {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      return endian::readNext<uint32_t, little, unaligned>(data);
+    }
+    
+    static ObjCContextInfo readUnversioned(internal_key_type key,
+                                           const uint8_t *&data) {
+      ObjCContextInfo info;
+      readCommonTypeInfo(data, info);
+      uint8_t payload = *data++;
+
+      if (payload & 0x01)
+        info.setHasDesignatedInits(true);
+      payload = payload >> 1;
+
+      if (payload & 0x4)
+        info.setDefaultNullability(static_cast<NullabilityKind>(payload&0x03));
+
+      return info;
+    }
+  };
+
+  /// Read serialized VariableInfo.
+  void readVariableInfo(const uint8_t *&data, VariableInfo &info) {
+    readCommonEntityInfo(data, info);
+    if (*data++) {
+      info.setNullabilityAudited(static_cast<NullabilityKind>(*data));
+    }
+    ++data;
+
+    auto typeLen
+      = endian::readNext<uint16_t, little, unaligned>(data);
+    info.setType(std::string(data, data + typeLen));
+    data += typeLen;
+  }
+
+  /// Used to deserialize the on-disk Objective-C property table.
+  class ObjCPropertyTableInfo
+    : public VersionedTableInfo<ObjCPropertyTableInfo,
+                                std::tuple<unsigned, unsigned, char>,
+                                ObjCPropertyInfo>
+  {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto classID = endian::readNext<uint32_t, little, unaligned>(data);
+      auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
+      char isInstance = endian::readNext<uint8_t, little, unaligned>(data);
+      return std::make_tuple(classID, nameID, isInstance);
+    }
+    
+    static ObjCPropertyInfo readUnversioned(internal_key_type key,
+                                            const uint8_t *&data) {
+      ObjCPropertyInfo info;
+      readVariableInfo(data, info);
+      uint8_t flags = *data++;
+      if (flags & (1 << 0))
+        info.setSwiftImportAsAccessors(flags & (1 << 1));
+      return info;
+    }
+  };
+
+  /// Read serialized ParamInfo.
+  void readParamInfo(const uint8_t *&data, ParamInfo &info) {
+    readVariableInfo(data, info);
+
+    uint8_t payload = endian::readNext<uint8_t, little, unaligned>(data);
+    if (payload & 0x01) {
+      info.setNoEscape(payload & 0x02);
+    }
+    payload >>= 2; assert(payload == 0 && "Bad API notes");
+  }
+
+  /// Read serialized FunctionInfo.
+  void readFunctionInfo(const uint8_t *&data, FunctionInfo &info) {
+    readCommonEntityInfo(data, info);
+    info.NullabilityAudited
+      = endian::readNext<uint8_t, little, unaligned>(data);
+    info.NumAdjustedNullable
+      = endian::readNext<uint8_t, little, unaligned>(data);
+    info.NullabilityPayload
+      = endian::readNext<uint64_t, little, unaligned>(data);
+
+    unsigned numParams = endian::readNext<uint16_t, little, unaligned>(data);
+    while (numParams > 0) {
+      ParamInfo pi;
+      readParamInfo(data, pi);
+      info.Params.push_back(pi);
+      --numParams;
+    }
+
+    unsigned resultTypeLen
+      = endian::readNext<uint16_t, little, unaligned>(data);
+    info.ResultType = std::string(data, data + resultTypeLen);
+    data += resultTypeLen;
+  }
+
+  /// Used to deserialize the on-disk Objective-C method table.
+  class ObjCMethodTableInfo
+    : public VersionedTableInfo<ObjCMethodTableInfo,
+                                std::tuple<unsigned, unsigned, char>,
+                                ObjCMethodInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto classID = endian::readNext<uint32_t, little, unaligned>(data);
+      auto selectorID = endian::readNext<uint32_t, little, unaligned>(data);
+      auto isInstance = endian::readNext<uint8_t, little, unaligned>(data);
+      return internal_key_type{ classID, selectorID, isInstance };
+    }
+    
+    static ObjCMethodInfo readUnversioned(internal_key_type key,
+                                          const uint8_t *&data) {
+      ObjCMethodInfo info;
+      uint8_t payload = *data++;
+      info.Required = payload & 0x01;
+      payload >>= 1;
+      info.DesignatedInit = payload & 0x01;
+      payload >>= 1;
+      info.FactoryAsInit = payload & 0x03;
+      payload >>= 2;
+
+      readFunctionInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk Objective-C selector table.
+  class ObjCSelectorTableInfo {
+  public:
+    using internal_key_type = StoredObjCSelector; 
+    using external_key_type = internal_key_type;
+    using data_type = SelectorID;
+    using hash_value_type = unsigned;
+    using offset_type = unsigned;
+
+    internal_key_type GetInternalKey(external_key_type key) {
+      return key;
+    }
+
+    external_key_type GetExternalKey(internal_key_type key) {
+      return key;
+    }
+
+    hash_value_type ComputeHash(internal_key_type key) {
+      return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(key);
+    }
+    
+    static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+      return llvm::DenseMapInfo<StoredObjCSelector>::isEqual(lhs, rhs);
+    }
+    
+    static std::pair<unsigned, unsigned> 
+    ReadKeyDataLength(const uint8_t *&data) {
+      unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
+      return { keyLength, dataLength };
+    }
+    
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      internal_key_type key;
+      key.NumPieces = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned numIdents = (length - sizeof(uint16_t)) / sizeof(uint32_t);
+      for (unsigned i = 0; i != numIdents; ++i) {
+        key.Identifiers.push_back(
+          endian::readNext<uint32_t, little, unaligned>(data));
+      }
+      return key;
+    }
+    
+    static data_type ReadData(internal_key_type key, const uint8_t *data,
+                              unsigned length) {
+      return endian::readNext<uint32_t, little, unaligned>(data);
+    }
+  };
+
+  /// Used to deserialize the on-disk global variable table.
+  class GlobalVariableTableInfo
+    : public VersionedTableInfo<GlobalVariableTableInfo, unsigned,
+                                GlobalVariableInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
+      return nameID;
+    }
+
+    static GlobalVariableInfo readUnversioned(internal_key_type key,
+                                              const uint8_t *&data) {
+      GlobalVariableInfo info;
+      readVariableInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk global function table.
+  class GlobalFunctionTableInfo
+    : public VersionedTableInfo<GlobalFunctionTableInfo, unsigned,
+                                GlobalFunctionInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
+      return nameID;
+    }
+    
+    static GlobalFunctionInfo readUnversioned(internal_key_type key,
+                                              const uint8_t *&data) {
+      GlobalFunctionInfo info;
+      readFunctionInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk enumerator table.
+  class EnumConstantTableInfo
+    : public VersionedTableInfo<EnumConstantTableInfo, unsigned,
+                                EnumConstantInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
+      return nameID;
+    }
+    
+    static EnumConstantInfo readUnversioned(internal_key_type key,
+                                            const uint8_t *&data) {
+      EnumConstantInfo info;
+      readCommonEntityInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk tag table.
+  class TagTableInfo
+    : public VersionedTableInfo<TagTableInfo, unsigned, TagInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<IdentifierID, little, unaligned>(data);
+      return nameID;
+    }
+    
+    static TagInfo readUnversioned(internal_key_type key,
+                                   const uint8_t *&data) {
+      TagInfo info;
+      readCommonTypeInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk typedef table.
+  class TypedefTableInfo
+    : public VersionedTableInfo<TypedefTableInfo, unsigned, TypedefInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<IdentifierID, little, unaligned>(data);
+      return nameID;
+    }
+
+    static TypedefInfo readUnversioned(internal_key_type key,
+                                       const uint8_t *&data) {
+      TypedefInfo info;
+
+      uint8_t payload = *data++;
+      if (payload > 0) {
+        info.SwiftWrapper = static_cast<SwiftWrapperKind>((payload & 0x3) - 1);
+      }
+
+      readCommonTypeInfo(data, info);
+      return info;
+    }
+  };
+} // end anonymous namespace
+
+class APINotesReader::Implementation {
+public:
+  /// The input buffer for the API notes data.
+  llvm::MemoryBuffer *InputBuffer;
+
+  /// Whether we own the input buffer.
+  bool OwnsInputBuffer;
+
+  /// The Swift version to use for filtering.
+  VersionTuple SwiftVersion;
+
+  /// The name of the module that we read from the control block.
+  std::string ModuleName;
+
+  // The size and modification time of the source file from
+  // which this API notes file was created, if known.
+  Optional<std::pair<off_t, time_t>> SourceFileSizeAndModTime;
+
+  /// Various options and attributes for the module
+  ModuleOptions ModuleOpts;
+
+  using SerializedIdentifierTable =
+      llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>;
+
+  /// The identifier table.
+  std::unique_ptr<SerializedIdentifierTable> IdentifierTable;
+
+  using SerializedObjCContextIDTable =
+      llvm::OnDiskIterableChainedHashTable<ObjCContextIDTableInfo>;
+
+  /// The Objective-C context ID table.
+  std::unique_ptr<SerializedObjCContextIDTable> ObjCContextIDTable;
+
+  using SerializedObjCContextInfoTable =
+    llvm::OnDiskIterableChainedHashTable<ObjCContextInfoTableInfo>;
+
+  /// The Objective-C context info table.
+  std::unique_ptr<SerializedObjCContextInfoTable> ObjCContextInfoTable;
+
+  using SerializedObjCPropertyTable =
+      llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>;
+
+  /// The Objective-C property table.
+  std::unique_ptr<SerializedObjCPropertyTable> ObjCPropertyTable;
+
+  using SerializedObjCMethodTable =
+      llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;
+
+  /// The Objective-C method table.
+  std::unique_ptr<SerializedObjCMethodTable> ObjCMethodTable;
+
+  using SerializedObjCSelectorTable =
+      llvm::OnDiskIterableChainedHashTable<ObjCSelectorTableInfo>;
+
+  /// The Objective-C selector table.
+  std::unique_ptr<SerializedObjCSelectorTable> ObjCSelectorTable;
+
+  using SerializedGlobalVariableTable =
+      llvm::OnDiskIterableChainedHashTable<GlobalVariableTableInfo>;
+
+  /// The global variable table.
+  std::unique_ptr<SerializedGlobalVariableTable> GlobalVariableTable;
+
+  using SerializedGlobalFunctionTable =
+      llvm::OnDiskIterableChainedHashTable<GlobalFunctionTableInfo>;
+
+  /// The global function table.
+  std::unique_ptr<SerializedGlobalFunctionTable> GlobalFunctionTable;
+
+  using SerializedEnumConstantTable =
+      llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>;
+
+  /// The enumerator table.
+  std::unique_ptr<SerializedEnumConstantTable> EnumConstantTable;
+
+  using SerializedTagTable =
+      llvm::OnDiskIterableChainedHashTable<TagTableInfo>;
+
+  /// The tag table.
+  std::unique_ptr<SerializedTagTable> TagTable;
+
+  using SerializedTypedefTable =
+      llvm::OnDiskIterableChainedHashTable<TypedefTableInfo>;
+
+  /// The typedef table.
+  std::unique_ptr<SerializedTypedefTable> TypedefTable;
+
+  /// Retrieve the identifier ID for the given string, or an empty
+  /// optional if the string is unknown.
+  Optional<IdentifierID> getIdentifier(StringRef str);
+
+  /// Retrieve the selector ID for the given selector, or an empty
+  /// optional if the string is unknown.
+  Optional<SelectorID> getSelector(ObjCSelectorRef selector);
+
+  bool readControlBlock(llvm::BitstreamCursor &cursor, 
+                        SmallVectorImpl<uint64_t> &scratch);
+  bool readIdentifierBlock(llvm::BitstreamCursor &cursor,
+                           SmallVectorImpl<uint64_t> &scratch);
+  bool readObjCContextBlock(llvm::BitstreamCursor &cursor,
+                            SmallVectorImpl<uint64_t> &scratch);
+  bool readObjCPropertyBlock(llvm::BitstreamCursor &cursor, 
+                             SmallVectorImpl<uint64_t> &scratch);
+  bool readObjCMethodBlock(llvm::BitstreamCursor &cursor, 
+                             SmallVectorImpl<uint64_t> &scratch);
+  bool readObjCSelectorBlock(llvm::BitstreamCursor &cursor, 
+                             SmallVectorImpl<uint64_t> &scratch);
+  bool readGlobalVariableBlock(llvm::BitstreamCursor &cursor,
+                               SmallVectorImpl<uint64_t> &scratch);
+  bool readGlobalFunctionBlock(llvm::BitstreamCursor &cursor,
+                               SmallVectorImpl<uint64_t> &scratch);
+  bool readEnumConstantBlock(llvm::BitstreamCursor &cursor,
+                             SmallVectorImpl<uint64_t> &scratch);
+  bool readTagBlock(llvm::BitstreamCursor &cursor,
+                    SmallVectorImpl<uint64_t> &scratch);
+  bool readTypedefBlock(llvm::BitstreamCursor &cursor,
+                        SmallVectorImpl<uint64_t> &scratch);
+};
+
+Optional<IdentifierID> APINotesReader::Implementation::getIdentifier(
+                         StringRef str) {
+  if (!IdentifierTable)
+    return None;
+
+  if (str.empty())
+    return IdentifierID(0);
+
+  auto known = IdentifierTable->find(str);
+  if (known == IdentifierTable->end())
+    return None;
+
+  return *known;
+}
+
+Optional<SelectorID> APINotesReader::Implementation::getSelector(
+                       ObjCSelectorRef selector) {
+  if (!ObjCSelectorTable || !IdentifierTable)
+    return None;
+
+  // Translate the identifiers.
+  StoredObjCSelector key;
+  key.NumPieces = selector.NumPieces;
+  for (auto ident : selector.Identifiers) {
+    if (auto identID = getIdentifier(ident)) {
+      key.Identifiers.push_back(*identID);
+    } else {
+      return None;
+    }
+  }
+
+  auto known = ObjCSelectorTable->find(key);
+  if (known == ObjCSelectorTable->end())
+    return None;
+
+  return *known;
+
+}
+
+bool APINotesReader::Implementation::readControlBlock(
+       llvm::BitstreamCursor &cursor,
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(CONTROL_BLOCK_ID))
+    return true;
+
+  bool sawMetadata = false;
+  
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown metadata sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case control_block::METADATA:
+      // Already saw metadata.
+      if (sawMetadata)
+        return true;
+
+      if (scratch[0] != VERSION_MAJOR || scratch[1] != VERSION_MINOR)
+        return true;
+
+      sawMetadata = true;
+      break;
+
+    case control_block::MODULE_NAME:
+      ModuleName = blobData.str();
+      break;
+
+    case control_block::MODULE_OPTIONS:
+      ModuleOpts.SwiftInferImportAsMember = (scratch.front() & 1) != 0;
+      break;
+
+    case control_block::SOURCE_FILE:
+      SourceFileSizeAndModTime = { scratch[0], scratch[1] };
+      break;
+
+    default:
+      // Unknown metadata record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return !sawMetadata;
+}
+
+bool APINotesReader::Implementation::readIdentifierBlock(
+       llvm::BitstreamCursor &cursor,
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(IDENTIFIER_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case identifier_block::IDENTIFIER_DATA: {
+      // Already saw identifier table.
+      if (IdentifierTable)
+        return true;
+
+      uint32_t tableOffset;
+      identifier_block::IdentifierDataLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      IdentifierTable.reset(
+        SerializedIdentifierTable::Create(base + tableOffset,
+                                          base + sizeof(uint32_t),
+                                          base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readObjCContextBlock(
+       llvm::BitstreamCursor &cursor,
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(OBJC_CONTEXT_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case objc_context_block::OBJC_CONTEXT_ID_DATA: {
+      // Already saw Objective-C context ID table.
+      if (ObjCContextIDTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_context_block::ObjCContextIDLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCContextIDTable.reset(
+        SerializedObjCContextIDTable::Create(base + tableOffset,
+                                             base + sizeof(uint32_t),
+                                             base));
+      break;
+    }
+
+    case objc_context_block::OBJC_CONTEXT_INFO_DATA: {
+      // Already saw Objective-C context info table.
+      if (ObjCContextInfoTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_context_block::ObjCContextInfoLayout::readRecord(scratch,
+                                                            tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCContextInfoTable.reset(
+        SerializedObjCContextInfoTable::Create(base + tableOffset,
+                                               base + sizeof(uint32_t),
+                                               base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readObjCPropertyBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(OBJC_PROPERTY_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case objc_property_block::OBJC_PROPERTY_DATA: {
+      // Already saw Objective-C property table.
+      if (ObjCPropertyTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_property_block::ObjCPropertyDataLayout::readRecord(scratch, 
+                                                              tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCPropertyTable.reset(
+        SerializedObjCPropertyTable::Create(base + tableOffset,
+                                            base + sizeof(uint32_t),
+                                            base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readObjCMethodBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(OBJC_METHOD_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case objc_method_block::OBJC_METHOD_DATA: {
+      // Already saw Objective-C method table.
+      if (ObjCMethodTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_method_block::ObjCMethodDataLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCMethodTable.reset(
+        SerializedObjCMethodTable::Create(base + tableOffset,
+                                          base + sizeof(uint32_t),
+                                          base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readObjCSelectorBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case objc_selector_block::OBJC_SELECTOR_DATA: {
+      // Already saw Objective-C selector table.
+      if (ObjCSelectorTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_selector_block::ObjCSelectorDataLayout::readRecord(scratch, 
+                                                              tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCSelectorTable.reset(
+        SerializedObjCSelectorTable::Create(base + tableOffset,
+                                          base + sizeof(uint32_t),
+                                          base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readGlobalVariableBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(GLOBAL_VARIABLE_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case global_variable_block::GLOBAL_VARIABLE_DATA: {
+      // Already saw global variable table.
+      if (GlobalVariableTable)
+        return true;
+
+      uint32_t tableOffset;
+      global_variable_block::GlobalVariableDataLayout::readRecord(scratch,
+                                                                  tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      GlobalVariableTable.reset(
+        SerializedGlobalVariableTable::Create(base + tableOffset,
+                                              base + sizeof(uint32_t),
+                                              base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readGlobalFunctionBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(GLOBAL_FUNCTION_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case global_function_block::GLOBAL_FUNCTION_DATA: {
+      // Already saw global function table.
+      if (GlobalFunctionTable)
+        return true;
+
+      uint32_t tableOffset;
+      global_function_block::GlobalFunctionDataLayout::readRecord(scratch,
+                                                                  tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      GlobalFunctionTable.reset(
+        SerializedGlobalFunctionTable::Create(base + tableOffset,
+                                              base + sizeof(uint32_t),
+                                              base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readEnumConstantBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(ENUM_CONSTANT_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case enum_constant_block::ENUM_CONSTANT_DATA: {
+      // Already saw enumerator table.
+      if (EnumConstantTable)
+        return true;
+
+      uint32_t tableOffset;
+      enum_constant_block::EnumConstantDataLayout::readRecord(scratch,
+                                                              tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      EnumConstantTable.reset(
+        SerializedEnumConstantTable::Create(base + tableOffset,
+                                            base + sizeof(uint32_t),
+                                            base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readTagBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(TAG_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case tag_block::TAG_DATA: {
+      // Already saw tag table.
+      if (TagTable)
+        return true;
+
+      uint32_t tableOffset;
+      tag_block::TagDataLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      TagTable.reset(
+        SerializedTagTable::Create(base + tableOffset,
+                                   base + sizeof(uint32_t),
+                                   base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readTypedefBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(TYPEDEF_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case typedef_block::TYPEDEF_DATA: {
+      // Already saw typedef table.
+      if (TypedefTable)
+        return true;
+
+      uint32_t tableOffset;
+      typedef_block::TypedefDataLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      TypedefTable.reset(
+        SerializedTypedefTable::Create(base + tableOffset,
+                                       base + sizeof(uint32_t),
+                                       base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+APINotesReader::APINotesReader(llvm::MemoryBuffer *inputBuffer, 
+                               bool ownsInputBuffer,
+                               VersionTuple swiftVersion,
+                               bool &failed) 
+  : Impl(*new Implementation)
+{
+  failed = false;
+
+  // Initialize the input buffer.
+  Impl.InputBuffer = inputBuffer;
+  Impl.OwnsInputBuffer = ownsInputBuffer;
+  Impl.SwiftVersion = swiftVersion;
+  llvm::BitstreamCursor cursor(*Impl.InputBuffer);
+
+  // Validate signature.
+  for (auto byte : API_NOTES_SIGNATURE) {
+    if (cursor.AtEndOfStream() || cursor.Read(8) != byte) {
+      failed = true;
+      return;
+    }
+  }
+
+  // Look at all of the blocks.
+  bool hasValidControlBlock = false;
+  SmallVector<uint64_t, 64> scratch;
+  while (!cursor.AtEndOfStream()) {
+    auto topLevelEntry = cursor.advance();
+    if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
+      break;
+
+    switch (topLevelEntry.ID) {
+    case llvm::bitc::BLOCKINFO_BLOCK_ID:
+      if (!cursor.ReadBlockInfoBlock()) {
+        failed = true;
+        break;
+      }
+      break;
+
+    case CONTROL_BLOCK_ID:
+      // Only allow a single control block.
+      if (hasValidControlBlock || Impl.readControlBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+
+      hasValidControlBlock = true;
+      break;
+
+    case IDENTIFIER_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readIdentifierBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case OBJC_CONTEXT_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readObjCContextBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+
+      break;
+
+    case OBJC_PROPERTY_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readObjCPropertyBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case OBJC_METHOD_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readObjCMethodBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case OBJC_SELECTOR_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readObjCSelectorBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case GLOBAL_VARIABLE_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readGlobalVariableBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case GLOBAL_FUNCTION_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readGlobalFunctionBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case ENUM_CONSTANT_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readEnumConstantBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case TAG_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readTagBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case TYPEDEF_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readTypedefBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    default:
+      // Unknown top-level block, possibly for use by a future version of the
+      // module format.
+      if (cursor.SkipBlock()) {
+        failed = true;
+        return;
+      }
+      break;
+    }
+  }
+
+  if (!cursor.AtEndOfStream()) {
+    failed = true;
+    return;
+  }
+}
+
+APINotesReader::~APINotesReader() {
+  if (Impl.OwnsInputBuffer)
+    delete Impl.InputBuffer;
+
+  delete &Impl;
+}
+
+std::unique_ptr<APINotesReader> 
+APINotesReader::get(std::unique_ptr<llvm::MemoryBuffer> inputBuffer,
+                    VersionTuple swiftVersion) {
+  bool failed = false;
+  std::unique_ptr<APINotesReader> 
+    reader(new APINotesReader(inputBuffer.release(), /*ownsInputBuffer=*/true,
+                              swiftVersion, failed));
+  if (failed)
+    return nullptr;
+
+  return reader;
+}
+
+std::unique_ptr<APINotesReader> 
+APINotesReader::getUnmanaged(llvm::MemoryBuffer *inputBuffer,
+                             VersionTuple swiftVersion) {
+  bool failed = false;
+  std::unique_ptr<APINotesReader> 
+    reader(new APINotesReader(inputBuffer, /*ownsInputBuffer=*/false,
+                              swiftVersion, failed));
+  if (failed)
+    return nullptr;
+
+  return reader;
+}
+
+StringRef APINotesReader::getModuleName() const {
+  return Impl.ModuleName;
+}
+
+Optional<std::pair<off_t, time_t>>
+APINotesReader::getSourceFileSizeAndModTime() const {
+  return Impl.SourceFileSizeAndModTime;
+}
+
+ModuleOptions APINotesReader::getModuleOptions() const {
+  return Impl.ModuleOpts;
+}
+
+template<typename T>
+APINotesReader::VersionedInfo<T>::VersionedInfo(
+    VersionTuple version,
+    SmallVector<std::pair<VersionTuple, T>, 1> results)
+  : Results(std::move(results)) {
+
+  // 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;
+    }
+
+    if (!Results[i].first) {
+      assert(!unversioned && "Two unversioned entries?");
+      unversioned = i;
+    }
+  }
+
+  // If we didn't find a match but we have an unversioned result, use the
+  // unversioned result.
+  if (Selected == Results.size() && unversioned) {
+    Selected = *unversioned;
+    SelectedRole = VersionedInfoRole::AugmentSource;
+  }
+  }
+
+auto APINotesReader::lookupObjCClassID(StringRef name) -> Optional<ContextID> {
+  if (!Impl.ObjCContextIDTable)
+    return None;
+
+  Optional<IdentifierID> classID = Impl.getIdentifier(name);
+  if (!classID)
+    return None;
+
+  auto knownID = Impl.ObjCContextIDTable->find({*classID, '\0'});
+  if (knownID == Impl.ObjCContextIDTable->end())
+    return None;
+
+  return ContextID(*knownID);
+}
+
+auto APINotesReader::lookupObjCClassInfo(StringRef name)
+       -> VersionedInfo<ObjCContextInfo> {
+  if (!Impl.ObjCContextInfoTable)
+    return None;
+
+  Optional<ContextID> contextID = lookupObjCClassID(name);
+  if (!contextID)
+    return None;
+
+  auto knownInfo = Impl.ObjCContextInfoTable->find(contextID->Value);
+  if (knownInfo == Impl.ObjCContextInfoTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *knownInfo };
+}
+
+auto APINotesReader::lookupObjCProtocolID(StringRef name)
+       -> Optional<ContextID> {
+   if (!Impl.ObjCContextIDTable)
+     return None;
+
+   Optional<IdentifierID> classID = Impl.getIdentifier(name);
+   if (!classID)
+     return None;
+
+   auto knownID = Impl.ObjCContextIDTable->find({*classID, '\1'});
+   if (knownID == Impl.ObjCContextIDTable->end())
+     return None;
+
+   return ContextID(*knownID);
+}
+
+auto APINotesReader::lookupObjCProtocolInfo(StringRef name)
+       -> VersionedInfo<ObjCContextInfo> {
+   if (!Impl.ObjCContextInfoTable)
+     return None;
+
+   Optional<ContextID> contextID = lookupObjCProtocolID(name);
+   if (!contextID)
+     return None;
+
+   auto knownInfo = Impl.ObjCContextInfoTable->find(contextID->Value);
+   if (knownInfo == Impl.ObjCContextInfoTable->end())
+     return None;
+   
+   return { Impl.SwiftVersion, *knownInfo };
+}
+
+
+auto APINotesReader::lookupObjCProperty(ContextID contextID,
+                                        StringRef name,
+                                        bool isInstance)
+    -> VersionedInfo<ObjCPropertyInfo> {
+  if (!Impl.ObjCPropertyTable)
+    return None;
+
+  Optional<IdentifierID> propertyID = Impl.getIdentifier(name);
+  if (!propertyID)
+    return None;
+
+  auto known = Impl.ObjCPropertyTable->find(std::make_tuple(contextID.Value,
+                                                            *propertyID,
+                                                            (char)isInstance));
+  if (known == Impl.ObjCPropertyTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupObjCMethod(
+                                      ContextID contextID,
+                                      ObjCSelectorRef selector,
+                                      bool isInstanceMethod)
+    -> VersionedInfo<ObjCMethodInfo> {
+  if (!Impl.ObjCMethodTable)
+    return None;
+
+  Optional<SelectorID> selectorID = Impl.getSelector(selector);
+  if (!selectorID)
+    return None;
+
+  auto known = Impl.ObjCMethodTable->find(
+      ObjCMethodTableInfo::internal_key_type{
+          contextID.Value, *selectorID, isInstanceMethod});
+  if (known == Impl.ObjCMethodTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupGlobalVariable(
+                                          StringRef name)
+    -> VersionedInfo<GlobalVariableInfo> {
+  if (!Impl.GlobalVariableTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.GlobalVariableTable->find(*nameID);
+  if (known == Impl.GlobalVariableTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupGlobalFunction(StringRef name)
+    -> VersionedInfo<GlobalFunctionInfo> {
+  if (!Impl.GlobalFunctionTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.GlobalFunctionTable->find(*nameID);
+  if (known == Impl.GlobalFunctionTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupEnumConstant(StringRef name)
+    -> VersionedInfo<EnumConstantInfo> {
+  if (!Impl.EnumConstantTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.EnumConstantTable->find(*nameID);
+  if (known == Impl.EnumConstantTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupTag(StringRef name) -> VersionedInfo<TagInfo> {
+  if (!Impl.TagTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.TagTable->find(*nameID);
+  if (known == Impl.TagTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupTypedef(StringRef name)
+    -> VersionedInfo<TypedefInfo> {
+  if (!Impl.TypedefTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.TypedefTable->find(*nameID);
+  if (known == Impl.TypedefTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+APINotesReader::Visitor::~Visitor() { }
+
+void APINotesReader::Visitor::visitObjCClass(
+       ContextID contextID,
+       StringRef name,
+       const ObjCContextInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitObjCProtocol(
+       ContextID contextID,
+       StringRef name,
+       const ObjCContextInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitObjCMethod(
+       ContextID contextID,
+       StringRef selector,
+       bool isInstanceMethod,
+       const ObjCMethodInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitObjCProperty(
+       ContextID contextID,
+       StringRef name,
+       bool isInstance,
+       const ObjCPropertyInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitGlobalVariable(
+       StringRef name,
+       const GlobalVariableInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitGlobalFunction(
+       StringRef name,
+       const GlobalFunctionInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitEnumConstant(
+       StringRef name,
+       const EnumConstantInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitTag(
+       StringRef name,
+       const TagInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitTypedef(
+       StringRef name,
+       const TypedefInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::visit(Visitor &visitor) {
+  // FIXME: All of these iterations would be significantly more efficient if we
+  // could get the keys and data together, but OnDiskIterableHashTable doesn't
+  // support that.
+
+  // Build an identifier ID -> string mapping, which we'll need when visiting
+  // any of the tables.
+  llvm::DenseMap<unsigned, StringRef> identifiers;
+  if (Impl.IdentifierTable) {
+    for (auto key : Impl.IdentifierTable->keys()) {
+      unsigned ID = *Impl.IdentifierTable->find(key);
+      assert(identifiers.count(ID) == 0);
+      identifiers[ID] = key;
+    }
+  }
+
+  // Visit classes and protocols.
+  if (Impl.ObjCContextIDTable && Impl.ObjCContextInfoTable) {
+    for (auto key : Impl.ObjCContextIDTable->keys()) {
+      auto name = identifiers[key.first];
+      auto contextID = *Impl.ObjCContextIDTable->find(key);
+
+      auto knownInfo = Impl.ObjCContextInfoTable->find(contextID);
+      if (knownInfo == Impl.ObjCContextInfoTable->end()) continue;
+
+      for (const auto &versioned : *knownInfo) {
+        if (key.second)
+          visitor.visitObjCProtocol(ContextID(contextID), name,
+                                    versioned.second, versioned.first);
+        else
+          visitor.visitObjCClass(ContextID(contextID), name, versioned.second,
+                                 versioned.first);
+      }
+    }
+  }
+
+  // Build a selector ID -> stored Objective-C selector mapping, which we need
+  // when visiting the method tables.
+  llvm::DenseMap<unsigned, std::string> selectors;
+  if (Impl.ObjCSelectorTable) {
+    for (auto key : Impl.ObjCSelectorTable->keys()) {
+      std::string selector;
+      if (key.NumPieces == 0)
+        selector = identifiers[key.Identifiers[0]];
+      else {
+        for (auto identID : key.Identifiers) {
+          selector += identifiers[identID];
+          selector += ':';
+        }
+      }
+
+      unsigned selectorID = *Impl.ObjCSelectorTable->find(key);
+      selectors[selectorID] = selector;
+    }
+  }
+
+  // Visit methods.
+  if (Impl.ObjCMethodTable) {
+    for (auto key : Impl.ObjCMethodTable->keys()) {
+      ContextID contextID(std::get<0>(key));
+      const auto &selector = selectors[std::get<1>(key)];
+      for (const auto &versioned : *Impl.ObjCMethodTable->find(key))
+        visitor.visitObjCMethod(contextID, selector, std::get<2>(key),
+                                versioned.second, versioned.first);
+    }
+  }
+
+  // Visit properties.
+  if (Impl.ObjCPropertyTable) {
+    for (auto key : Impl.ObjCPropertyTable->keys()) {
+      ContextID contextID(std::get<0>(key));
+      auto name = identifiers[std::get<1>(key)];
+      char isInstance = std::get<2>(key);
+      for (const auto &versioned : *Impl.ObjCPropertyTable->find(key)) {
+        visitor.visitObjCProperty(contextID, name, isInstance, versioned.second,
+                                  versioned.first);
+      }
+    }
+  }
+
+  // Visit global functions.
+  if (Impl.GlobalFunctionTable) {
+    for (auto key : Impl.GlobalFunctionTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.GlobalFunctionTable->find(key))
+        visitor.visitGlobalFunction(name, versioned.second, versioned.first);
+    }
+  }
+
+  // Visit global variables.
+  if (Impl.GlobalVariableTable) {
+    for (auto key : Impl.GlobalVariableTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.GlobalVariableTable->find(key))
+        visitor.visitGlobalVariable(name, versioned.second, versioned.first);
+    }
+  }
+
+  // Visit global variables.
+  if (Impl.EnumConstantTable) {
+    for (auto key : Impl.EnumConstantTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.EnumConstantTable->find(key))
+        visitor.visitEnumConstant(name, versioned.second, versioned.first);
+    }
+  }
+
+  // Visit tags.
+  if (Impl.TagTable) {
+    for (auto key : Impl.TagTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.TagTable->find(key))
+        visitor.visitTag(name, versioned.second, versioned.first);
+    }
+  }
+
+  // Visit typedefs.
+  if (Impl.TypedefTable) {
+    for (auto key : Impl.TypedefTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.TypedefTable->find(key))
+        visitor.visitTypedef(name, versioned.second, versioned.first);
+    }
+  }
+}
+
diff --git a/lib/APINotes/APINotesWriter.cpp b/lib/APINotes/APINotesWriter.cpp
new file mode 100644
index 0000000..86b6abd
--- /dev/null
+++ b/lib/APINotes/APINotesWriter.cpp
@@ -0,0 +1,1289 @@
+//===--- APINotesWriter.cpp - API Notes Writer --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the \c APINotesWriter class that writes out
+// source API notes data providing additional information about source
+// code as a separate input, such as the non-nil/nilable annotations
+// for method parameters.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/APINotesWriter.h"
+#include "APINotesFormat.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/OnDiskHashTable.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/DataTypes.h"
+#include <tuple>
+#include <vector>
+using namespace clang;
+using namespace api_notes;
+using namespace llvm::support;
+
+namespace {
+  template<typename T> using VersionedSmallVector =
+    SmallVector<std::pair<VersionTuple, T>, 1>;
+}
+
+class APINotesWriter::Implementation {
+  /// Mapping from strings to identifier IDs.
+  llvm::StringMap<IdentifierID> IdentifierIDs;
+
+  /// Mapping from selectors to selector ID.
+  llvm::DenseMap<StoredObjCSelector, SelectorID> SelectorIDs;
+
+  /// Scratch space for bitstream writing.
+  SmallVector<uint64_t, 64> ScratchRecord;
+
+public:
+  /// The name of the module
+  std::string ModuleName;
+
+  /// The source file from which this binary representation was
+  /// created, if known.
+  const FileEntry *SourceFile;
+
+  bool SwiftInferImportAsMember = false;
+
+  /// Information about Objective-C contexts (classes or protocols).
+  ///
+  /// Indexed by the identifier ID and a bit indication whether we're looking
+  /// for a class (0) or protocol (1) and provides both the context ID and
+  /// information describing the context within that module.
+  llvm::DenseMap<std::pair<unsigned, char>,
+                 std::pair<unsigned, VersionedSmallVector<ObjCContextInfo>>>
+    ObjCContexts;
+
+  /// Mapping from context IDs to the identifier ID holding the name.
+  llvm::DenseMap<unsigned, unsigned> ObjCContextNames;
+
+  /// Information about Objective-C properties.
+  ///
+  /// Indexed by the context ID, property name, and whether this is an
+  /// instance property.
+  llvm::DenseMap<std::tuple<unsigned, unsigned, char>,
+                 llvm::SmallVector<std::pair<VersionTuple, ObjCPropertyInfo>,
+                 1>>
+    ObjCProperties;
+
+  /// Information about Objective-C methods.
+  ///
+  /// Indexed by the context ID, selector ID, and Boolean (stored as a
+  /// char) indicating whether this is a class or instance method.
+  llvm::DenseMap<std::tuple<unsigned, unsigned, char>,
+                 llvm::SmallVector<std::pair<VersionTuple, ObjCMethodInfo>, 1>>
+    ObjCMethods;
+
+  /// Information about global variables.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, GlobalVariableInfo>,
+                                   1>>
+    GlobalVariables;
+
+  /// Information about global functions.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, GlobalFunctionInfo>,
+                                   1>>
+    GlobalFunctions;
+
+  /// Information about enumerators.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, EnumConstantInfo>,
+                                   1>>
+    EnumConstants;
+
+  /// Information about tags.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, TagInfo>, 1>>
+    Tags;
+
+  /// Information about typedefs.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, TypedefInfo>, 1>>
+    Typedefs;
+
+  /// Retrieve the ID for the given identifier.
+  IdentifierID getIdentifier(StringRef identifier) {
+    if (identifier.empty())
+      return 0;
+
+    auto known = IdentifierIDs.find(identifier);
+    if (known != IdentifierIDs.end())
+      return known->second;
+
+    // Add to the identifier table.
+    known = IdentifierIDs.insert({identifier, IdentifierIDs.size() + 1}).first;
+    return known->second;
+  }
+
+  /// Retrieve the ID for the given selector.
+  SelectorID getSelector(ObjCSelectorRef selectorRef) {
+    // Translate the selector reference into a stored selector.
+    StoredObjCSelector selector;
+    selector.NumPieces = selectorRef.NumPieces;
+    selector.Identifiers.reserve(selectorRef.Identifiers.size());
+    for (auto piece : selectorRef.Identifiers) {
+      selector.Identifiers.push_back(getIdentifier(piece));
+    }
+
+    // Look for the stored selector.
+    auto known = SelectorIDs.find(selector);
+    if (known != SelectorIDs.end())
+      return known->second;
+
+    // Add to the selector table.
+    known = SelectorIDs.insert({selector, SelectorIDs.size()}).first;
+    return known->second;
+  }
+
+  void writeToStream(llvm::raw_ostream &os);
+
+private:
+  void writeBlockInfoBlock(llvm::BitstreamWriter &writer);
+  void writeControlBlock(llvm::BitstreamWriter &writer);
+  void writeIdentifierBlock(llvm::BitstreamWriter &writer);
+  void writeObjCContextBlock(llvm::BitstreamWriter &writer);
+  void writeObjCPropertyBlock(llvm::BitstreamWriter &writer);
+  void writeObjCMethodBlock(llvm::BitstreamWriter &writer);
+  void writeObjCSelectorBlock(llvm::BitstreamWriter &writer);
+  void writeGlobalVariableBlock(llvm::BitstreamWriter &writer);
+  void writeGlobalFunctionBlock(llvm::BitstreamWriter &writer);
+  void writeEnumConstantBlock(llvm::BitstreamWriter &writer);
+  void writeTagBlock(llvm::BitstreamWriter &writer);
+  void writeTypedefBlock(llvm::BitstreamWriter &writer);
+};
+
+/// Record the name of a block.
+static void emitBlockID(llvm::BitstreamWriter &out, unsigned ID,
+                        StringRef name,
+                        SmallVectorImpl<unsigned char> &nameBuffer) {
+  SmallVector<unsigned, 1> idBuffer;
+  idBuffer.push_back(ID);
+  out.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, idBuffer);
+
+  // Emit the block name if present.
+  if (name.empty())
+    return;
+  nameBuffer.resize(name.size());
+  memcpy(nameBuffer.data(), name.data(), name.size());
+  out.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, nameBuffer);
+}
+
+/// Record the name of a record within a block.
+static void emitRecordID(llvm::BitstreamWriter &out, unsigned ID,
+                         StringRef name,
+                         SmallVectorImpl<unsigned char> &nameBuffer) {
+  assert(ID < 256 && "can't fit record ID in next to name");
+  nameBuffer.resize(name.size()+1);
+  nameBuffer[0] = ID;
+  memcpy(nameBuffer.data()+1, name.data(), name.size());
+  out.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, nameBuffer);
+}
+
+void APINotesWriter::Implementation::writeBlockInfoBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, llvm::bitc::BLOCKINFO_BLOCK_ID, 2);  
+
+  SmallVector<unsigned char, 64> nameBuffer;
+#define BLOCK(X) emitBlockID(writer, X ## _ID, #X, nameBuffer)
+#define BLOCK_RECORD(K, X) emitRecordID(writer, K::X, #X, nameBuffer)
+
+  BLOCK(CONTROL_BLOCK);
+  BLOCK_RECORD(control_block, METADATA);
+  BLOCK_RECORD(control_block, MODULE_NAME);
+
+  BLOCK(IDENTIFIER_BLOCK);
+  BLOCK_RECORD(identifier_block, IDENTIFIER_DATA);
+
+  BLOCK(OBJC_CONTEXT_BLOCK);
+  BLOCK_RECORD(objc_context_block, OBJC_CONTEXT_ID_DATA);
+
+  BLOCK(OBJC_PROPERTY_BLOCK);
+  BLOCK_RECORD(objc_property_block, OBJC_PROPERTY_DATA);
+
+  BLOCK(OBJC_METHOD_BLOCK);
+  BLOCK_RECORD(objc_method_block, OBJC_METHOD_DATA);
+
+  BLOCK(OBJC_SELECTOR_BLOCK);
+  BLOCK_RECORD(objc_selector_block, OBJC_SELECTOR_DATA);
+
+  BLOCK(GLOBAL_VARIABLE_BLOCK);
+  BLOCK_RECORD(global_variable_block, GLOBAL_VARIABLE_DATA);
+
+  BLOCK(GLOBAL_FUNCTION_BLOCK);
+  BLOCK_RECORD(global_function_block, GLOBAL_FUNCTION_DATA);
+#undef BLOCK
+#undef BLOCK_RECORD
+}
+
+void APINotesWriter::Implementation::writeControlBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, CONTROL_BLOCK_ID, 3);
+  control_block::MetadataLayout metadata(writer);
+  metadata.emit(ScratchRecord, VERSION_MAJOR, VERSION_MINOR);
+
+  control_block::ModuleNameLayout moduleName(writer);
+  moduleName.emit(ScratchRecord, ModuleName);
+
+  if (SwiftInferImportAsMember) {
+    control_block::ModuleOptionsLayout moduleOptions(writer);
+    moduleOptions.emit(ScratchRecord, SwiftInferImportAsMember);
+  }
+
+  if (SourceFile) {
+    control_block::SourceFileLayout sourceFile(writer);
+    sourceFile.emit(ScratchRecord, SourceFile->getSize(),
+                    SourceFile->getModificationTime());
+  }
+}
+
+namespace {
+  /// Used to serialize the on-disk identifier table.
+  class IdentifierTableInfo {
+  public:
+    using key_type = StringRef;
+    using key_type_ref = key_type;
+    using data_type = IdentifierID;
+    using data_type_ref = const data_type &;
+    using hash_value_type = uint32_t;
+    using offset_type = unsigned;
+
+    hash_value_type ComputeHash(key_type_ref key) {
+      return llvm::HashString(key);
+    }
+
+    std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
+                                                    key_type_ref key,
+                                                    data_type_ref data) {
+      uint32_t keyLength = key.size();
+      uint32_t dataLength = sizeof(uint32_t);
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(keyLength);
+      writer.write<uint16_t>(dataLength);
+      return { keyLength, dataLength };
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      out << key;
+    }
+
+    void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                  unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(data);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeIdentifierBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, IDENTIFIER_BLOCK_ID, 3);
+
+  if (IdentifierIDs.empty())
+    return;
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<IdentifierTableInfo> generator;
+    for (auto &entry : IdentifierIDs)
+      generator.insert(entry.first(), entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  identifier_block::IdentifierDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Retrieve the serialized size of the given CommonEntityInfo, for use in
+  /// on-disk hash tables.
+  static unsigned getCommonEntityInfoSize(const CommonEntityInfo &info) {
+    return 5 + info.UnavailableMsg.size() + info.SwiftName.size();
+  }
+
+  /// Emit a serialized representation of the common entity information.
+  static void emitCommonEntityInfo(raw_ostream &out,
+                                   const CommonEntityInfo &info) {
+    endian::Writer<little> writer(out);
+    uint8_t payload = 0;
+    if (auto swiftPrivate = info.isSwiftPrivate()) {
+      payload |= 0x01;
+      if (*swiftPrivate) payload |= 0x02;
+    }
+    payload <<= 1;
+    payload |= info.Unavailable;
+    payload <<= 1;
+    payload |= info.UnavailableInSwift;
+
+    writer.write<uint8_t>(payload);
+
+    writer.write<uint16_t>(info.UnavailableMsg.size());
+    out.write(info.UnavailableMsg.c_str(), info.UnavailableMsg.size());
+    writer.write<uint16_t>(info.SwiftName.size());
+    out.write(info.SwiftName.c_str(), info.SwiftName.size());
+  }
+
+  // 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() ? info.getSwiftBridge()->size() : 0) +
+           2 + (info.getNSErrorDomain() ? info.getNSErrorDomain()->size() : 0) +
+           getCommonEntityInfoSize(info);
+  }
+
+  /// Emit a serialized representation of the common type information.
+  static void emitCommonTypeInfo(raw_ostream &out, const CommonTypeInfo &info) {
+    emitCommonEntityInfo(out, info);
+    endian::Writer<little> writer(out);
+    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.
+  class ObjCContextIDTableInfo {
+  public:
+    using key_type = std::pair<unsigned, char>; // identifier ID, is-protocol
+    using key_type_ref = key_type;
+    using data_type = unsigned;
+    using data_type_ref = const data_type &;
+    using hash_value_type = size_t;
+    using offset_type = unsigned;
+
+    hash_value_type ComputeHash(key_type_ref key) {
+      return static_cast<size_t>(llvm::hash_value(key));
+    }
+
+    std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
+                                                    key_type_ref key,
+                                                    data_type_ref data) {
+      uint32_t keyLength = sizeof(uint32_t) + 1;
+      uint32_t dataLength = sizeof(uint32_t);
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(keyLength);
+      writer.write<uint16_t>(dataLength);
+      return { keyLength, dataLength };
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key.first);
+      writer.write<uint8_t>(key.second);
+    }
+
+    void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                  unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(data);
+    }
+  };
+} // end anonymous namespace
+
+namespace {
+  /// Retrieve the serialized size of the given VersionTuple, for use in
+  /// on-disk hash tables.
+  unsigned getVersionTupleSize(const VersionTuple &version) {
+    unsigned size = sizeof(uint8_t) + /*major*/sizeof(uint32_t);
+    if (version.getMinor()) size += sizeof(uint32_t);
+    if (version.getSubminor()) size += sizeof(uint32_t);
+    if (version.getBuild()) size += sizeof(uint32_t);
+    return size;
+  }
+
+  /// Emit a serialized representation of a version tuple.
+  void emitVersionTuple(raw_ostream &out, const VersionTuple &version) {
+    endian::Writer<little> writer(out);
+
+    // First byte contains the number of components beyond the 'major'
+    // component.
+    uint8_t descriptor;
+    if (version.getBuild()) descriptor = 3;
+    else if (version.getSubminor()) descriptor = 2;
+    else if (version.getMinor()) descriptor = 1;
+    else descriptor = 0;
+    assert(!version.usesUnderscores() && "Not a serializable version");
+    writer.write<uint8_t>(descriptor);
+
+    // Write the components.
+    writer.write<uint32_t>(version.getMajor());
+    if (auto minor = version.getMinor())
+      writer.write<uint32_t>(*minor);
+    if (auto subminor = version.getSubminor())
+      writer.write<uint32_t>(*subminor);
+    if (auto build = version.getBuild())
+      writer.write<uint32_t>(*build);
+  }
+
+  /// Localized helper to make a type dependent, thwarting template argument
+  /// deduction.
+  template<typename T>
+  struct MakeDependent {
+    typedef T Type;
+  };
+
+  /// Determine the size of an array of versioned information,
+  template<typename T>
+  unsigned getVersionedInfoSize(
+             const SmallVectorImpl<std::pair<VersionTuple, T>> &infoArray,
+            llvm::function_ref<unsigned(const typename MakeDependent<T>::Type&)>
+              getInfoSize) {
+    unsigned result = sizeof(uint16_t); // # of elements
+    for (const auto &element : infoArray) {
+      result += getVersionTupleSize(element.first);
+      result += getInfoSize(element.second);
+    }
+
+    return result;
+  }
+
+  /// Emit versioned information.
+  template<typename T>
+  void emitVersionedInfo(
+         raw_ostream &out,
+         const SmallVectorImpl<std::pair<VersionTuple, T>> &infoArray,
+         llvm::function_ref<void(raw_ostream &out,
+                                 const typename MakeDependent<T>::Type& info)>
+           emitInfo) {
+    endian::Writer<little> writer(out);
+    writer.write<uint16_t>(infoArray.size());
+    for (const auto &element : infoArray) {
+      emitVersionTuple(out, element.first);
+      emitInfo(out, element.second);
+    }
+  }
+
+  /// Retrieve the serialized size of the given VariableInfo, for use in
+  /// on-disk hash tables.
+  unsigned getVariableInfoSize(const VariableInfo &info) {
+    return 2 + getCommonEntityInfoSize(info) + 2 + info.getType().size();
+  }
+
+  /// Emit a serialized representation of the variable information.
+  void emitVariableInfo(raw_ostream &out, const VariableInfo &info) {
+    emitCommonEntityInfo(out, info);
+
+    uint8_t bytes[2] = { 0, 0 };
+    if (auto nullable = info.getNullability()) {
+      bytes[0] = 1;
+      bytes[1] = static_cast<uint8_t>(*nullable);
+    } else {
+      // Nothing to do.
+    }
+
+    out.write(reinterpret_cast<const char *>(bytes), 2);
+
+    endian::Writer<little> writer(out);
+    writer.write<uint16_t>(info.getType().size());
+    out.write(info.getType().data(), info.getType().size());
+  }
+
+  /// On-dish hash table info key base for handling versioned data.
+  template<typename Derived, typename KeyType, typename UnversionedDataType>
+  class VersionedTableInfo {
+    Derived &asDerived() {
+      return *static_cast<Derived *>(this);
+    }
+
+    const Derived &asDerived() const {
+      return *static_cast<const Derived *>(this);
+    }
+
+  public:
+    using key_type = KeyType;
+    using key_type_ref = key_type;
+    using data_type =
+      SmallVector<std::pair<VersionTuple, UnversionedDataType>, 1>;
+    using data_type_ref = const data_type &;
+    using hash_value_type = size_t;
+    using offset_type = unsigned;
+
+    hash_value_type ComputeHash(key_type_ref key) {
+      return llvm::hash_value(key);
+    }
+
+    std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
+                                                    key_type_ref key,
+                                                    data_type_ref data) {
+      uint32_t keyLength = asDerived().getKeyLength(key);
+      uint32_t dataLength = getVersionedInfoSize(data,
+        [this](const UnversionedDataType &unversionedInfo) {
+          return asDerived().getUnversionedInfoSize(unversionedInfo);
+      });
+
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(keyLength);
+      writer.write<uint16_t>(dataLength);
+      return { keyLength, dataLength };
+    }
+
+    void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                  unsigned len) {
+      emitVersionedInfo(out, data,
+        [this](llvm::raw_ostream &out,
+               const UnversionedDataType &unversionedInfo) {
+          asDerived().emitUnversionedInfo(out, unversionedInfo);
+      });
+    }
+  };
+
+  /// Used to serialize the on-disk Objective-C property table.
+  class ObjCContextInfoTableInfo
+    : public VersionedTableInfo<ObjCContextInfoTableInfo,
+                                unsigned,
+                                ObjCContextInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const ObjCContextInfo &info) {
+      return getCommonTypeInfoSize(info) + 1;
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const ObjCContextInfo &info) {
+      emitCommonTypeInfo(out, info);
+
+      uint8_t payload = 0;
+      if (auto nullable = info.getDefaultNullability()) {
+        payload = (0x01 << 2) | static_cast<uint8_t>(*nullable);
+      }
+      payload = (payload << 1) | (info.hasDesignatedInits() ? 1 : 0);
+      out << payload;
+    }
+  };
+
+  /// Used to serialize the on-disk Objective-C property table.
+  class ObjCPropertyTableInfo
+    : public VersionedTableInfo<ObjCPropertyTableInfo,
+                                std::tuple<unsigned, unsigned, char>,
+                                ObjCPropertyInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(std::get<0>(key));
+      writer.write<uint32_t>(std::get<1>(key));
+      writer.write<uint8_t>(std::get<2>(key));
+    }
+
+    unsigned getUnversionedInfoSize(const ObjCPropertyInfo &info) {
+      return getVariableInfoSize(info) + 1;
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const ObjCPropertyInfo &info) {
+      emitVariableInfo(out, info);
+      uint8_t flags = 0;
+      if (Optional<bool> value = info.getSwiftImportAsAccessors()) {
+        flags |= 1 << 0;
+        flags |= value.getValue() << 1;
+      }
+      out << flags;
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeObjCContextBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, OBJC_CONTEXT_BLOCK_ID, 3);
+
+  if (ObjCContexts.empty())
+    return;  
+
+  {
+    llvm::SmallString<4096> hashTableBlob;
+    uint32_t tableOffset;
+    {
+      llvm::OnDiskChainedHashTableGenerator<ObjCContextIDTableInfo> generator;
+      for (auto &entry : ObjCContexts)
+        generator.insert(entry.first, entry.second.first);
+
+      llvm::raw_svector_ostream blobStream(hashTableBlob);
+      // Make sure that no bucket is at offset 0
+      endian::Writer<little>(blobStream).write<uint32_t>(0);
+      tableOffset = generator.Emit(blobStream);
+    }
+
+    objc_context_block::ObjCContextIDLayout layout(writer);
+    layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+  }
+
+  {
+    llvm::SmallString<4096> hashTableBlob;
+    uint32_t tableOffset;
+    {
+      llvm::OnDiskChainedHashTableGenerator<ObjCContextInfoTableInfo>
+        generator;
+      for (auto &entry : ObjCContexts)
+        generator.insert(entry.second.first, entry.second.second);
+
+      llvm::raw_svector_ostream blobStream(hashTableBlob);
+      // Make sure that no bucket is at offset 0
+      endian::Writer<little>(blobStream).write<uint32_t>(0);
+      tableOffset = generator.Emit(blobStream);
+    }
+
+    objc_context_block::ObjCContextInfoLayout layout(writer);
+    layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+  }
+}
+
+void APINotesWriter::Implementation::writeObjCPropertyBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, OBJC_PROPERTY_BLOCK_ID, 3);
+
+  if (ObjCProperties.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<ObjCPropertyTableInfo> generator;
+    for (auto &entry : ObjCProperties)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  objc_property_block::ObjCPropertyDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  static unsigned getParamInfoSize(const ParamInfo &info) {
+    return getVariableInfoSize(info) + 1;
+  }
+
+  static void emitParamInfo(raw_ostream &out, const ParamInfo &info) {
+    emitVariableInfo(out, info);
+
+    endian::Writer<little> writer(out);
+
+    uint8_t payload = 0;
+    if (auto noescape = info.isNoEscape()) {
+      payload |= 0x01;
+      if (*noescape)
+        payload |= 0x02;
+    }
+    writer.write<uint8_t>(payload);
+  }
+
+  /// Retrieve the serialized size of the given FunctionInfo, for use in
+  /// on-disk hash tables.
+  static unsigned getFunctionInfoSize(const FunctionInfo &info) {
+    unsigned size = 2 + sizeof(uint64_t) + getCommonEntityInfoSize(info) + 2;
+
+    for (const auto &param : info.Params)
+      size += getParamInfoSize(param);
+
+    size += 2 + info.ResultType.size();
+    return size;
+  }
+
+  /// Emit a serialized representation of the function information.
+  static void emitFunctionInfo(raw_ostream &out, const FunctionInfo &info) {
+    emitCommonEntityInfo(out, info);
+
+    endian::Writer<little> writer(out);
+    writer.write<uint8_t>(info.NullabilityAudited);
+    writer.write<uint8_t>(info.NumAdjustedNullable);
+    writer.write<uint64_t>(info.NullabilityPayload);
+
+    // Parameters.
+    writer.write<uint16_t>(info.Params.size());
+    for (const auto &pi : info.Params)
+      emitParamInfo(out, pi);
+
+    // Result type.
+    writer.write<uint16_t>(info.ResultType.size());
+    out.write(info.ResultType.data(), info.ResultType.size());
+  }
+
+  /// Used to serialize the on-disk Objective-C method table.
+  class ObjCMethodTableInfo
+    : public VersionedTableInfo<ObjCMethodTableInfo,
+                                std::tuple<unsigned, unsigned, char>,
+                                ObjCMethodInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t) + sizeof(uint32_t) + 1;
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(std::get<0>(key));
+      writer.write<uint32_t>(std::get<1>(key));
+      writer.write<uint8_t>(std::get<2>(key));
+    }
+
+    unsigned getUnversionedInfoSize(const ObjCMethodInfo &info) {
+      return 1 + getFunctionInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const ObjCMethodInfo &info) {
+      uint8_t payload = info.FactoryAsInit;
+      payload = (payload << 1) | info.DesignatedInit;
+      payload = (payload << 1) | info.Required;
+      endian::Writer<little> writer(out);
+      writer.write<uint8_t>(payload);
+
+      emitFunctionInfo(out, info);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeObjCMethodBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, OBJC_METHOD_BLOCK_ID, 3);
+
+  if (ObjCMethods.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<ObjCMethodTableInfo> generator;
+    for (auto &entry : ObjCMethods) {
+      generator.insert(entry.first, entry.second);
+    }
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  objc_method_block::ObjCMethodDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk Objective-C selector table.
+  class ObjCSelectorTableInfo {
+  public:
+    using key_type = StoredObjCSelector;
+    using key_type_ref = const key_type &;
+    using data_type = SelectorID;
+    using data_type_ref = data_type;
+    using hash_value_type = unsigned;
+    using offset_type = unsigned;
+
+    hash_value_type ComputeHash(key_type_ref key) {
+      return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(key);
+    }
+
+    std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
+                                                    key_type_ref key,
+                                                    data_type_ref data) {
+      uint32_t keyLength = sizeof(uint16_t) 
+                         + sizeof(uint32_t) * key.Identifiers.size();
+      uint32_t dataLength = sizeof(uint32_t);
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(keyLength);
+      writer.write<uint16_t>(dataLength);
+      return { keyLength, dataLength };
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(key.NumPieces);
+      for (auto piece : key.Identifiers) {
+        writer.write<uint32_t>(piece);
+      }
+    }
+
+    void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                  unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(data);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeObjCSelectorBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, OBJC_SELECTOR_BLOCK_ID, 3);
+
+  if (SelectorIDs.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<ObjCSelectorTableInfo> generator;
+    for (auto &entry : SelectorIDs)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  objc_selector_block::ObjCSelectorDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk global variable table.
+  class GlobalVariableTableInfo
+    : public VersionedTableInfo<GlobalVariableTableInfo,
+                                unsigned,
+                                GlobalVariableInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref key) {
+      return sizeof(uint32_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const GlobalVariableInfo &info) {
+      return getVariableInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out,
+                             const GlobalVariableInfo &info) {
+      emitVariableInfo(out, info);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeGlobalVariableBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, GLOBAL_VARIABLE_BLOCK_ID, 3);
+
+  if (GlobalVariables.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<GlobalVariableTableInfo> generator;
+    for (auto &entry : GlobalVariables)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  global_variable_block::GlobalVariableDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk global function table.
+  class GlobalFunctionTableInfo
+    : public VersionedTableInfo<GlobalFunctionTableInfo,
+                                unsigned,
+                                GlobalFunctionInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const GlobalFunctionInfo &info) {
+      return getFunctionInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out,
+                             const GlobalFunctionInfo &info) {
+      emitFunctionInfo(out, info);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeGlobalFunctionBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, GLOBAL_FUNCTION_BLOCK_ID, 3);
+
+  if (GlobalFunctions.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<GlobalFunctionTableInfo> generator;
+    for (auto &entry : GlobalFunctions) {
+      generator.insert(entry.first, entry.second);
+    }
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  global_function_block::GlobalFunctionDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk global enum constant.
+  class EnumConstantTableInfo
+    : public VersionedTableInfo<EnumConstantTableInfo,
+                                unsigned,
+                                EnumConstantInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const EnumConstantInfo &info) {
+      return getCommonEntityInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const EnumConstantInfo &info) {
+      emitCommonEntityInfo(out, info);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeEnumConstantBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, ENUM_CONSTANT_BLOCK_ID, 3);
+
+  if (EnumConstants.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<EnumConstantTableInfo> generator;
+    for (auto &entry : EnumConstants)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  enum_constant_block::EnumConstantDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  template<typename Derived, typename UnversionedDataType>
+  class CommonTypeTableInfo
+    : public VersionedTableInfo<Derived, unsigned, UnversionedDataType> {
+  public:
+    using key_type_ref = typename CommonTypeTableInfo::key_type_ref;
+
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(IdentifierID);
+    }
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<IdentifierID>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const UnversionedDataType &info) {
+      return getCommonTypeInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out,
+                             const UnversionedDataType &info) {
+      emitCommonTypeInfo(out, info);
+    }
+  };
+
+  /// Used to serialize the on-disk tag table.
+  class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> { };
+
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeTagBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, TAG_BLOCK_ID, 3);
+
+  if (Tags.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<TagTableInfo> generator;
+    for (auto &entry : Tags)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  tag_block::TagDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk typedef table.
+  class TypedefTableInfo
+    : public CommonTypeTableInfo<TypedefTableInfo, TypedefInfo> {
+
+  public:
+    unsigned getUnversionedInfoSize(const TypedefInfo &info) {
+      return 1 + getCommonTypeInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const TypedefInfo &info) {
+      endian::Writer<little> writer(out);
+
+      uint8_t payload = 0;
+      if (auto swiftWrapper = info.SwiftWrapper) {
+        payload |= static_cast<uint8_t>(*swiftWrapper) + 1;
+      }
+
+      writer.write<uint8_t>(payload);
+
+      emitCommonTypeInfo(out, info);
+    }
+
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeTypedefBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, TYPEDEF_BLOCK_ID, 3);
+
+  if (Typedefs.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<TypedefTableInfo> generator;
+    for (auto &entry : Typedefs)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  typedef_block::TypedefDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+void APINotesWriter::Implementation::writeToStream(llvm::raw_ostream &os) {
+  // Write the API notes file into a buffer.
+  SmallVector<char, 0> buffer;
+  {
+    llvm::BitstreamWriter writer(buffer);
+
+    // Emit the signature.
+    for (unsigned char byte : API_NOTES_SIGNATURE)
+      writer.Emit(byte, 8);
+
+    // Emit the blocks.
+    writeBlockInfoBlock(writer);
+    writeControlBlock(writer);
+    writeIdentifierBlock(writer);
+    writeObjCContextBlock(writer);
+    writeObjCPropertyBlock(writer);
+    writeObjCMethodBlock(writer);
+    writeObjCSelectorBlock(writer);
+    writeGlobalVariableBlock(writer);
+    writeGlobalFunctionBlock(writer);
+    writeEnumConstantBlock(writer);
+    writeTagBlock(writer);
+    writeTypedefBlock(writer);
+  }
+
+  // Write the buffer to the stream.
+  os.write(buffer.data(), buffer.size());
+  os.flush();
+}
+
+APINotesWriter::APINotesWriter(StringRef moduleName, const FileEntry *sourceFile)
+  : Impl(*new Implementation)
+{
+  Impl.ModuleName = moduleName;
+  Impl.SourceFile = sourceFile;
+}
+
+APINotesWriter::~APINotesWriter() {
+  delete &Impl;
+}
+
+
+void APINotesWriter::writeToStream(raw_ostream &os) {
+  Impl.writeToStream(os);
+}
+
+ContextID APINotesWriter::addObjCContext(StringRef name, bool isClass,
+                                         const ObjCContextInfo &info,
+                                         VersionTuple swiftVersion) {
+  IdentifierID nameID = Impl.getIdentifier(name);
+
+  std::pair<unsigned, char> key(nameID, isClass ? 0 : 1);
+  auto known = Impl.ObjCContexts.find(key);
+  if (known == Impl.ObjCContexts.end()) {
+    unsigned nextID = Impl.ObjCContexts.size() + 1;
+
+    VersionedSmallVector<ObjCContextInfo> emptyVersionedInfo;
+    known = Impl.ObjCContexts.insert(
+              std::make_pair(key, std::make_pair(nextID, emptyVersionedInfo)))
+              .first;
+
+    Impl.ObjCContextNames[nextID] = nameID;
+  }
+
+  // Add this version information.
+  auto &versionedVec = known->second.second;
+  bool found = false;
+  for (auto &versioned : versionedVec){
+    if (versioned.first == swiftVersion) {
+      versioned.second |= info;
+      found = true;
+      break;
+    }
+  }
+
+  if (!found)
+    versionedVec.push_back({swiftVersion, info});
+
+  return ContextID(known->second.first);
+}
+
+void APINotesWriter::addObjCProperty(ContextID contextID, StringRef name,
+                                     bool isInstance,
+                                     const ObjCPropertyInfo &info,
+                                     VersionTuple swiftVersion) {
+  IdentifierID nameID = Impl.getIdentifier(name);
+  Impl.ObjCProperties[std::make_tuple(contextID.Value, nameID, isInstance)]
+    .push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addObjCMethod(ContextID contextID,
+                                   ObjCSelectorRef selector,
+                                   bool isInstanceMethod,
+                                   const ObjCMethodInfo &info,
+                                   VersionTuple swiftVersion) {
+  SelectorID selectorID = Impl.getSelector(selector);
+  auto key = std::tuple<unsigned, unsigned, char>{
+      contextID.Value, selectorID, isInstanceMethod};
+  Impl.ObjCMethods[key].push_back({swiftVersion, info});
+
+  // If this method is a designated initializer, update the class to note that
+  // it has designated initializers.
+  if (info.DesignatedInit) {
+    assert(Impl.ObjCContexts.count({Impl.ObjCContextNames[contextID.Value],
+                                    (char)0}));
+    auto &versionedVec =
+      Impl.ObjCContexts[{Impl.ObjCContextNames[contextID.Value], (char)0}]
+        .second;
+    bool found = false;
+    for (auto &versioned : versionedVec) {
+      if (versioned.first == swiftVersion) {
+        versioned.second.setHasDesignatedInits(true);
+        found = true;
+        break;
+      }
+    }
+
+    if (!found) {
+      versionedVec.push_back({swiftVersion, ObjCContextInfo()});
+      versionedVec.back().second.setHasDesignatedInits(true);
+    }
+  }
+}
+
+void APINotesWriter::addGlobalVariable(llvm::StringRef name,
+                                       const GlobalVariableInfo &info,
+                                       VersionTuple swiftVersion) {
+  IdentifierID variableID = Impl.getIdentifier(name);
+  Impl.GlobalVariables[variableID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addGlobalFunction(llvm::StringRef name,
+                                       const GlobalFunctionInfo &info,
+                                       VersionTuple swiftVersion) {
+  IdentifierID nameID = Impl.getIdentifier(name);
+  Impl.GlobalFunctions[nameID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addEnumConstant(llvm::StringRef name,
+                                     const EnumConstantInfo &info,
+                                     VersionTuple swiftVersion) {
+  IdentifierID enumConstantID = Impl.getIdentifier(name);
+  Impl.EnumConstants[enumConstantID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addTag(llvm::StringRef name, const TagInfo &info,
+                            VersionTuple swiftVersion) {
+  IdentifierID tagID = Impl.getIdentifier(name);
+  Impl.Tags[tagID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addTypedef(llvm::StringRef name, const TypedefInfo &info,
+                                VersionTuple swiftVersion) {
+  IdentifierID typedefID = Impl.getIdentifier(name);
+  Impl.Typedefs[typedefID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addModuleOptions(ModuleOptions opts) {
+  Impl.SwiftInferImportAsMember = opts.SwiftInferImportAsMember;
+}
+
diff --git a/lib/APINotes/APINotesYAMLCompiler.cpp b/lib/APINotes/APINotesYAMLCompiler.cpp
new file mode 100644
index 0000000..0ac0b6d
--- /dev/null
+++ b/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -0,0 +1,1411 @@
+//===--- APINotesYAMLCompiler.cpp - API Notes YAML format reader *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file reads API notes specified in YAML format.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/APINotesYAMLCompiler.h"
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/APINotes/Types.h"
+#include "clang/APINotes/APINotesWriter.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <algorithm>
+
+/*
+ 
+ YAML Format specification.
+
+ Nullability should be expressed using one of the following values:
+   O - Optional (or Nullable)
+   N - Not Optional
+   S - Scalar
+   U - Unknown
+ Note, the API is considered 'audited' when at least the return value or a
+ 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
+
+ Availability: OSX        # Optional: Specifies which platform the API is
+                          # available on. [OSX / iOS / none/
+                          #                available / nonswift]
+
+ AvailabilityMsg: ""  # Optional: Custom availability message to display to
+                          # the user, when API is not available.
+
+ Classes:                 # List of classes
+ ...
+ Protocols:               # List of protocols
+ ...
+ Functions:               # List of functions
+ ...
+ Globals:                 # List of globals
+ ...
+ Enumerators:             # List of enumerators
+ ...
+ Tags:                    # List of tags (struct/union/enum/C++ class)
+ ...
+ Typedefs:                # List of typedef-names and C++11 type aliases
+ ...
+
+ Each class and protocol is defined as following:
+
+ - Name: NSView                       # The name of the class
+ 
+   AuditedForNullability: false       # Optional: Specifies if the whole class
+                                      # has been audited for nullability.
+                                      # If yes, we assume all the methods and
+                                      # properties of the class have default
+                                      # nullability unless it is overwritten by
+                                      # a method/property specific info below.
+                                      # This applies to all classes, extensions,
+                                      # and categories of the class defined in
+                                      # the current framework/module.
+                                      # (false/true)
+
+   Availability: OSX
+
+   AvailabilityMsg: ""
+
+   Methods:
+     - Selector: "setSubviews:"       # Full name
+
+       MethodKind: Instance           # [Class/Instance]
+
+       Nullability: [N, N, O, S]      # The nullability of parameters in
+                                      # the signature.
+
+       NullabilityOfRet: O            # The nullability of the return value.
+
+       Availability: OSX
+
+       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)
+
+       Required: false                # Optional: Specifies if this method is a
+                                      # required initializer (false/true)
+
+   Properties:
+     - Name: window
+
+       Nullability: O
+
+       Availability: OSX
+
+       AvailabilityMsg: ""
+
+ The protocol definition format is the same as the class definition.
+
+ Each function definition is of the following form:
+
+ - Name: "myGlobalFunction"           # Full name
+
+   Nullability: [N, N, O, S]          # The nullability of parameters in
+                                      # the signature.
+
+   NullabilityOfRet: O                # The nullability of the return value.
+
+   Availability: OSX
+
+   AvailabilityMsg: ""
+
+Each global variable definition is of the following form:
+
+ - Name: MyGlobalVar
+
+   Nullability: O
+
+   Availability: OSX
+
+   AvailabilityMsg: ""
+
+*/
+
+using llvm::StringRef;
+using namespace clang;
+namespace {
+  enum class APIAvailability {
+    Available = 0,
+    OSX,
+    IOS,
+    None,
+    NonSwift,
+  };
+
+  enum class MethodKind {
+    Class,
+    Instance,
+  };
+
+  struct AvailabilityItem {
+    APIAvailability Mode = APIAvailability::Available;
+    StringRef Msg;
+    AvailabilityItem() : Mode(APIAvailability::Available), Msg("") {}
+  };
+
+  static llvm::Optional<NullabilityKind> AbsentNullability = llvm::None;
+  static llvm::Optional<NullabilityKind> DefaultNullability =
+    NullabilityKind::NonNull;
+  typedef std::vector<clang::NullabilityKind> NullabilitySeq;
+
+  struct Param {
+    unsigned Position;
+    Optional<bool> NoEscape = false;
+    llvm::Optional<NullabilityKind> Nullability;
+    StringRef Type;
+  };
+  typedef std::vector<Param> ParamsSeq;
+
+  struct Method {
+    StringRef Selector;
+    MethodKind Kind;
+    ParamsSeq Params;
+    NullabilitySeq Nullability;
+    llvm::Optional<NullabilityKind> NullabilityOfRet;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    api_notes::FactoryAsInitKind FactoryAsInit
+      = api_notes::FactoryAsInitKind::Infer;
+    bool DesignatedInit = false;
+    bool Required = false;
+    StringRef ResultType;
+  };
+  typedef std::vector<Method> MethodsSeq;
+
+  struct Property {
+    StringRef Name;
+    llvm::Optional<MethodKind> Kind;
+    llvm::Optional<NullabilityKind> Nullability;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    Optional<bool> SwiftImportAsAccessors;
+    StringRef Type;
+  };
+  typedef std::vector<Property> PropertiesSeq;
+
+  struct Class {
+    StringRef Name;
+    bool AuditedForNullability = false;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
+    MethodsSeq Methods;
+    PropertiesSeq Properties;
+  };
+  typedef std::vector<Class> ClassesSeq;
+
+  struct Function {
+    StringRef Name;
+    ParamsSeq Params;
+    NullabilitySeq Nullability;
+    llvm::Optional<NullabilityKind> NullabilityOfRet;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    StringRef Type;
+    StringRef ResultType;
+  };
+  typedef std::vector<Function> FunctionsSeq;
+
+  struct GlobalVariable {
+    StringRef Name;
+    llvm::Optional<NullabilityKind> Nullability;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    StringRef Type;
+  };
+  typedef std::vector<GlobalVariable> GlobalVariablesSeq;
+
+  struct EnumConstant {
+    StringRef Name;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+  };
+  typedef std::vector<EnumConstant> EnumConstantsSeq;
+
+  struct Tag {
+    StringRef Name;
+    AvailabilityItem Availability;
+    StringRef SwiftName;
+    Optional<bool> SwiftPrivate;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
+  };
+  typedef std::vector<Tag> TagsSeq;
+
+  struct Typedef {
+    StringRef Name;
+    AvailabilityItem Availability;
+    StringRef SwiftName;
+    Optional<bool> SwiftPrivate;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
+    Optional<api_notes::SwiftWrapperKind> SwiftWrapper;
+  };
+  typedef std::vector<Typedef> TypedefsSeq;
+
+  struct TopLevelItems {
+    ClassesSeq Classes;
+    ClassesSeq Protocols;
+    FunctionsSeq Functions;
+    GlobalVariablesSeq Globals;
+    EnumConstantsSeq EnumConstants;
+    TagsSeq Tags;
+    TypedefsSeq Typedefs;
+  };
+
+  struct Versioned {
+    VersionTuple Version;
+    TopLevelItems Items;
+  };
+
+  typedef std::vector<Versioned> VersionedSeq;
+
+  struct Module {
+    StringRef Name;
+    AvailabilityItem Availability;
+    TopLevelItems TopLevel;
+    VersionedSeq SwiftVersions;
+
+    llvm::Optional<bool> SwiftInferImportAsMember = {llvm::None};
+
+    LLVM_ATTRIBUTE_DEPRECATED(
+      void dump() LLVM_ATTRIBUTE_USED,
+      "only for use within the debugger");
+  };
+}
+
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(clang::NullabilityKind)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
+LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
+LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
+
+namespace llvm {
+  namespace yaml {
+
+    template <>
+    struct ScalarEnumerationTraits<NullabilityKind > {
+      static void enumeration(IO &io, NullabilityKind  &value) {
+        io.enumCase(value, "N", NullabilityKind::NonNull);
+        io.enumCase(value, "O", NullabilityKind::Nullable);
+        io.enumCase(value, "U", NullabilityKind::Unspecified);
+        // TODO: Mapping this to it's own value would allow for better cross
+        // checking. Also the default should be Unknown.
+        io.enumCase(value, "S", NullabilityKind::Unspecified);
+      }
+    };
+
+    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);
+      }
+    };
+
+    template <>
+    struct ScalarEnumerationTraits<MethodKind> {
+      static void enumeration(IO &io, MethodKind &value) {
+        io.enumCase(value, "Class",    MethodKind::Class);
+        io.enumCase(value, "Instance", MethodKind::Instance);
+      }
+    };
+
+    template <>
+    struct ScalarEnumerationTraits<APIAvailability> {
+      static void enumeration(IO &io, APIAvailability &value) {
+        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);
+      }
+    };
+
+    template<>
+    struct ScalarEnumerationTraits<api_notes::SwiftWrapperKind> {
+      static void enumeration(IO &io, api_notes::SwiftWrapperKind &value) {
+        io.enumCase(value, "none",      api_notes::SwiftWrapperKind::None);
+        io.enumCase(value, "struct",    api_notes::SwiftWrapperKind::Struct);
+        io.enumCase(value, "enum",      api_notes::SwiftWrapperKind::Enum);
+      }
+    };
+
+    template <>
+    struct ScalarTraits<VersionTuple> {
+      static void output(const VersionTuple &value, void*,
+                         llvm::raw_ostream &out) {
+        out << value;
+      }
+      static StringRef input(StringRef scalar, void*, VersionTuple &value) {
+        if (value.tryParse(scalar))
+          return "not a version number in the form XX.YY";
+
+        // Canonicalize on '.' as a separator.
+        value.UseDotAsSeparator();
+        return StringRef();
+      }
+
+      static bool mustQuote(StringRef) { return false; }
+    };
+
+    template <>
+    struct MappingTraits<Param> {
+      static void mapping(IO &io, Param& p) {
+        io.mapRequired("Position",        p.Position);
+        io.mapOptional("Nullability",     p.Nullability, 
+                                          AbsentNullability);
+        io.mapOptional("NoEscape",        p.NoEscape);
+        io.mapOptional("Type",            p.Type, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<Property> {
+      static void mapping(IO &io, Property& p) {
+        io.mapRequired("Name",            p.Name);
+        io.mapOptional("PropertyKind",    p.Kind);
+        io.mapOptional("Nullability",     p.Nullability, 
+                                          AbsentNullability);
+        io.mapOptional("Availability",    p.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", p.Availability.Msg);
+        io.mapOptional("SwiftPrivate",    p.SwiftPrivate);
+        io.mapOptional("SwiftName",       p.SwiftName);
+        io.mapOptional("SwiftImportAsAccessors", p.SwiftImportAsAccessors);
+        io.mapOptional("Type",            p.Type, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<Method> {
+      static void mapping(IO &io, Method& m) {
+        io.mapRequired("Selector",        m.Selector);
+        io.mapRequired("MethodKind",      m.Kind);
+        io.mapOptional("Parameters",      m.Params);
+        io.mapOptional("Nullability",     m.Nullability);
+        io.mapOptional("NullabilityOfRet",  m.NullabilityOfRet,
+                                            AbsentNullability);
+        io.mapOptional("Availability",    m.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", m.Availability.Msg);
+        io.mapOptional("SwiftPrivate",    m.SwiftPrivate);
+        io.mapOptional("SwiftName",       m.SwiftName);
+        io.mapOptional("FactoryAsInit",   m.FactoryAsInit,
+                                          api_notes::FactoryAsInitKind::Infer);
+        io.mapOptional("DesignatedInit",  m.DesignatedInit, false);
+        io.mapOptional("Required",        m.Required, false);
+        io.mapOptional("ResultType",      m.ResultType, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<Class> {
+      static void mapping(IO &io, Class& c) {
+        io.mapRequired("Name",                  c.Name);
+        io.mapOptional("AuditedForNullability", c.AuditedForNullability, false);
+        io.mapOptional("Availability",          c.Availability.Mode);
+        io.mapOptional("AvailabilityMsg",       c.Availability.Msg);
+        io.mapOptional("SwiftPrivate",          c.SwiftPrivate);
+        io.mapOptional("SwiftName",             c.SwiftName);
+        io.mapOptional("SwiftBridge",           c.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         c.NSErrorDomain);
+        io.mapOptional("Methods",               c.Methods);
+        io.mapOptional("Properties",            c.Properties);
+      }
+    };
+
+    template <>
+    struct MappingTraits<Function> {
+      static void mapping(IO &io, Function& f) {
+        io.mapRequired("Name",             f.Name);
+        io.mapOptional("Parameters",       f.Params);
+        io.mapOptional("Nullability",      f.Nullability);
+        io.mapOptional("NullabilityOfRet", f.NullabilityOfRet,
+                                           AbsentNullability);
+        io.mapOptional("Availability",     f.Availability.Mode);
+        io.mapOptional("AvailabilityMsg",  f.Availability.Msg);
+        io.mapOptional("SwiftPrivate",     f.SwiftPrivate);
+        io.mapOptional("SwiftName",        f.SwiftName);
+        io.mapOptional("ResultType",       f.ResultType, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<GlobalVariable> {
+      static void mapping(IO &io, GlobalVariable& v) {
+        io.mapRequired("Name",            v.Name);
+        io.mapOptional("Nullability",     v.Nullability,
+                                          AbsentNullability);
+        io.mapOptional("Availability",    v.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", v.Availability.Msg);
+        io.mapOptional("SwiftPrivate",    v.SwiftPrivate);
+        io.mapOptional("SwiftName",       v.SwiftName);
+        io.mapOptional("Type",            v.Type, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<EnumConstant> {
+      static void mapping(IO &io, EnumConstant& v) {
+        io.mapRequired("Name",            v.Name);
+        io.mapOptional("Availability",    v.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", v.Availability.Msg);
+        io.mapOptional("SwiftPrivate",    v.SwiftPrivate);
+        io.mapOptional("SwiftName",       v.SwiftName);
+      }
+    };
+
+    template <>
+    struct MappingTraits<Tag> {
+      static void mapping(IO &io, Tag& t) {
+        io.mapRequired("Name",                  t.Name);
+        io.mapOptional("Availability",          t.Availability.Mode);
+        io.mapOptional("AvailabilityMsg",       t.Availability.Msg);
+        io.mapOptional("SwiftPrivate",          t.SwiftPrivate);
+        io.mapOptional("SwiftName",             t.SwiftName);
+        io.mapOptional("SwiftBridge",           t.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         t.NSErrorDomain);
+      }
+    };
+
+    template <>
+    struct MappingTraits<Typedef> {
+      static void mapping(IO &io, Typedef& t) {
+        io.mapRequired("Name",                  t.Name);
+        io.mapOptional("Availability",          t.Availability.Mode);
+        io.mapOptional("AvailabilityMsg",       t.Availability.Msg);
+        io.mapOptional("SwiftPrivate",          t.SwiftPrivate);
+        io.mapOptional("SwiftName",             t.SwiftName);
+        io.mapOptional("SwiftBridge",           t.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         t.NSErrorDomain);
+        io.mapOptional("SwiftWrapper",         t.SwiftWrapper);
+      }
+    };
+
+    static void mapTopLevelItems(IO &io, TopLevelItems &i) {
+      io.mapOptional("Classes",         i.Classes);
+      io.mapOptional("Protocols",       i.Protocols);
+      io.mapOptional("Functions",       i.Functions);
+      io.mapOptional("Globals",         i.Globals);
+      io.mapOptional("Enumerators",     i.EnumConstants);
+      io.mapOptional("Tags",            i.Tags);
+      io.mapOptional("Typedefs",        i.Typedefs);
+    }
+
+    template <>
+    struct MappingTraits<Versioned> {
+      static void mapping(IO &io, Versioned& v) {
+        io.mapRequired("Version", v.Version);
+        mapTopLevelItems(io, v.Items);
+      }
+    };
+
+    template <>
+    struct MappingTraits<Module> {
+      static void mapping(IO &io, Module& m) {
+        io.mapRequired("Name",            m.Name);
+        io.mapOptional("Availability",    m.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", m.Availability.Msg);
+        io.mapOptional("SwiftInferImportAsMember", m.SwiftInferImportAsMember);
+
+        mapTopLevelItems(io, m.TopLevel);
+
+        io.mapOptional("SwiftVersions",  m.SwiftVersions);
+      }
+    };
+  }
+}
+
+using llvm::yaml::Input;
+using llvm::yaml::Output;
+
+void Module::dump() {
+  Output yout(llvm::errs());
+  yout << *this;
+}
+
+static bool parseAPINotes(StringRef yamlInput, Module &module,
+                          llvm::SourceMgr::DiagHandlerTy diagHandler,
+                          void *diagHandlerCtxt) {
+  Input yin(yamlInput, nullptr, diagHandler, diagHandlerCtxt);
+  yin >> module;
+
+  return static_cast<bool>(yin.error());
+}
+
+namespace {
+  using namespace api_notes;
+
+  class YAMLConverter {
+    const Module &TheModule;
+    const FileEntry *SourceFile;
+    APINotesWriter *Writer;
+    OSType TargetOS;
+    llvm::raw_ostream &OS;
+    llvm::SourceMgr::DiagHandlerTy DiagHandler;
+    void *DiagHandlerCtxt;
+    bool ErrorOccured;
+
+    /// Emit a diagnostic
+    bool emitError(llvm::Twine message) {
+      DiagHandler(llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error,
+                                     message.str()),
+                  DiagHandlerCtxt);
+      ErrorOccured = true;
+      return true;
+    }
+
+  public:
+    YAMLConverter(const Module &module,
+                  const FileEntry *sourceFile,
+                  OSType targetOS,
+                  llvm::raw_ostream &os,
+                  llvm::SourceMgr::DiagHandlerTy diagHandler,
+                  void *diagHandlerCtxt) :
+      TheModule(module), SourceFile(sourceFile), Writer(0), TargetOS(targetOS), OS(os),
+      DiagHandler(diagHandler), DiagHandlerCtxt(diagHandlerCtxt),
+      ErrorOccured(false) {}
+
+    bool isAvailable(const AvailabilityItem &in) {
+      // Check if the API is available on the OS for which we are building.
+      if (in.Mode == APIAvailability::OSX && TargetOS != OSType::OSX)
+        return false;
+      if (in.Mode == APIAvailability::IOS && TargetOS != OSType::IOS)
+        return false;
+      return true;
+    }
+
+    bool convertAvailability(const AvailabilityItem &in,
+                             CommonEntityInfo &outInfo,
+                             llvm::StringRef apiName) {
+      // Populate the unavailability information.
+      outInfo.Unavailable = (in.Mode == APIAvailability::None);
+      outInfo.UnavailableInSwift = (in.Mode == APIAvailability::NonSwift);
+      if (outInfo.Unavailable || outInfo.UnavailableInSwift) {
+        outInfo.UnavailableMsg = in.Msg;
+      } else {
+        if (!in.Msg.empty()) {
+          emitError("availability message for available API '" +
+                    apiName + "' will not be used");
+        }
+      }
+      return false;
+    }
+
+    void convertParams(const ParamsSeq &params, FunctionInfo &outInfo) {
+      for (const auto &p : params) {
+        ParamInfo pi;
+        if (p.Nullability)
+          pi.setNullabilityAudited(*p.Nullability);
+        pi.setNoEscape(p.NoEscape);
+        pi.setType(p.Type);
+        while (outInfo.Params.size() <= p.Position) {
+          outInfo.Params.push_back(ParamInfo());
+        }
+        outInfo.Params[p.Position] |= pi;
+      }
+    }
+
+    void convertNullability(const NullabilitySeq &nullability,
+                            Optional<NullabilityKind> nullabilityOfRet,
+                            FunctionInfo &outInfo,
+                            llvm::StringRef apiName) {
+      if (nullability.size() > FunctionInfo::getMaxNullabilityIndex()) {
+        emitError("nullability info for " + apiName + " does not fit");
+        return;
+      }
+
+      bool audited = false;
+      unsigned int idx = 1;
+      for (auto i = nullability.begin(),
+                e = nullability.end(); i != e; ++i, ++idx){
+        outInfo.addTypeInfo(idx, *i);
+        audited = true;
+      }
+      if (nullabilityOfRet) {
+        outInfo.addTypeInfo(0, *nullabilityOfRet);
+        audited = true;
+      } else if (audited) {
+        outInfo.addTypeInfo(0, *DefaultNullability);
+      }
+      if (audited) {
+        outInfo.NullabilityAudited = audited;
+        outInfo.NumAdjustedNullable = idx;
+      }
+    }
+
+    /// Convert the common parts of an entity from YAML.
+    template<typename T>
+    bool convertCommon(const T& common, CommonEntityInfo &info,
+                       StringRef apiName) {
+      if (!isAvailable(common.Availability))
+        return true;
+
+      convertAvailability(common.Availability, info, apiName);
+      info.setSwiftPrivate(common.SwiftPrivate);
+      info.SwiftName = common.SwiftName;
+      return false;
+    }
+    
+    /// Convert the common parts of a type entity from YAML.
+    template<typename T>
+    bool convertCommonType(const T& common, CommonTypeInfo &info,
+                           StringRef apiName) {
+      if (convertCommon(common, info, apiName))
+        return true;
+
+      info.setSwiftBridge(common.SwiftBridge);
+      info.setNSErrorDomain(common.NSErrorDomain);
+      return false;
+    }
+
+    // Translate from Method into ObjCMethodInfo and write it out.
+    void convertMethod(const Method &meth,
+                       ContextID classID, StringRef className,
+                       VersionTuple swiftVersion) {
+      ObjCMethodInfo mInfo;
+
+      if (convertCommon(meth, mInfo, meth.Selector))
+        return;
+
+      // Check if the selector ends with ':' to determine if it takes arguments.
+      bool takesArguments = meth.Selector.endswith(":");
+
+      // Split the selector into pieces.
+      llvm::SmallVector<StringRef, 4> a;
+      meth.Selector.split(a, ":", /*MaxSplit*/ -1, /*KeepEmpty*/ false);
+      if (!takesArguments && a.size() > 1 ) {
+        emitError("selector " + meth.Selector + "is missing a ':' at the end");
+        return;
+      }
+
+      // Construct ObjCSelectorRef.
+      api_notes::ObjCSelectorRef selectorRef;
+      selectorRef.NumPieces = !takesArguments ? 0 : a.size();
+      selectorRef.Identifiers = a;
+
+      // Translate the initializer info.
+      mInfo.DesignatedInit = meth.DesignatedInit;
+      mInfo.Required = meth.Required;
+      if (meth.FactoryAsInit != FactoryAsInitKind::Infer)
+        mInfo.setFactoryAsInitKind(meth.FactoryAsInit);
+      mInfo.ResultType = meth.ResultType;
+
+      // Translate parameter information.
+      convertParams(meth.Params, mInfo);
+
+      // Translate nullability info.
+      convertNullability(meth.Nullability, meth.NullabilityOfRet,
+                         mInfo, meth.Selector);
+
+      // Write it.
+      Writer->addObjCMethod(classID, selectorRef,
+                            meth.Kind == MethodKind::Instance,
+                            mInfo, swiftVersion);
+    }
+
+    void convertContext(const Class &cl, bool isClass,
+                        VersionTuple swiftVersion) {
+      // Write the class.
+      ObjCContextInfo cInfo;
+
+      if (convertCommonType(cl, cInfo, cl.Name))
+        return;
+
+      if (cl.AuditedForNullability)
+        cInfo.setDefaultNullability(*DefaultNullability);
+
+      ContextID clID = Writer->addObjCContext(cl.Name, isClass, cInfo,
+                                              swiftVersion);
+
+      // Write all methods.
+      llvm::StringMap<std::pair<bool, bool>> knownMethods;
+      for (const auto &method : cl.Methods) {
+        // Check for duplicate method definitions.
+        bool isInstanceMethod = method.Kind == MethodKind::Instance;
+        bool &known = isInstanceMethod ? knownMethods[method.Selector].first
+                                       : knownMethods[method.Selector].second;
+        if (known) {
+          emitError(llvm::Twine("duplicate definition of method '") +
+                    (isInstanceMethod? "-" : "+") + "[" + cl.Name + " " +
+                    method.Selector + "]'");
+          continue;
+        }
+        known = true;
+
+        convertMethod(method, clID, cl.Name, swiftVersion);
+      }
+
+      // Write all properties.
+      llvm::StringSet<> knownInstanceProperties;
+      llvm::StringSet<> knownClassProperties;
+      for (const auto &prop : cl.Properties) {
+        // Check for duplicate property definitions.
+        if ((!prop.Kind || *prop.Kind == MethodKind::Instance) &&
+            !knownInstanceProperties.insert(prop.Name).second) {
+          emitError("duplicate definition of instance property '" + cl.Name +
+                    "." + prop.Name + "'");
+          continue;
+        }
+
+        if ((!prop.Kind || *prop.Kind == MethodKind::Class) &&
+            !knownClassProperties.insert(prop.Name).second) {
+          emitError("duplicate definition of class property '" + cl.Name + "." +
+                    prop.Name + "'");
+          continue;
+        }
+
+        // Translate from Property into ObjCPropertyInfo.
+        ObjCPropertyInfo pInfo;
+        if (!isAvailable(prop.Availability))
+          continue;
+        convertAvailability(prop.Availability, pInfo, prop.Name);
+        pInfo.setSwiftPrivate(prop.SwiftPrivate);
+        pInfo.SwiftName = prop.SwiftName;
+        if (prop.Nullability)
+          pInfo.setNullabilityAudited(*prop.Nullability);
+        if (prop.SwiftImportAsAccessors)
+          pInfo.setSwiftImportAsAccessors(*prop.SwiftImportAsAccessors);
+        pInfo.setType(prop.Type);
+        if (prop.Kind) {
+          Writer->addObjCProperty(clID, prop.Name,
+                                  *prop.Kind == MethodKind::Instance, pInfo,
+                                  swiftVersion);
+        } else {
+          // Add both instance and class properties with this name.
+          Writer->addObjCProperty(clID, prop.Name, true, pInfo, swiftVersion);
+          Writer->addObjCProperty(clID, prop.Name, false, pInfo, swiftVersion);
+        }
+      }
+    }
+
+    void convertTopLevelItems(const TopLevelItems &items,
+                              VersionTuple swiftVersion) {
+      // Write all classes.
+      llvm::StringSet<> knownClasses;
+      for (const auto &cl : items.Classes) {
+        // Check for duplicate class definitions.
+        if (!knownClasses.insert(cl.Name).second) {
+          emitError("multiple definitions of class '" + cl.Name + "'");
+          continue;
+        }
+
+        convertContext(cl, /*isClass*/ true, swiftVersion);
+      }
+
+      // Write all protocols.
+      llvm::StringSet<> knownProtocols;
+      for (const auto &pr : items.Protocols) {
+        // Check for duplicate protocol definitions.
+        if (!knownProtocols.insert(pr.Name).second) {
+          emitError("multiple definitions of protocol '" + pr.Name + "'");
+          continue;
+        }
+
+        convertContext(pr, /*isClass*/ false, swiftVersion);
+      }
+
+      // Write all global variables.
+      llvm::StringSet<> knownGlobals;
+      for (const auto &global : items.Globals) {
+        // Check for duplicate global variables.
+        if (!knownGlobals.insert(global.Name).second) {
+          emitError("multiple definitions of global variable '" +
+                    global.Name + "'");
+          continue;
+        }
+
+        GlobalVariableInfo info;
+        if (!isAvailable(global.Availability))
+          continue;
+        convertAvailability(global.Availability, info, global.Name);
+        info.setSwiftPrivate(global.SwiftPrivate);
+        info.SwiftName = global.SwiftName;
+        if (global.Nullability)
+          info.setNullabilityAudited(*global.Nullability);
+        info.setType(global.Type);
+        Writer->addGlobalVariable(global.Name, info, swiftVersion);
+      }
+
+      // Write all global functions.
+      llvm::StringSet<> knownFunctions;
+      for (const auto &function : items.Functions) {
+        // Check for duplicate global functions.
+        if (!knownFunctions.insert(function.Name).second) {
+          emitError("multiple definitions of global function '" +
+                    function.Name + "'");
+          continue;
+        }
+
+        GlobalFunctionInfo info;
+        if (!isAvailable(function.Availability))
+          continue;
+        convertAvailability(function.Availability, info, function.Name);
+        info.setSwiftPrivate(function.SwiftPrivate);
+        info.SwiftName = function.SwiftName;
+        convertParams(function.Params, info);
+        convertNullability(function.Nullability,
+                           function.NullabilityOfRet,
+                           info, function.Name);
+        info.ResultType = function.ResultType;
+        Writer->addGlobalFunction(function.Name, info, swiftVersion);
+      }
+
+      // Write all enumerators.
+      llvm::StringSet<> knownEnumConstants;
+      for (const auto &enumConstant : items.EnumConstants) {
+        // Check for duplicate enumerators
+        if (!knownEnumConstants.insert(enumConstant.Name).second) {
+          emitError("multiple definitions of enumerator '" +
+                    enumConstant.Name + "'");
+          continue;
+        }
+
+        EnumConstantInfo info;
+        if (!isAvailable(enumConstant.Availability))
+          continue;
+        convertAvailability(enumConstant.Availability, info, enumConstant.Name);
+        info.setSwiftPrivate(enumConstant.SwiftPrivate);
+        info.SwiftName = enumConstant.SwiftName;
+        Writer->addEnumConstant(enumConstant.Name, info, swiftVersion);
+      }
+
+      // Write all tags.
+      llvm::StringSet<> knownTags;
+      for (const auto &t : items.Tags) {
+        // Check for duplicate tag definitions.
+        if (!knownTags.insert(t.Name).second) {
+          emitError("multiple definitions Of tag '" + t.Name + "'");
+          continue;
+        }
+
+        TagInfo tagInfo;
+        if (convertCommonType(t, tagInfo, t.Name))
+          continue;
+
+        Writer->addTag(t.Name, tagInfo, swiftVersion);
+      }
+
+      // Write all typedefs.
+      llvm::StringSet<> knownTypedefs;
+      for (const auto &t : items.Typedefs) {
+        // Check for duplicate typedef definitions.
+        if (!knownTypedefs.insert(t.Name).second) {
+          emitError("multiple definitions of typedef '" + t.Name + "'");
+          continue;
+        }
+
+        TypedefInfo typedefInfo;
+        if (convertCommonType(t, typedefInfo, t.Name))
+          continue;
+        typedefInfo.SwiftWrapper = t.SwiftWrapper;
+
+        Writer->addTypedef(t.Name, typedefInfo, swiftVersion);
+      }
+    }
+
+    bool convertModule() {
+      if (!isAvailable(TheModule.Availability))
+        return false;
+
+      // Set up the writer.
+      // FIXME: This is kindof ugly.
+      APINotesWriter writer(TheModule.Name, SourceFile);
+      Writer = &writer;
+
+      // Write the top-level items.
+      convertTopLevelItems(TheModule.TopLevel, VersionTuple());
+
+      if (TheModule.SwiftInferImportAsMember) {
+        ModuleOptions opts;
+        opts.SwiftInferImportAsMember = true;
+        Writer->addModuleOptions(opts);
+      }
+
+      // Convert the versioned information.
+      for (const auto &versioned : TheModule.SwiftVersions) {
+        convertTopLevelItems(versioned.Items, versioned.Version);
+      }
+
+      if (!ErrorOccured)
+        Writer->writeToStream(OS);
+
+      return ErrorOccured;
+    }
+  };
+}
+
+static bool compile(const Module &module,
+                    const FileEntry *sourceFile,
+                    llvm::raw_ostream &os,
+                    api_notes::OSType targetOS,
+                    llvm::SourceMgr::DiagHandlerTy diagHandler,
+                    void *diagHandlerCtxt){
+  using namespace api_notes;
+
+  YAMLConverter c(module, sourceFile, targetOS, os, diagHandler, diagHandlerCtxt);
+  return c.convertModule();
+}
+
+bool api_notes::parseAndDumpAPINotes(StringRef yamlInput)  {
+  Module module;
+
+  if (parseAPINotes(yamlInput, module, nullptr, nullptr))
+    return true;
+
+  Output yout(llvm::outs());
+  yout << module;
+
+  return false;
+}
+
+/// Simple diagnostic handler that prints diagnostics to standard error.
+static void printDiagnostic(const llvm::SMDiagnostic &diag, void *context) {
+  diag.print(nullptr, llvm::errs());
+}
+
+bool api_notes::compileAPINotes(StringRef yamlInput,
+                                const FileEntry *sourceFile,
+                                llvm::raw_ostream &os,
+                                OSType targetOS,
+                                llvm::SourceMgr::DiagHandlerTy diagHandler,
+                                void *diagHandlerCtxt) {
+  Module module;
+
+  if (!diagHandler) {
+    diagHandler = &printDiagnostic;
+  }
+
+  if (parseAPINotes(yamlInput, module, diagHandler, diagHandlerCtxt))
+    return true;
+
+  return compile(module, sourceFile, os, targetOS, diagHandler, diagHandlerCtxt);
+}
+
+namespace {
+  // Deserialize the API notes file into a module.
+  class DecompileVisitor : public APINotesReader::Visitor {
+    /// Allocator used to clone those strings that need it.
+    llvm::BumpPtrAllocator Allocator;
+
+    /// The module we're building.
+    Module TheModule;
+
+    /// A known context, which tracks what we know about a context ID.
+    struct KnownContext {
+      /// Whether this is a protocol (vs. a class).
+      bool isProtocol;
+
+      /// The indices into the top-level items for this context at each
+      /// Swift version.
+      SmallVector<std::pair<VersionTuple, unsigned>, 1> indices;
+
+      Class &getContext(const VersionTuple &swiftVersion,
+                        TopLevelItems &items) {
+        ClassesSeq &seq = isProtocol ? items.Protocols : items.Classes;
+
+        for (auto &index : indices) {
+          if (index.first == swiftVersion)
+            return seq[index.second];
+        }
+
+        indices.push_back({swiftVersion, seq.size()});
+        seq.push_back(Class());
+        return seq.back();
+      }
+    };
+
+    /// A mapping from context ID to a pair (index, is-protocol) that indicates
+    /// the index of that class or protocol in the global "classes" or
+    /// "protocols" list.
+    llvm::DenseMap<unsigned, KnownContext> knownContexts;
+
+    /// Copy a string into allocated memory so it does disappear on us.
+    StringRef copyString(StringRef string) {
+      if (string.empty()) return StringRef();
+
+      void *ptr = Allocator.Allocate(string.size(), 1);
+      memcpy(ptr, string.data(), string.size());
+      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);
+      record.SwiftPrivate = info.isSwiftPrivate();
+      record.SwiftName = copyString(info.SwiftName);
+    }
+
+    template<typename T>
+    void handleCommonType(T &record, const CommonTypeInfo &info) {
+      handleCommon(record, info);
+      record.SwiftBridge = maybeCopyString(info.getSwiftBridge());
+      record.NSErrorDomain = maybeCopyString(info.getNSErrorDomain());
+    }
+
+    /// Map Objective-C context info.
+    void handleObjCContext(Class &record, StringRef name,
+                           const ObjCContextInfo &info) {
+      record.Name = name;
+
+      handleCommonType(record, info);
+
+      if (info.getDefaultNullability()) {
+        record.AuditedForNullability = true;
+      }
+    }
+
+    /// Map availability information, if present.
+    void handleAvailability(AvailabilityItem &availability,
+                            const CommonEntityInfo &info) {
+      if (info.Unavailable) {
+        availability.Mode = APIAvailability::None;
+        availability.Msg = copyString(info.UnavailableMsg);
+      }
+
+      if (info.UnavailableInSwift) {
+        availability.Mode = APIAvailability::NonSwift;
+        availability.Msg = copyString(info.UnavailableMsg);
+      }
+    }
+
+    /// Map parameter information for a function.
+    void handleParameters(ParamsSeq &params,
+                          const FunctionInfo &info) {
+      unsigned position = 0;
+      for (const auto &pi: info.Params) {
+        Param p;
+        p.Position = position++;
+        p.Nullability = pi.getNullability();
+        p.NoEscape = pi.isNoEscape();
+        p.Type = copyString(pi.getType());
+        params.push_back(p);
+      }
+    }
+
+    /// Map nullability information for a function.
+    void handleNullability(NullabilitySeq &nullability,
+                           llvm::Optional<NullabilityKind> &nullabilityOfRet,
+                           const FunctionInfo &info,
+                           unsigned numParams) {
+      if (info.NullabilityAudited) {
+        nullabilityOfRet = info.getReturnTypeInfo();
+
+        // Figure out the number of parameters from the selector.
+        for (unsigned i = 0; i != numParams; ++i)
+          nullability.push_back(info.getParamTypeInfo(i));
+      }
+    }
+
+    TopLevelItems &getTopLevelItems(VersionTuple swiftVersion) {
+      if (!swiftVersion) return TheModule.TopLevel;
+
+      for (auto &versioned : TheModule.SwiftVersions) {
+        if (versioned.Version == swiftVersion)
+          return versioned.Items;
+      }
+
+      TheModule.SwiftVersions.push_back(Versioned());
+      TheModule.SwiftVersions.back().Version = swiftVersion;
+      return TheModule.SwiftVersions.back().Items;
+    }
+
+  public:
+    virtual void visitObjCClass(ContextID contextID, StringRef name,
+                                const ObjCContextInfo &info,
+                                VersionTuple swiftVersion) {
+      // Record this known context.
+      auto &items = getTopLevelItems(swiftVersion);
+      auto &known = knownContexts[contextID.Value];
+      known.isProtocol = false;
+
+      handleObjCContext(known.getContext(swiftVersion, items), name, info);
+    }
+
+    virtual void visitObjCProtocol(ContextID contextID, StringRef name,
+                                   const ObjCContextInfo &info,
+                                   VersionTuple swiftVersion) {
+      // Record this known context.
+      auto &items = getTopLevelItems(swiftVersion);
+      auto &known = knownContexts[contextID.Value];
+      known.isProtocol = true;
+
+      handleObjCContext(known.getContext(swiftVersion, items), name, info);
+    }
+
+    virtual void visitObjCMethod(ContextID contextID, StringRef selector,
+                                 bool isInstanceMethod,
+                                 const ObjCMethodInfo &info,
+                                 VersionTuple swiftVersion) {
+      Method method;
+      method.Selector = copyString(selector);
+      method.Kind = isInstanceMethod ? MethodKind::Instance : MethodKind::Class;
+
+      handleCommon(method, info);
+      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);
+      auto &items = getTopLevelItems(swiftVersion);
+      knownContexts[contextID.Value].getContext(swiftVersion, items)
+        .Methods.push_back(method);
+    }
+
+    virtual void visitObjCProperty(ContextID contextID, StringRef name,
+                                   bool isInstance,
+                                   const ObjCPropertyInfo &info,
+                                   VersionTuple swiftVersion) {
+      Property property;
+      property.Name = name;
+      property.Kind = isInstance ? MethodKind::Instance : MethodKind::Class;
+      handleCommon(property, info);
+
+      // FIXME: No way to represent "not audited for nullability".
+      if (auto nullability = info.getNullability()) {
+        property.Nullability = *nullability;
+      }
+
+      property.SwiftImportAsAccessors = info.getSwiftImportAsAccessors();
+
+      property.Type = copyString(info.getType());
+
+      auto &items = getTopLevelItems(swiftVersion);
+      knownContexts[contextID.Value].getContext(swiftVersion, items)
+        .Properties.push_back(property);
+    }
+
+    virtual void visitGlobalFunction(StringRef name,
+                                     const GlobalFunctionInfo &info,
+                                     VersionTuple swiftVersion) {
+      Function function;
+      function.Name = name;
+      handleCommon(function, info);
+      handleParameters(function.Params, info);
+      if (info.NumAdjustedNullable > 0)
+        handleNullability(function.Nullability, function.NullabilityOfRet,
+                          info, info.NumAdjustedNullable-1);
+      function.ResultType = copyString(info.ResultType);
+      auto &items = getTopLevelItems(swiftVersion);
+      items.Functions.push_back(function);
+    }
+
+    virtual void visitGlobalVariable(StringRef name,
+                                     const GlobalVariableInfo &info,
+                                     VersionTuple swiftVersion) {
+      GlobalVariable global;
+      global.Name = name;
+      handleCommon(global, info);
+
+      // FIXME: No way to represent "not audited for nullability".
+      if (auto nullability = info.getNullability()) {
+        global.Nullability = *nullability;
+      }
+      global.Type = copyString(info.getType());
+
+      auto &items = getTopLevelItems(swiftVersion);
+      items.Globals.push_back(global);
+    }
+
+    virtual void visitEnumConstant(StringRef name,
+                                   const EnumConstantInfo &info,
+                                   VersionTuple swiftVersion) {
+      EnumConstant enumConstant;
+      enumConstant.Name = name;
+      handleCommon(enumConstant, info);
+
+      auto &items = getTopLevelItems(swiftVersion);
+      items.EnumConstants.push_back(enumConstant);
+    }
+
+    virtual void visitTag(StringRef name, const TagInfo &info,
+                          VersionTuple swiftVersion) {
+      Tag tag;
+      tag.Name = name;
+      handleCommonType(tag, info);
+      auto &items = getTopLevelItems(swiftVersion);
+      items.Tags.push_back(tag);
+    }
+
+    virtual void visitTypedef(StringRef name, const TypedefInfo &info,
+                              VersionTuple swiftVersion) {
+      Typedef td;
+      td.Name = name;
+      handleCommonType(td, info);
+      td.SwiftWrapper = info.SwiftWrapper;
+      auto &items = getTopLevelItems(swiftVersion);
+      items.Typedefs.push_back(td);
+    }
+
+    /// Retrieve the module.
+    Module &getModule() { return TheModule; }
+  };
+}
+
+/// Produce a flattened, numeric value for optional method/property kinds.
+static unsigned flattenPropertyKind(llvm::Optional<MethodKind> kind) {
+  return kind ? (*kind == MethodKind::Instance ? 2 : 1) : 0;
+}
+
+/// Sort the items in the given block of "top-level" items.
+static void sortTopLevelItems(TopLevelItems &items) {
+  // Sort classes.
+  std::sort(items.Classes.begin(), items.Classes.end(),
+            [](const Class &lhs, const Class &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort protocols.
+  std::sort(items.Protocols.begin(), items.Protocols.end(),
+            [](const Class &lhs, const Class &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort methods and properties within each class and protocol.
+  auto sortMembers = [](Class &record) {
+    // Sort properties.
+    std::sort(record.Properties.begin(), record.Properties.end(),
+              [](const Property &lhs, const Property &rhs) -> bool {
+                return lhs.Name < rhs.Name ||
+                (lhs.Name == rhs.Name &&
+                 flattenPropertyKind(lhs.Kind) <
+                 flattenPropertyKind(rhs.Kind));
+              });
+
+    // Sort methods.
+    std::sort(record.Methods.begin(), record.Methods.end(),
+              [](const Method &lhs, const Method &rhs) -> bool {
+                return lhs.Selector < rhs.Selector ||
+                (lhs.Selector == rhs.Selector &&
+                 static_cast<unsigned>(lhs.Kind)
+                 < static_cast<unsigned>(rhs.Kind));
+              });
+  };
+  std::for_each(items.Classes.begin(), items.Classes.end(), sortMembers);
+  std::for_each(items.Protocols.begin(), items.Protocols.end(), sortMembers);
+
+  // Sort functions.
+  std::sort(items.Functions.begin(), items.Functions.end(),
+            [](const Function &lhs, const Function &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort global variables.
+  std::sort(items.Globals.begin(), items.Globals.end(),
+            [](const GlobalVariable &lhs, const GlobalVariable &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort enum constants.
+  std::sort(items.EnumConstants.begin(), items.EnumConstants.end(),
+            [](const EnumConstant &lhs, const EnumConstant &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort tags.
+  std::sort(items.Tags.begin(), items.Tags.end(),
+            [](const Tag &lhs, const Tag &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort typedefs.
+  std::sort(items.Typedefs.begin(), items.Typedefs.end(),
+            [](const Typedef &lhs, const Typedef &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+}
+
+bool api_notes::decompileAPINotes(std::unique_ptr<llvm::MemoryBuffer> input,
+                                  llvm::raw_ostream &os) {
+  // Try to read the file.
+  auto reader = APINotesReader::get(std::move(input), VersionTuple());
+  if (!reader) {
+    llvm::errs() << "not a well-formed API notes binary file\n";
+    return true;
+  }
+
+  DecompileVisitor decompileVisitor;
+  reader->visit(decompileVisitor);
+
+  // Sort the data in the module, because the API notes reader doesn't preserve
+  // order.
+  auto &module = decompileVisitor.getModule();
+
+  // Set module name.
+  module.Name = reader->getModuleName();
+
+  // Set module options
+  auto opts = reader->getModuleOptions();
+  if (opts.SwiftInferImportAsMember)
+    module.SwiftInferImportAsMember = true;
+
+  // Sort the top-level items.
+  sortTopLevelItems(module.TopLevel);
+
+  // Sort the Swift versions.
+  std::sort(module.SwiftVersions.begin(), module.SwiftVersions.end(),
+            [](const Versioned &lhs, const Versioned &rhs) -> bool {
+              return lhs.Version < rhs.Version;
+            });
+
+  // Sort the top-level items within each Swift version.
+  for (auto &versioned : module.SwiftVersions)
+    sortTopLevelItems(versioned.Items);
+
+  // Output the YAML representation.
+  Output yout(os);
+  yout << module;
+
+  return false;
+}
+
diff --git a/lib/APINotes/CMakeLists.txt b/lib/APINotes/CMakeLists.txt
new file mode 100644
index 0000000..da9d0d1
--- /dev/null
+++ b/lib/APINotes/CMakeLists.txt
@@ -0,0 +1,15 @@
+set(LLVM_LINK_COMPONENTS
+  BitReader
+  Support
+  )
+
+add_clang_library(clangAPINotes
+  APINotesManager.cpp
+  APINotesWriter.cpp
+  APINotesReader.cpp
+  APINotesYAMLCompiler.cpp
+  Types.cpp
+
+  LINK_LIBS
+  clangBasic
+)
diff --git a/lib/APINotes/Types.cpp b/lib/APINotes/Types.cpp
new file mode 100644
index 0000000..963780f
--- /dev/null
+++ b/lib/APINotes/Types.cpp
@@ -0,0 +1,55 @@
+//===--- Types.cpp - API Notes Data Types ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines data types used in the representation of API notes data.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/Types.h"
+#include "llvm/Support/raw_ostream.h"
+
+void clang::api_notes::ObjCMethodInfo::dump(llvm::raw_ostream &os) {
+    os << DesignatedInit << " " << FactoryAsInit << " " << Unavailable << " "
+       << NullabilityAudited << " " << NumAdjustedNullable << " "
+       << NullabilityPayload << " " << UnavailableMsg << "\n";
+}
+
+void clang::api_notes::ObjCContextInfo::dump(llvm::raw_ostream &os) {
+  os << HasDefaultNullability << " " << DefaultNullability << " "
+     << HasDesignatedInits << "\n";
+}
+
+void clang::api_notes::ObjCMethodInfo::mergePropInfoIntoSetter(
+      const ObjCPropertyInfo &pInfo) {
+  // Set the type of the first argument of the the setter or check that the
+  // value we have is consistent with the property.
+  // TODO: Can we provide proper error handling here?
+  if (auto pNullability = pInfo.getNullability()) {
+    if (!NullabilityAudited) {
+      addParamTypeInfo(0, *pNullability);
+      assert(NumAdjustedNullable == 2);
+    } else {
+      assert(getParamTypeInfo(0) == *pNullability);
+    }
+  }
+}
+
+void clang::api_notes::ObjCMethodInfo::mergePropInfoIntoGetter(
+      const ObjCPropertyInfo &pInfo) {
+  // Set the return type of the getter or check that the value we have is
+  // consistent with the property.
+  // TODO: Can we provide proper error handling here?
+  if (auto pNullability = pInfo.getNullability()) {
+    if (!NullabilityAudited) {
+      addReturnTypeInfo(*pNullability);
+      assert(NumAdjustedNullable == 1);
+    } else {
+      assert(getReturnTypeInfo() == *pNullability);
+    }
+  }
+}
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index b531a66..c8cdc72 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4078,11 +4078,6 @@
                   bool allowOnPointerType) const {
   hasError = false;
 
-  if (const ObjCTypeParamType *objT =
-      dyn_cast<ObjCTypeParamType>(type.getTypePtr())) {
-    return getObjCTypeParamType(objT->getDecl(), protocols);
-  }
-
   // Apply protocol qualifiers to ObjCObjectPointerType.
   if (allowOnPointerType) {
     if (const ObjCObjectPointerType *objPtr =
@@ -8870,22 +8865,30 @@
     return GVA_Internal;
 
   if (VD->isStaticLocal()) {
-    GVALinkage StaticLocalLinkage = GVA_DiscardableODR;
     const DeclContext *LexicalContext = VD->getParentFunctionOrMethod();
     while (LexicalContext && !isa<FunctionDecl>(LexicalContext))
       LexicalContext = LexicalContext->getLexicalParent();
 
-    // Let the static local variable inherit its linkage from the nearest
-    // enclosing function.
-    if (LexicalContext)
-      StaticLocalLinkage =
-          Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+    // ObjC Blocks can create local variables that don't have a FunctionDecl
+    // LexicalContext.
+    if (!LexicalContext)
+      return GVA_DiscardableODR;
 
-    // GVA_StrongODR function linkage is stronger than what we need,
-    // downgrade to GVA_DiscardableODR.
-    // This allows us to discard the variable if we never end up needing it.
-    return StaticLocalLinkage == GVA_StrongODR ? GVA_DiscardableODR
-                                               : StaticLocalLinkage;
+    // Otherwise, let the static local variable inherit its linkage from the
+    // nearest enclosing function.
+    auto StaticLocalLinkage =
+        Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+
+    // Itanium ABI 5.2.2: "Each COMDAT group [for a static local variable] must
+    // be emitted in any object with references to the symbol for the object it
+    // contains, whether inline or out-of-line."
+    // Similar behavior is observed with MSVC. An alternative ABI could use
+    // StrongODR/AvailableExternally to match the function, but none are
+    // known/supported currently.
+    if (StaticLocalLinkage == GVA_StrongODR ||
+        StaticLocalLinkage == GVA_AvailableExternally)
+      return GVA_DiscardableODR;
+    return StaticLocalLinkage;
   }
 
   // MSVC treats in-class initialized static data members as definitions.
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 60d05f6..5d894c5 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -1329,12 +1329,8 @@
                                              IdentifierInfo *name,
                                              SourceLocation colonLoc,
                                              TypeSourceInfo *boundInfo) {
-  auto *TPDecl =
-    new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
-                                    nameLoc, name, colonLoc, boundInfo);
-  QualType TPType = ctx.getObjCTypeParamType(TPDecl, {});
-  TPDecl->setTypeForDecl(TPType.getTypePtr());
-  return TPDecl;
+  return new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
+                                         nameLoc, name, colonLoc, boundInfo);
 }
 
 ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx,
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index b8ebe1c..b8d90b0 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -1231,6 +1231,9 @@
     return;
   }
   bool eolnOut = false;
+  prettyPrintAttributes(OID);
+  if (OID->hasAttrs()) Out << "\n";
+
   Out << "@interface " << I;
 
   if (auto TypeParams = OID->getTypeParamListAsWritten()) {
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 0d0cd2e..f3724aa 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1081,24 +1081,13 @@
 
     // Replace an Objective-C type parameter reference with the corresponding
     // type argument.
-    if (const auto *OTPTy = dyn_cast<ObjCTypeParamType>(splitType.Ty)) {
-      if (auto *typeParam = dyn_cast<ObjCTypeParamDecl>(OTPTy->getDecl())) {
+    if (const auto *typedefTy = dyn_cast<TypedefType>(splitType.Ty)) {
+      if (auto *typeParam = dyn_cast<ObjCTypeParamDecl>(typedefTy->getDecl())) {
         // If we have type arguments, use them.
         if (!typeArgs.empty()) {
+          // FIXME: Introduce SubstObjCTypeParamType ?
           QualType argType = typeArgs[typeParam->getIndex()];
-          if (OTPTy->qual_empty())
-            return ctx.getQualifiedType(argType, splitType.Quals);
-
-          // Apply protocol lists if exists.
-          bool hasError;
-          SmallVector<ObjCProtocolDecl*, 8> protocolsVec;
-          protocolsVec.append(OTPTy->qual_begin(),
-                              OTPTy->qual_end());
-          ArrayRef<ObjCProtocolDecl *> protocolsToApply = protocolsVec;
-          QualType resultTy = ctx.applyObjCProtocolQualifiers(argType,
-              protocolsToApply, hasError, true/*allowOnPointerType*/);
-
-          return ctx.getQualifiedType(resultTy, splitType.Quals);
+          return ctx.getQualifiedType(argType, splitType.Quals);
         }
 
         switch (context) {
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 8929ec3..42e0167 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -82,6 +82,7 @@
   Sanitizers.cpp
   SourceLocation.cpp
   SourceManager.cpp
+  SourceMgrAdapter.cpp
   TargetInfo.cpp
   Targets.cpp
   TokenKinds.cpp
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 7529c47..0c27ae4 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -16,6 +16,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CrashRecoveryContext.h"
@@ -131,13 +132,13 @@
 
   // Clear state related to #pragma diagnostic.
   DiagStates.clear();
-  DiagStatePoints.clear();
+  DiagStatesByLoc.clear();
   DiagStateOnPushStack.clear();
 
   // Create a DiagState and DiagStatePoint representing diagnostic changes
   // through command-line.
   DiagStates.emplace_back();
-  DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc()));
+  DiagStatesByLoc.appendFirst(&DiagStates.back());
 }
 
 void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
@@ -157,27 +158,94 @@
   DelayedDiagArg2.clear();
 }
 
-DiagnosticsEngine::DiagStatePointsTy::iterator
-DiagnosticsEngine::GetDiagStatePointForLoc(SourceLocation L) const {
-  assert(!DiagStatePoints.empty());
-  assert(DiagStatePoints.front().Loc.isInvalid() &&
-         "Should have created a DiagStatePoint for command-line");
+void DiagnosticsEngine::DiagStateMap::appendFirst(
+                                             DiagState *State) {
+  assert(Files.empty() && "not first");
+  FirstDiagState = CurDiagState = State;
+  CurDiagStateLoc = SourceLocation();
+}
 
-  if (!SourceMgr)
-    return DiagStatePoints.end() - 1;
+void DiagnosticsEngine::DiagStateMap::append(SourceManager &SrcMgr,
+                                             SourceLocation Loc,
+                                             DiagState *State) {
+  CurDiagState = State;
+  CurDiagStateLoc = Loc;
 
-  FullSourceLoc Loc(L, *SourceMgr);
-  if (Loc.isInvalid())
-    return DiagStatePoints.end() - 1;
+  std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
+  unsigned Offset = Decomp.second;
+  for (File *F = getFile(SrcMgr, Decomp.first); F;
+       Offset = F->ParentOffset, F = F->Parent) {
+    F->HasLocalTransitions = true;
+    auto &Last = F->StateTransitions.back();
+    assert(Last.Offset <= Offset && "state transitions added out of order");
 
-  DiagStatePointsTy::iterator Pos = DiagStatePoints.end();
-  FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
-  if (LastStateChangePos.isValid() &&
-      Loc.isBeforeInTranslationUnitThan(LastStateChangePos))
-    Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(),
-                           DiagStatePoint(nullptr, Loc));
-  --Pos;
-  return Pos;
+    if (Last.Offset == Offset) {
+      if (Last.State == State)
+        break;
+      Last.State = State;
+      continue;
+    }
+
+    F->StateTransitions.push_back({State, Offset});
+  }
+}
+
+DiagnosticsEngine::DiagState *
+DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr,
+                                        SourceLocation Loc) const {
+  // Common case: we have not seen any diagnostic pragmas.
+  if (Files.empty())
+    return FirstDiagState;
+
+  std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
+  const File *F = getFile(SrcMgr, Decomp.first);
+  return F->lookup(Decomp.second);
+}
+
+DiagnosticsEngine::DiagState *
+DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const {
+  auto OnePastIt = std::upper_bound(
+      StateTransitions.begin(), StateTransitions.end(), Offset,
+      [](unsigned Offset, const DiagStatePoint &P) {
+        return Offset < P.Offset;
+      });
+  assert(OnePastIt != StateTransitions.begin() && "missing initial state");
+  return OnePastIt[-1].State;
+}
+
+DiagnosticsEngine::DiagStateMap::File *
+DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
+                                         FileID ID) const {
+  // Get or insert the File for this ID.
+  auto Range = Files.equal_range(ID);
+  if (Range.first != Range.second)
+    return &Range.first->second;
+  auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second;
+
+  // We created a new File; look up the diagnostic state at the start of it and
+  // initialize it.
+  if (ID.isValid()) {
+    std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedIncludedLoc(ID);
+    F.Parent = getFile(SrcMgr, Decomp.first);
+    F.ParentOffset = Decomp.second;
+    F.StateTransitions.push_back({F.Parent->lookup(Decomp.second), 0});
+  } else {
+    // This is the (imaginary) root file into which we pretend all top-level
+    // files are included; it descends from the initial state.
+    //
+    // FIXME: This doesn't guarantee that we use the same ordering as
+    // isBeforeInTranslationUnit in the cases where someone invented another
+    // top-level file and added diagnostic pragmas to it. See the code at the
+    // end of isBeforeInTranslationUnit for the quirks it deals with.
+    F.StateTransitions.push_back({FirstDiagState, 0});
+  }
+  return &F;
+}
+
+void DiagnosticsEngine::PushDiagStatePoint(DiagState *State,
+                                           SourceLocation Loc) {
+  assert(Loc.isValid() && "Adding invalid loc point");
+  DiagStatesByLoc.append(*SourceMgr, Loc, State);
 }
 
 void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
@@ -187,11 +255,8 @@
   assert((Diags->isBuiltinWarningOrExtension(Diag) ||
           (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
          "Cannot map errors into warnings!");
-  assert(!DiagStatePoints.empty());
   assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
 
-  FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc();
-  FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
   // Don't allow a mapping to a warning override an error/fatal mapping.
   if (Map == diag::Severity::Warning) {
     DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
@@ -202,50 +267,22 @@
   DiagnosticMapping Mapping = makeUserMapping(Map, L);
 
   // Common case; setting all the diagnostics of a group in one place.
-  if (Loc.isInvalid() || Loc == LastStateChangePos) {
-    GetCurDiagState()->setMapping(Diag, Mapping);
+  if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) &&
+      DiagStatesByLoc.getCurDiagState()) {
+    // FIXME: This is theoretically wrong: if the current state is shared with
+    // some other location (via push/pop) we will change the state for that
+    // other location as well. This cannot currently happen, as we can't update
+    // the diagnostic state at the same location at which we pop.
+    DiagStatesByLoc.getCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
-  // Another common case; modifying diagnostic state in a source location
-  // after the previous one.
-  if ((Loc.isValid() && LastStateChangePos.isInvalid()) ||
-      LastStateChangePos.isBeforeInTranslationUnitThan(Loc)) {
-    // A diagnostic pragma occurred, create a new DiagState initialized with
-    // the current one and a new DiagStatePoint to record at which location
-    // the new state became active.
-    DiagStates.push_back(*GetCurDiagState());
-    PushDiagStatePoint(&DiagStates.back(), Loc);
-    GetCurDiagState()->setMapping(Diag, Mapping);
-    return;
-  }
-
-  // We allow setting the diagnostic state in random source order for
-  // completeness but it should not be actually happening in normal practice.
-
-  DiagStatePointsTy::iterator Pos = GetDiagStatePointForLoc(Loc);
-  assert(Pos != DiagStatePoints.end());
-
-  // Update all diagnostic states that are active after the given location.
-  for (DiagStatePointsTy::iterator
-         I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
-    I->State->setMapping(Diag, Mapping);
-  }
-
-  // If the location corresponds to an existing point, just update its state.
-  if (Pos->Loc == Loc) {
-    Pos->State->setMapping(Diag, Mapping);
-    return;
-  }
-
-  // Create a new state/point and fit it into the vector of DiagStatePoints
-  // so that the vector is always ordered according to location.
-  assert(Pos->Loc.isBeforeInTranslationUnitThan(Loc));
-  DiagStates.push_back(*Pos->State);
-  DiagState *NewState = &DiagStates.back();
-  NewState->setMapping(Diag, Mapping);
-  DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
-                                               FullSourceLoc(Loc, *SourceMgr)));
+  // A diagnostic pragma occurred, create a new DiagState initialized with
+  // the current one and a new DiagStatePoint to record at which location
+  // the new state became active.
+  DiagStates.push_back(*GetCurDiagState());
+  DiagStates.back().setMapping(Diag, Mapping);
+  PushDiagStatePoint(&DiagStates.back(), L);
 }
 
 bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 3c370f6..e0580af 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -411,11 +411,8 @@
   // to error.  Errors can only be mapped to fatal.
   diag::Severity Result = diag::Severity::Fatal;
 
-  DiagnosticsEngine::DiagStatePointsTy::iterator
-    Pos = Diag.GetDiagStatePointForLoc(Loc);
-  DiagnosticsEngine::DiagState *State = Pos->State;
-
   // Get the mapping information, or compute it lazily.
+  DiagnosticsEngine::DiagState *State = Diag.GetDiagStateForLoc(Loc);
   DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
 
   // TODO: Can a null severity really get here?
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index af424cd..851b3ab 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -42,7 +42,6 @@
   NeedsHandleIdentifier = false;
   IsFromAST = false;
   ChangedAfterLoad = false;
-  FEChangedAfterLoad = false;
   RevertedTokenID = false;
   OutOfDate = false;
   IsModulesImport = false;
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index 80bbc24..88e5cc2 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -31,7 +31,8 @@
       IsMissingRequirement(false), HasIncompatibleModuleFile(false),
       IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
       IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
-      IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
+      IsInferred(false), IsSwiftInferImportAsMember(false),
+      InferSubmodules(false), InferExplicitSubmodules(false),
       InferExportWildcard(false), ConfigMacrosExhaustive(false),
       NoUndeclaredIncludes(false), NameVisibility(Hidden) {
   if (Parent) {
@@ -83,11 +84,16 @@
 
 bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
                          Requirement &Req,
-                         UnresolvedHeaderDirective &MissingHeader) const {
+                         UnresolvedHeaderDirective &MissingHeader,
+                         Module *&ShadowingModule) const {
   if (IsAvailable)
     return true;
 
   for (const Module *Current = this; Current; Current = Current->Parent) {
+    if (Current->ShadowingModule) {
+      ShadowingModule = Current->ShadowingModule;
+      return false;
+    }
     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
               Current->Requirements[I].second) {
@@ -341,6 +347,8 @@
       OS << " [system]";
     if (IsExternC)
       OS << " [extern_c]";
+    if (IsSwiftInferImportAsMember)
+      OS << " [swift_infer_import_as_member]";
   }
 
   OS << " {\n";
diff --git a/lib/Basic/SourceMgrAdapter.cpp b/lib/Basic/SourceMgrAdapter.cpp
new file mode 100644
index 0000000..1d52a24
--- /dev/null
+++ b/lib/Basic/SourceMgrAdapter.cpp
@@ -0,0 +1,137 @@
+//=== SourceMgrAdapter.cpp - SourceMgr to SourceManager Adapter -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the adapter that maps diagnostics from llvm::SourceMgr
+// to Clang's SourceManager.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/SourceMgrAdapter.h"
+#include "clang/Basic/Diagnostic.h"
+
+using namespace clang;
+
+void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &diag,
+                                  void *context) {
+  static_cast<SourceMgrAdapter *>(context)->handleDiag(diag);
+}
+
+SourceMgrAdapter::SourceMgrAdapter(SourceManager &srcMgr,
+                                   DiagnosticsEngine &diag,
+                                   unsigned errorDiagID,
+                                   unsigned warningDiagID,
+                                   unsigned noteDiagID,
+                                   const FileEntry *defaultFile)
+  : SrcMgr(srcMgr), Diag(diag), ErrorDiagID(errorDiagID),
+    WarningDiagID(warningDiagID), NoteDiagID(noteDiagID),
+    DefaultFile(defaultFile) { }
+
+SourceMgrAdapter::~SourceMgrAdapter() { }
+
+SourceLocation SourceMgrAdapter::mapLocation(const llvm::SourceMgr &llvmSrcMgr,
+                                             llvm::SMLoc loc) {
+  // Map invalid locations.
+  if (!loc.isValid())
+    return SourceLocation();
+
+  // Find the buffer containing the location.
+  unsigned bufferID = llvmSrcMgr.FindBufferContainingLoc(loc);
+  if (!bufferID)
+    return SourceLocation();
+
+
+  // If we haven't seen this buffer before, copy it over.
+  auto buffer = llvmSrcMgr.getMemoryBuffer(bufferID);
+  auto knownBuffer = FileIDMapping.find(std::make_pair(&llvmSrcMgr, bufferID));
+  if (knownBuffer == FileIDMapping.end()) {
+    FileID fileID;
+    if (DefaultFile) {
+      // Map to the default file.
+      fileID = SrcMgr.createFileID(DefaultFile, SourceLocation(),
+                                   SrcMgr::C_User);
+
+      // Only do this once.
+      DefaultFile = nullptr;
+    } else {
+      // Make a copy of the memory buffer.
+      StringRef bufferName = buffer->getBufferIdentifier();
+      auto bufferCopy
+        = std::unique_ptr<llvm::MemoryBuffer>(
+            llvm::MemoryBuffer::getMemBufferCopy(buffer->getBuffer(),
+                                                 bufferName));
+
+      // Add this memory buffer to the Clang source manager.
+      fileID = SrcMgr.createFileID(std::move(bufferCopy));
+    }
+
+    // Save the mapping.
+    knownBuffer = FileIDMapping.insert(
+                    std::make_pair(std::make_pair(&llvmSrcMgr, bufferID),
+                                   fileID)).first;
+  }
+
+  // Translate the offset into the file.
+  unsigned offset = loc.getPointer() - buffer->getBufferStart();
+  return SrcMgr.getLocForStartOfFile(knownBuffer->second)
+           .getLocWithOffset(offset);
+}
+
+SourceRange SourceMgrAdapter::mapRange(const llvm::SourceMgr &llvmSrcMgr,
+                                       llvm::SMRange range) {
+  if (!range.isValid())
+    return SourceRange();
+
+  SourceLocation start = mapLocation(llvmSrcMgr, range.Start);
+  SourceLocation end = mapLocation(llvmSrcMgr, range.End);
+  return SourceRange(start, end);
+}
+
+void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &diag) {
+  // Map the location.
+  SourceLocation loc;
+  if (auto *llvmSrcMgr = diag.getSourceMgr())
+    loc = mapLocation(*llvmSrcMgr, diag.getLoc());
+
+  // Extract the message.
+  StringRef message = diag.getMessage();
+
+  // Map the diagnostic kind.
+  unsigned diagID;
+  switch (diag.getKind()) {
+  case llvm::SourceMgr::DK_Error:
+    diagID = ErrorDiagID;
+    break;
+
+  case llvm::SourceMgr::DK_Warning:
+    diagID = WarningDiagID;
+    break;
+
+  case llvm::SourceMgr::DK_Note:
+    diagID = NoteDiagID;
+    break;
+  }
+
+  // Report the diagnostic.
+  DiagnosticBuilder builder = Diag.Report(loc, diagID) << message;
+
+  if (auto *llvmSrcMgr = diag.getSourceMgr()) {
+    // Translate ranges.
+    SourceLocation startOfLine = loc.getLocWithOffset(-diag.getColumnNo());
+    for (auto range : diag.getRanges()) {
+      builder << SourceRange(startOfLine.getLocWithOffset(range.first),
+                             startOfLine.getLocWithOffset(range.second));
+    }
+
+    // Translate Fix-Its.
+    for (const llvm::SMFixIt &fixIt : diag.getFixIts()) {
+      CharSourceRange range(mapRange(*llvmSrcMgr, fixIt.getRange()), false);
+      builder << FixItHint::CreateReplacement(range, fixIt.getText());
+    }
+  }
+}
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 1a95ff2..fdedd91 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -8976,11 +8976,19 @@
     return new SPIR64TargetInfo(Triple, Opts);
   }
   case llvm::Triple::wasm32:
-    if (!(Triple == llvm::Triple("wasm32-unknown-unknown")))
+    if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
+        Triple.getVendor() != llvm::Triple::UnknownVendor ||
+        Triple.getOS() != llvm::Triple::UnknownOS ||
+        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment ||
+        !(Triple.isOSBinFormatELF() || Triple.isOSBinFormatWasm()))
       return nullptr;
     return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
   case llvm::Triple::wasm64:
-    if (!(Triple == llvm::Triple("wasm64-unknown-unknown")))
+    if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
+        Triple.getVendor() != llvm::Triple::UnknownVendor ||
+        Triple.getOS() != llvm::Triple::UnknownOS ||
+        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment ||
+        !(Triple.isOSBinFormatELF() || Triple.isOSBinFormatWasm()))
       return nullptr;
     return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
 
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index dfd819a..574c511 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_subdirectory(Headers)
 add_subdirectory(Basic)
+add_subdirectory(APINotes)
 add_subdirectory(Lex)
 add_subdirectory(Parse)
 add_subdirectory(AST)
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index d2ce6ea..328ac5b 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -996,6 +996,7 @@
     return "__LLVM,__bitcode";
   case Triple::COFF:
   case Triple::ELF:
+  case Triple::Wasm:
   case Triple::UnknownObjectFormat:
     return ".llvmbc";
   }
@@ -1008,6 +1009,7 @@
     return "__LLVM,__cmdline";
   case Triple::COFF:
   case Triple::ELF:
+  case Triple::Wasm:
   case Triple::UnknownObjectFormat:
     return ".llvmcmd";
   }
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 0a88b23..b7c1743 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -1022,11 +1022,21 @@
       // Emit a lifetime intrinsic if meaningful. There's no point in doing this
       // if we don't have a valid insertion point (?).
       if (HaveInsertPoint() && !IsMSCatchParam) {
-        // goto or switch-case statements can break lifetime into several
-        // regions which need more efforts to handle them correctly. PR28267
-        // This is rare case, but it's better just omit intrinsics than have
-        // them incorrectly placed.
-        if (!Bypasses.IsBypassed(&D)) {
+        // If there's a jump into the lifetime of this variable, its lifetime
+        // gets broken up into several regions in IR, which requires more work
+        // to handle correctly. For now, just omit the intrinsics; this is a
+        // rare case, and it's better to just be conservatively correct.
+        // PR28267.
+        //
+        // We have to do this in all language modes if there's a jump past the
+        // declaration. We also have to do it in C if there's a jump to an
+        // earlier point in the current block because non-VLA lifetimes begin as
+        // soon as the containing block is entered, not when its variables
+        // actually come into scope; suppressing the lifetime annotations
+        // completely in this case is unnecessarily pessimistic, but again, this
+        // is rare.
+        if (!Bypasses.IsBypassed(&D) &&
+            !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) {
           uint64_t size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
           emission.SizeForLifetimeMarkers =
               EmitLifetimeStart(size, address.getPointer());
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index e5e34a5..d2cd9ed 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -3335,7 +3335,9 @@
     AlignmentSource AlignSource;
     Address Addr = EmitPointerWithAlignment(BaseExpr, &AlignSource);
     QualType PtrTy = BaseExpr->getType()->getPointeeType();
-    EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy);
+    bool SkipNullCheck = isa<llvm::ConstantPointerNull>(Addr.getPointer());
+    EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy,
+                  /*Alignment=*/CharUnits::Zero(), SkipNullCheck);
     BaseLV = MakeAddrLValue(Addr, PtrTy, AlignSource);
   } else
     BaseLV = EmitCheckedLValue(BaseExpr, TCK_MemberAccess);
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 1b85c45..12b14be 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -2751,8 +2751,8 @@
            isa<llvm::IntegerType>(Ops.LHS->getType())) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks;
-    llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS);
-    llvm::Value *ValidExponent = Builder.CreateICmpULE(RHS, WidthMinusOne);
+    llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
+    llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
 
     if (SanitizeExponent) {
       Checks.push_back(
@@ -2767,12 +2767,14 @@
       llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
       llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check");
       Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
+      llvm::Value *PromotedWidthMinusOne =
+          (RHS == Ops.RHS) ? WidthMinusOne
+                           : GetWidthMinusOneValue(Ops.LHS, RHS);
       CGF.EmitBlock(CheckShiftBase);
-      llvm::Value *BitsShiftedOff =
-        Builder.CreateLShr(Ops.LHS,
-                           Builder.CreateSub(WidthMinusOne, RHS, "shl.zeros",
-                                             /*NUW*/true, /*NSW*/true),
-                           "shl.check");
+      llvm::Value *BitsShiftedOff = Builder.CreateLShr(
+          Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros",
+                                     /*NUW*/ true, /*NSW*/ true),
+          "shl.check");
       if (CGF.getLangOpts().CPlusPlus) {
         // In C99, we are not permitted to shift a 1 bit into the sign bit.
         // Under C++11's rules, shifting a 1 bit into the sign bit is
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 7219592..01793e2 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -7147,7 +7147,12 @@
   }
 
   assert(GV->getLinkage() == L);
-  return GV;
+
+  if (IsForDefinition ||
+      GV->getValueType() == ObjCTypes.ClassnfABITy)
+    return GV;
+
+  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ClassnfABIPtrTy);
 }
 
 llvm::Value *
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 5861340..11a2b95 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -212,6 +212,13 @@
   /// value. This is invalid iff the function has no return value.
   Address ReturnValue;
 
+  /// Return true if a label was seen in the current scope.
+  bool hasLabelBeenSeenInCurrentScope() const {
+    if (CurLexicalScope)
+      return CurLexicalScope->hasLabels();
+    return !LabelMap.empty();
+  }
+
   /// AllocaInsertPoint - This is an instruction in the entry block before which
   /// we prefer to insert allocas.
   llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
@@ -620,6 +627,10 @@
         rescopeLabels();
     }
 
+    bool hasLabels() const {
+      return !Labels.empty();
+    }
+
     void rescopeLabels();
   };
 
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 3600543..a6b2559 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -3341,6 +3341,7 @@
     llvm_unreachable("unknown file format");
   case llvm::Triple::COFF:
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     GV->setSection("cfstring");
     break;
   case llvm::Triple::MachO:
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index f7a8dd6..490fadb 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2015,10 +2015,11 @@
 
     // The ABI says: "It is suggested that it be emitted in the same COMDAT
     // group as the associated data object." In practice, this doesn't work for
-    // non-ELF object formats, so only do it for ELF.
+    // non-ELF and non-Wasm object formats, so only do it for ELF and Wasm.
     llvm::Comdat *C = var->getComdat();
     if (!D.isLocalVarDecl() && C &&
-        CGM.getTarget().getTriple().isOSBinFormatELF()) {
+        (CGM.getTarget().getTriple().isOSBinFormatELF() ||
+         CGM.getTarget().getTriple().isOSBinFormatWasm())) {
       guard->setComdat(C);
       // An inline variable's guard function is run from the per-TU
       // initialization function, not via a dedicated global ctor function, so
@@ -3534,8 +3535,9 @@
     return StructorCodegen::RAUW;
 
   if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
-    // Only ELF supports COMDATs with arbitrary names (C5/D5).
-    if (CGM.getTarget().getTriple().isOSBinFormatELF())
+    // Only ELF and wasm support COMDATs with arbitrary names (C5/D5).
+    if (CGM.getTarget().getTriple().isOSBinFormatELF() ||
+        CGM.getTarget().getTriple().isOSBinFormatWasm())
       return StructorCodegen::COMDAT;
     return StructorCodegen::Emit;
   }
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 15f830d..d8f5bfc 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -3186,7 +3186,8 @@
   const JobAction *JA = cast<JobAction>(A);
   ActionList CollapsedOffloadActions;
 
-  ToolSelector TS(JA, *TC, C, isSaveTempsEnabled(), embedBitcodeInObject());
+  ToolSelector TS(JA, *TC, C, isSaveTempsEnabled(),
+                  embedBitcodeInObject() && !isUsingLTO());
   const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
 
   if (!T)
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 9fd8808..595d6e6 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -88,6 +88,8 @@
     return HaveCrashVFS ? false : true;
   if (FlagRef.startswith("-fmodules-cache-path="))
     return true;
+  if (FlagRef.startswith("-fapinotes-cache-path="))
+    return true;
 
   SkipNum = 0;
   return false;
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 9bc9ae4..7e52514 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1109,10 +1109,6 @@
                      options::OPT_fno_omit_frame_pointer, false))
       getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
           << "-fomit-frame-pointer" << BoundArch;
-    if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
-                     options::OPT_mno_omit_leaf_frame_pointer, false))
-      getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
-          << "-momit-leaf-frame-pointer" << BoundArch;
   }
 
   return DAL;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index b4a8334..30d48b7 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1363,9 +1363,9 @@
                                options::OPT_mno_global_merge)) {
     CmdArgs.push_back("-backend-option");
     if (A->getOption().matches(options::OPT_mno_global_merge))
-      CmdArgs.push_back("-aarch64-global-merge=false");
+      CmdArgs.push_back("-aarch64-enable-global-merge=false");
     else
-      CmdArgs.push_back("-aarch64-global-merge=true");
+      CmdArgs.push_back("-aarch64-enable-global-merge=true");
   }
 }
 
@@ -3409,7 +3409,7 @@
   return false;
 }
 
-static bool mustUseFramePointerForTarget(const llvm::Triple &Triple) {
+static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
   switch (Triple.getArch()){
   default:
     return false;
@@ -3475,7 +3475,7 @@
   if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
                                options::OPT_fomit_frame_pointer))
     return A->getOption().matches(options::OPT_fno_omit_frame_pointer) ||
-           mustUseFramePointerForTarget(Triple);
+           mustUseNonLeafFramePointerForTarget(Triple);
 
   if (Args.hasArg(options::OPT_pg))
     return true;
@@ -3487,8 +3487,7 @@
                                       const llvm::Triple &Triple) {
   if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
                                options::OPT_momit_leaf_frame_pointer))
-    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer) ||
-           mustUseFramePointerForTarget(Triple);
+    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
 
   if (Args.hasArg(options::OPT_pg))
     return true;
@@ -4250,14 +4249,14 @@
   }
 
   // Embed-bitcode option.
-  if (C.getDriver().embedBitcodeInObject() &&
+  if (C.getDriver().embedBitcodeInObject() && !C.getDriver().isUsingLTO() &&
       (isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
     // Add flags implied by -fembed-bitcode.
     Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
     // Disable all llvm IR level optimizations.
     CmdArgs.push_back("-disable-llvm-passes");
   }
-  if (C.getDriver().embedBitcodeMarkerOnly())
+  if (C.getDriver().embedBitcodeMarkerOnly() && !C.getDriver().isUsingLTO())
     CmdArgs.push_back("-fembed-bitcode=marker");
 
   // We normally speed up the clang process a bit by skipping destructors at
@@ -5638,6 +5637,42 @@
                     options::OPT_fno_assume_sane_operator_new))
     CmdArgs.push_back("-fno-assume-sane-operator-new");
 
+  if (Args.hasFlag(options::OPT_fapinotes, options::OPT_fno_apinotes,
+                   false) ||
+      Args.hasFlag(options::OPT_fapinotes_modules,
+                     options::OPT_fno_apinotes_modules, false) ||
+      Args.hasArg(options::OPT_iapinotes_modules)) {
+    if (Args.hasFlag(options::OPT_fapinotes, options::OPT_fno_apinotes, false))
+      CmdArgs.push_back("-fapinotes");
+    if (Args.hasFlag(options::OPT_fapinotes_modules,
+                     options::OPT_fno_apinotes_modules, false))
+      CmdArgs.push_back("-fapinotes-modules");
+
+    SmallString<128> APINotesCachePath;
+    if (Arg *A = Args.getLastArg(options::OPT_fapinotes_cache_path)) {
+      APINotesCachePath = A->getValue();
+    }
+
+    if (C.isForDiagnostics()) {
+      // When generating crash reports, we want to emit the API notes along with
+      // the reproduction sources, so we ignore any provided API notes path.
+      APINotesCachePath = Output.getFilename();
+      llvm::sys::path::replace_extension(APINotesCachePath, ".cache");
+      llvm::sys::path::append(APINotesCachePath, "apinotes");
+    } else if (APINotesCachePath.empty()) {
+      // No API notes path was provided: use the default.
+      llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
+                                             APINotesCachePath);
+      llvm::sys::path::append(APINotesCachePath, "org.llvm.clang");
+      llvm::sys::path::append(APINotesCachePath, "APINotesCache");
+    }
+    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.
   if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
                    getToolChain().IsBlocksDefault()) ||
@@ -6449,7 +6484,8 @@
   // pristine IR generated by the frontend. Ideally, a new compile action should
   // be added so both IR can be captured.
   if (C.getDriver().isSaveTempsEnabled() &&
-      !C.getDriver().embedBitcodeInObject() && isa<CompileJobAction>(JA))
+      !C.getDriver().embedBitcodeInObject() && !C.getDriver().isUsingLTO() &&
+      isa<CompileJobAction>(JA))
     CmdArgs.push_back("-disable-llvm-passes");
 
   if (Output.getType() == types::TY_Dependencies) {
@@ -8422,9 +8458,13 @@
   // for embed-bitcode, use -bitcode_bundle in linker command
   if (C.getDriver().embedBitcodeEnabled()) {
     // Check if the toolchain supports bitcode build flow.
-    if (MachOTC.SupportsEmbeddedBitcode())
+    if (MachOTC.SupportsEmbeddedBitcode()) {
       CmdArgs.push_back("-bitcode_bundle");
-    else
+      if (C.getDriver().embedBitcodeMarkerOnly() && Version[0] >= 278) {
+        CmdArgs.push_back("-bitcode_process_mode");
+        CmdArgs.push_back("marker");
+      }
+    } else
       D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
   }
 
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index d892996..c29b908 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -619,6 +619,10 @@
     StoredDiags.emplace_back(Level, Info);
 }
 
+IntrusiveRefCntPtr<ASTReader> ASTUnit::getASTReader() const {
+  return Reader;
+}
+
 ASTMutationListener *ASTUnit::getASTMutationListener() {
   if (WriterData)
     return &WriterData->Writer;
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index afcaa6e..e391d10 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/APINotes/APINotesReader.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -615,6 +616,27 @@
                                   CodeCompleteConsumer *CompletionConsumer) {
   TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
                          TUKind, CompletionConsumer));
+
+  // Set up API notes.
+  TheSema->APINotes.setSwiftVersion(getAPINotesOpts().SwiftVersion);
+
+  // If we're building a module and are supposed to load API notes,
+  // notify the API notes manager.
+  if (auto currentModule = getPreprocessor().getCurrentModule()) {
+    (void)TheSema->APINotes.loadCurrentModuleAPINotes(
+            currentModule,
+            getLangOpts().APINotesModules,
+            getAPINotesOpts().ModuleSearchPaths);
+    // Check for any attributes we should add to the module
+    for (auto reader : TheSema->APINotes.getCurrentModuleReaders()) {
+      // swift_infer_import_as_member
+      if (reader->getModuleOptions().SwiftInferImportAsMember) {
+        currentModule->IsSwiftInferImportAsMember = true;
+        break;
+      }
+    }
+  }
+
   // Attach the external sema source if there is any.
   if (ExternalSemaSrc) {
     TheSema->addExternalSource(ExternalSemaSrc.get());
@@ -1016,7 +1038,7 @@
                               SourceLocation ImportLoc,
                               Module *Module,
                               StringRef ModuleFileName) {
-  ModuleMap &ModMap 
+  ModuleMap &ModMap
     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
     
   // Construct a compiler invocation for creating this module.
@@ -1794,8 +1816,13 @@
     // Check whether this module is available.
     clang::Module::Requirement Requirement;
     clang::Module::UnresolvedHeaderDirective MissingHeader;
+    clang::Module *ShadowingModule = nullptr;
     if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement,
-                             MissingHeader)) {
+                             MissingHeader, ShadowingModule)) {
+
+      assert(!ShadowingModule &&
+             "lookup of module by name should never find shadowed module");
+
       if (MissingHeader.FileNameLoc.isValid()) {
         getDiagnostics().Report(MissingHeader.FileNameLoc,
                                 diag::err_module_header_missing)
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 36f6b0a..7acc5ef 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1085,6 +1085,7 @@
 
 static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) {
   Opts.WorkingDir = Args.getLastArgValue(OPT_working_directory);
+  Opts.APINotesCachePath = Args.getLastArgValue(OPT_fapinotes_cache_path);
 }
 
 /// Parse the argument to the -ftest-module-file-extension
@@ -1525,6 +1526,18 @@
     Opts.AddVFSOverlayFile(A->getValue());
 }
 
+static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
+                              DiagnosticsEngine &diags) {
+  using namespace options;
+  if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
+    if (Opts.SwiftVersion.tryParse(A->getValue()))
+      diags.Report(diag::err_drv_invalid_value)
+        << A->getAsString(Args) << A->getValue();
+  }
+  for (const Arg *A : Args.filtered(OPT_iapinotes_modules))
+    Opts.ModuleSearchPaths.push_back(A->getValue());
+}
+
 static bool isOpenCL(LangStandard::Kind LangStd) {
   return LangStd == LangStandard::lang_opencl ||
          LangStd == LangStandard::lang_opencl11 ||
@@ -2031,6 +2044,8 @@
   // is enabled.
   Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns)
                             | Opts.NativeHalfArgsAndReturns;
+  Opts.APINotes = Args.hasArg(OPT_fapinotes);
+  Opts.APINotesModules = Args.hasArg(OPT_fapinotes_modules);
   Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
 
   // __declspec is enabled by default for the PS4 by the driver, and also
@@ -2441,6 +2456,8 @@
   Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
                               Res.getTargetOpts());
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args);
+  ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
+
   if (DashX == IK_AST || DashX == IK_LLVM_IR) {
     // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
     // PassManager in BackendUtil.cpp. They need to be initializd no matter
@@ -2459,6 +2476,13 @@
       Res.getPreprocessorOpts(), Diags);
     if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
       LangOpts.ObjCExceptions = 1;
+
+    // -fapinotes and -fapinotes-modules requires -fapinotes-cache-path=<directory>.
+    if ((LangOpts.APINotes || LangOpts.APINotesModules) &&
+        Res.getFileSystemOpts().APINotesCachePath.empty()) {
+      Diags.Report(diag::err_no_apinotes_cache_path);
+      Success = false;
+    }
   }
 
   if (LangOpts.CUDA) {
@@ -2566,7 +2590,19 @@
   // Extend the signature with the module file extensions.
   const FrontendOptions &frontendOpts = getFrontendOpts();
   for (const auto &ext : frontendOpts.ModuleFileExtensions) {
-    code = ext->hashExtension(code);
+    code = hash_combine(code, ext->hashExtension(code));
+  }
+
+  // Extend the signature with the SWift version for API notes.
+  const APINotesOptions &apiNotesOpts = getAPINotesOpts();
+  if (apiNotesOpts.SwiftVersion) {
+    code = hash_combine(code, apiNotesOpts.SwiftVersion.getMajor());
+    if (auto minor = apiNotesOpts.SwiftVersion.getMinor())
+      code = hash_combine(code, *minor);
+    if (auto subminor = apiNotesOpts.SwiftVersion.getSubminor())
+      code = hash_combine(code, *subminor);
+    if (auto build = apiNotesOpts.SwiftVersion.getBuild())
+      code = hash_combine(code, *build);
   }
 
   // Darwin-specific hack: if we have a sysroot, use the contents and
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 39fc137..f9ad97c 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -414,6 +414,13 @@
       CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
   }
 
+  // Add a module declaration scope so that modules from -fmodule-map-file
+  // arguments may shadow modules found implicitly in search paths.
+  CI.getPreprocessor()
+      .getHeaderSearchInfo()
+      .getModuleMap()
+      .finishModuleDeclarationScope();
+
   // If we were asked to load any module files, do so now.
   for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
     if (!CI.loadModuleFile(ModuleFile))
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index f795a1d..bfea1df 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -341,8 +341,13 @@
   // Check whether we can build this module at all.
   clang::Module::Requirement Requirement;
   clang::Module::UnresolvedHeaderDirective MissingHeader;
+  clang::Module *ShadowingModule = nullptr;
   if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement,
-                           MissingHeader)) {
+                           MissingHeader, ShadowingModule)) {
+
+    assert(!ShadowingModule &&
+           "lookup of module by name should never find shadowed module");
+
     if (MissingHeader.FileNameLoc.isValid()) {
       CI.getDiagnostics().Report(MissingHeader.FileNameLoc,
                                  diag::err_module_header_missing)
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 4502c92..e5a0796 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -593,9 +593,6 @@
         Builder.defineMacro("OBJC_ZEROCOST_EXCEPTIONS");
     }
 
-    Builder.defineMacro("__OBJC_BOOL_IS_BOOL",
-                        Twine(TI.useSignedCharForObjCBool() ? "0" : "1"));
-
     if (LangOpts.getGC() != LangOptions::NonGC)
       Builder.defineMacro("__OBJC_GC__");
 
@@ -626,6 +623,11 @@
     Builder.defineMacro("IB_DESIGNABLE", "");
   }
 
+  // Define a macro that describes the Objective-C boolean type even for C
+  // and C++ since BOOL can be used from non Objective-C code.
+  Builder.defineMacro("__OBJC_BOOL_IS_BOOL",
+                      Twine(TI.useSignedCharForObjCBool() ? "0" : "1"));
+
   if (LangOpts.CPlusPlus)
     InitializeCPlusPlusFeatureTestMacros(LangOpts, Builder);
 
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt
index 8f51ccb..c9fbfaf 100644
--- a/lib/Index/CMakeLists.txt
+++ b/lib/Index/CMakeLists.txt
@@ -24,5 +24,6 @@
   clangFormat
   clangFrontend
   clangRewrite
+  clangSerialization
   clangToolingCore
   )
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index 84984fc..f3de472 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -389,6 +389,20 @@
   case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
   case SymbolSubKind::AccessorGetter: return "acc-get";
   case SymbolSubKind::AccessorSetter: return "acc-set";
+  case SymbolSubKind::SwiftAccessorWillSet: return "acc-willset";
+  case SymbolSubKind::SwiftAccessorDidSet: return "acc-didset";
+  case SymbolSubKind::SwiftAccessorAddressor: return "acc-addr";
+  case SymbolSubKind::SwiftAccessorMutableAddressor: return "acc-mutaddr";
+  case SymbolSubKind::SwiftExtensionOfStruct: return "ext-struct";
+  case SymbolSubKind::SwiftExtensionOfClass: return "ext-class";
+  case SymbolSubKind::SwiftExtensionOfEnum: return "ext-enum";
+  case SymbolSubKind::SwiftExtensionOfProtocol: return "ext-protocol";
+  case SymbolSubKind::SwiftPrefixOperator: return "prefix-operator";
+  case SymbolSubKind::SwiftPostfixOperator: return "postfix-operator";
+  case SymbolSubKind::SwiftInfixOperator: return "infix-operator";
+  case SymbolSubKind::SwiftSubscript: return "subscript";
+  case SymbolSubKind::SwiftAssociatedType: return "associated-type";
+  case SymbolSubKind::SwiftGenericTypeParam: return "generic-type-param";
   }
   llvm_unreachable("invalid symbol subkind");
 }
@@ -398,6 +412,7 @@
   case SymbolLanguage::C: return "C";
   case SymbolLanguage::ObjC: return "ObjC";
   case SymbolLanguage::CXX: return "C++";
+  case SymbolLanguage::Swift: return "Swift";
   }
   llvm_unreachable("invalid symbol language kind");
 }
diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp
index d744293..cac24d4 100644
--- a/lib/Index/IndexingAction.cpp
+++ b/lib/Index/IndexingAction.cpp
@@ -13,6 +13,7 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/ASTReader.h"
 
 using namespace clang;
 using namespace clang::index;
@@ -173,4 +174,20 @@
   IndexCtx.setASTContext(Unit.getASTContext());
   DataConsumer->initialize(Unit.getASTContext());
   indexTranslationUnit(Unit, IndexCtx);
+  DataConsumer->finish();
+}
+
+void index::indexModuleFile(serialization::ModuleFile &Mod,
+                            ASTReader &Reader,
+                            std::shared_ptr<IndexDataConsumer> DataConsumer,
+                            IndexingOptions Opts) {
+  ASTContext &Ctx = Reader.getContext();
+  IndexingContext IndexCtx(Opts, *DataConsumer);
+  IndexCtx.setASTContext(Ctx);
+  DataConsumer->initialize(Ctx);
+
+  for (const Decl *D :Reader.getModuleFileLevelDecls(Mod)) {
+    IndexCtx.indexTopLevelDecl(D);
+  }
+  DataConsumer->finish();
 }
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 58f61c3..f9ed3c4 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -911,21 +911,30 @@
 bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD,
                                        const SourceManager &SM,
                                        SmallVectorImpl<char> &Buf) {
+  if (!MD)
+    return true;
+  return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
+                             SM, Buf);
+
+}
+
+bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
+                                       const SourceManager &SM,
+                                       SmallVectorImpl<char> &Buf) {
   // Don't generate USRs for things with invalid locations.
-  if (!MD || MD->getLocation().isInvalid())
+  if (MacroName.empty() || Loc.isInvalid())
     return true;
 
   llvm::raw_svector_ostream Out(Buf);
 
   // Assume that system headers are sane.  Don't put source location
   // information into the USR if the macro comes from a system header.
-  SourceLocation Loc = MD->getLocation();
   bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc);
 
   Out << getUSRSpacePrefix();
   if (ShouldGenerateLocation)
     printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
   Out << "@macro@";
-  Out << MD->getName()->getName();
+  Out << MacroName;
   return false;
 }
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 1488f62..b207a5a 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -568,10 +568,25 @@
     if (LangOpts.CurrentModule == Name)
       SourceModule = Result;
     Modules[Name] = Result;
+    ModuleScopeIDs[Result] = CurrentModuleScopeID;
   }
   return std::make_pair(Result, true);
 }
 
+Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
+                                        Module *ShadowingModule) {
+
+  // Create a new module with this name.
+  Module *Result =
+      new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
+                 /*IsExplicit=*/false, NumCreatedModules++);
+  Result->ShadowingModule = ShadowingModule;
+  Result->IsAvailable = false;
+  ModuleScopeIDs[Result] = CurrentModuleScopeID;
+
+  return Result;
+}
+
 Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
                                                 StringRef Name) {
   assert(LangOpts.CurrentModule == Name && "module name mismatch");
@@ -713,6 +728,8 @@
   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
                               /*IsFramework=*/true, /*IsExplicit=*/false,
                               NumCreatedModules++);
+  if (!Parent)
+    ModuleScopeIDs[Result] = CurrentModuleScopeID;
   InferredModuleAllowedBy[Result] = ModuleMapFile;
   Result->IsInferred = true;
   if (!Parent) {
@@ -1324,6 +1341,8 @@
     AT_extern_c,
     /// \brief The 'exhaustive' attribute.
     AT_exhaustive,
+    // \brief The 'swift_infer_import_as_member' attribute.
+    AT_swift_infer_import_as_member,
     /// \brief The 'no_undeclared_includes' attribute.
     AT_no_undeclared_includes
   };
@@ -1460,6 +1479,7 @@
   SourceLocation LBraceLoc = consumeToken();
   
   // Determine whether this (sub)module has already been defined.
+  Module *ShadowingModule = nullptr;
   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
       // Skip the module definition.
@@ -1473,23 +1493,35 @@
       }
       return;
     }
-    
-    Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
-      << ModuleName;
-    Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
-    
-    // Skip the module definition.
-    skipUntil(MMToken::RBrace);
-    if (Tok.is(MMToken::RBrace))
-      consumeToken();
-    
-    HadError = true;
-    return;
+
+    if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
+      ShadowingModule = Existing;
+    } else {
+      // This is not a shawdowed module decl, it is an illegal redefinition.
+      Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
+          << ModuleName;
+      Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
+
+      // Skip the module definition.
+      skipUntil(MMToken::RBrace);
+      if (Tok.is(MMToken::RBrace))
+        consumeToken();
+
+      HadError = true;
+      return;
+    }
   }
 
   // Start defining this module.
-  ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
-                                        Explicit).first;
+  if (ShadowingModule) {
+    ActiveModule =
+        Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
+  } else {
+    ActiveModule =
+        Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
+            .first;
+  }
+
   ActiveModule->DefinitionLoc = ModuleNameLoc;
   if (Attrs.IsSystem || IsSystem)
     ActiveModule->IsSystem = true;
@@ -2428,6 +2460,7 @@
           .Case("extern_c", AT_extern_c)
           .Case("no_undeclared_includes", AT_no_undeclared_includes)
           .Case("system", AT_system)
+          .Case("swift_infer_import_as_member", AT_swift_infer_import_as_member)
           .Default(AT_unknown);
     switch (Attribute) {
     case AT_unknown:
@@ -2443,6 +2476,10 @@
       Attrs.IsExternC = true;
       break;
 
+    case AT_swift_infer_import_as_member:
+      Attrs.IsSwiftInferImportAsMember = true;
+      break;
+
     case AT_exhaustive:
       Attrs.IsExhaustive = true;
       break;
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 322c580..7449b5f 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1869,13 +1869,17 @@
     if (!SuggestedModule.getModule()->isAvailable()) {
       Module::Requirement Requirement;
       Module::UnresolvedHeaderDirective MissingHeader;
+      Module *ShadowingModule = nullptr;
       Module *M = SuggestedModule.getModule();
       // Identify the cause.
       (void)M->isAvailable(getLangOpts(), getTargetInfo(), Requirement,
-                           MissingHeader);
+                           MissingHeader, ShadowingModule);
       if (MissingHeader.FileNameLoc.isValid()) {
         Diag(MissingHeader.FileNameLoc, diag::err_module_header_missing)
             << MissingHeader.IsUmbrella << MissingHeader.FileName;
+      } else if (ShadowingModule) {
+        Diag(M->DefinitionLoc, diag::err_module_shadowed) << M->Name;
+        Diag(ShadowingModule->DefinitionLoc, diag::note_previous_definition);
       } else {
         Diag(M->DefinitionLoc, diag::err_module_unavailable)
             << M->getFullModuleName() << Requirement.second << Requirement.first;
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 862a471..2e1b5de 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -157,51 +157,6 @@
     PP.LexNonComment(PeekTok);
   }
 
-  // [cpp.cond]p4:
-  //   Prior to evaluation, macro invocations in the list of preprocessing
-  //   tokens that will become the controlling constant expression are replaced
-  //   (except for those macro names modified by the 'defined' unary operator),
-  //   just as in normal text. If the token 'defined' is generated as a result
-  //   of this replacement process or use of the 'defined' unary operator does
-  //   not match one of the two specified forms prior to macro replacement, the
-  //   behavior is undefined.
-  // This isn't an idle threat, consider this program:
-  //   #define FOO
-  //   #define BAR defined(FOO)
-  //   #if BAR
-  //   ...
-  //   #else
-  //   ...
-  //   #endif
-  // clang and gcc will pick the #if branch while Visual Studio will take the
-  // #else branch.  Emit a warning about this undefined behavior.
-  if (beginLoc.isMacroID()) {
-    bool IsFunctionTypeMacro =
-        PP.getSourceManager()
-            .getSLocEntry(PP.getSourceManager().getFileID(beginLoc))
-            .getExpansion()
-            .isFunctionMacroExpansion();
-    // For object-type macros, it's easy to replace
-    //   #define FOO defined(BAR)
-    // with
-    //   #if defined(BAR)
-    //   #define FOO 1
-    //   #else
-    //   #define FOO 0
-    //   #endif
-    // and doing so makes sense since compilers handle this differently in
-    // practice (see example further up).  But for function-type macros,
-    // there is no good way to write
-    //   # define FOO(x) (defined(M_ ## x) && M_ ## x)
-    // in a different way, and compilers seem to agree on how to behave here.
-    // So warn by default on object-type macros, but only warn in -pedantic
-    // mode on function-type macros.
-    if (IsFunctionTypeMacro)
-      PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro);
-    else
-      PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro);
-  }
-
   // Invoke the 'defined' callback.
   if (PPCallbacks *Callbacks = PP.getPPCallbacks()) {
     Callbacks->Defined(macroToken, Macro,
@@ -241,8 +196,8 @@
   if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
     // Handle "defined X" and "defined(X)".
     if (II->isStr("defined"))
-      return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);
-
+      return(EvaluateDefined(Result, PeekTok, DT, ValueLive, PP));
+    
     // If this identifier isn't 'defined' or one of the special
     // preprocessor keywords and it wasn't macro expanded, it turns
     // into a simple 0, unless it is the C++ keyword "true", in which case it
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index de166c7..822ac8f 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -1106,6 +1106,7 @@
       .Case("attribute_availability_with_version_underscores", true)
       .Case("attribute_availability_tvos", true)
       .Case("attribute_availability_watchos", true)
+      .Case("attribute_availability_swift", true)
       .Case("attribute_availability_with_strict", true)
       .Case("attribute_availability_with_replacement", true)
       .Case("attribute_availability_in_templates", true)
@@ -1130,6 +1131,7 @@
       .Case("cxx_exceptions", LangOpts.CXXExceptions)
       .Case("cxx_rtti", LangOpts.RTTI && LangOpts.RTTIData)
       .Case("enumerator_attributes", true)
+      .Case("generalized_swift_name", true)
       .Case("nullability", true)
       .Case("nullability_on_arrays", true)
       .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory))
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index c52b61e..a456c9b 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -47,6 +47,7 @@
                                            VS, ICIS_NoInit);
     if (FnD) {
       Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs);
+      Actions.ProcessAPINotes(FnD);
       if (PureSpecLoc.isValid())
         Actions.ActOnPureSpecifier(FnD, PureSpecLoc);
     }
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 2d32087..b129394 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -244,6 +244,38 @@
   return IL;
 }
 
+void Parser::ParseSwiftNewtypeAttribute(
+    IdentifierInfo &SwiftNewtype, SourceLocation SwiftNewtypeLoc,
+    ParsedAttributes &attrs, SourceLocation *endLoc, IdentifierInfo *ScopeName,
+    SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+
+  BalancedDelimiterTracker Parens(*this, tok::l_paren);
+  Parens.consumeOpen();
+
+  if (Tok.is(tok::r_paren)) {
+    Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
+    Parens.consumeClose();
+    return;
+  }
+  if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
+    Diag(Tok.getLocation(), diag::warn_attribute_type_not_supported)
+        << &SwiftNewtype << Tok.getIdentifierInfo();
+    if (!isTokenSpecial())
+      ConsumeToken();
+    Parens.consumeClose();
+    return;
+  }
+  auto IL = IdentifierLoc::create(Actions.Context, Tok.getLocation(),
+                                  Tok.getIdentifierInfo());
+  ConsumeToken();
+  auto identLoc = ArgsUnion(IL);
+
+  attrs.addNew(&SwiftNewtype,
+               SourceRange(SwiftNewtypeLoc, Parens.getCloseLocation()),
+               ScopeName, ScopeLoc, &identLoc, 1, Syntax);
+  Parens.consumeClose();
+}
+
 void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
                                        SourceLocation AttrNameLoc,
                                        ParsedAttributes &Attrs,
@@ -364,6 +396,10 @@
     ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
                                      ScopeName, ScopeLoc, Syntax);
     return;
+  } else if (AttrKind == AttributeList::AT_SwiftNewtype) {
+    ParseSwiftNewtypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                               ScopeName, ScopeLoc, Syntax);
+    return;
   } else if (attributeIsTypeArgAttr(*AttrName)) {
     ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
                               ScopeLoc, Syntax);
@@ -855,7 +891,7 @@
 ///
 /// version-arg:
 ///   'introduced' '=' version
-///   'deprecated' '=' version
+///   'deprecated' ['=' version]
 ///   'obsoleted' = version
 ///   'unavailable'
 /// opt-replacement:
@@ -943,6 +979,21 @@
       continue;
     }
 
+    if (Keyword == Ident_deprecated && Platform->Ident &&
+        Platform->Ident->getName() == "swift") {
+      // For swift, we deprecate for all versions.
+      if (!Changes[Deprecated].KeywordLoc.isInvalid()) {
+        Diag(KeywordLoc, diag::err_availability_redundant)
+          << Keyword
+          << SourceRange(Changes[Deprecated].KeywordLoc);
+      }
+
+      Changes[Deprecated].KeywordLoc = KeywordLoc;
+      // Use a fake version here.
+      Changes[Deprecated].Version = VersionTuple(1);
+      continue;
+    }
+
     if (Tok.isNot(tok::equal)) {
       Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
       SkipUntil(tok::r_paren, StopAtSemi);
@@ -6553,3 +6604,68 @@
   }
   return false;
 }
+
+TypeResult Parser::parseTypeFromString(StringRef typeStr, StringRef context,
+                                       SourceLocation includeLoc) {
+  // Consume (unexpanded) tokens up to the end-of-directive.
+  SmallVector<Token, 4> tokens;
+  {
+    // Create a new buffer from which we will parse the type.
+    auto &sourceMgr = PP.getSourceManager();
+    FileID fileID = sourceMgr.createFileID(
+                      llvm::MemoryBuffer::getMemBufferCopy(typeStr, context),
+                      SrcMgr::C_User, 0, 0, includeLoc);
+
+    // Form a new lexer that references the buffer.
+    Lexer lexer(fileID, sourceMgr.getBuffer(fileID), PP);
+    lexer.setParsingPreprocessorDirective(true);
+    lexer.setIsPragmaLexer(true);
+
+    // Lex the tokens from that buffer.
+    Token tok;
+    do {
+      lexer.Lex(tok);
+      tokens.push_back(tok);
+    } while (tok.isNot(tok::eod));
+  }
+
+  // Replace the "eod" token with an "eof" token identifying the end of
+  // the provided string.
+  Token &endToken = tokens.back();
+  endToken.startToken();
+  endToken.setKind(tok::eof);
+  endToken.setLocation(Tok.getLocation());
+  endToken.setEofData(typeStr.data());
+
+  // Add the current token back.
+  tokens.push_back(Tok);
+
+  // Enter the tokens into the token stream.
+  PP.EnterTokenStream(tokens, /*DisableMacroExpansion=*/false);
+
+  // Consume the current token so that we'll start parsing the tokens we
+  // added to the stream.
+  ConsumeAnyToken();
+
+  // Enter a new scope.
+  ParseScope localScope(this, 0);
+
+  // Parse the type.
+  TypeResult result = ParseTypeName(nullptr);
+
+  // Check if we parsed the whole thing.
+  if (result.isUsable() &&
+      (Tok.isNot(tok::eof) || Tok.getEofData() != typeStr.data())) {
+    Diag(Tok.getLocation(), diag::err_type_unparsed);
+  }
+
+  // There could be leftover tokens (e.g. because of an error).
+  // Skip through until we reach the 'end of directive' token.
+  while (Tok.isNot(tok::eof))
+    ConsumeAnyToken();
+
+  // Consume the end token.
+  if (Tok.is(tok::eof) && Tok.getEofData() == typeStr.data())
+    ConsumeAnyToken();
+  return result;
+}
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 3f1fe7e..02e1f3f 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -2724,8 +2724,10 @@
         // initialize it.
         ThisDecl = VT->getTemplatedDecl();
 
-      if (ThisDecl && AccessAttrs)
+      if (ThisDecl) {
         Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
+        Actions.ProcessAPINotes(ThisDecl);
+      }
     }
 
     // Error recovery might have converted a non-static member into a static
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 81761bf..3a24ad9 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -212,6 +212,8 @@
 ///     __attribute__((unavailable))
 ///     __attribute__((objc_exception)) - used by NSException on 64-bit
 ///     __attribute__((objc_root_class))
+///     __attribute__((objc_subclassing_restricted))
+///     __attribute__((objc_complete_definition))
 ///
 Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
                                               ParsedAttributes &attrs) {
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 52e5194..e1a99fd 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -87,6 +87,11 @@
   PP.addCommentHandler(CommentSemaHandler.get());
 
   PP.setCodeCompletionHandler(*this);
+
+  Actions.ParseTypeFromStringCallback =
+    [this](StringRef typeStr, StringRef context, SourceLocation includeLoc) {
+      return this->parseTypeFromString(typeStr, context, includeLoc);
+    };
 }
 
 DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
@@ -419,6 +424,9 @@
 //===----------------------------------------------------------------------===//
 
 Parser::~Parser() {
+  // Clear out the parse-type-from-string callback.
+  Actions.ParseTypeFromStringCallback = nullptr;
+
   // If we still have scopes active, delete the scope tree.
   delete getCurScope();
   Actions.CurScope = nullptr;
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 7a59732..c92879a 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -20,6 +20,7 @@
   Sema.cpp
   SemaAccess.cpp
   SemaAttr.cpp
+  SemaAPINotes.cpp
   SemaCXXScopeSpec.cpp
   SemaCast.cpp
   SemaChecking.cpp
@@ -61,4 +62,5 @@
   clangBasic
   clangEdit
   clangLex
+  clangAPINotes
   )
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 0bdb194..53263ba 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -381,7 +381,7 @@
     PP.getExternalSource()->updateOutOfDateIdentifier(II);
   
   if (II.isFromAST())
-    II.setFETokenInfoChangedSinceDeserialization();
+    II.setChangedSinceDeserialization();
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp
index 3970b41..58d44ba 100644
--- a/lib/Sema/ScopeInfo.cpp
+++ b/lib/Sema/ScopeInfo.cpp
@@ -184,7 +184,7 @@
   }
 
   // Has this weak object been seen before?
-  FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
+  FunctionScopeInfo::WeakObjectUseMap::iterator Uses = WeakObjectUses.end();
   if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
     if (!RefExpr->isObjectReceiver())
       return;
@@ -197,10 +197,10 @@
   }
   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
-  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-    Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
-  else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
-    Uses = WeakObjectUses.end();
+  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (isa<VarDecl>(DRE->getDecl()))
+      Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
+  } else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
     if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
       if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
         Uses =
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 412f944..221058c 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -77,7 +77,8 @@
     isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()),
     LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
-    CollectStats(false), CodeCompleter(CodeCompleter),
+    APINotes(SourceMgr, LangOpts), CollectStats(false),
+    CodeCompleter(CodeCompleter),
     CurContext(nullptr), OriginalLexicalContext(nullptr),
     MSStructPragmaOn(false),
     MSPointerToMemberRepresentationMethod(
diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp
new file mode 100644
index 0000000..078445e
--- /dev/null
+++ b/lib/Sema/SemaAPINotes.cpp
@@ -0,0 +1,840 @@
+//===--- SemaAPINotes.cpp - API Notes Handling ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Sema/SemaInternal.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/APINotes/APINotesReader.h"
+using namespace clang;
+using clang::api_notes::VersionedInfoRole;
+
+namespace {
+  struct VersionedInfoMetadata {
+    VersionTuple Version;
+    VersionedInfoRole Role;
+
+    /*implicit*/ VersionedInfoMetadata(VersionedInfoRole role) : Role(role) {
+      assert(role != VersionedInfoRole::Versioned &&
+             "explicit version required");
+    }
+
+    /*implicit*/ VersionedInfoMetadata(VersionTuple version)
+        : Version(version), Role(VersionedInfoRole::Versioned) {}
+  };
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isMultiLevelPointerType(QualType type) {
+  QualType pointee = type->getPointeeType();
+  if (pointee.isNull())
+    return false;
+
+  return pointee->isAnyPointerType() || pointee->isObjCObjectPointerType() ||
+         pointee->isMemberPointerType();
+}
+
+// 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?
+    return;
+  }
+
+  QualType type;
+
+  // Nullability for a function/method appertains to the retain type.
+  if (auto function = dyn_cast<FunctionDecl>(decl)) {
+    type = function->getReturnType();
+  } else if (auto method = dyn_cast<ObjCMethodDecl>(decl)) {
+    type = method->getReturnType();
+  } else if (auto value = dyn_cast<ValueDecl>(decl)) {
+    type = value->getType();
+  } else if (auto property = dyn_cast<ObjCPropertyDecl>(decl)) {
+    type = property->getType();
+  } else {
+    return;
+  }
+
+  // Check the nullability specifier on this type.
+  QualType origType = type;
+  S.checkNullabilityTypeSpecifier(type, nullability, decl->getLocation(),
+                                  /*isContextSensitive=*/false,
+                                  isa<ParmVarDecl>(decl), /*implicit=*/true,
+                                  overrideExisting);
+  if (type.getTypePtr() == origType.getTypePtr())
+    return;
+
+  if (auto function = dyn_cast<FunctionDecl>(decl)) {
+    const FunctionType *fnType = function->getType()->castAs<FunctionType>();
+    if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) {
+      function->setType(S.Context.getFunctionType(type, proto->getParamTypes(),
+                                                  proto->getExtProtoInfo()));
+    } else {
+      function->setType(S.Context.getFunctionNoProtoType(type,
+                                                         fnType->getExtInfo()));
+    }
+  } else if (auto method = dyn_cast<ObjCMethodDecl>(decl)) {
+    method->setReturnType(type);
+
+    // Make it a context-sensitive keyword if we can.
+    if (!isMultiLevelPointerType(type)) {
+      method->setObjCDeclQualifier(
+        Decl::ObjCDeclQualifier(method->getObjCDeclQualifier() |
+                                Decl::OBJC_TQ_CSNullability));
+    }
+  } else if (auto value = dyn_cast<ValueDecl>(decl)) {
+    value->setType(type);
+
+    // Make it a context-sensitive keyword if we can.
+    if (auto parm = dyn_cast<ParmVarDecl>(decl)) {
+      if (parm->isObjCMethodParameter() && !isMultiLevelPointerType(type)) {
+        parm->setObjCDeclQualifier(
+          Decl::ObjCDeclQualifier(parm->getObjCDeclQualifier() |
+                                  Decl::OBJC_TQ_CSNullability));
+      }
+    }
+  } else if (auto property = dyn_cast<ObjCPropertyDecl>(decl)) {
+    property->setType(type, property->getTypeSourceInfo());
+
+    // Make it a property attribute if we can.
+    if (!isMultiLevelPointerType(type)) {
+      property->setPropertyAttributes(
+        ObjCPropertyDecl::OBJC_PR_null_resettable);
+    }
+  } else {
+    llvm_unreachable("cannot handle nullability here");
+  }
+}
+
+/// Copy a string into ASTContext-allocated memory.
+static StringRef CopyString(ASTContext &ctx, StringRef string) {
+  void *mem = ctx.Allocate(string.size(), alignof(char));
+  memcpy(mem, string.data(), string.size());
+  return StringRef(static_cast<char *>(mem), string.size());
+}
+
+namespace {
+  template <typename A>
+  struct AttrKindFor {};
+
+#define ATTR(X) \
+  template <> struct AttrKindFor<X##Attr> { \
+    static const attr::Kind value = attr::X; \
+  };
+#include "clang/Basic/AttrList.inc"
+
+  /// 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.
+  template<typename A>
+  void handleAPINotedAttribute(
+         Sema &S, Decl *D, bool shouldAddAttribute,
+         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: {
+      auto end = D->specific_attr_end<A>();
+      auto existing = getExistingAttr(D);
+      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);
+
+        D->getAttrs().erase(existing.getCurrent());
+        D->addAttr(versioned);
+      }
+
+      // If we're supposed to add a new attribute, do so.
+      if (shouldAddAttribute) {
+        if (auto attr = createAttr()) {
+          D->addAttr(attr);
+        }
+      }
+      break;
+    }
+
+    case VersionedInfoRole::Versioned:
+      // FIXME: Include the actual version instead of making one up.
+      if (shouldAddAttribute) {
+        if (auto attr = createAttr()) {
+          auto *versioned =
+              SwiftVersionedAttr::CreateImplicit(S.Context, metadata.Version, 
+                                                 attr);
+          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);
+        D->addAttr(versioned);
+      }
+      break;
+    }
+  }
+  
+  template<typename A>
+  void handleAPINotedAttribute(
+         Sema &S, Decl *D, bool shouldAddAttribute,
+         VersionedInfoMetadata metadata,
+         llvm::function_ref<A *()> createAttr) {
+    handleAPINotedAttribute<A>(S, D, shouldAddAttribute, metadata, createAttr,
+    [](Decl *decl) {
+        return decl->specific_attr_begin<A>();
+    });
+  }
+}
+
+static void ProcessAPINotes(Sema &S, Decl *D,
+                            const api_notes::CommonEntityInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Availability
+  if (info.Unavailable) {
+    handleAPINotedAttribute<UnavailableAttr>(S, D, true, metadata,
+      [&] {
+        return UnavailableAttr::CreateImplicit(S.Context,
+                                               CopyString(S.Context,
+                                                          info.UnavailableMsg));
+    });
+  }
+
+  if (info.UnavailableInSwift) {
+    handleAPINotedAttribute<AvailabilityAttr>(S, D, true, metadata, [&] {
+      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 (auto swiftPrivate = info.isSwiftPrivate()) {
+    handleAPINotedAttribute<SwiftPrivateAttr>(S, D, *swiftPrivate, metadata,
+                                              [&] {
+      return SwiftPrivateAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // swift_name
+  if (!info.SwiftName.empty()) {
+    handleAPINotedAttribute<SwiftNameAttr>(S, D, true, metadata,
+                                           [&]() -> 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,
+                            VersionedInfoMetadata metadata) {
+  // swift_bridge
+  if (auto swiftBridge = info.getSwiftBridge()) {
+    handleAPINotedAttribute<SwiftBridgeAttr>(S, D, !swiftBridge->empty(),
+                                             metadata, [&] {
+      return SwiftBridgeAttr::CreateImplicit(S.Context,
+                                             CopyString(S.Context,
+                                                        *swiftBridge));
+    });
+  }
+
+  // ns_error_domain
+  if (auto nsErrorDomain = info.getNSErrorDomain()) {
+    handleAPINotedAttribute<NSErrorDomainAttr>(S, D, !nsErrorDomain->empty(),
+                                               metadata, [&] {
+      return NSErrorDomainAttr::CreateImplicit(
+               S.Context,
+               &S.Context.Idents.get(*nsErrorDomain));
+    });
+  }
+
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  metadata);
+}
+
+/// Check that the replacement type provided by API notes is reasonable.
+///
+/// This is a very weak form of ABI check.
+static bool checkAPINotesReplacementType(Sema &S, SourceLocation loc,
+                                         QualType origType,
+                                         QualType replacementType) {
+  if (S.Context.getTypeSize(origType) !=
+        S.Context.getTypeSize(replacementType)) {
+    S.Diag(loc, diag::err_incompatible_replacement_type)
+      << replacementType << origType;
+    return true;
+  }
+
+  return false;
+}
+
+/// Process API notes for a variable or property.
+static void ProcessAPINotes(Sema &S, Decl *D,
+                            const api_notes::VariableInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Type override.
+  if (metadata.Role != VersionedInfoRole::Versioned &&
+      !info.getType().empty() && S.ParseTypeFromStringCallback) {
+    auto parsedType = S.ParseTypeFromStringCallback(info.getType(),
+                                                    "<API Notes>",
+                                                    D->getLocation());
+    if (parsedType.isUsable()) {
+      QualType type = Sema::GetTypeFromParser(parsedType.get());
+      auto typeInfo =
+        S.Context.getTrivialTypeSourceInfo(type, D->getLocation());
+
+      if (auto var = dyn_cast<VarDecl>(D)) {
+        // Make adjustments to parameter types.
+        if (isa<ParmVarDecl>(var)) {
+          type = S.adjustParameterTypeForObjCAutoRefCount(type,
+                                                          D->getLocation());
+          type = S.Context.getAdjustedParameterType(type);
+        }
+
+        if (!checkAPINotesReplacementType(S, var->getLocation(), var->getType(),
+                                          type)) {
+          var->setType(type);
+          var->setTypeSourceInfo(typeInfo);
+        }
+      } else if (auto property = dyn_cast<ObjCPropertyDecl>(D)) {
+        if (!checkAPINotesReplacementType(S, property->getLocation(),
+                                          property->getType(),
+                                          type)) {
+          property->setType(type, typeInfo);
+        }
+      } else {
+        llvm_unreachable("API notes allowed a type on an unknown declaration");
+      }
+    }
+  }
+
+  // Nullability.
+  if (auto Nullability = info.getNullability()) {
+    applyNullability(S, D, *Nullability, metadata);
+  }
+
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for a parameter.
+static void ProcessAPINotes(Sema &S, ParmVarDecl *D,
+                            const api_notes::ParamInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // noescape
+  if (auto noescape = info.isNoEscape()) {
+    handleAPINotedAttribute<NoEscapeAttr>(S, D, *noescape, metadata, [&] {
+      return NoEscapeAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for a global variable.
+static void ProcessAPINotes(Sema &S, VarDecl *D,
+                            const api_notes::GlobalVariableInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for an Objective-C property.
+static void ProcessAPINotes(Sema &S, ObjCPropertyDecl *D,
+                            const api_notes::ObjCPropertyInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  metadata);
+  if (auto asAccessors = info.getSwiftImportAsAccessors()) {
+    handleAPINotedAttribute<SwiftImportPropertyAsAccessorsAttr>(S, D,
+                                                                *asAccessors,
+                                                                metadata, [&] {
+      return SwiftImportPropertyAsAccessorsAttr::CreateImplicit(S.Context);
+    });
+  }
+}
+
+namespace {
+  typedef llvm::PointerUnion<FunctionDecl *, ObjCMethodDecl *> FunctionOrMethod;
+}
+
+/// Process API notes for a function or method.
+static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc,
+                            const api_notes::FunctionInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Find the declaration itself.
+  FunctionDecl *FD = AnyFunc.dyn_cast<FunctionDecl *>();
+  Decl *D = FD;
+  ObjCMethodDecl *MD = 0;
+  if (!D) {
+    MD = AnyFunc.get<ObjCMethodDecl *>();
+    D = MD;
+  }
+
+  // Nullability of return type.
+  if (info.NullabilityAudited) {
+    applyNullability(S, D, info.getReturnTypeInfo(), metadata);
+  }
+
+  // Parameters.
+  unsigned NumParams;
+  if (FD)
+    NumParams = FD->getNumParams();
+  else
+    NumParams = MD->param_size();
+
+  bool anyTypeChanged = false;
+  for (unsigned I = 0; I != NumParams; ++I) {
+    ParmVarDecl *Param;
+    if (FD)
+      Param = FD->getParamDecl(I);
+    else
+      Param = MD->param_begin()[I];
+
+    QualType paramTypeBefore = Param->getType();
+
+    if (I < info.Params.size()) {
+      ProcessAPINotes(S, Param, info.Params[I], metadata);
+    }
+
+    // Nullability.
+    if (info.NullabilityAudited)
+      applyNullability(S, Param, info.getParamTypeInfo(I), metadata);
+
+    if (paramTypeBefore.getAsOpaquePtr() != Param->getType().getAsOpaquePtr())
+      anyTypeChanged = true;
+  }
+
+  // Result type override.
+  QualType overriddenResultType;
+  if (metadata.Role != VersionedInfoRole::Versioned &&
+      !info.ResultType.empty() && S.ParseTypeFromStringCallback) {
+    auto parsedType = S.ParseTypeFromStringCallback(info.ResultType,
+                                                    "<API Notes>",
+                                                    D->getLocation());
+    if (parsedType.isUsable()) {
+      QualType resultType = Sema::GetTypeFromParser(parsedType.get());
+
+      if (MD) {
+        if (!checkAPINotesReplacementType(S, D->getLocation(),
+                                          MD->getReturnType(), resultType)) {
+          auto resultTypeInfo =
+            S.Context.getTrivialTypeSourceInfo(resultType, D->getLocation());
+          MD->setReturnType(resultType);
+          MD->setReturnTypeSourceInfo(resultTypeInfo);
+        }
+      } else if (!checkAPINotesReplacementType(S, FD->getLocation(),
+                                               FD->getReturnType(),
+                                               resultType)) {
+        overriddenResultType = resultType;
+        anyTypeChanged = true;
+      }
+    }
+  }
+
+  // If the result type or any of the parameter types changed for a function
+  // declaration, we have to rebuild the type.
+  if (FD && anyTypeChanged) {
+    if (const auto *fnProtoType = FD->getType()->getAs<FunctionProtoType>()) {
+      if (overriddenResultType.isNull())
+        overriddenResultType = fnProtoType->getReturnType();
+
+      SmallVector<QualType, 4> paramTypes;
+      for (auto param : FD->parameters()) {
+        paramTypes.push_back(param->getType());
+      }
+      FD->setType(S.Context.getFunctionType(overriddenResultType,
+                                            paramTypes,
+                                            fnProtoType->getExtProtoInfo()));
+    } else if (!overriddenResultType.isNull()) {
+      const auto *fnNoProtoType = FD->getType()->castAs<FunctionNoProtoType>();
+      FD->setType(
+              S.Context.getFunctionNoProtoType(overriddenResultType,
+                                               fnNoProtoType->getExtInfo()));
+    }
+  }
+
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for a global function.
+static void ProcessAPINotes(Sema &S, FunctionDecl *D,
+                            const api_notes::GlobalFunctionInfo &info,
+                            VersionedInfoMetadata metadata) {
+
+  // Handle common function information.
+  ProcessAPINotes(S, FunctionOrMethod(D),
+                  static_cast<const api_notes::FunctionInfo &>(info), metadata);
+}
+
+/// Process API notes for an enumerator.
+static void ProcessAPINotes(Sema &S, EnumConstantDecl *D,
+                            const api_notes::EnumConstantInfo &info,
+                            VersionedInfoMetadata metadata) {
+
+  // Handle common information.
+  ProcessAPINotes(S, D,
+                  static_cast<const api_notes::CommonEntityInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for an Objective-C method.
+static void ProcessAPINotes(Sema &S, ObjCMethodDecl *D,
+                            const api_notes::ObjCMethodInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Designated initializers.
+  if (info.DesignatedInit) {
+    handleAPINotedAttribute<ObjCDesignatedInitializerAttr>(S, D, true, metadata,
+                                                           [&] {
+      if (ObjCInterfaceDecl *IFace = D->getClassInterface()) {
+        IFace->setHasDesignatedInitializers();
+      }
+      return ObjCDesignatedInitializerAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // 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);
+}
+
+/// Process API notes for a tag.
+static void ProcessAPINotes(Sema &S, TagDecl *D,
+                            const api_notes::TagInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Handle common type information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for a typedef.
+static void ProcessAPINotes(Sema &S, TypedefNameDecl *D,
+                            const api_notes::TypedefInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // swift_wrapper
+  using SwiftWrapperKind = api_notes::SwiftWrapperKind;
+
+  if (auto swiftWrapper = info.SwiftWrapper) {
+    handleAPINotedAttribute<SwiftNewtypeAttr>(S, D,
+      *swiftWrapper != SwiftWrapperKind::None, metadata,
+      [&] {
+        SwiftNewtypeAttr::NewtypeKind kind;
+        switch (*swiftWrapper) {
+        case SwiftWrapperKind::None:
+          llvm_unreachable("Shouldn't build an attribute");
+
+        case SwiftWrapperKind::Struct:
+          kind = SwiftNewtypeAttr::NK_Struct;
+          break;
+
+        case SwiftWrapperKind::Enum:
+          kind = SwiftNewtypeAttr::NK_Enum;
+          break;
+        }
+        return SwiftNewtypeAttr::CreateImplicit(
+                 S.Context,
+                 SwiftNewtypeAttr::GNU_swift_wrapper,
+                 kind);
+    });
+  }
+
+  // Handle common type information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for an Objective-C class or protocol.
+static void ProcessAPINotes(Sema &S, ObjCContainerDecl *D,
+                            const api_notes::ObjCContextInfo &info,
+                            VersionedInfoMetadata metadata) {
+
+  // Handle common type information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for an Objective-C class.
+static void ProcessAPINotes(Sema &S, ObjCInterfaceDecl *D,
+                            const api_notes::ObjCContextInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Handle information common to Objective-C classes and protocols.
+  ProcessAPINotes(S, static_cast<clang::ObjCContainerDecl *>(D), info,
+                  metadata);
+}
+
+/// Processes all versions of versioned API notes.
+///
+/// Just dispatches to the various ProcessAPINotes functions in this file.
+template <typename SpecificDecl, typename SpecificInfo>
+static void ProcessVersionedAPINotes(
+    Sema &S, SpecificDecl *D,
+    const api_notes::APINotesReader::VersionedInfo<SpecificInfo> Info) {
+  unsigned Selected = Info.getSelected().getValueOr(Info.size());
+
+  VersionTuple Version;
+  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());
+    }
+  }
+}
+
+/// Process API notes that are associated with this declaration, mapping them
+/// to attributes as appropriate.
+void Sema::ProcessAPINotes(Decl *D) {
+  if (!D)
+    return;
+
+  // Globals.
+  if (D->getDeclContext()->isFileContext()) {
+    // Global variables.
+    if (auto VD = dyn_cast<VarDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupGlobalVariable(VD->getName());
+        ProcessVersionedAPINotes(*this, VD, Info);
+      }
+
+      return;
+    }
+
+    // Global functions.
+    if (auto FD = dyn_cast<FunctionDecl>(D)) {
+      if (FD->getDeclName().isIdentifier()) {
+        for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+          auto Info = Reader->lookupGlobalFunction(FD->getName());
+          ProcessVersionedAPINotes(*this, FD, Info);
+        }
+      }
+
+      return;
+    }
+
+    // Objective-C classes.
+    if (auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupObjCClassInfo(Class->getName());
+        ProcessVersionedAPINotes(*this, Class, Info);
+      }
+
+      return;
+    }
+
+    // Objective-C protocols.
+    if (auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());
+        ProcessVersionedAPINotes(*this, Protocol, Info);
+      }
+
+      return;
+    }
+
+    // Tags
+    if (auto Tag = dyn_cast<TagDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupTag(Tag->getName());
+        ProcessVersionedAPINotes(*this, Tag, Info);
+      }
+
+      return;
+    }
+
+    // Typedefs
+    if (auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupTypedef(Typedef->getName());
+        ProcessVersionedAPINotes(*this, Typedef, Info);
+      }
+
+      return;
+    }
+
+    return;
+  }
+
+  // Enumerators.
+  if (D->getDeclContext()->getRedeclContext()->isFileContext()) {
+    if (auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupEnumConstant(EnumConstant->getName());
+        ProcessVersionedAPINotes(*this, EnumConstant, Info);
+      }
+
+      return;
+    }
+  }
+
+  if (auto ObjCContainer = dyn_cast<ObjCContainerDecl>(D->getDeclContext())) {
+    // Location function that looks up an Objective-C context.
+    auto GetContext = [&](api_notes::APINotesReader *Reader)
+                        -> Optional<api_notes::ContextID> {
+      if (auto Protocol = dyn_cast<ObjCProtocolDecl>(ObjCContainer)) {
+        if (auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))
+          return *Found;
+
+        return None;
+      }
+
+      if (auto Impl = dyn_cast<ObjCCategoryImplDecl>(ObjCContainer)) {
+        if (auto Cat = Impl->getCategoryDecl())
+          ObjCContainer = Cat;
+        else
+          return None;
+      }
+
+      if (auto Category = dyn_cast<ObjCCategoryDecl>(ObjCContainer)) {
+        if (Category->getClassInterface())
+          ObjCContainer = Category->getClassInterface();
+        else
+          return None;
+      }
+
+      if (auto Impl = dyn_cast<ObjCImplDecl>(ObjCContainer)) {
+        if (Impl->getClassInterface())
+          ObjCContainer = Impl->getClassInterface();
+        else
+          return None;
+      }
+
+      if (auto Class = dyn_cast<ObjCInterfaceDecl>(ObjCContainer)) {
+        if (auto Found = Reader->lookupObjCClassID(Class->getName()))
+          return *Found;
+
+        return None;
+
+      }
+
+      return None;
+    };
+
+    // Objective-C methods.
+    if (auto Method = dyn_cast<ObjCMethodDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        if (auto Context = GetContext(Reader)) {
+          // Map the selector.
+          Selector Sel = Method->getSelector();
+          SmallVector<StringRef, 2> SelPieces;
+          if (Sel.isUnarySelector())
+            SelPieces.push_back(Sel.getNameForSlot(0));
+          else {
+            for (unsigned i = 0, n = Sel.getNumArgs(); i != n; ++i)
+              SelPieces.push_back(Sel.getNameForSlot(i));
+          }
+
+          api_notes::ObjCSelectorRef SelectorRef;
+          SelectorRef.NumPieces = Sel.getNumArgs();
+          SelectorRef.Identifiers = SelPieces;
+
+          auto Info = Reader->lookupObjCMethod(*Context, SelectorRef,
+                                               Method->isInstanceMethod());
+          ProcessVersionedAPINotes(*this, Method, Info);
+        }
+      }
+    }
+
+    // Objective-C properties.
+    if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        if (auto Context = GetContext(Reader)) {
+          bool isInstanceProperty =
+            (Property->getPropertyAttributesAsWritten() &
+               ObjCPropertyDecl::OBJC_PR_class) == 0;
+          auto Info = Reader->lookupObjCProperty(*Context, Property->getName(),
+                                                 isInstanceProperty);
+          ProcessVersionedAPINotes(*this, Property, Info);
+        }
+      }
+
+      return;
+    }
+
+    return;
+  }
+}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 3aedb2a..2565f0c 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -4623,20 +4623,6 @@
 
     return SLCT_NotALiteral;
   }
-  case Stmt::ObjCMessageExprClass: {
-    const auto *ME = cast<ObjCMessageExpr>(E);
-    if (const auto *ND = ME->getMethodDecl()) {
-      if (const auto *FA = ND->getAttr<FormatArgAttr>()) {
-        unsigned ArgIndex = FA->getFormatIdx();
-        const Expr *Arg = ME->getArg(ArgIndex - 1);
-        return checkFormatStringExpr(
-            S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type,
-            CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset);
-      }
-    }
-
-    return SLCT_NotALiteral;
-  }
   case Stmt::ObjCStringLiteralClass:
   case Stmt::StringLiteralClass: {
     const StringLiteral *StrE = nullptr;
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 94cfc4b..85343cd 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -5230,24 +5230,22 @@
 /// when it has the same number of parameters as we have selector identifiers.
 ///
 /// \param Results the structure into which we'll add results.
-static void AddObjCMethods(ObjCContainerDecl *Container, 
-                           bool WantInstanceMethods,
-                           ObjCMethodKind WantKind,
+static void AddObjCMethods(ObjCContainerDecl *Container,
+                           bool WantInstanceMethods, ObjCMethodKind WantKind,
                            ArrayRef<IdentifierInfo *> SelIdents,
                            DeclContext *CurContext,
-                           VisitedSelectorSet &Selectors,
-                           bool AllowSameLength,
-                           ResultBuilder &Results,
-                           bool InOriginalClass = true) {
+                           VisitedSelectorSet &Selectors, bool AllowSameLength,
+                           ResultBuilder &Results, bool InOriginalClass = true,
+                           bool IsRootClass = false) {
   typedef CodeCompletionResult Result;
   Container = getContainerDef(Container);
   ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
-  bool isRootClass = IFace && !IFace->getSuperClass();
+  IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass());
   for (auto *M : Container->methods()) {
     // The instance methods on the root class can be messaged via the
     // metaclass.
     if (M->isInstanceMethod() == WantInstanceMethods ||
-        (isRootClass && !WantInstanceMethods)) {
+        (IsRootClass && !WantInstanceMethods)) {
       // Check whether the selector identifiers we've been given are a 
       // subset of the identifiers for this particular method.
       if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))
@@ -5273,8 +5271,8 @@
       for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
                                                 E = Protocols.end(); 
            I != E; ++I)
-        AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
-                       CurContext, Selectors, AllowSameLength, Results, false);
+        AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                       Selectors, AllowSameLength, Results, false, IsRootClass);
     }
   }
   
@@ -5283,43 +5281,43 @@
   
   // Add methods in protocols.
   for (auto *I : IFace->protocols())
-    AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength, Results, false);
-  
+    AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                   Selectors, AllowSameLength, Results, false, IsRootClass);
+
   // Add methods in categories.
   for (auto *CatDecl : IFace->known_categories()) {
     AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength,
-                   Results, InOriginalClass);
-    
+                   CurContext, Selectors, AllowSameLength, Results,
+                   InOriginalClass, IsRootClass);
+
     // Add a categories protocol methods.
     const ObjCList<ObjCProtocolDecl> &Protocols 
       = CatDecl->getReferencedProtocols();
     for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
                                               E = Protocols.end();
          I != E; ++I)
-      AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
-                     CurContext, Selectors, AllowSameLength,
-                     Results, false);
-    
+      AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                     Selectors, AllowSameLength, Results, false, IsRootClass);
+
     // Add methods in category implementations.
     if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
-      AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 
-                     CurContext, Selectors, AllowSameLength,
-                     Results, InOriginalClass);
+      AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                     Selectors, AllowSameLength, Results, InOriginalClass,
+                     IsRootClass);
   }
   
   // Add methods in superclass.
+  // Avoid passing in IsRootClass since root classes won't have super classes.
   if (IFace->getSuperClass())
-    AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, 
-                   SelIdents, CurContext, Selectors,
-                   AllowSameLength, Results, false);
+    AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
+                   SelIdents, CurContext, Selectors, AllowSameLength, Results,
+                   /*IsRootClass=*/false);
 
   // Add methods in our implementation, if any.
   if (ObjCImplementationDecl *Impl = IFace->getImplementation())
-    AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength,
-                   Results, InOriginalClass);
+    AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                   Selectors, AllowSameLength, Results, InOriginalClass,
+                   IsRootClass);
 }
 
 
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index adcf2ee..eff3aeb 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2307,6 +2307,10 @@
     NewAttr = S.mergeMinSizeAttr(D, MA->getRange(), AttrSpellingListIndex);
   else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr))
     NewAttr = S.mergeOptimizeNoneAttr(D, OA->getRange(), AttrSpellingListIndex);
+  else if (const auto *SNA = dyn_cast<SwiftNameAttr>(Attr))
+    NewAttr = S.mergeSwiftNameAttr(D, SNA->getRange(), SNA->getName(),
+                                   AMK == Sema::AMK_Override,
+                                   AttrSpellingListIndex);
   else if (const auto *InternalLinkageA = dyn_cast<InternalLinkageAttr>(Attr))
     NewAttr = S.mergeInternalLinkageAttr(
         D, InternalLinkageA->getRange(),
@@ -2324,6 +2328,8 @@
            (AMK == Sema::AMK_Override ||
             AMK == Sema::AMK_ProtocolImplementation))
     NewAttr = nullptr;
+  else if (isa<SwiftPrivateAttr>(Attr) && AMK == Sema::AMK_Override)
+    NewAttr = nullptr;
   else if (const auto *UA = dyn_cast<UuidAttr>(Attr))
     NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,
                               UA->getGuid());
@@ -11370,10 +11376,8 @@
   }
 }
 
-ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
-                                  SourceLocation NameLoc, IdentifierInfo *Name,
-                                  QualType T, TypeSourceInfo *TSInfo,
-                                  StorageClass SC) {
+QualType Sema::adjustParameterTypeForObjCAutoRefCount(QualType T,
+                                                      SourceLocation Loc) {
   // In ARC, infer a lifetime qualifier for appropriate parameter types.
   if (getLangOpts().ObjCAutoRefCount &&
       T.getObjCLifetime() == Qualifiers::OCL_None &&
@@ -11388,7 +11392,7 @@
       if (!T.isConstQualified()) {
         DelayedDiagnostics.add(
             sema::DelayedDiagnostic::makeForbiddenType(
-            NameLoc, diag::err_arc_array_param_no_ownership, T, false));
+            Loc, diag::err_arc_array_param_no_ownership, T, false));
       }
       lifetime = Qualifiers::OCL_ExplicitNone;
     } else {
@@ -11397,6 +11401,16 @@
     T = Context.getLifetimeQualifiedType(T, lifetime);
   }
 
+  return T;
+}
+
+ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
+                                  SourceLocation NameLoc, IdentifierInfo *Name,
+                                  QualType T, TypeSourceInfo *TSInfo,
+                                  StorageClass SC) {
+  // Perform Objective-C ARC adjustments.
+  T = adjustParameterTypeForObjCAutoRefCount(T, NameLoc);
+
   ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name,
                                          Context.getAdjustedParameterType(T),
                                          TSInfo, SC, nullptr);
@@ -12149,7 +12163,9 @@
   // Always attach attributes to the underlying decl.
   if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
     D = TD->getTemplatedDecl();
-  ProcessDeclAttributeList(S, D, Attrs.getList());
+
+  ProcessDeclAttributeList(S, D, Attrs.getList());  
+  ProcessAPINotes(D);
 
   if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(D))
     if (Method->isStatic())
@@ -13491,6 +13507,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, New, Attr);
+  ProcessAPINotes(New);
 
   // Set the lexical context. If the tag has a C++ scope specifier, the
   // lexical context will be different from the semantic context.
@@ -14721,6 +14738,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Record, Attr);
+  ProcessAPINotes(Record);
 }
 
 /// \brief Determine whether the given integral value is representable within
@@ -15020,6 +15038,8 @@
   // Process attributes.
   if (Attr) ProcessDeclAttributeList(S, New, Attr);
 
+  ProcessAPINotes(New);
+
   // Register this decl in the current scope stack.
   New->setAccess(TheEnumDecl->getAccess());
   PushOnScopeChains(New, S);
@@ -15243,6 +15263,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Enum, Attr);
+  ProcessAPINotes(Enum);
 
   if (Enum->isDependentType()) {
     for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index c6a5bc7..fba9aea 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1476,6 +1476,26 @@
                                Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleNoEscapeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D);
+  if (!PD)
+    return;
+
+  // noescape only applies to pointer types.
+  QualType T = PD->getType();
+  if (!T->isAnyPointerType() && !T->isBlockPointerType() && 
+      !T->isReferenceType() && !T->isArrayType() && 
+      !T->isMemberPointerType()) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_noescape_non_pointer)
+      << T;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) NoEscapeAttr(
+                                 Attr.getRange(), S.Context,
+                                 Attr.getAttributeSpellingListIndex()));
+}
+
 static void handleAssumeAlignedAttr(Sema &S, Decl *D,
                                     const AttributeList &Attr) {
   Expr *E = Attr.getArgAsExpr(0),
@@ -2322,6 +2342,15 @@
           dyn_cast_or_null<StringLiteral>(Attr.getReplacementExpr()))
     Replacement = SE->getString();
 
+  if (II->getName() == "swift") {
+    if (Introduced.isValid() || Obsoleted.isValid() ||
+        (!IsUnavailable && !Deprecated.isValid())) {
+      S.Diag(Attr.getLoc(),
+             diag::warn_availability_swift_unavailable_deprecated_only);
+      return;
+    }
+  }
+
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II,
                                                       false/*Implicit*/,
                                                       Introduced.Version,
@@ -3845,6 +3874,27 @@
                                           AttrSpellingListIndex);
 }
 
+SwiftNameAttr *Sema::mergeSwiftNameAttr(Decl *D, SourceRange Range,
+                                        StringRef Name, bool Override,
+                                        unsigned AttrSpellingListIndex) {
+  if (SwiftNameAttr *Inline = D->getAttr<SwiftNameAttr>()) {
+    if (Override) {
+      // FIXME: Warn about an incompatible override.
+      return nullptr;
+    }
+
+    if (Inline->getName() != Name && !Inline->isImplicit()) {
+      Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
+      Diag(Range.getBegin(), diag::note_conflicting_attribute);
+    }
+
+    D->dropAttr<SwiftNameAttr>();
+  }
+
+  return ::new (Context) SwiftNameAttr(Range, Context, Name,
+                                       AttrSpellingListIndex);
+}
+
 static void handleAlwaysInlineAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
   if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, Attr.getRange(),
@@ -4622,6 +4672,40 @@
                                         attr.getAttributeSpellingListIndex()));
 }
 
+static void handleNSErrorDomain(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (!isa<TagDecl>(D)) {
+    S.Diag(D->getLocStart(), diag::err_nserrordomain_not_tagdecl)
+        << S.getLangOpts().CPlusPlus;
+    return;
+  }
+  IdentifierLoc *identLoc =
+      Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
+  if (!identLoc || !identLoc->Ident) {
+    // Try to locate the argument directly
+    SourceLocation loc = Attr.getLoc();
+    if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))
+      loc = Attr.getArgAsExpr(0)->getLocStart();
+
+    S.Diag(loc, diag::err_nserrordomain_requires_identifier);
+    return;
+  }
+
+  // Verify that the identifier is a valid decl in the C decl namespace
+  LookupResult lookupResult(S, DeclarationName(identLoc->Ident),
+                            SourceLocation(),
+                            Sema::LookupNameKind::LookupOrdinaryName);
+  if (!S.LookupName(lookupResult, S.TUScope) ||
+      !lookupResult.getAsSingle<VarDecl>()) {
+    S.Diag(identLoc->Loc, diag::err_nserrordomain_invalid_decl)
+        << identLoc->Ident;
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+                 NSErrorDomainAttr(Attr.getRange(), S.Context, identLoc->Ident,
+                                   Attr.getAttributeSpellingListIndex()));
+}
+
 static void handleCFAuditedTransferAttr(Sema &S, Decl *D,
                                         const AttributeList &Attr) {
   if (checkAttrMutualExclusion<CFUnknownTransferAttr>(S, D, Attr.getRange(),
@@ -4811,6 +4895,421 @@
                                      Attr.getAttributeSpellingListIndex()));
 }
 
+static Optional<unsigned>
+validateSwiftFunctionName(StringRef Name,
+                          unsigned &SwiftParamCount,
+                          bool &IsSingleParamInit) {
+  SwiftParamCount = 0;
+
+  // Check whether this will be mapped to a getter or setter of a
+  // property.
+  bool isGetter = false;
+  bool isSetter = false;
+  if (Name.startswith("getter:")) {
+    isGetter = true;
+    Name = Name.substr(7);
+  } else if (Name.startswith("setter:")) {
+    isSetter = true;
+    Name = Name.substr(7);
+  }
+
+  if (Name.back() != ')')
+    return diag::warn_attr_swift_name_function;
+
+  StringRef BaseName, Parameters;
+  std::tie(BaseName, Parameters) = Name.split('(');
+
+  // Split at the first '.', if it exists, which separates the context
+  // name from the base name.
+  StringRef ContextName;
+  bool IsMember = false;
+  std::tie(ContextName, BaseName) = BaseName.split('.');
+  if (BaseName.empty()) {
+    BaseName = ContextName;
+    ContextName = StringRef();
+  } else if (ContextName.empty() || !isValidIdentifier(ContextName)) {
+    return diag::warn_attr_swift_name_context_name_invalid_identifier;
+  } else {
+    IsMember = true;
+  }
+
+  if (!isValidIdentifier(BaseName) || BaseName == "_")
+    return diag::warn_attr_swift_name_basename_invalid_identifier;
+
+  bool IsSubscript = BaseName == "subscript";
+  // A subscript accessor must be a getter or setter.
+  if (IsSubscript && !isGetter && !isSetter)
+    return diag::warn_attr_swift_name_subscript_not_accessor;
+  
+  if (Parameters.empty())
+    return diag::warn_attr_swift_name_missing_parameters;
+  Parameters = Parameters.drop_back(); // ')'
+
+  if (Parameters.empty()) {
+    // Setters and subscripts must have at least one parameter.
+    if (IsSubscript)
+      return diag::warn_attr_swift_name_subscript_no_parameter;
+    if (isSetter)
+      return diag::warn_attr_swift_name_setter_parameters;
+    
+    return None;
+  }
+
+  if (Parameters.back() != ':')
+    return diag::warn_attr_swift_name_function;
+
+  Optional<unsigned> SelfLocation;
+  Optional<unsigned> NewValueLocation;
+  unsigned NewValueCount = 0;
+  StringRef NextParam;
+  do {
+    std::tie(NextParam, Parameters) = Parameters.split(':');
+
+    if (!isValidIdentifier(NextParam))
+      return diag::warn_attr_swift_name_parameter_invalid_identifier;
+
+    // "self" indicates the "self" argument for a member.
+    if (IsMember && NextParam == "self") {
+      // More than one "self"?
+      if (SelfLocation) return diag::warn_attr_swift_name_multiple_selfs;
+
+      // The "self" location is the current parameter.
+      SelfLocation = SwiftParamCount;
+    }
+    
+    // "newValue" indicates the "newValue" argument for a setter.
+    if (NextParam == "newValue") {
+      // There should only be one 'newValue', but it's only significant for
+      // subscript accessors, so don't error right away.
+      ++NewValueCount;
+      
+      NewValueLocation = SwiftParamCount;
+    }
+    ++SwiftParamCount;
+  } while (!Parameters.empty());
+
+  // Only instance subscripts are currently supported.
+  if (IsSubscript && !SelfLocation)
+    return diag::warn_attr_swift_name_static_subscript;
+
+  IsSingleParamInit =
+      (SwiftParamCount == 1 && BaseName == "init" && NextParam != "_");
+
+  // Check the number of parameters for a getter/setter.
+  if (isGetter || isSetter) {
+    // Setters have one parameter for the new value.
+    unsigned NumExpectedParams;
+    unsigned ParamDiag;
+    
+    if (isSetter) {
+      NumExpectedParams = 1;
+      ParamDiag = diag::warn_attr_swift_name_setter_parameters;
+    } else {
+      NumExpectedParams = 0;
+      ParamDiag = diag::warn_attr_swift_name_getter_parameters;
+    }
+
+    // Instance methods have one parameter for "self".
+    if (SelfLocation) ++NumExpectedParams;
+    
+    // Subscripts may have additional parameters beyond the expected params for
+    // the index.
+    if (IsSubscript) {
+      if (SwiftParamCount < NumExpectedParams)
+        return ParamDiag;
+      // A subscript setter must explicitly label its newValue parameter to
+      // distinguish it from index parameters.
+      if (isSetter) {
+        if (!NewValueLocation)
+          return diag::warn_attr_swift_name_subscript_setter_no_newValue;
+        // There can only be one.
+        if (NewValueCount > 1)
+          return diag::warn_attr_swift_name_subscript_setter_multiple_newValues;
+      } else {
+        // Subscript getters should have no 'newValue:' parameter.
+        if (NewValueLocation)
+          return diag::warn_attr_swift_name_subscript_getter_newValue;
+      }
+    } else {
+      // Property accessors must have exactly the number of expected params.
+      if (SwiftParamCount != NumExpectedParams)
+        return ParamDiag;
+    }
+  }
+  
+  return None;
+}
+
+/// Do a check to make sure \p Name looks like a legal swift_name
+/// attribute for the decl \p D. Raise a diagnostic if the name is invalid
+/// for the given declaration.
+///
+/// For a function, this will validate a compound Swift name,
+/// e.g. <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>,
+/// and the function will output the number of parameter names, and whether this
+/// is a single-arg initializer.
+///
+/// For a type, enum constant, property, or variable declaration, this will
+/// validate either a simple identifier, or a qualified
+/// <code>context.identifier</code> name.
+///
+/// \returns true if the name is a valid swift name for \p D, false otherwise.
+bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name,
+                             SourceLocation ArgLoc,
+                             IdentifierInfo *AttrName) {
+  if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
+    ArrayRef<ParmVarDecl*> Params;
+    unsigned ParamCount;
+
+    if (const auto *Method = dyn_cast<ObjCMethodDecl>(D)) {
+      ParamCount = Method->getSelector().getNumArgs();
+      Params = Method->parameters().slice(0, ParamCount);
+    } else {
+      const auto *Function = cast<FunctionDecl>(D);
+      ParamCount = Function->getNumParams();
+      Params = Function->parameters();
+      
+      if (!Function->hasWrittenPrototype()) {
+        Diag(ArgLoc, diag::warn_attr_swift_name_function_no_prototype)
+          << AttrName;
+        return false;
+      }
+    }
+
+    unsigned SwiftParamCount;
+    bool IsSingleParamInit;
+    if (auto diagID = validateSwiftFunctionName(Name, SwiftParamCount,
+                                                IsSingleParamInit)) {
+      Diag(ArgLoc, *diagID) << AttrName;
+      return false;
+    }
+  
+    bool ParamsOK;
+    if (SwiftParamCount == ParamCount) {
+      ParamsOK = true;
+    } else if (SwiftParamCount > ParamCount) {
+      ParamsOK = IsSingleParamInit && ParamCount == 0;
+    } else {
+      // We have fewer Swift parameters than Objective-C parameters, but that
+      // might be because we've transformed some of them. Check for potential
+      // "out" parameters and err on the side of not warning.
+      unsigned MaybeOutParamCount =
+          std::count_if(Params.begin(), Params.end(),
+                        [](const ParmVarDecl *Param) -> bool {
+        QualType ParamTy = Param->getType();
+        if (ParamTy->isReferenceType() || ParamTy->isPointerType())
+          return !ParamTy->getPointeeType().isConstQualified();
+        return false;
+      });
+      ParamsOK = (SwiftParamCount + MaybeOutParamCount >= ParamCount);
+    }
+
+    if (!ParamsOK) {
+      Diag(ArgLoc, diag::warn_attr_swift_name_num_params)
+          << (SwiftParamCount > ParamCount) << AttrName
+          << ParamCount << SwiftParamCount;
+      return false;
+    }
+
+  } else if (isa<EnumConstantDecl>(D) || isa<ObjCProtocolDecl>(D) ||
+             isa<ObjCInterfaceDecl>(D) || isa<ObjCPropertyDecl>(D) ||
+             isa<VarDecl>(D) || isa<TypedefNameDecl>(D) || isa<TagDecl>(D) ||
+             isa<IndirectFieldDecl>(D) || isa<FieldDecl>(D)) {
+    StringRef ContextName, BaseName;
+    std::tie(ContextName, BaseName) = Name.split('.');
+    if (BaseName.empty()) {
+      BaseName = ContextName;
+      ContextName = StringRef();
+    } else if (!isValidIdentifier(ContextName)) {
+      Diag(ArgLoc, diag::warn_attr_swift_name_context_name_invalid_identifier)
+        << AttrName;
+      return false;
+    }
+
+    if (!isValidIdentifier(BaseName)) {
+      Diag(ArgLoc, diag::warn_attr_swift_name_basename_invalid_identifier)
+        << AttrName;
+      return false;
+    }
+
+  } else {
+    Diag(ArgLoc, diag::warn_attr_swift_name_decl_kind) << AttrName;
+    return false;
+  }
+  return true;
+}
+
+static void handleSwiftName(Sema &S, Decl *D, const AttributeList &Attr) {
+  StringRef Name;
+  SourceLocation ArgLoc;
+  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Name, &ArgLoc))
+    return;
+
+  if (!S.DiagnoseSwiftName(D, Name, ArgLoc, Attr.getName()))
+    return;
+
+  D->addAttr(::new (S.Context) SwiftNameAttr(Attr.getRange(), S.Context, Name,
+                                         Attr.getAttributeSpellingListIndex()));
+}
+
+static bool isErrorParameter(Sema &S, QualType paramType) {
+  if (auto ptr = paramType->getAs<PointerType>()) {
+    auto outerPointee = ptr->getPointeeType();
+
+    // NSError**.
+    if (auto objcPtr = outerPointee->getAs<ObjCObjectPointerType>()) {
+      if (auto iface = objcPtr->getInterfaceDecl())
+        if (iface->getIdentifier() == S.getNSErrorIdent())
+          return true;
+    }
+
+    // CFErrorRef*.
+    if (auto cPtr = outerPointee->getAs<PointerType>()) {
+      auto innerPointee = cPtr->getPointeeType();
+      if (auto recordType = innerPointee->getAs<RecordType>()) {
+        if (S.isCFError(recordType->getDecl()))
+          return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+static void handleSwiftError(Sema &S, Decl *D, const AttributeList &attr) {
+  SwiftErrorAttr::ConventionKind convention;
+  IdentifierLoc *conventionLoc = attr.getArgAsIdent(0);
+  StringRef conventionStr = conventionLoc->Ident->getName();
+  if (!SwiftErrorAttr::ConvertStrToConventionKind(conventionStr, convention)) {
+    S.Diag(attr.getLoc(), diag::warn_attribute_type_not_supported)
+      << attr.getName() << conventionLoc->Ident;
+    return;
+  }
+
+  auto requireErrorParameter = [&]() -> bool {
+    if (D->isInvalidDecl()) return true;
+
+    for (unsigned i = 0, e = getFunctionOrMethodNumParams(D); i != e; ++i) {
+      if (isErrorParameter(S, getFunctionOrMethodParamType(D, i)))
+        return true;
+    }
+
+    S.Diag(attr.getLoc(), diag::err_attr_swift_error_no_error_parameter)
+      << attr.getName() << isa<ObjCMethodDecl>(D);
+    return false;
+  };
+
+  auto requirePointerResult = [&] {
+    if (D->isInvalidDecl()) return true;
+
+    // C, ObjC, and block pointers are definitely okay.
+    // References are definitely not okay.
+    // nullptr_t is weird but acceptable.
+    QualType returnType = getFunctionOrMethodResultType(D);
+    if (returnType->hasPointerRepresentation() &&
+        !returnType->isReferenceType()) return true;
+
+    S.Diag(attr.getLoc(), diag::err_attr_swift_error_return_type)
+      << attr.getName() << conventionStr
+      << isa<ObjCMethodDecl>(D) << /*pointer*/ 1;
+    return false;
+  };
+
+  auto requireIntegerResult = [&] {
+    if (D->isInvalidDecl()) return true;
+
+    QualType returnType = getFunctionOrMethodResultType(D);
+    if (returnType->isIntegralType(S.Context)) return true;
+
+    S.Diag(attr.getLoc(), diag::err_attr_swift_error_return_type)
+      << attr.getName() << conventionStr
+      << isa<ObjCMethodDecl>(D) << /*integral*/ 0;
+    return false;
+  };
+
+  switch (convention) {
+  case SwiftErrorAttr::None:
+    // No additional validation required.
+    break;
+
+  case SwiftErrorAttr::NonNullError:
+    if (!requireErrorParameter()) return;
+    break;
+
+  case SwiftErrorAttr::NullResult:
+    if (!requireErrorParameter()) return;
+    if (!requirePointerResult()) return;
+    break;
+
+  case SwiftErrorAttr::NonZeroResult:
+  case SwiftErrorAttr::ZeroResult:
+    if (!requireErrorParameter()) return;
+    if (!requireIntegerResult()) return;
+    break;
+  }
+
+  D->addAttr(::new (S.Context)
+             SwiftErrorAttr(attr.getRange(), S.Context, convention,
+                            attr.getAttributeSpellingListIndex()));
+}
+
+static void handleSwiftBridgeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  // Make sure that there is a string literal as the annotation's single
+  // argument.
+  StringRef Str;
+  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
+    return;
+
+  // Don't duplicate annotations that are already set.
+  if (D->hasAttr<SwiftBridgeAttr>()) {
+    S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+             SwiftBridgeAttr(Attr.getRange(), S.Context, Str,
+                             Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleSwiftNewtypeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  // Make sure that there is an identifier as the annotation's single
+  // argument.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+      << Attr.getName() << 1;
+    Attr.setInvalid();
+    return;
+  }
+  if (!Attr.isArgIdent(0)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
+      << Attr.getName() << AANT_ArgumentIdentifier;
+    Attr.setInvalid();
+    return;
+  }
+
+  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
+  SwiftNewtypeAttr::NewtypeKind Kind;
+  if (II->isStr("struct"))
+    Kind = SwiftNewtypeAttr::NK_Struct;
+  else if (II->isStr("enum"))
+    Kind = SwiftNewtypeAttr::NK_Enum;
+  else {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
+      << Attr.getName() << II;
+    Attr.setInvalid();
+    return;
+  }
+
+  if (!isa<TypedefNameDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_swift_newtype_attribute_non_typedef);
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+             SwiftNewtypeAttr(Attr.getRange(), S.Context, Kind,
+                              Attr.getAttributeSpellingListIndex()));
+}
+
 //===----------------------------------------------------------------------===//
 // Microsoft specific attribute handlers.
 //===----------------------------------------------------------------------===//
@@ -5834,6 +6333,9 @@
   case AttributeList::AT_ReturnsNonNull:
     handleReturnsNonNullAttr(S, D, Attr);
     break;
+  case AttributeList::AT_NoEscape:
+    handleNoEscapeAttr(S, D, Attr);
+    break;
   case AttributeList::AT_AssumeAligned:
     handleAssumeAlignedAttr(S, D, Attr);
     break;
@@ -5897,6 +6399,9 @@
   case AttributeList::AT_ObjCBoxable:
     handleObjCBoxable(S, D, Attr);
     break;
+  case AttributeList::AT_NSErrorDomain:
+    handleNSErrorDomain(S, D, Attr);
+    break;
   case AttributeList::AT_CFAuditedTransfer:
     handleCFAuditedTransferAttr(S, D, Attr);
     break;
@@ -5953,6 +6458,9 @@
   case AttributeList::AT_ObjCSubclassingRestricted:
     handleSimpleAttribute<ObjCSubclassingRestrictedAttr>(S, D, Attr);
     break;
+  case AttributeList::AT_ObjCCompleteDefinition:
+    handleSimpleAttribute<ObjCCompleteDefinitionAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_ObjCExplicitProtocolImpl:
     handleObjCSuppresProtocolAttr(S, D, Attr);
     break;
@@ -6219,6 +6727,22 @@
   case AttributeList::AT_RenderScriptKernel:
     handleSimpleAttribute<RenderScriptKernelAttr>(S, D, Attr);
     break;
+  // Swift attributes.
+  case AttributeList::AT_SwiftPrivate:
+    handleSimpleAttribute<SwiftPrivateAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftName:
+    handleSwiftName(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftError:
+    handleSwiftError(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftBridge:
+    handleSwiftBridgeAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftNewtype:
+    handleSwiftNewtypeAttr(S, D, Attr);
+    break;
   // XRay attributes.
   case AttributeList::AT_XRayInstrument:
     handleSimpleAttribute<XRayInstrumentAttr>(S, D, Attr);
@@ -6443,6 +6967,9 @@
   // Finally, apply any attributes on the decl itself.
   if (const AttributeList *Attrs = PD.getAttributes())
     ProcessDeclAttributeList(S, D, Attrs);
+
+  // Look for API notes that map to attributes.
+  ProcessAPINotes(D);
 }
 
 /// Is the given declaration allowed to use a forbidden type?
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index f265f4c..b1bec1c 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -8161,6 +8161,7 @@
     Namespc->setInvalidDecl();
   
   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
+  ProcessAPINotes(Namespc);
 
   // FIXME: Should we be merging attributes?
   if (const VisibilityAttr *Attr = Namespc->getAttr<VisibilityAttr>())
@@ -8550,6 +8551,7 @@
 
   if (UDir)
     ProcessDeclAttributeList(S, UDir, AttrList);
+  ProcessAPINotes(UDir);
 
   return UDir;
 }
@@ -9641,6 +9643,7 @@
     NewTD->setInvalidDecl();
 
   ProcessDeclAttributeList(S, NewTD, AttrList);
+  ProcessAPINotes(NewTD);
 
   CheckTypedefForVariablyModifiedType(S, NewTD);
   Invalid |= NewTD->isInvalidDecl();
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index b43e5b9..8885b09 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -980,6 +980,10 @@
   ObjCInterfaceDecl *IDecl
     = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
                                 typeParamList, PrevIDecl, ClassLoc);
+  if (AttrList)
+    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+  ProcessAPINotes(IDecl);
+
   if (PrevIDecl) {
     // Class already seen. Was it a definition?
     if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
@@ -990,8 +994,6 @@
     }
   }
   
-  if (AttrList)
-    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
   PushOnScopeChains(IDecl, TUScope);
 
   // Start the definition of this class. If we're in a redefinition case, there 
@@ -1175,6 +1177,7 @@
   
   if (AttrList)
     ProcessDeclAttributeList(TUScope, PDecl, AttrList);
+  ProcessAPINotes(PDecl);
   
   // Merge attributes from previous declarations.
   if (PrevDecl)
@@ -1699,12 +1702,14 @@
       = ObjCProtocolDecl::Create(Context, CurContext, Ident, 
                                  IdentPair.second, AtProtocolLoc,
                                  PrevDecl);
-        
+    ProcessAPINotes(PDecl);
+
     PushOnScopeChains(PDecl, TUScope);
     CheckObjCDeclScope(PDecl);
     
     if (attrList)
       ProcessDeclAttributeList(TUScope, PDecl, attrList);
+    ProcessAPINotes(PDecl);
     
     if (PrevDecl)
       mergeDeclAttributes(PDecl, PrevDecl);
@@ -3037,7 +3042,8 @@
                                   ClassName, TypeParams, PrevIDecl,
                                   IdentLocs[i]);
     IDecl->setAtEndRange(IdentLocs[i]);
-    
+    ProcessAPINotes(IDecl);
+
     PushOnScopeChains(IDecl, TUScope);
     CheckObjCDeclScope(IDecl);
     DeclsInGroup.push_back(IDecl);
@@ -3837,7 +3843,7 @@
       if (IDecl->getSuperClass() == nullptr) {
         // This class has no superclass, so check that it has been marked with
         // __attribute((objc_root_class)).
-        if (!HasRootClassAttr) {
+        if (!HasRootClassAttr && !IDecl->hasAttr<ObjCCompleteDefinitionAttr>()) {
           SourceLocation DeclLoc(IDecl->getLocation());
           SourceLocation SuperClassLoc(getLocForEndOfToken(DeclLoc));
           Diag(DeclLoc, diag::warn_objc_root_class_missing)
@@ -3932,12 +3938,10 @@
   return (Decl::ObjCDeclQualifier) (unsigned) PQTVal;
 }
 
-/// \brief Check whether the declared result type of the given Objective-C
-/// method declaration is compatible with the method's class.
-///
-static Sema::ResultTypeCompatibilityKind 
-CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method,
-                                    ObjCInterfaceDecl *CurrentClass) {
+Sema::ResultTypeCompatibilityKind
+Sema::checkRelatedResultTypeCompatibility(
+    const ObjCMethodDecl *Method,
+    const ObjCInterfaceDecl *CurrentClass) {
   QualType ResultType = Method->getReturnType();
 
   // If an Objective-C method inherits its related result type, then its 
@@ -4393,6 +4397,7 @@
 
     // Apply the attributes to the parameter.
     ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
+    ProcessAPINotes(Param);
 
     if (Param->hasAttr<BlocksAttr>()) {
       Diag(Param->getLocation(), diag::err_block_on_nonlocal);
@@ -4423,6 +4428,7 @@
 
   if (AttrList)
     ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
+  ProcessAPINotes(ObjCMethod);
 
   // Add the method now.
   const ObjCMethodDecl *PrevMethod = nullptr;
@@ -4478,7 +4484,7 @@
   }
 
   ResultTypeCompatibilityKind RTC
-    = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass);
+    = checkRelatedResultTypeCompatibility(ObjCMethod, CurrentClass);
 
   CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC);
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 0077d6c..267dbe4 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -7531,22 +7531,6 @@
         return IncompatibleVectors;
       }
     }
-
-    // When the RHS comes from another lax conversion (e.g. binops between
-    // scalars and vectors) the result is canonicalized as a vector. When the
-    // LHS is also a vector, the lax is allowed by the condition above. Handle
-    // the case where LHS is a scalar.
-    if (LHSType->isScalarType()) {
-      const VectorType *VecType = RHSType->getAs<VectorType>();
-      if (VecType && VecType->getNumElements() == 1 &&
-          isLaxVectorConversion(RHSType, LHSType)) {
-        ExprResult *VecExpr = &RHS;
-        *VecExpr = ImpCastExprToType(VecExpr->get(), LHSType, CK_BitCast);
-        Kind = CK_BitCast;
-        return Compatible;
-      }
-    }
-
     return Incompatible;
   }
 
@@ -8081,7 +8065,6 @@
 
   // If there's an ext-vector type and a scalar, try to convert the scalar to
   // the vector element type and splat.
-  // FIXME: this should also work for regular vector types as supported in GCC.
   if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
     if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
                                   LHSVecType->getElementType(), LHSType))
@@ -8094,31 +8077,14 @@
       return RHSType;
   }
 
-  // FIXME: The code below also handles convertion between vectors and
-  // non-scalars, we should break this down into fine grained specific checks
-  // and emit proper diagnostics.
-  QualType VecType = LHSVecType ? LHSType : RHSType;
-  const VectorType *VT = LHSVecType ? LHSVecType : RHSVecType;
-  QualType OtherType = LHSVecType ? RHSType : LHSType;
-  ExprResult *OtherExpr = LHSVecType ? &RHS : &LHS;
-  if (isLaxVectorConversion(OtherType, VecType)) {
-    // If we're allowing lax vector conversions, only the total (data) size
-    // needs to be the same. For non compound assignment, if one of the types is
-    // scalar, the result is always the vector type.
-    if (!IsCompAssign) {
-      *OtherExpr = ImpCastExprToType(OtherExpr->get(), VecType, CK_BitCast);
-      return VecType;
-    // In a compound assignment, lhs += rhs, 'lhs' is a lvalue src, forbidding
-    // any implicit cast. Here, the 'rhs' should be implicit casted to 'lhs'
-    // type. Note that this is already done by non-compound assignments in
-    // CheckAssignmentConstraints. If it's a scalar type, only bitcast for
-    // <1 x T> -> T. The result is also a vector type.
-    } else if (OtherType->isExtVectorType() ||
-               (OtherType->isScalarType() && VT->getNumElements() == 1)) {
-      ExprResult *RHSExpr = &RHS;
-      *RHSExpr = ImpCastExprToType(RHSExpr->get(), LHSType, CK_BitCast);
-      return VecType;
-    }
+  // If we're allowing lax vector conversions, only the total (data) size
+  // needs to be the same.
+  // FIXME: Should we really be allowing this?
+  // FIXME: We really just pick the LHS type arbitrarily?
+  if (isLaxVectorConversion(RHSType, LHSType)) {
+    QualType resultType = LHSType;
+    RHS = ImpCastExprToType(RHS.get(), resultType, CK_BitCast);
+    return resultType;
   }
 
   // Okay, the expression is invalid.
@@ -9724,7 +9690,7 @@
   }
   
   // Return a signed type for the vector.
-  return GetSignedVectorType(vType);
+  return GetSignedVectorType(LHSType);
 }
 
 QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
@@ -13577,11 +13543,28 @@
   }
 
   // Warn about implicitly autoreleasing indirect parameters captured by blocks.
-  if (auto *PT = dyn_cast<PointerType>(CaptureType)) {
+  if (const auto *PT = CaptureType->getAs<PointerType>()) {
+    // This function finds out whether there is an AttributedType of kind
+    // attr_objc_ownership in Ty. The existence of AttributedType of kind
+    // attr_objc_ownership implies __autoreleasing was explicitly specified
+    // rather than being added implicitly by the compiler.
+    auto IsObjCOwnershipAttributedType = [](QualType Ty) {
+      while (const auto *AttrTy = Ty->getAs<AttributedType>()) {
+        if (AttrTy->getAttrKind() == AttributedType::attr_objc_ownership)
+          return true;
+
+        // Peel off AttributedTypes that are not of kind objc_ownership.
+        Ty = AttrTy->getModifiedType();
+      }
+
+      return false;
+    };
+
     QualType PointeeTy = PT->getPointeeType();
-    if (isa<ObjCObjectPointerType>(PointeeTy.getCanonicalType()) &&
+
+    if (PointeeTy->getAs<ObjCObjectPointerType>() &&
         PointeeTy.getObjCLifetime() == Qualifiers::OCL_Autoreleasing &&
-        !isa<AttributedType>(PointeeTy)) {
+        !IsObjCOwnershipAttributedType(PointeeTy)) {
       if (BuildAndDiagnose) {
         SourceLocation VarLoc = Var->getLocation();
         S.Diag(Loc, diag::warn_block_capture_autoreleasing);
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 3afa95f..9b5fe9a 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -6402,6 +6402,23 @@
   return false;
 }
 
+/// \brief Check if it's ok to try and recover dot pseudo destructor calls on
+/// pointer objects.
+static bool
+canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef,
+                                                   QualType DestructedType) {
+  // If this is a record type, check if its destructor is callable.
+  if (auto *RD = DestructedType->getAsCXXRecordDecl()) {
+    if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD))
+      return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false);
+    return false;
+  }
+
+  // Otherwise, check if it's a type for which it's valid to use a pseudo-dtor.
+  return DestructedType->isDependentType() || DestructedType->isScalarType() ||
+         DestructedType->isVectorType();
+}
+
 ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
                                            SourceLocation OpLoc,
                                            tok::TokenKind OpKind,
@@ -6436,15 +6453,36 @@
       = DestructedTypeInfo->getTypeLoc().getLocalSourceRange().getBegin();
     if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) {
       if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
-        Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
-          << ObjectType << DestructedType << Base->getSourceRange()
-          << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
+        // Detect dot pseudo destructor calls on pointer objects, e.g.:
+        //   Foo *foo;
+        //   foo.~Foo();
+        if (OpKind == tok::period && ObjectType->isPointerType() &&
+            Context.hasSameUnqualifiedType(DestructedType,
+                                           ObjectType->getPointeeType())) {
+          auto Diagnostic =
+              Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+              << ObjectType << /*IsArrow=*/0 << Base->getSourceRange();
 
-        // Recover by setting the destructed type to the object type.
-        DestructedType = ObjectType;
-        DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
-                                                           DestructedTypeStart);
-        Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
+          // Issue a fixit only when the destructor is valid.
+          if (canRecoverDotPseudoDestructorCallsOnPointerObjects(
+                  *this, DestructedType))
+            Diagnostic << FixItHint::CreateReplacement(OpLoc, "->");
+
+          // Recover by setting the object type to the destructed type and the
+          // operator to '->'.
+          ObjectType = DestructedType;
+          OpKind = tok::arrow;
+        } else {
+          Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
+              << ObjectType << DestructedType << Base->getSourceRange()
+              << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
+
+          // Recover by setting the destructed type to the object type.
+          DestructedType = ObjectType;
+          DestructedTypeInfo =
+              Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart);
+          Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
+        }
       } else if (DestructedType.getObjCLifetime() !=
                                                 ObjectType.getObjCLifetime()) {
 
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index b053c83..aae08a9 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2237,6 +2237,10 @@
     }
 
     unsigned FieldIndex = 0;
+
+    if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+      FieldIndex = CXXRD->getNumBases();
+
     for (auto *FI : RT->getDecl()->fields()) {
       if (FI->isUnnamedBitfield())
         continue;
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 38a7b8c..43147b0 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -3427,6 +3427,12 @@
           SM == ShadowMaps.rbegin())
         continue;
 
+      // A shadow declaration that's created by a resolved using declaration
+      // is not hidden by the same using declaration.
+      if (isa<UsingShadowDecl>(ND) && isa<UsingDecl>(D) &&
+          cast<UsingShadowDecl>(ND)->getUsingDecl() == D)
+        continue;
+
       // We've found a declaration that hides this one.
       return D;
     }
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 3481b82..eea44eb 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -636,8 +636,6 @@
     PDecl->setInvalidDecl();
   }
 
-  ProcessDeclAttributes(S, PDecl, FD.D);
-
   // Regardless of setter/getter attribute, we save the default getter/setter
   // selector names in anticipation of declaration of setter/getter methods.
   PDecl->setGetterName(GetterSel);
@@ -645,6 +643,8 @@
   PDecl->setPropertyAttributesAsWritten(
                           makePropertyAttributesAsWritten(AttributesAsWritten));
 
+  ProcessDeclAttributes(S, PDecl, FD.D);
+
   if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
 
@@ -2250,6 +2250,8 @@
           SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section,
                                       SA->getName(), Loc));
 
+    ProcessAPINotes(GetterMethod);
+
     if (getLangOpts().ObjCAutoRefCount)
       CheckARCMethodDecl(GetterMethod);
   } else
@@ -2315,6 +2317,9 @@
         SetterMethod->addAttr(
             SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section,
                                         SA->getName(), Loc));
+
+    ProcessAPINotes(SetterMethod);
+
       // It's possible for the user to have set a very odd custom
       // setter selector that causes it to have a method family.
       if (getLangOpts().ObjCAutoRefCount)
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index ad1e89a..7dfac4e 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1288,6 +1288,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, NewClass, Attr);
+  ProcessAPINotes(NewClass);
 
   if (PrevClassTemplate)
     mergeDeclAttributes(NewClass, PrevClassTemplate->getTemplatedDecl());
@@ -6763,6 +6764,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
+  ProcessAPINotes(Specialization);
 
   // Add alignment attributes if necessary; these attributes are checked when
   // the ASTContext lays out the structure.
@@ -7796,6 +7798,7 @@
   bool PreviouslyDLLExported = Specialization->hasAttr<DLLExportAttr>();
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
+  ProcessAPINotes(Specialization);
 
   // Add the explicit instantiation into its lexical context. However,
   // since explicit instantiations are never found by name lookup, we
@@ -8215,6 +8218,7 @@
         // Merge attributes.
         if (AttributeList *Attr = D.getDeclSpec().getAttributes().getList())
           ProcessDeclAttributeList(S, Prev, Attr);
+        ProcessAPINotes(Prev);
       }
       if (TSK == TSK_ExplicitInstantiationDefinition)
         InstantiateVariableDefinition(D.getIdentifierLoc(), Prev);
@@ -8374,6 +8378,7 @@
   Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
+  ProcessAPINotes(Specialization);
 
   if (Specialization->isDefined()) {
     // Let the ASTConsumer know that this function has been explicitly
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 29b2142..ffc965e 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1159,20 +1159,6 @@
     ResultTL = ObjCObjectPointerTL.getPointeeLoc();
   }
 
-  if (auto OTPTL = ResultTL.getAs<ObjCTypeParamTypeLoc>()) {
-    // Protocol qualifier information.
-    if (OTPTL.getNumProtocols() > 0) {
-      assert(OTPTL.getNumProtocols() == Protocols.size());
-      OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc);
-      OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc);
-      for (unsigned i = 0, n = Protocols.size(); i != n; ++i)
-        OTPTL.setProtocolLoc(i, ProtocolLocs[i]);
-    }
-
-    // We're done. Return the completed type to the parser.
-    return CreateParsedType(Result, ResultTInfo);
-  }
-
   auto ObjCObjectTL = ResultTL.castAs<ObjCObjectTypeLoc>();
 
   // Type argument information.
@@ -3355,25 +3341,9 @@
     if (auto recordType = type->getAs<RecordType>()) {
       RecordDecl *recordDecl = recordType->getDecl();
 
-      bool isCFError = false;
-      if (S.CFError) {
-        // If we already know about CFError, test it directly.
-        isCFError = (S.CFError == recordDecl);
-      } else {
-        // Check whether this is CFError, which we identify based on its bridge
-        // to NSError.
-        if (recordDecl->getTagKind() == TTK_Struct && numNormalPointers > 0) {
-          if (auto bridgeAttr = recordDecl->getAttr<ObjCBridgeAttr>()) {
-            if (bridgeAttr->getBridgedType() == S.getNSErrorIdent()) {
-              S.CFError = recordDecl;
-              isCFError = true;
-            }
-          }
-        }
-      }
-
       // If this is CFErrorRef*, report it as such.
-      if (isCFError && numNormalPointers == 2 && numTypeSpecifierPointers < 2) {
+      if (numNormalPointers == 2 && numTypeSpecifierPointers < 2 &&
+          S.isCFError(recordDecl)) {
         return PointerDeclaratorKind::CFErrorRefPointer;
       }
       break;
@@ -3397,6 +3367,26 @@
   }
 }
 
+bool Sema::isCFError(RecordDecl *recordDecl) {
+  // If we already know about CFError, test it directly.
+  if (CFError) {
+    return (CFError == recordDecl);
+  }
+
+  // Check whether this is CFError, which we identify based on being
+  // bridged to NSError.
+  if (recordDecl->getTagKind() == TTK_Struct) {
+    if (auto bridgeAttr = recordDecl->getAttr<ObjCBridgeAttr>()) {
+      if (bridgeAttr->getBridgedType() == getNSErrorIdent()) {
+        CFError = recordDecl;
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
 static FileID getNullabilityCompletenessCheckFileID(Sema &S,
                                                     SourceLocation loc) {
   // If we're anywhere in a function, method, or closure context, don't perform
@@ -5979,12 +5969,34 @@
   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 allowOnArrayType) {
-  recordNullabilitySeen(*this, nullabilityLoc);
+                                         bool allowOnArrayType,
+                                         bool implicit,
+                                         bool overrideExisting) {
+  if (!implicit)
+    recordNullabilitySeen(*this, nullabilityLoc);
 
   // Check for existing nullability attributes on the type.
   QualType desugared = type;
@@ -5993,6 +6005,9 @@
     if (auto existingNullability = attributed->getImmediateNullability()) {
       // Duplicated nullability.
       if (nullability == *existingNullability) {
+        if (implicit)
+          break;
+
         Diag(nullabilityLoc, diag::warn_nullability_duplicate)
           << DiagNullabilityKind(nullability, isContextSensitive)
           << FixItHint::CreateRemoval(nullabilityLoc);
@@ -6000,11 +6015,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();
@@ -6015,7 +6035,7 @@
   // have nullability specifiers on them, which means we cannot
   // provide a useful Fix-It.
   if (auto existingNullability = desugared->getNullability(Context)) {
-    if (nullability != *existingNullability) {
+    if (nullability != *existingNullability && !implicit) {
       Diag(nullabilityLoc, diag::err_nullability_conflicting)
         << DiagNullabilityKind(nullability, isContextSensitive)
         << DiagNullabilityKind(*existingNullability, false);
@@ -6040,15 +6060,16 @@
   // If this definitely isn't a pointer type, reject the specifier.
   if (!desugared->canHaveNullability() &&
       !(allowOnArrayType && desugared->isArrayType())) {
-    Diag(nullabilityLoc, diag::err_nullability_nonpointer)
-      << DiagNullabilityKind(nullability, isContextSensitive) << type;
+    if (!implicit) {
+      Diag(nullabilityLoc, diag::err_nullability_nonpointer)
+        << DiagNullabilityKind(nullability, isContextSensitive) << type;
+    }
     return true;
   }
   
   // For the context-sensitive keywords/Objective-C property
   // attributes, require that the type be a single-level pointer.
   if (isContextSensitive) {
-    // Make sure that the pointee isn't itself a pointer type.
     const Type *pointeeType;
     if (desugared->isArrayType())
       pointeeType = desugared->getArrayElementTypeNoTypeQual();
@@ -6077,13 +6098,6 @@
 }
 
 bool Sema::checkObjCKindOfType(QualType &type, SourceLocation loc) {
-  if (isa<ObjCTypeParamType>(type)) {
-    // Build the attributed type to record where __kindof occurred.
-    type = Context.getAttributedType(AttributedType::attr_objc_kindof,
-                                     type, type);
-    return false;
-  }
-
   // Find out if it's an Objective-C object or object pointer type;
   const ObjCObjectPointerType *ptrType = type->getAs<ObjCObjectPointerType>();
   const ObjCObjectType *objType = ptrType ? ptrType->getObjectType() 
@@ -6829,7 +6843,7 @@
               mapNullabilityAttrKind(attr.getKind()),
               attr.getLoc(),
               attr.isContextSensitiveKeywordAttribute(),
-              allowOnArrayType)) {
+              allowOnArrayType, /*implicit=*/false)) {
           attr.setInvalid();
         }
 
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 53224e2..00db74a 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -2513,6 +2513,7 @@
       F.InputFileOffsets =
           (const llvm::support::unaligned_uint64_t *)Blob.data();
       F.InputFilesLoaded.resize(NumInputs);
+      F.NumUserInputFiles = NumUserInputs;
       break;
     }
   }
@@ -3245,8 +3246,11 @@
         for (unsigned I = 0, N = Record.size(); I != N; /**/) {
           unsigned GlobalID = getGlobalSubmoduleID(F, Record[I++]);
           SourceLocation Loc = ReadSourceLocation(F, Record, I);
-          if (GlobalID)
+          if (GlobalID) {
             ImportedModules.push_back(ImportedSubmodule(GlobalID, Loc));
+            if (DeserializationListener)
+              DeserializationListener->ModuleImportRead(GlobalID, Loc);
+          }
         }
       }
       break;
@@ -4617,6 +4621,7 @@
       bool IsExplicit = Record[Idx++];
       bool IsSystem = Record[Idx++];
       bool IsExternC = Record[Idx++];
+      bool IsSwiftInferImportAsMember = Record[Idx++];
       bool InferSubmodules = Record[Idx++];
       bool InferExplicitSubmodules = Record[Idx++];
       bool InferExportWildcard = Record[Idx++];
@@ -4661,6 +4666,7 @@
       CurrentModule->IsFromModuleFile = true;
       CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
       CurrentModule->IsExternC = IsExternC;
+      CurrentModule->IsSwiftInferImportAsMember = IsSwiftInferImportAsMember;
       CurrentModule->InferSubmodules = InferSubmodules;
       CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
       CurrentModule->InferExportWildcard = InferExportWildcard;
@@ -5288,48 +5294,84 @@
 }
 
 void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
-  // FIXME: Make it work properly with modules.
-  SmallVector<DiagnosticsEngine::DiagState *, 32> DiagStates;
+  using DiagState = DiagnosticsEngine::DiagState;
+  SmallVector<DiagState *, 32> DiagStates;
+
   for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
     ModuleFile &F = *(*I);
     unsigned Idx = 0;
-    DiagStates.clear();
-    assert(!Diag.DiagStates.empty());
-    DiagStates.push_back(&Diag.DiagStates.front()); // the command-line one.
-    while (Idx < F.PragmaDiagMappings.size()) {
-      SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
-      unsigned DiagStateID = F.PragmaDiagMappings[Idx++];
-      if (DiagStateID != 0) {
-        Diag.DiagStatePoints.push_back(
-                    DiagnosticsEngine::DiagStatePoint(DiagStates[DiagStateID-1],
-                    FullSourceLoc(Loc, SourceMgr)));
-        continue;
-      }
+    auto &Record = F.PragmaDiagMappings;
+    if (Record.empty())
+      continue;
 
-      assert(DiagStateID == 0);
+    DiagStates.clear();
+
+    auto ReadDiagState =
+        [&](const DiagState &BasedOn, SourceLocation Loc,
+            bool IncludeNonPragmaStates) -> DiagnosticsEngine::DiagState * {
+      unsigned BackrefID = Record[Idx++];
+      if (BackrefID != 0)
+        return DiagStates[BackrefID - 1];
+
       // A new DiagState was created here.
-      Diag.DiagStates.push_back(*Diag.GetCurDiagState());
-      DiagnosticsEngine::DiagState *NewState = &Diag.DiagStates.back();
+      Diag.DiagStates.push_back(BasedOn);
+      DiagState *NewState = &Diag.DiagStates.back();
       DiagStates.push_back(NewState);
-      Diag.DiagStatePoints.push_back(
-          DiagnosticsEngine::DiagStatePoint(NewState,
-                                            FullSourceLoc(Loc, SourceMgr)));
-      while (true) {
-        assert(Idx < F.PragmaDiagMappings.size() &&
-               "Invalid data, didn't find '-1' marking end of diag/map pairs");
-        if (Idx >= F.PragmaDiagMappings.size()) {
-          break; // Something is messed up but at least avoid infinite loop in
-                 // release build.
-        }
-        unsigned DiagID = F.PragmaDiagMappings[Idx++];
-        if (DiagID == (unsigned)-1) {
-          break; // no more diag/map pairs for this location.
-        }
-        diag::Severity Map = (diag::Severity)F.PragmaDiagMappings[Idx++];
+      while (Idx + 1 < Record.size() && Record[Idx] != unsigned(-1)) {
+        unsigned DiagID = Record[Idx++];
+        diag::Severity Map = (diag::Severity)Record[Idx++];
         DiagnosticMapping Mapping = Diag.makeUserMapping(Map, Loc);
-        Diag.GetCurDiagState()->setMapping(DiagID, Mapping);
+        if (Mapping.isPragma() || IncludeNonPragmaStates)
+          NewState->setMapping(DiagID, Mapping);
+      }
+      assert(Idx != Record.size() && Record[Idx] == unsigned(-1) &&
+             "Invalid data, didn't find '-1' marking end of diag/map pairs");
+      ++Idx;
+      return NewState;
+    };
+
+    auto *FirstState = ReadDiagState(
+        F.isModule() ? DiagState() : *Diag.DiagStatesByLoc.CurDiagState,
+        SourceLocation(), F.isModule());
+    SourceLocation CurStateLoc =
+        ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
+    auto *CurState = ReadDiagState(*FirstState, CurStateLoc, false);
+
+    if (!F.isModule()) {
+      Diag.DiagStatesByLoc.CurDiagState = CurState;
+      Diag.DiagStatesByLoc.CurDiagStateLoc = CurStateLoc;
+
+      // Preserve the property that the imaginary root file describes the
+      // current state.
+      auto &T = Diag.DiagStatesByLoc.Files[FileID()].StateTransitions;
+      if (T.empty())
+        T.push_back({CurState, 0});
+      else
+        T[0].State = CurState;
+    }
+
+    while (Idx < Record.size()) {
+      SourceLocation Loc = ReadSourceLocation(F, Record[Idx++]);
+      auto IDAndOffset = SourceMgr.getDecomposedLoc(Loc);
+      assert(IDAndOffset.second == 0 && "not a start location for a FileID");
+      unsigned Transitions = Record[Idx++];
+
+      // Note that we don't need to set up Parent/ParentOffset here, because
+      // we won't be changing the diagnostic state within imported FileIDs
+      // (other than perhaps appending to the main source file, which has no
+      // parent).
+      auto &F = Diag.DiagStatesByLoc.Files[IDAndOffset.first];
+      F.StateTransitions.reserve(F.StateTransitions.size() + Transitions);
+      for (unsigned I = 0; I != Transitions; ++I) {
+        unsigned Offset = Record[Idx++];
+        auto *State =
+            ReadDiagState(*FirstState, Loc.getLocWithOffset(Offset), false);
+        F.StateTransitions.push_back({State, Offset});
       }
     }
+
+    // Don't try to read these mappings again.
+    Record.clear();
   }
 }
 
@@ -8493,6 +8535,21 @@
   }
 }
 
+void ASTReader::visitInputFiles(serialization::ModuleFile &MF,
+                                bool IncludeSystem, bool Complain,
+                    llvm::function_ref<void(const serialization::InputFile &IF,
+                                            bool isSystem)> Visitor) {
+  unsigned NumUserInputs = MF.NumUserInputFiles;
+  unsigned NumInputs = MF.InputFilesLoaded.size();
+  assert(NumUserInputs <= NumInputs);
+  unsigned N = IncludeSystem ? NumInputs : NumUserInputs;
+  for (unsigned I = 0; I < N; ++I) {
+    bool IsSystem = I >= NumUserInputs;
+    InputFile IF = getInputFile(MF, I+1, Complain);
+    Visitor(IF, IsSystem);
+  }
+}
+
 std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
   // If we know the owning module, use it.
   if (Module *M = D->getImportedOwningModule())
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 886523e..3d8ecfa 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2558,6 +2558,7 @@
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExternC
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSwiftInferIAM...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild...
@@ -2652,9 +2653,9 @@
     {
       RecordData::value_type Record[] = {
           SUBMODULE_DEFINITION, ID, ParentID, Mod->IsFramework, Mod->IsExplicit,
-          Mod->IsSystem, Mod->IsExternC, Mod->InferSubmodules,
-          Mod->InferExplicitSubmodules, Mod->InferExportWildcard,
-          Mod->ConfigMacrosExhaustive};
+          Mod->IsSystem, Mod->IsExternC, Mod->IsSwiftInferImportAsMember,
+          Mod->InferSubmodules, Mod->InferExplicitSubmodules,
+          Mod->InferExportWildcard, Mod->ConfigMacrosExhaustive};
       Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name);
     }
 
@@ -2789,38 +2790,43 @@
 
 void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
                                               bool isModule) {
-  // Make sure set diagnostic pragmas don't affect the translation unit that
-  // imports the module.
-  // FIXME: Make diagnostic pragma sections work properly with modules.
-  if (isModule)
-    return;
-
   llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64>
       DiagStateIDMap;
   unsigned CurrID = 0;
-  DiagStateIDMap[&Diag.DiagStates.front()] = ++CurrID; // the command-line one.
   RecordData Record;
-  for (DiagnosticsEngine::DiagStatePointsTy::const_iterator
-         I = Diag.DiagStatePoints.begin(), E = Diag.DiagStatePoints.end();
-         I != E; ++I) {
-    const DiagnosticsEngine::DiagStatePoint &point = *I;
-    if (point.Loc.isInvalid())
-      continue;
 
-    AddSourceLocation(point.Loc, Record);
-    unsigned &DiagStateID = DiagStateIDMap[point.State];
+  auto AddDiagState = [&](const DiagnosticsEngine::DiagState *State,
+                          bool IncludeNonPragmaStates) {
+    unsigned &DiagStateID = DiagStateIDMap[State];
     Record.push_back(DiagStateID);
-    
+  
     if (DiagStateID == 0) {
       DiagStateID = ++CurrID;
-      for (const auto &I : *(point.State)) {
-        if (I.second.isPragma()) {
+      for (const auto &I : *State) {
+        if (I.second.isPragma() || IncludeNonPragmaStates) {
           Record.push_back(I.first);
           Record.push_back((unsigned)I.second.getSeverity());
         }
       }
-      Record.push_back(-1); // mark the end of the diag/map pairs for this
-                            // location.
+      // Add a sentinel to mark the end of the diag IDs.
+      Record.push_back(unsigned(-1));
+    }
+  };
+
+  AddDiagState(Diag.DiagStatesByLoc.FirstDiagState, isModule);
+  AddSourceLocation(Diag.DiagStatesByLoc.CurDiagStateLoc, Record);
+  AddDiagState(Diag.DiagStatesByLoc.CurDiagState, false);
+
+  for (auto &FileIDAndFile : Diag.DiagStatesByLoc.Files) {
+    if (!FileIDAndFile.first.isValid() ||
+        !FileIDAndFile.second.HasLocalTransitions)
+      continue;
+    AddSourceLocation(Diag.SourceMgr->getLocForStartOfFile(FileIDAndFile.first),
+                      Record);
+    Record.push_back(FileIDAndFile.second.StateTransitions.size());
+    for (auto &StatePoint : FileIDAndFile.second.StateTransitions) {
+      Record.push_back(StatePoint.Offset);
+      AddDiagState(StatePoint.State, false);
     }
   }
 
@@ -3283,8 +3289,6 @@
         NeedDecls(!IsModule || !Writer.getLangOpts().CPlusPlus),
         InterestingIdentifierOffsets(InterestingIdentifierOffsets) {}
 
-  bool needDecls() const { return NeedDecls; }
-
   static hash_value_type ComputeHash(const IdentifierInfo* II) {
     return llvm::HashString(II->getName());
   }
@@ -3434,10 +3438,8 @@
       assert(II && "NULL identifier in identifier table");
       // Write out identifiers if either the ID is local or the identifier has
       // changed since it was loaded.
-      if (ID >= FirstIdentID || !Chain || !II->isFromAST()
-          || II->hasChangedSinceDeserialization() ||
-          (Trait.needDecls() &&
-           II->hasFETokenInfoChangedSinceDeserialization()))
+      if (ID >= FirstIdentID || !Chain || !II->isFromAST() ||
+          II->hasChangedSinceDeserialization())
         Generator.insert(II, ID, Trait);
     }
 
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 0891ea8..26fd83f 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -626,7 +626,7 @@
       : public RecursiveASTVisitor<IsObjCTypeParamDependentTypeVisitor> {
   public:
     IsObjCTypeParamDependentTypeVisitor() : Result(false) {}
-    bool VisitObjCTypeParamType(const ObjCTypeParamType *Type) {
+    bool VisitTypedefType(const TypedefType *Type) {
       if (isa<ObjCTypeParamDecl>(Type->getDecl())) {
         Result = true;
         return false;
diff --git a/test/APINotes/Inputs/APINotes/SomeOtherKit.apinotes b/test/APINotes/Inputs/APINotes/SomeOtherKit.apinotes
new file mode 100644
index 0000000..ccdc4e1
--- /dev/null
+++ b/test/APINotes/Inputs/APINotes/SomeOtherKit.apinotes
@@ -0,0 +1,8 @@
+Name: SomeOtherKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "methodB"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
diff --git a/test/APINotes/Inputs/BrokenHeaders/APINotes.apinotes b/test/APINotes/Inputs/BrokenHeaders/APINotes.apinotes
new file mode 100644
index 0000000..d547317
--- /dev/null
+++ b/test/APINotes/Inputs/BrokenHeaders/APINotes.apinotes
@@ -0,0 +1,4 @@
+Name: SomeBrokenLib
+Functions:
+  - Name: do_something_with_pointers
+    Nu llabilityOfRet: O
diff --git a/test/APINotes/Inputs/BrokenHeaders/SomeBrokenLib.h b/test/APINotes/Inputs/BrokenHeaders/SomeBrokenLib.h
new file mode 100644
index 0000000..b09c6f6
--- /dev/null
+++ b/test/APINotes/Inputs/BrokenHeaders/SomeBrokenLib.h
@@ -0,0 +1,6 @@
+#ifndef SOME_BROKEN_LIB_H
+#define SOME_BROKEN_LIB_H
+
+void do_something_with_pointers(int *ptr1, int *ptr2);
+
+#endif // SOME_BROKEN_LIB_H
diff --git a/test/APINotes/Inputs/BrokenHeaders2/APINotes.apinotes b/test/APINotes/Inputs/BrokenHeaders2/APINotes.apinotes
new file mode 100644
index 0000000..33eeaaa
--- /dev/null
+++ b/test/APINotes/Inputs/BrokenHeaders2/APINotes.apinotes
@@ -0,0 +1,7 @@
+Name: SomeBrokenLib
+Functions:
+  - Name: do_something_with_pointers
+    NullabilityOfRet: O
+  - Name: do_something_with_pointers
+    NullabilityOfRet: O
+    
diff --git a/test/APINotes/Inputs/BrokenHeaders2/SomeBrokenLib.h b/test/APINotes/Inputs/BrokenHeaders2/SomeBrokenLib.h
new file mode 100644
index 0000000..b09c6f6
--- /dev/null
+++ b/test/APINotes/Inputs/BrokenHeaders2/SomeBrokenLib.h
@@ -0,0 +1,6 @@
+#ifndef SOME_BROKEN_LIB_H
+#define SOME_BROKEN_LIB_H
+
+void do_something_with_pointers(int *ptr1, int *ptr2);
+
+#endif // SOME_BROKEN_LIB_H
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes
new file mode 100644
index 0000000..817af12
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes
@@ -0,0 +1,74 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "transform:"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
+      - Selector: "transform:integer:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+    Properties:
+      - Name: intValue
+        PropertyKind:    Instance
+        Availability: none
+        AvailabilityMsg: "wouldn't work anyway"
+      - Name: nonnullAInstance
+        PropertyKind:    Instance
+        Nullability:     N
+      - Name: nonnullAClass
+        PropertyKind:    Class
+        Nullability:     N
+      - Name: nonnullABoth
+        Nullability:     N
+  - Name: B
+    Availability: none
+    AvailabilityMsg: "just don't"
+  - Name: C
+    Methods:
+      - Selector: "initWithA:"
+        MethodKind: Instance
+        DesignatedInit: true
+  - Name: OverriddenTypes
+    Methods:
+      - Selector: "methodToMangle:second:"
+        MethodKind: Instance
+        ResultType: 'char *'
+        Parameters:
+          - Position: 0
+            Type: 'SOMEKIT_DOUBLE *'
+          - Position: 1
+            Type: 'float *'
+    Properties:
+      - Name: intPropertyToMangle
+        PropertyKind: Instance
+        Type: 'double *'
+Functions:
+  - Name: global_int_fun
+    ResultType: 'char *'
+    Parameters:
+      - Position: 0
+        Type: 'double *'
+      - Position: 1
+        Type: 'float *'
+Globals:
+  - Name: global_int_ptr
+    Type: 'double *'
+SwiftVersions:
+  - Version: 3.0
+    Classes:
+      - Name: A
+        Methods:
+          - Selector: "transform:integer:"
+            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/APINotes/SomeKit_private.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit_private.apinotes
new file mode 100644
index 0000000..28ede9d
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit_private.apinotes
@@ -0,0 +1,15 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:         
+      - Selector: "privateTransform:input:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+    Properties:
+      - Name: internalProperty
+        Nullability: N
+Protocols:
+  - Name: InternalProtocol
+    Availability: none
+    AvailabilityMsg: "not for you"
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
new file mode 100644
index 0000000..ff88fdb
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
@@ -0,0 +1,98 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "transform:"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
+      - Selector: "transform:integer:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+      - Selector: "implicitGetOnlyInstance"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetOnlyClass"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetSetInstance"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetSetClass"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "setImplicitGetSetInstance:"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "setter gone"
+      - Selector: "setImplicitGetSetClass:"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "setter gone"
+    Properties:
+      - Name: intValue
+        PropertyKind:    Instance
+        Availability: none
+        AvailabilityMsg: "wouldn't work anyway"
+      - Name: nonnullAInstance
+        PropertyKind:    Instance
+        Nullability:     N
+      - Name: nonnullAClass
+        PropertyKind:    Class
+        Nullability:     N
+      - Name: nonnullABoth
+        Nullability:     N
+  - Name: B
+    Availability: none
+    AvailabilityMsg: "just don't"
+  - Name: C
+    Methods:
+      - Selector: "initWithA:"
+        MethodKind: Instance
+        DesignatedInit: true
+  - Name: OverriddenTypes
+    Methods:
+      - Selector: "methodToMangle:second:"
+        MethodKind: Instance
+        ResultType: 'char *'
+        Parameters:
+          - Position: 0
+            Type: 'SOMEKIT_DOUBLE *'
+          - Position: 1
+            Type: 'float *'
+    Properties:
+      - Name: intPropertyToMangle
+        PropertyKind: Instance
+        Type: 'double *'
+Functions:
+  - Name: global_int_fun
+    ResultType: 'char *'
+    Parameters:
+      - Position: 0
+        Type: 'double *'
+      - Position: 1
+        Type: 'float *'
+Globals:
+  - Name: global_int_ptr
+    Type: 'double (*)(int, int)'
+SwiftVersions:
+  - Version: 3.0
+    Classes:
+      - Name: A
+        Methods:
+          - Selector: "transform:integer:"
+            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
new file mode 100644
index 0000000..1a192f5
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
@@ -0,0 +1,60 @@
+#ifndef SOMEKIT_H
+#define SOMEKIT_H
+
+__attribute__((objc_root_class))
+@interface A
+-(A*)transform:(A*)input;
+-(A*)transform:(A*)input integer:(int)integer;
+
+@property (nonatomic, readonly, retain) A* someA;
+@property (nonatomic, retain) A* someOtherA;
+
+@property (nonatomic) int intValue;
+@end
+
+@interface B : A
+@end
+
+@interface C : A
+- (instancetype)init;
+- (instancetype)initWithA:(A*)a;
+@end
+
+@interface ProcessInfo : A
++(instancetype)processInfo;
+@end
+
+@interface A(NonNullProperties)
+@property (nonatomic, readwrite, retain) A *nonnullAInstance;
+@property (class, nonatomic, readwrite, retain) A *nonnullAInstance;
+
+@property (nonatomic, readwrite, retain) A *nonnullAClass;
+@property (class, nonatomic, readwrite, retain) A *nonnullAClass;
+
+@property (nonatomic, readwrite, retain) A *nonnullABoth;
+@property (class, nonatomic, readwrite, retain) A *nonnullABoth;
+@end
+
+#import <SomeKit/SomeKitExplicitNullability.h>
+
+extern int *global_int_ptr;
+
+int *global_int_fun(int *ptr, int *ptr2);
+
+#define SOMEKIT_DOUBLE double
+
+__attribute__((objc_root_class))
+@interface OverriddenTypes
+-(int *)methodToMangle:(int *)ptr1 second:(int *)ptr2;
+@property int *intPropertyToMangle;
+@end
+
+@interface A(ImplicitGetterSetters)
+@property (nonatomic, readonly, retain) A *implicitGetOnlyInstance;
+@property (class, nonatomic, readonly, retain) A *implicitGetOnlyClass;
+
+@property (nonatomic, readwrite, retain) A *implicitGetSetInstance;
+@property (class, nonatomic, readwrite, retain) A *implicitGetSetClass;
+@end
+
+#endif
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h
new file mode 100644
index 0000000..40be241
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h
@@ -0,0 +1,5 @@
+@interface A(ExplicitNullabilityProperties)
+@property (nonatomic, readwrite, retain, nonnull) A *explicitNonnullInstance;
+@property (nonatomic, readwrite, retain, nullable) A *explicitNullableInstance;
+@end
+
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitForNullAnnotation.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitForNullAnnotation.h
new file mode 100644
index 0000000..d1eeb61
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitForNullAnnotation.h
@@ -0,0 +1,55 @@
+#ifndef SOMEKIT_H
+#define SOMEKIT_H
+
+#define ROOT_CLASS __attribute__((objc_root_class))
+
+ROOT_CLASS
+@interface A
+-(A*)transform:(A*)input;
+-(A*)transform:(A*)input integer:(int)integer;
+
+@property (nonatomic, readonly, retain) A* someA;
+@property (nonatomic, retain) A* someOtherA;
+
+@property (nonatomic) int intValue;
+@end
+
+@interface B : A
+@end
+
+@interface C : A
+- (instancetype)init;
+- (instancetype)initWithA:(A*)a;
+@end
+
+
+@interface MyClass : A
+- Inst;
++ Clas;
+@end
+
+struct CGRect {
+  float origin;
+  float size;
+};
+typedef struct CGRect NSRect;
+
+@interface I
+- (void) Meth : (NSRect[4])exposedRects;
+- (void) Meth1 : (const  I*)exposedRects;
+- (void) Meth2 : (const I*)exposedRects;
+- (void) Meth3 : (I*)exposedRects;
+- (const I*) Meth4;
+- (const I*) Meth5 : (int) Arg1 : (const I*)Arg2 : (double)Arg3 :   (const I*) Arg4 :(const  volatile id) Arg5;
+- (volatile const I*) Meth6 : (const char *)Arg1 : (const char *)Arg2 : (double)Arg3 :   (const I*) Arg4 :(const  volatile id) Arg5;
+@end
+
+@class NSURL,  NSArray, NSError;
+@interface INTF_BLOCKS
+  + (void)getNonLocalVersionsOfItemAtURL:(NSURL *)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+  + (void *)getNonLocalVersionsOfItemAtURL2:(NSURL *)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+  + (NSError **)getNonLocalVersionsOfItemAtURL3:(int)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+  + (id)getNonLocalVersionsOfItemAtURL4:(NSURL *)url completionHandler:(void (^)(int nonLocalFileVersions, NSError *error, NSURL*))completionHandler;
+@end
+
+#endif
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.modulemap b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..3abee2d
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module SomeKit {
+  umbrella header "SomeKit.h"
+  export *
+  module * { export * }
+}
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.private.modulemap b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..bbda9d0
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.private.modulemap
@@ -0,0 +1,8 @@
+module SomeKit.Private {
+  header "SomeKit_Private.h"
+  export *
+
+  explicit module NullAnnotation {
+    header "SomeKit_PrivateForNullAnnotation.h"
+  }
+}
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module_private.modulemap b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module_private.modulemap
new file mode 100644
index 0000000..e310343
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module_private.modulemap
@@ -0,0 +1,8 @@
+explicit framework module SomeKit.Private {
+  header "SomeKit_Private.h"
+  explicit NullAnnotation { header "SomeKit_PrivateForNullAnnotation.h" }
+  export *
+  module * { export * }
+syntax error
+
+}
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_Private.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_Private.h
new file mode 100644
index 0000000..c761112
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_Private.h
@@ -0,0 +1,16 @@
+#ifndef SOMEKIT_PRIVATE_H
+#define SOMEKIT_PRIVATE_H
+
+#import <SomeKit/SomeKit.h>
+
+@interface A(Private)
+-(A*)privateTransform:(A*)input;
+
+@property (nonatomic) A* internalProperty;
+@end
+
+@protocol InternalProtocol
+@end
+
+#endif
+
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_PrivateForNullAnnotation.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_PrivateForNullAnnotation.h
new file mode 100644
index 0000000..bae4456
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_PrivateForNullAnnotation.h
@@ -0,0 +1,17 @@
+#ifndef SOMEKIT_PRIVATE_H
+#define SOMEKIT_PRIVATE_H
+
+#import <SomeKit/SomeKitForNullAnnotation.h>
+
+@interface A(Private)
+-(A*)privateTransform:(A*)input;
+
+@property (nonatomic) A* internalProperty;
+@end
+
+@protocol InternalProtocol
+- (id) MomeMethod;
+@end
+
+#endif
+
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_private.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_private.apinotes
new file mode 100644
index 0000000..28ede9d
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_private.apinotes
@@ -0,0 +1,15 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:         
+      - Selector: "privateTransform:input:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+    Properties:
+      - Name: internalProperty
+        Nullability: N
+Protocols:
+  - Name: InternalProtocol
+    Availability: none
+    AvailabilityMsg: "not for you"
diff --git a/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/APINotes/SomeOtherKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/APINotes/SomeOtherKit.apinotes
new file mode 100644
index 0000000..2ad546b
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/APINotes/SomeOtherKit.apinotes
@@ -0,0 +1,8 @@
+Name: SomeOtherKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "methodA"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
diff --git a/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes
new file mode 100644
index 0000000..2ad546b
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes
@@ -0,0 +1,8 @@
+Name: SomeOtherKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "methodA"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
diff --git a/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h
new file mode 100644
index 0000000..3911d76
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h
@@ -0,0 +1,9 @@
+#ifndef SOME_OTHER_KIT_H
+
+__attribute__((objc_root_class))
+@interface A
+-(void)methodA;
+-(void)methodB;
+@end
+
+#endif
diff --git a/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Modules/module.modulemap b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..0aaad92
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module SomeOtherKit {
+  umbrella header "SomeOtherKit.h"
+  export *
+  module * { export * }
+}
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..c3b70b6
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes
@@ -0,0 +1,53 @@
+Name: VersionedKit
+Classes:
+  - Name: TestProperties
+    Properties:
+      - Name: accessorsOnly
+        PropertyKind:    Instance
+        SwiftImportAsAccessors: true
+      - Name: accessorsOnlyForClass
+        PropertyKind:    Class
+        SwiftImportAsAccessors: true
+      - Name: accessorsOnlyExceptInVersion3
+        PropertyKind:    Instance
+        SwiftImportAsAccessors: true
+      - Name: accessorsOnlyForClassExceptInVersion3
+        PropertyKind:    Class
+        SwiftImportAsAccessors: true
+SwiftVersions:
+  - Version: 3.0
+    Classes:
+      - Name: MyReferenceType
+        SwiftBridge: ''
+      - Name: TestProperties
+        Properties:
+          - Name: accessorsOnlyInVersion3
+            PropertyKind:    Instance
+            SwiftImportAsAccessors: true
+          - Name: accessorsOnlyForClassInVersion3
+            PropertyKind:    Class
+            SwiftImportAsAccessors: true
+          - Name: accessorsOnlyExceptInVersion3
+            PropertyKind:    Instance
+            SwiftImportAsAccessors: false
+          - Name: accessorsOnlyForClassExceptInVersion3
+            PropertyKind:    Class
+            SwiftImportAsAccessors: false
+    Functions:
+      - Name: moveToPoint
+        SwiftName: 'moveTo(a:b:)'
+      - Name: acceptClosure
+        Parameters:      
+          - Position:        0
+            NoEscape:        false
+      - Name: privateFunc
+        SwiftPrivate: false
+    Tags:
+      - Name: MyErrorCode
+        NSErrorDomain: ''
+    Typedefs:
+      - Name: MyDoubleWrapper
+        SwiftWrapper: none
+
+
+  
\ 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..ffbc7df
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h
@@ -0,0 +1,30 @@
+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
+
+void privateFunc(void) __attribute__((swift_private));
+
+typedef double MyDoubleWrapper __attribute__((swift_wrapper(struct)));
+
+@interface TestProperties
+@property (nonatomic, readwrite, retain) id accessorsOnly;
+@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClass;
+
+@property (nonatomic, readwrite, retain) id accessorsOnlyInVersion3;
+@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClassInVersion3;
+
+@property (nonatomic, readwrite, retain) id accessorsOnlyExceptInVersion3;
+@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClassExceptInVersion3;
+@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/Headers/APINotes.apinotes b/test/APINotes/Inputs/Headers/APINotes.apinotes
new file mode 100644
index 0000000..08210fc
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/APINotes.apinotes
@@ -0,0 +1,18 @@
+Name: HeaderLib
+SwiftInferImportAsMember: true
+Functions:
+  - Name: custom_realloc
+    NullabilityOfRet: N
+    Nullability: [ N, S ]
+  - Name: unavailable_function
+    Availability: none
+    AvailabilityMsg: "I beg you not to use this"
+  - Name: do_something_with_pointers
+    NullabilityOfRet: O
+    Nullability: [ N, O ]
+    
+Globals:
+  - Name: global_int
+    Nullability: N
+  - Name: unavailable_global_int
+    Availability: none
diff --git a/test/APINotes/Inputs/Headers/BrokenTypes.apinotes b/test/APINotes/Inputs/Headers/BrokenTypes.apinotes
new file mode 100644
index 0000000..00f7b50
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/BrokenTypes.apinotes
@@ -0,0 +1,10 @@
+Name: BrokenTypes
+Functions:
+  - Name: break_me_function
+    ResultType: 'int * with extra junk'
+    Parameters:
+      - Position: 0
+        Type: 'not_a_type'
+Globals:
+  - Name: break_me_variable
+    Type: 'double'
diff --git a/test/APINotes/Inputs/Headers/BrokenTypes.h b/test/APINotes/Inputs/Headers/BrokenTypes.h
new file mode 100644
index 0000000..fee054b
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/BrokenTypes.h
@@ -0,0 +1,8 @@
+#ifndef BROKEN_TYPES_H
+#define BROKEN_TYPES_H
+
+char break_me_function(void *ptr);
+
+extern char break_me_variable;
+
+#endif // BROKEN_TYPES_H
diff --git a/test/APINotes/Inputs/Headers/HeaderLib.apinotes b/test/APINotes/Inputs/Headers/HeaderLib.apinotes
new file mode 100644
index 0000000..c822964
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/HeaderLib.apinotes
@@ -0,0 +1,37 @@
+Name: HeaderLib
+SwiftInferImportAsMember: true
+Functions:
+  - Name: custom_realloc
+    NullabilityOfRet: N
+    Nullability: [ N, S ]
+  - Name: unavailable_function
+    Availability: none
+    AvailabilityMsg: "I beg you not to use this"
+  - Name: do_something_with_pointers
+    NullabilityOfRet: O
+    Nullability: [ N, O ]
+  - Name: do_something_with_arrays
+    Parameters:
+      - Position: 0
+        Nullability: N
+      - Position: 1
+        Nullability: N
+  - Name: take_pointer_and_int
+    Parameters:
+      - Position: 0
+        Nullability: N
+        NoEscape: true
+      - Position: 1
+        NoEscape: true
+Globals:
+  - Name: global_int
+    Nullability: N
+  - Name: unavailable_global_int
+    Availability: none
+Tags:
+  - Name: unavailable_struct
+    Availability: none
+
+Typedefs:
+  - Name: unavailable_typedef
+    Availability: none
\ No newline at end of file
diff --git a/test/APINotes/Inputs/Headers/HeaderLib.h b/test/APINotes/Inputs/Headers/HeaderLib.h
new file mode 100644
index 0000000..8065249
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/HeaderLib.h
@@ -0,0 +1,19 @@
+#ifndef HEADER_LIB_H
+#define HEADER_LIB_H
+
+void *custom_realloc(void *member, unsigned size);
+
+int *global_int;
+
+int unavailable_function(void);
+int unavailable_global_int;
+
+void do_something_with_pointers(int *ptr1, int *ptr2);
+void do_something_with_arrays(int simple[], int nested[][2]);
+
+typedef int unavailable_typedef;
+struct unavailable_struct { int x, y, z; };
+
+void take_pointer_and_int(int *ptr1, int value);
+
+#endif
diff --git a/test/APINotes/Inputs/Headers/module.modulemap b/test/APINotes/Inputs/Headers/module.modulemap
new file mode 100644
index 0000000..54af0f5
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/module.modulemap
@@ -0,0 +1,7 @@
+module HeaderLib {
+  header "HeaderLib.h"
+}
+
+module BrokenTypes {
+  header "BrokenTypes.h"
+}
diff --git a/test/APINotes/Inputs/os-availability.apinotes b/test/APINotes/Inputs/os-availability.apinotes
new file mode 100644
index 0000000..d59e79c
--- /dev/null
+++ b/test/APINotes/Inputs/os-availability.apinotes
@@ -0,0 +1,53 @@
+Name:            Foundation
+Classes:
+  - Name:            NSCountedSet
+    Availability:    iOS
+    Methods:
+      - Selector:        'initWithCapacity:'
+        MethodKind:      Instance
+        DesignatedInit:  true
+  - Name:            NSArray
+    Methods:
+      - Selector:        'init'
+        MethodKind:      Instance
+        DesignatedInit:  true
+      - Selector:        'initWithObjects:'
+        MethodKind:      Instance
+        DesignatedInit:  true
+        Availability:    iOS
+      - Selector:        'initWithObjects:count:'
+        MethodKind:      Instance
+        DesignatedInit:  true
+        Availability:    iOS
+    Properties:
+      - Name:            'familyNameios'
+        Nullability:     N
+        Availability:    iOS
+      - Name:            'fontName'
+        Nullability:     N
+Protocols:        
+  - Name:            UIApplicationDelegate
+    AuditedForNullability: true
+    Methods:
+      - Selector:        'application:willFinishLaunchingWithOptions:'
+        MethodKind:      Instance
+        Nullability:     [ N, U ]
+  - Name:            UIApplicationDelegateIOS
+    Availability:    iOS
+    AuditedForNullability: true
+    Methods:
+      - Selector:        'application:willFinishLaunchingWithOptions:'
+        MethodKind:      Instance
+        Nullability:     [ N, U ]
+Functions:       
+  - Name:            NSAvailableWindowDepthsiOS
+    NullabilityOfRet: N
+    Availability:    iOS
+  - Name:            NSAvailableWindowDepths
+    NullabilityOfRet: N
+Globals:         
+  - Name:            NSCalibratedWhiteColorSpace
+    Nullability:     N
+    Availability:    OSX
+    AvailabilityMsg: ''
+
diff --git a/test/APINotes/Inputs/roundtrip.apinotes b/test/APINotes/Inputs/roundtrip.apinotes
new file mode 100644
index 0000000..05599a7
--- /dev/null
+++ b/test/APINotes/Inputs/roundtrip.apinotes
@@ -0,0 +1,181 @@
+---
+Name:            AppKit
+Availability:    available
+AvailabilityMsg: ''
+SwiftInferImportAsMember: true
+Classes:         
+  - Name:            NSCell
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       ''
+    Methods:         
+      - Selector:        'cellWithImage:'
+        MethodKind:      Class
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        FactoryAsInit:   C
+        ResultType:      id
+      - Selector:        init
+        MethodKind:      Instance
+        NullabilityOfRet: U
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    true
+        SwiftName:       ''
+        DesignatedInit:  true
+      - Selector:        'initImageCell:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: U
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        DesignatedInit:  true
+      - Selector:        'initTextCell:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: U
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        DesignatedInit:  true
+      - Selector:        'initWithCoder:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: U
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        DesignatedInit:  true
+        Required:        true
+  - Name:            NSView
+    AuditedForNullability: true
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       ''
+    SwiftBridge:     View
+    Methods:         
+      - Selector:        'addSubview:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: N
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+      - Selector:        'addSubview:positioned:relativeTo:'
+        MethodKind:      Instance
+        Parameters:      
+          - Position:        0
+            NoEscape:        false
+          - Position:        1
+          - Position:        2
+            NoEscape:        true
+            Type:            id
+        Nullability:     [ N, N, O ]
+        NullabilityOfRet: N
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftName:       ''
+      - Selector:        'beginDraggingSessionWithItems:event:source:'
+        MethodKind:      Instance
+        Nullability:     [ U, U, N ]
+        NullabilityOfRet: N
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       'beginDragginSession(_:event:source:)'
+    Properties:      
+      - Name:            enclosingScrollView
+        PropertyKind:    Instance
+        Nullability:     O
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftName:       enclosing
+        Type:            id
+      - Name:            makeBackingLayer
+        PropertyKind:    Class
+        Nullability:     N
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        SwiftImportAsAccessors: false
+Functions:       
+  - Name:            NSAvailableWindowDepths
+    NullabilityOfRet: N
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftName:       'availableWindowDepths()'
+    ResultType:      NSInteger
+Globals:         
+  - Name:            NSCalibratedWhiteColorSpace
+    Nullability:     N
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       calibratedWhite
+    Type:            id
+Enumerators:     
+  - Name:            NSColorRed
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       Red
+Tags:            
+  - Name:            NSSomeEnum
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       SomeEnum
+    NSErrorDomain:   some_error_domain
+  - Name:            NSSomeStruct
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       SomeStruct
+    NSErrorDomain:   ''
+Typedefs:        
+  - Name:            NSTypedef
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       Typedef
+    SwiftBridge:     ''
+    SwiftWrapper:    struct
+SwiftVersions:   
+  - Version:         3.0
+    Classes:         
+      - Name:            NSCell
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       NSBox
+        SwiftBridge:     ''
+        Methods:         
+          - Selector:        init
+            MethodKind:      Instance
+            NullabilityOfRet: N
+            Availability:    available
+            AvailabilityMsg: ''
+            SwiftPrivate:    true
+            SwiftName:       ''
+            DesignatedInit:  true
+      - Name:            NSView
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftName:       ''
+        Properties:      
+          - Name:            makeBackingLayer
+            PropertyKind:    Class
+            Availability:    available
+            AvailabilityMsg: ''
+            SwiftName:       ''
+            SwiftImportAsAccessors: true
diff --git a/test/APINotes/availability.m b/test/APINotes/availability.m
new file mode 100644
index 0000000..f9bee1a
--- /dev/null
+++ b/test/APINotes/availability.m
@@ -0,0 +1,48 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+#include "HeaderLib.h"
+#import <SomeKit/SomeKit.h>
+#import <SomeKit/SomeKit_Private.h>
+
+int main() {
+  int i;
+  i = unavailable_function(); // expected-error{{'unavailable_function' is unavailable: I beg you not to use this}}
+  // expected-note@HeaderLib.h:8{{'unavailable_function' has been explicitly marked unavailable here}}
+  i = unavailable_global_int; // expected-error{{'unavailable_global_int' is unavailable}}
+  // expected-note@HeaderLib.h:9{{'unavailable_global_int' has been explicitly marked unavailable here}}
+
+  unavailable_typedef t; // expected-error{{'unavailable_typedef' is unavailable}}
+  // expected-note@HeaderLib.h:14{{'unavailable_typedef' has been explicitly marked unavailable here}}
+
+  struct unavailable_struct s; // expected-error{{'unavailable_struct' is unavailable}}
+  // expected-note@HeaderLib.h:15{{'unavailable_struct' has been explicitly marked unavailable here}}
+
+  B *b = 0; // expected-error{{'B' is unavailable: just don't}}
+  // expected-note@SomeKit/SomeKit.h:15{{'B' has been explicitly marked unavailable here}}
+
+  id<InternalProtocol> proto = 0; // expected-error{{'InternalProtocol' is unavailable: not for you}}
+  // expected-note@SomeKit/SomeKit_Private.h:12{{'InternalProtocol' has been explicitly marked unavailable here}}
+
+  A *a = 0;
+  i = a.intValue; // expected-error{{intValue' is unavailable: wouldn't work anyway}}
+  // expected-note@SomeKit/SomeKit.h:12{{'intValue' has been explicitly marked unavailable here}}
+
+  [a transform:a]; // expected-error{{'transform:' is unavailable: anything but this}}
+  // expected-note@SomeKit/SomeKit.h:6{{'transform:' has been explicitly marked unavailable here}}
+
+  [a implicitGetOnlyInstance]; // expected-error{{'implicitGetOnlyInstance' is unavailable: getter gone}}
+  // expected-note@SomeKit/SomeKit.h:53{{'implicitGetOnlyInstance' has been explicitly marked unavailable here}}
+  [A implicitGetOnlyClass]; // expected-error{{'implicitGetOnlyClass' is unavailable: getter gone}}
+  // expected-note@SomeKit/SomeKit.h:54{{'implicitGetOnlyClass' has been explicitly marked unavailable here}}
+  [a implicitGetSetInstance]; // expected-error{{'implicitGetSetInstance' is unavailable: getter gone}}
+  // expected-note@SomeKit/SomeKit.h:56{{'implicitGetSetInstance' has been explicitly marked unavailable here}}
+  [a setImplicitGetSetInstance: a];  // expected-error{{'setImplicitGetSetInstance:' is unavailable: setter gone}}
+  // expected-note@SomeKit/SomeKit.h:56{{'setImplicitGetSetInstance:' has been explicitly marked unavailable here}}
+  [A implicitGetSetClass]; // expected-error{{'implicitGetSetClass' is unavailable: getter gone}}
+  // expected-note@SomeKit/SomeKit.h:57{{'implicitGetSetClass' has been explicitly marked unavailable here}}
+  [A setImplicitGetSetClass: a];  // expected-error{{'setImplicitGetSetClass:' is unavailable: setter gone}}
+  // expected-note@SomeKit/SomeKit.h:57{{'setImplicitGetSetClass:' has been explicitly marked unavailable here}}
+  return 0;
+}
+
diff --git a/test/APINotes/broken_types.m b/test/APINotes/broken_types.m
new file mode 100644
index 0000000..164ae79
--- /dev/null
+++ b/test/APINotes/broken_types.m
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s 2> %t.err
+// RUN: FileCheck %s < %t.err
+
+#include "BrokenTypes.h"
+
+// CHECK: <API Notes>:1:1: error: unknown type name 'not_a_type'
+// CHECK-NEXT: not_a_type
+// CHECK-NEXT: ^
+
+// CHECK: <API Notes>:1:7: error: unparsed tokens following type
+// CHECK-NEXT: int * with extra junk
+// CHECK-NEXT:       ^
+
+// CHECK: BrokenTypes.h:4:6: error: API notes replacement type 'int *' has a different size from original type 'char'
+
+// CHECK: BrokenTypes.h:6:13: error: API notes replacement type 'double' has a different size from original type 'char'
+
+// CHECK: 5 errors generated.
diff --git a/test/APINotes/cache.m b/test/APINotes/cache.m
new file mode 100644
index 0000000..b87bdf1
--- /dev/null
+++ b/test/APINotes/cache.m
@@ -0,0 +1,32 @@
+// RUN: rm -rf %t/APINotesCache
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+// Check for the presence of the cached compiled form.
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+
+// Run test again to ensure that caching doesn't cause problems.
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks  %s -verify
+
+// Check that the driver provides a default -fapinotes-cache-path=
+// RUN: %clang -fsyntax-only -fapinotes -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -### 2>&1 | FileCheck --check-prefix=CHECK-DEFAULT-PATH %s
+// CHECK-DEFAULT-PATH: -fapinotes-cache-path={{.*}}org.llvm.clang/APINotesCache
+
+// Check that the driver passes through a provided -fapinotes-cache-path=
+// RUN: %clang -fsyntax-only -fapinotes -fapinotes-modules -fapinotes-cache-path=/wobble -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -### 2>&1 | FileCheck --check-prefix=CHECK-PATH %s
+// CHECK-PATH: -fapinotes-cache-path=/wobble
+
+#include "HeaderLib.h"
+#import <SomeKit/SomeKit.h>
+
+int main() {
+  int i;
+  i = unavailable_function(); // expected-error{{'unavailable_function' is unavailable: I beg you not to use this}}
+  // expected-note@HeaderLib.h:8{{'unavailable_function' has been explicitly marked unavailable here}}
+
+  A *a = 0;
+  [a transform:a]; // expected-error{{'transform:' is unavailable: anything but this}}
+  // expected-note@SomeKit/SomeKit.h:6{{'transform:' has been explicitly marked unavailable here}}
+
+  return 0;
+}
diff --git a/test/APINotes/cache_pruning.m b/test/APINotes/cache_pruning.m
new file mode 100644
index 0000000..1a36570
--- /dev/null
+++ b/test/APINotes/cache_pruning.m
@@ -0,0 +1,49 @@
+// We need 'touch' and 'find' for this test to work.
+// REQUIRES: shell
+
+// RUN: rm -rf %t/APINotesCache
+
+// Run Clang. This should generated the cached versions of both and a timestamp.
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DINCLUDE_HEADERLIB
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+// Set the timestamp back a very long time. We should try to prune,
+// but nothing gets pruned because the API Notes files are new enough.
+// RUN: touch -m -a -t 201101010000 %t/APINotes.timestamp 
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+// Set the HeaderLib access time back a very long time.
+// This shouldn't prune anything, because the timestamp has been updated, so
+// the pruning mechanism won't fire.
+// RUN: find %t/APINotesCache -name APINotes-*.apinotesc | xargs touch -a -t 201101010000
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+// Set the timestack back a very long time. This should prune the
+// HeaderLib file, because the pruning mechanism should fire and
+// HeaderLib is both old and not used.
+// RUN: touch -m -a -t 201101010000 %t/APINotesCache/APINotes.timestamp 
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: ls %t/APINotesCache | not grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+// Run Clang. This should generated the cached versions of both and a timestamp.
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DINCLUDE_HEADERLIB
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+#ifdef INCLUDE_HEADERLIB
+#include "HeaderLib.h"
+#endif
+#include <SomeKit/SomeKit.h>
+
+int main() { return 0; }
diff --git a/test/APINotes/module-cache.m b/test/APINotes/module-cache.m
new file mode 100644
index 0000000..2324697
--- /dev/null
+++ b/test/APINotes/module-cache.m
@@ -0,0 +1,90 @@
+// RUN: rm -rf %t
+
+// Set up a directory with API notes
+// RUN: mkdir -p %t/APINotes
+// RUN: cp %S/Inputs/APINotes/SomeOtherKit.apinotes %t/APINotes/SomeOtherKit.apinotes
+
+// First build: check that 'methodB' is unavailable but 'methodA' is available.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/before.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/before.log
+// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/before.log
+// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/before.log
+
+// Do it again; now we're using caches.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/before.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/before.log
+// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/before.log
+// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/before.log
+
+// Change the API notes file.
+// RUN: echo '      - Selector: "methodA"' >> %t/APINotes/SomeOtherKit.apinotes
+// RUN: echo '        MethodKind: Instance' >> %t/APINotes/SomeOtherKit.apinotes
+// RUN: echo '        Availability: none' >> %t/APINotes/SomeOtherKit.apinotes
+// RUN: echo '        AvailabilityMsg: "not here either"' >> %t/APINotes/SomeOtherKit.apinotes
+
+// Build again: check that both methods are now unavailable and that the module rebuilt.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/after.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/after.log
+
+// Run the build again: check that both methods are now unavailable
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/after.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/after.log
+
+// Set up a directory with pre-compiled API notes.
+// RUN: mkdir -p %t/CompiledAPINotes
+// RUN: rm -rf %t/ModulesCache
+// RUN: rm -rf %t/APINotesCache
+// RUN: %clang -cc1apinotes -yaml-to-binary -o %t/CompiledAPINotes/SomeOtherKit.apinotesc %S/Inputs/APINotes/SomeOtherKit.apinotes
+
+// First build: check that 'methodB' is unavailable but 'methodA' is available.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/CompiledAPINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/compiled-before.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/compiled-before.log
+// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/compiled-before.log
+// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/compiled-before.log
+
+// Do it again; now we're using caches.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/CompiledAPINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/compiled-before.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/compiled-before.log
+// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/compiled-before.log
+// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/compiled-before.log
+
+// Compile a new API notes file to replace the old one.
+// RUN: %clang -cc1apinotes -yaml-to-binary -o %t/CompiledAPINotes/SomeOtherKit.apinotesc %t/APINotes/SomeOtherKit.apinotes
+
+// Build again: check that both methods are now unavailable and that the module rebuilt.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/CompiledAPINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/compiled-after.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/compiled-after.log
+
+// Run the build again: check that both methods are now unavailable
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/CompiledAPINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/compiled-after.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/compiled-after.log
+
+@import SomeOtherKit;
+
+void test(A *a) {
+  // CHECK-METHODA: error: 'methodA' is unavailable: not here either
+  [a methodA];
+
+  // CHECK-METHODB: error: 'methodB' is unavailable: anything but this
+  [a methodB];
+}
+
+// CHECK-REBUILD: remark: building module{{.*}}SomeOtherKit
+
+// CHECK-WITHOUT-REBUILD-NOT: remark: building module{{.*}}SomeOtherKit
+
+// CHECK-ONE-ERROR: 1 error generated.
+// CHECK-TWO-ERRORS: 2 errors generated.
+
diff --git a/test/APINotes/nullability.c b/test/APINotes/nullability.c
new file mode 100644
index 0000000..1fcd0ee
--- /dev/null
+++ b/test/APINotes/nullability.c
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+#include "HeaderLib.h"
+
+int main() {
+  custom_realloc(0, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  int i = 0;
+  do_something_with_pointers(&i, 0);
+  do_something_with_pointers(0, &i); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  
+  extern void *p;
+  do_something_with_arrays(0, p); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  do_something_with_arrays(p, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+  take_pointer_and_int(0, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+  float *fp = global_int; // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'int * _Nonnull'}}
+  return 0;
+}
+
diff --git a/test/APINotes/nullability.m b/test/APINotes/nullability.m
new file mode 100644
index 0000000..f70c363
--- /dev/null
+++ b/test/APINotes/nullability.m
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+// 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 -fmodules-ignore-macro=SWIFT_VERSION_3_0
+
+#import <SomeKit/SomeKit.h>
+
+int main() {
+  A *a;
+
+#if SWIFT_VERSION_3_0
+  float *fp =  // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'A * _Nullable'}}
+    [a transform: 0 integer: 0];
+#else
+  float *fp =  // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'A *'}}
+    [a transform: 0 integer: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+#endif
+
+  [a setNonnullAInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+  [A setNonnullAInstance: 0]; // no warning
+  
+  [a setNonnullAClass: 0]; // no warning
+  [A setNonnullAClass: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+  [a setNonnullABoth: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+  [A setNonnullABoth: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+  [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/objc_designated_inits.m b/test/APINotes/objc_designated_inits.m
new file mode 100644
index 0000000..1df8cf8
--- /dev/null
+++ b/test/APINotes/objc_designated_inits.m
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+#include "HeaderLib.h"
+#import <SomeKit/SomeKit.h>
+
+@interface CSub : C
+-(instancetype)initWithA:(A*)a;
+@end
+
+@implementation CSub
+-(instancetype)initWithA:(A*)a { // expected-warning{{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  // expected-note@SomeKit/SomeKit.h:20 2{{method marked as designated initializer of the class here}}
+  self = [super init]; // expected-warning{{designated initializer invoked a non-designated initializer}}
+  return self;
+}
+@end
diff --git a/test/APINotes/properties.m b/test/APINotes/properties.m
new file mode 100644
index 0000000..b1559b9
--- /dev/null
+++ b/test/APINotes/properties.m
@@ -0,0 +1,45 @@
+// RUN: rm -rf %t && mkdir -p %t
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fblocks -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'TestProperties::' | FileCheck -check-prefix=CHECK -check-prefix=CHECK-4 %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fblocks -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'TestProperties::' -fapinotes-swift-version=3 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-3 %s
+
+// I know, FileChecking an AST dump is brittle. However, the attributes being
+// tested aren't used for anything by Clang, and don't even have a spelling.
+
+@import VersionedKit;
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnly 'id'
+// CHECK-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClass 'id'
+// CHECK-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyInVersion3 'id'
+// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// 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: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyExceptInVersion3 'id'
+// CHECK-3-NEXT: SwiftVersionedAttr {{.+}} 0{{$}}
+// 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: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-4-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 3.0 {{[0-9]+}}
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: Decl
diff --git a/test/APINotes/search-order.m b/test/APINotes/search-order.m
new file mode 100644
index 0000000..2c667be
--- /dev/null
+++ b/test/APINotes/search-order.m
@@ -0,0 +1,25 @@
+// RUN: rm -rf %t && mkdir -p %t
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_FRAMEWORK=1 -verify
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %S/Inputs/APINotes -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_SEARCH_PATH=1 -verify
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -iapinotes-modules %S/Inputs/APINotes -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_FRAMEWORK=1 -verify
+
+@import SomeOtherKit;
+
+void test(A *a) {
+#if FROM_FRAMEWORK
+  [a methodA]; // expected-error{{unavailable}}
+  [a methodB];
+
+  // expected-note@SomeOtherKit/SomeOtherKit.h:5{{'methodA' has been explicitly marked unavailable here}}
+#elif FROM_SEARCH_PATH
+  [a methodA];
+  [a methodB]; // expected-error{{unavailable}}
+
+  // expected-note@SomeOtherKit/SomeOtherKit.h:6{{'methodB' has been explicitly marked unavailable here}}
+#else
+#  error Not something we need to test
+#endif
+}
diff --git a/test/APINotes/types.m b/test/APINotes/types.m
new file mode 100644
index 0000000..fccff80
--- /dev/null
+++ b/test/APINotes/types.m
@@ -0,0 +1,23 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+#import <SomeKit/SomeKit.h>
+
+void test(OverriddenTypes *overridden) {
+  int *ip1 = global_int_ptr; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'double (*)(int, int)'}}
+
+  int *ip2 = global_int_fun( // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'char *'}}
+               ip2, // expected-warning{{incompatible pointer types passing 'int *' to parameter of type 'double *'}}
+               ip2); // expected-warning{{incompatible pointer types passing 'int *' to parameter of type 'float *'}}
+
+  int *ip3 = [overridden // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'char *'}}
+                methodToMangle: ip3 // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'double *'}}
+                        second: ip3]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'float *'}}
+
+  int *ip4 = overridden.intPropertyToMangle; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'double *'}}
+}
+
+// expected-note@SomeKit/SomeKit.h:42{{passing argument to parameter 'ptr' here}}
+// expected-note@SomeKit/SomeKit.h:42{{passing argument to parameter 'ptr2' here}}
+// expected-note@SomeKit/SomeKit.h:48{{passing argument to parameter 'ptr1' here}}
+// expected-note@SomeKit/SomeKit.h:48{{passing argument to parameter 'ptr2' here}}
diff --git a/test/APINotes/versioned.m b/test/APINotes/versioned.m
new file mode 100644
index 0000000..38690fe
--- /dev/null
+++ b/test/APINotes/versioned.m
@@ -0,0 +1,50 @@
+// 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
+// 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 -ast-dump -ast-dump-filter 'moveToPoint' | FileCheck -check-prefix=CHECK-DUMP -check-prefix=CHECK-UNVERSIONED-DUMP %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 -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
+// 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 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'moveToPoint' | FileCheck -check-prefix=CHECK-DUMP -check-prefix=CHECK-VERSIONED-DUMP %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-DUMP-LABEL: Dumping moveToPoint
+// CHECK-VERSIONED-DUMP: SwiftVersionedAttr {{.+}} Implicit 0
+// 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: SwiftNameAttr {{.+}} Implicit "moveTo(a:b:)"
+// CHECK-DUMP-NOT: Dumping
+
+// 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-UNVERSIONED: void privateFunc() __attribute__((swift_private));
+
+// CHECK-UNVERSIONED: typedef double MyDoubleWrapper __attribute__((swift_wrapper("struct")));
+
+// CHECK-VERSIONED:      enum MyErrorCode {
+// CHECK-VERSIONED-NEXT:     MyErrorCodeFailed = 1
+// CHECK-VERSIONED-NEXT: };
+
+// CHECK-VERSIONED-NOT: __attribute__((swift_bridge("MyValueType")))
+// CHECK-VERSIONED: @interface MyReferenceType
+
+// CHECK-VERSIONED: void privateFunc();
+
+// CHECK-VERSIONED: typedef double MyDoubleWrapper;
diff --git a/test/APINotes/yaml-convert-diags.c b/test/APINotes/yaml-convert-diags.c
new file mode 100644
index 0000000..e8767f2
--- /dev/null
+++ b/test/APINotes/yaml-convert-diags.c
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fsyntax-only -fapinotes -fapinotes-cache-path=%t %s -I %S/Inputs/BrokenHeaders2 2>&1 | FileCheck %s
+
+#include "SomeBrokenLib.h"
+
+// CHECK: error: multiple definitions of global function 'do_something_with_pointers'
diff --git a/test/APINotes/yaml-os-availability.c b/test/APINotes/yaml-os-availability.c
new file mode 100644
index 0000000..62301af
--- /dev/null
+++ b/test/APINotes/yaml-os-availability.c
@@ -0,0 +1,31 @@
+# RUN: %clang -cc1apinotes -yaml-to-binary -target i386-apple-ios7 -o %t-ios.apinotesc %S/Inputs/os-availability.apinotes
+# RUN: %clang -cc1apinotes -binary-to-yaml %t-ios.apinotesc -o %t.os-availability-ios.apinotes
+# RUN: FileCheck %s -check-prefix=IOS < %t.os-availability-ios.apinotes
+
+# RUN: %clang -cc1apinotes -yaml-to-binary -target x86_64-apple-macosx10.9 -o %t-osx.apinotesc %S/Inputs/os-availability.apinotes
+# RUN: %clang -cc1apinotes -binary-to-yaml %t-osx.apinotesc -o %t.os-availability-osx.apinotes
+# RUN: FileCheck %s -check-prefix=OSX < %t.os-availability-osx.apinotes
+
+# IOS: Foundation
+# IOS: NSArray
+# IOS: initWithObjects
+# IOS: familyNameios
+# IOS: fontName
+# IOS: NSCountedSet
+# IOS: UIApplicationDelegate
+# IOS: UIApplicationDelegateIOS
+# IOS: NSAvailableWindowDepths
+# IOS: NSAvailableWindowDepthsiOS
+# IOS-NOT: NSCalibratedWhiteColorSpace
+  
+# OSX: Foundation
+# qqOSX: NSArray
+# OSX-NOT: initWithObjects
+# OSX-NOT: familyNameios
+# OSX: fontName
+# OSX-NOT: NSCountedSet
+# OSX: UIApplicationDelegate
+# OSX-NOT: UIApplicationDelegateIOS
+# OSX: NSAvailableWindowDepths
+# OSX-NOT: NSAvailableWindowDepthsiOS
+# OSX: NSCalibratedWhiteColorSpace
diff --git a/test/APINotes/yaml-parse-diags.c b/test/APINotes/yaml-parse-diags.c
new file mode 100644
index 0000000..4505e29
--- /dev/null
+++ b/test/APINotes/yaml-parse-diags.c
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fsyntax-only -fapinotes -fapinotes-cache-path=%t %s -I %S/Inputs/BrokenHeaders -verify
+
+#include "SomeBrokenLib.h"
+
+// expected-error@APINotes.apinotes:4{{unknown key 'Nu llabilityOfRet'}}
diff --git a/test/APINotes/yaml-reader-errors.c b/test/APINotes/yaml-reader-errors.c
new file mode 100644
index 0000000..3e01eaa
--- /dev/null
+++ b/test/APINotes/yaml-reader-errors.c
@@ -0,0 +1,65 @@
+# RUN: not %clang -cc1apinotes -yaml-to-binary -target i386-apple-ios7 -o %t.apinotesc %s > %t.err 2>&1
+# RUN: FileCheck %s < %t.err
+
+---
+Name:            UIKit
+Availability:    iOS
+AvailabilityMsg: iOSOnly
+Classes:
+  - Name:            UIFont
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+    Methods:
+      - Selector:        'fontWithName:size:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: O
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+        DesignatedInit:  true
+# CHECK: duplicate definition of method '-[UIFont fontWithName:size:]'
+      - Selector:        'fontWithName:size:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: O
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+        DesignatedInit:  true
+    Properties:
+      - Name:            familyName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+      - Name:            fontName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+# CHECK: duplicate definition of instance property 'UIFont.familyName'
+      - Name:            familyName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+# CHECK: multiple definitions of class 'UIFont'
+  - Name:            UIFont
+Protocols:
+  - Name:            MyProto
+    AuditedForNullability: true
+# CHECK: multiple definitions of protocol 'MyProto'
+  - Name:            MyProto
+    AuditedForNullability: true
+Functions:
+  - Name:        'globalFoo'
+    Nullability:     [ N, N, O, S ]
+    NullabilityOfRet: O
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+  - Name:        'globalFoo2'
+    Nullability:     [ N, N, O, S ]
+    NullabilityOfRet: O
+Globals:
+  - Name:            globalVar
+    Nullability:     O
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+  - Name:            globalVar2
+    Nullability:     O
diff --git a/test/APINotes/yaml-reader-test.c b/test/APINotes/yaml-reader-test.c
new file mode 100644
index 0000000..01ad90a
--- /dev/null
+++ b/test/APINotes/yaml-reader-test.c
@@ -0,0 +1,102 @@
+# RUN: %clang -cc1apinotes -dump %s | FileCheck %s
+---
+Name:            UIKit
+Availability:    iOS
+AvailabilityMsg: iOSOnly
+Classes:
+  - Name:            UIFont
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+    Methods:
+      - Selector:        'fontWithName:size:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: O
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+        DesignatedInit:  true
+    Properties:
+      - Name:            familyName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+      - Name:            fontName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+Protocols:
+  - Name:            MyProto
+    AuditedForNullability: true
+  - Name:            MyProto2
+    AuditedForNullability: true
+Functions:
+  - Name:        'globalFoo'
+    Nullability:     [ N, N, O, S ]
+    NullabilityOfRet: O
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+  - Name:        'globalFoo2'
+    Nullability:     [ N, N, O, S ]
+    NullabilityOfRet: O
+Globals:
+  - Name:            globalVar
+    Nullability:     O
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+  - Name:            globalVar2
+    Nullability:     O
+
+
+# CHECK: Name:            UIKit
+# CHECK: Availability:    iOS
+# CHECK: AvailabilityMsg: iOSOnly
+# CHECK: Classes:
+# CHECK:   - Name:            UIFont
+# CHECK:     Availability:    iOS
+# CHECK:     AvailabilityMsg: iOSOnly
+# CHECK:     Methods:
+# CHECK:       - Selector:        'fontWithName:size:'
+# CHECK:         MethodKind:      Instance
+# CHECK:         Nullability:     [ N ]
+# CHECK:         NullabilityOfRet: O
+# CHECK:         Availability:    iOS
+# CHECK:         AvailabilityMsg: iOSOnly
+# CHECK:         DesignatedInit:  true
+# CHECK:     Properties:
+# CHECK:       - Name:            familyName
+# CHECK:         Nullability:     N
+# CHECK:         Availability:    iOS
+# CHECK:         AvailabilityMsg: iOSOnly
+# CHECK:       - Name:            fontName
+# CHECK:         Nullability:     N
+# CHECK:         Availability:    iOS
+# CHECK:         AvailabilityMsg: iOSOnly
+# CHECK:Protocols:       
+# CHECK:  - Name:            MyProto
+# CHECK:    AuditedForNullability: true
+# CHECK:    Availability:    available
+# CHECK:    AvailabilityMsg: ''
+# CHECK:  - Name:            MyProto2
+# CHECK:    AuditedForNullability: true
+# CHECK:    Availability:    available
+# CHECK:    AvailabilityMsg: ''
+# CHECK:Functions:       
+# CHECK:  - Name:            globalFoo
+# CHECK:    Nullability:     [ N, N, O, U ]
+# CHECK:    NullabilityOfRet: O
+# CHECK:    Availability:    iOS
+# CHECK:    AvailabilityMsg: iOSOnly
+# CHECK:  - Name:            globalFoo2
+# CHECK:    Nullability:     [ N, N, O, U ]
+# CHECK:    NullabilityOfRet: O
+# CHECK:    Availability:    available
+# CHECK:    AvailabilityMsg: ''
+# CHECK:Globals:         
+# CHECK:  - Name:            globalVar
+# CHECK:    Nullability:     O
+# CHECK:    Availability:    iOS
+# CHECK:    AvailabilityMsg: iOSOnly
+# CHECK:  - Name:            globalVar2
+# CHECK:    Nullability:     O
+# CHECK:    Availability:    available
+# CHECK:    AvailabilityMsg: 
diff --git a/test/APINotes/yaml-roundtrip.c b/test/APINotes/yaml-roundtrip.c
new file mode 100644
index 0000000..b721b6a
--- /dev/null
+++ b/test/APINotes/yaml-roundtrip.c
@@ -0,0 +1,10 @@
+# RUN: %clang -cc1apinotes -yaml-to-binary -o %t.apinotesc %S/Inputs/roundtrip.apinotes
+# RUN: %clang -cc1apinotes -binary-to-yaml -o %t.apinotes %t.apinotesc
+
+# Handle the infurating '...' the YAML writer adds but the parser
+# can't read.
+
+# RUN: cp %S/Inputs/roundtrip.apinotes %t-reference.apinotes
+# RUN: echo "..." >> %t-reference.apinotes
+# RUN: diff %t-reference.apinotes %t.apinotes
+
diff --git a/test/Analysis/ns_error_enum.m b/test/Analysis/ns_error_enum.m
new file mode 100644
index 0000000..bf61629
--- /dev/null
+++ b/test/Analysis/ns_error_enum.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -verify %s
+
+#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#define NS_ENUM(_type, _name) CF_ENUM(_type, _name)
+
+#define NS_ERROR_ENUM(_type, _name, _domain)  \
+  enum _name : _type _name; enum __attribute__((ns_error_domain(_domain))) _name : _type
+
+typedef NS_ENUM(unsigned, MyEnum) {
+  MyFirst,
+  MySecond,
+};
+
+typedef NS_ENUM(invalidType, MyInvalidEnum) {
+// expected-error@-1{{unknown type name 'invalidType'}}
+// expected-error@-2{{unknown type name 'invalidType'}}
+  MyFirstInvalid,
+  MySecondInvalid,
+};
+
+const char *MyErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnum, MyErrorDomain) {
+	MyErrFirst,
+	MyErrSecond,
+};
+struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructErrorDomain {};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, InvalidDomain) {
+	// expected-error@-1{{domain argument 'InvalidDomain' does not refer to global constant}}
+	MyErrFirstInvalid,
+	MyErrSecondInvalid,
+};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, "domain-string");
+  // expected-error@-1{{domain argument must be an identifier}}
+
+int __attribute__((ns_error_domain(MyErrorDomain))) NotTagDecl;
+  // expected-error@-1{{ns_error_domain attribute only valid on enums, structs, and unions}}
+
+void foo() {}
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalidFunction, foo);
+  // expected-error@-1{{domain argument 'foo' does not refer to global constant}}
diff --git a/test/CXX/special/class.dtor/p10-0x.cpp b/test/CXX/special/class.dtor/p10-0x.cpp
index 3b8a0ad..3be0a98 100644
--- a/test/CXX/special/class.dtor/p10-0x.cpp
+++ b/test/CXX/special/class.dtor/p10-0x.cpp
@@ -33,7 +33,7 @@
                              expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
   i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
   pi->~decltype(int())();
-  pi.~decltype(int())(); // expected-error{{the type of object expression ('int *') does not match the type being destroyed ('decltype(int())' (aka 'int')) in pseudo-destructor expression}}
+  pi.~decltype(int())(); // expected-error{{member reference type 'int *' is a pointer; did you mean to use '->'?}}
   pi.~decltype(intp())();
   pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
 }
diff --git a/test/CodeGen/lifetime2.c b/test/CodeGen/lifetime2.c
index 4374b3c..55c6d91 100644
--- a/test/CodeGen/lifetime2.c
+++ b/test/CodeGen/lifetime2.c
@@ -1,7 +1,7 @@
-// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefixes=CHECK,O2
-// RUN: %clang -S -emit-llvm -o - -O2 -Xclang -disable-lifetime-markers %s \
+// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s -check-prefixes=CHECK,O2
+// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-lifetime-markers %s \
 // RUN:       | FileCheck %s -check-prefixes=CHECK,O0
-// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
+// RUN: %clang_cc1 -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
 
 extern int bar(char *A, int n);
 
@@ -25,13 +25,11 @@
   char x;
 l1:
   bar(&x, 1);
-  // O2: @llvm.lifetime.start(i64 5
-  // O2: @llvm.lifetime.end(i64 5
   char y[5];
   bar(y, 5);
   goto l1;
   // Infinite loop
-  // O2-NOT: @llvm.lifetime.end(i64 1
+  // O2-NOT: @llvm.lifetime.end(
 }
 
 // CHECK-LABEL: @goto_bypass
@@ -91,3 +89,27 @@
 L:
   bar(&x, 1);
 }
+
+// O2-LABEL: @jump_backward_over_declaration(
+// O2: %[[p:.*]] = alloca i32*
+// O2: %[[v0:.*]] = bitcast i32** %[[p]] to i8*
+// O2: call void @llvm.lifetime.start(i64 {{.*}}, i8* %[[v0]])
+// O2-NOT: call void @llvm.lifetime.start(
+
+extern void foo2(int p);
+
+int jump_backward_over_declaration(int a) {
+  int *p = 0;
+label1:
+  if (p) {
+    foo2(*p);
+    return 0;
+  }
+
+  int i = 999;
+  if (a != 2) {
+    p = &i;
+    goto label1;
+  }
+  return -1;
+}
diff --git a/test/CodeGen/ubsan-null.c b/test/CodeGen/ubsan-null.c
new file mode 100644
index 0000000..6ddae8a
--- /dev/null
+++ b/test/CodeGen/ubsan-null.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsanitize=null -emit-llvm %s -o - | FileCheck %s
+
+struct A {
+  int a[2];
+  int b;
+};
+
+// CHECK-LABEL: @f1
+int *f1() {
+// CHECK-NOT: __ubsan_handle_type_mismatch
+// CHECK: ret
+// CHECK-SAME: getelementptr inbounds (%struct.A, %struct.A* null, i32 0, i32 1)
+  return &((struct A *)0)->b;
+}
+
+// CHECK-LABEL: @f2
+int f2() {
+// CHECK: __ubsan_handle_type_mismatch
+// CHECK: load
+// CHECK-SAME: getelementptr inbounds (%struct.A, %struct.A* null, i32 0, i32 1)
+// CHECK: ret
+  return ((struct A *)0)->b;
+}
diff --git a/test/CodeGen/ubsan-shift.c b/test/CodeGen/ubsan-shift.c
new file mode 100644
index 0000000..90c15d8
--- /dev/null
+++ b/test/CodeGen/ubsan-shift.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fsanitize=shift-exponent,shift-base -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: define i32 @f1
+int f1(int c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+  return 1 << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f2
+int f2(long c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 63, !nosanitize
+// CHECK: icmp ule i64 %{{.*}}, 31, !nosanitize
+  return 1 << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f3
+unsigned f3(unsigned c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+  return 1U << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f4
+unsigned f4(unsigned long c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 63, !nosanitize
+// CHECK: icmp ule i64 %{{.*}}, 31, !nosanitize
+  return 1U << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f5
+int f5(int c, long long shamt) {
+// CHECK: icmp ule i64 %{{[0-9]+}}, 31, !nosanitize
+//
+// CHECK: sub nuw nsw i32 31, %sh_prom, !nosanitize
+// CHECK: lshr i32 %{{.*}}, %shl.zeros, !nosanitize
+  return c << shamt;
+}
+
+// CHECK-LABEL: define i32 @f6
+int f6(int c, int shamt) {
+// CHECK: icmp ule i32 %[[WIDTH:.*]], 31, !nosanitize
+//
+// CHECK: sub nuw nsw i32 31, %[[WIDTH]], !nosanitize
+// CHECK: lshr i32 %{{.*}}, %shl.zeros, !nosanitize
+  return c << shamt;
+}
diff --git a/test/CodeGen/vector.c b/test/CodeGen/vector.c
index ebaea84..2e36dcc 100644
--- a/test/CodeGen/vector.c
+++ b/test/CodeGen/vector.c
@@ -60,23 +60,3 @@
   extern __typeof(_mm_extract_epi16(_mm_setzero_si128(), 3)) check_result_int;
   extern __typeof(_mm_extract_epi32(_mm_setzero_si128(), 3)) check_result_int;
 }
-
-// Test some logic around our lax vector comparison rules with integers.
-
-typedef int vec_int1 __attribute__((vector_size(4)));
-vec_int1 lax_vector_compare1(int x, vec_int1 y) {
-  y = x == y;
-  return y;
-}
-
-// CHECK: define i32 @lax_vector_compare1(i32 {{.*}}, i32 {{.*}})
-// CHECK: icmp eq <1 x i32>
-
-typedef int vec_int2 __attribute__((vector_size(8)));
-vec_int2 lax_vector_compare2(long long x, vec_int2 y) {
-  y = x == y;
-  return y;
-}
-
-// CHECK: define void @lax_vector_compare2(<2 x i32>* {{.*sret.*}}, i64 {{.*}}, i64 {{.*}})
-// CHECK: icmp eq <2 x i32>
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index fb57118..85857fb 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -5,6 +5,9 @@
 // This check logically is attached to 'template int S<int>::i;' below.
 // CHECK: @_ZN1SIiE1iE = weak_odr global i32
 
+// This check is logically attached to 'template int ExportedStaticLocal::f<int>()' below.
+// CHECK-OPT: @_ZZN19ExportedStaticLocal1fIiEEvvE1i = linkonce_odr global
+
 template<typename T, typename U, typename Result>
 struct plus {
   Result operator()(const T& t, const U& u) const;
@@ -153,3 +156,17 @@
 template <typename T> void S<T>::g() {}
 template <typename T> int S<T>::i;
 template <typename T> void S<T>::S2::h() {}
+
+namespace ExportedStaticLocal {
+void sink(int&);
+template <typename T>
+inline void f() {
+  static int i;
+  sink(i);
+}
+// See the check line at the top of the file.
+extern template void f<int>();
+void use() {
+  f<int>();
+}
+}
diff --git a/test/Driver/embed-bitcode.c b/test/Driver/embed-bitcode.c
index 36314e6..fa86c2c3 100644
--- a/test/Driver/embed-bitcode.c
+++ b/test/Driver/embed-bitcode.c
@@ -34,6 +34,13 @@
 // CHECK-LTO-NOT: warning: argument unused during compilation: '-fembed-bitcode'
 // CHECK-LTO-NOT: -cc1
 // CHECK-LTO-NOT: -fembed-bitcode=all
+// RUN: touch %t.o
+// RUN: %clang  -target armv7-apple-darwin -miphoneos-version-min=6.0 %t.o -fembed-bitcode  -fembed-bitcode-marker -mlinker-version=277  2>&1 -### | FileCheck %s -check-prefix=CHECK-LTO-MARKER-277
+// RUN: %clang  -target armv7-apple-darwin -miphoneos-version-min=6.0 %t.o -fembed-bitcode  -fembed-bitcode-marker -mlinker-version=278  2>&1 -### | FileCheck %s -check-prefix=CHECK-LTO-MARKER-278
+// CHECK-LTO-MARKER-277-NOT: bitcode_process_mode
+// CHECK-LTO-MARKER-278: bitcode_process_mode
+
+
 
 // RUN: %clang -c %s -fembed-bitcode-marker -fintegrated-as 2>&1 -### | FileCheck %s -check-prefix=CHECK-MARKER
 // CHECK-MARKER: -cc1
diff --git a/test/Driver/frame-pointer-elim.c b/test/Driver/frame-pointer-elim.c
index e1d816e..e39499a 100644
--- a/test/Driver/frame-pointer-elim.c
+++ b/test/Driver/frame-pointer-elim.c
@@ -49,9 +49,9 @@
 
 // RUN: %clang -### -target armv7s-apple-ios8.0 -momit-leaf-frame-pointer %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=WARN-OMIT-LEAF-7S %s
-// WARN-OMIT-LEAF-7S: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
+// WARN-OMIT-LEAF-7S-NOT: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
 // WARN-OMIT-LEAF-7S: "-mdisable-fp-elim"
-// WARN-OMIT-LEAF-7S-NOT: "-momit-leaf-frame-pointer"
+// WARN-OMIT-LEAF-7S: "-momit-leaf-frame-pointer"
 
 // On the PS4, we default to omitting the frame pointer on leaf functions
 // (OMIT_LEAF check line is above)
diff --git a/test/Driver/mglobal-merge.c b/test/Driver/mglobal-merge.c
index ad76736..271011e 100644
--- a/test/Driver/mglobal-merge.c
+++ b/test/Driver/mglobal-merge.c
@@ -11,7 +11,7 @@
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
 
 // CHECK-NGM-ARM: "-backend-option" "-arm-global-merge=false"
-// CHECK-NGM-AARCH64: "-backend-option" "-aarch64-global-merge=false"
+// CHECK-NGM-AARCH64: "-backend-option" "-aarch64-enable-global-merge=false"
 
 // RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t \
 // RUN:   -mglobal-merge
@@ -26,7 +26,7 @@
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
 
 // CHECK-GM-ARM: "-backend-option" "-arm-global-merge=true"
-// CHECK-GM-AARCH64: "-backend-option" "-aarch64-global-merge=true"
+// CHECK-GM-AARCH64: "-backend-option" "-aarch64-enable-global-merge=true"
 
 // RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp
index c43aac9..0b7fc62 100644
--- a/test/FixIt/fixit.cpp
+++ b/test/FixIt/fixit.cpp
@@ -409,3 +409,14 @@
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"{}"
 int use_czi = czi.a;
 
+namespace dotPointerDestructor {
+
+struct Bar {
+  ~Bar();
+};
+
+void bar(Bar *o) {
+  o.~Bar(); // expected-error {{member reference type 'dotPointerDestructor::Bar *' is a pointer; did you mean to use '->'}}
+}  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:5}:"->"
+
+}
diff --git a/test/FixIt/no-fixit.cpp b/test/FixIt/no-fixit.cpp
index 7e8e1fb..2dad28d 100644
--- a/test/FixIt/no-fixit.cpp
+++ b/test/FixIt/no-fixit.cpp
@@ -11,3 +11,15 @@
     (void)&i;
   }
 } x;
+
+namespace dotPointerDestructor {
+
+struct Bar {
+  ~Bar() = delete;
+};
+
+void bar(Bar *o) {
+  o.~Bar(); // no fixit
+}
+
+}
diff --git a/test/Frontend/objc-bool-is-bool.m b/test/Frontend/objc-bool-is-bool.m
index 464fe2e..ee4fb58 100644
--- a/test/Frontend/objc-bool-is-bool.m
+++ b/test/Frontend/objc-bool-is-bool.m
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -E -dM -triple=armv7k-apple-watchos %s | FileCheck --check-prefix=BOOL %s
 // RUN: %clang_cc1 -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
-// RUN: %clang_cc1 -x c -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=NONE %s
+// RUN: %clang_cc1 -x c -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
 
 // rdar://21170440
 
@@ -9,5 +11,3 @@
 
 // CHAR: #define __OBJC_BOOL_IS_BOOL 0
 // CHAR-NOT: #define __OBJC_BOOL_IS_BOOL 1
-
-// NONE-NOT: __OBJC_BOOL_IS_BOOL
diff --git a/test/Index/Core/index-pch.c b/test/Index/Core/index-pch.c
new file mode 100644
index 0000000..773cfc5
--- /dev/null
+++ b/test/Index/Core/index-pch.c
@@ -0,0 +1,13 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+// RUN: %clang_cc1 -emit-pch %s -o %t.pch
+// RUN: c-index-test core -print-source-symbols -module-file %t.pch | FileCheck %s
+
+// CHECK: [[@LINE+1]]:6 | function/C | test1 | [[TEST1_USR:.*]] | [[TEST1_CG:.*]] | Decl | rel: 0
+void test1();
+
+// CHECK: [[@LINE+1]]:20 | function/C | test2 | [[TEST2_USR:.*]] | {{.*}} | Def | rel: 0
+static inline void test2() {
+  // CHECK: [[@LINE+2]]:3 | function/C | test1 | [[TEST1_USR]] | [[TEST1_CG]] | Ref,Call,RelCall,RelCont | rel: 1
+  // CHECK-NEXT: RelCall,RelCont | test2 | [[TEST2_USR]]
+  test1();
+}
diff --git a/test/Index/Core/index-with-module.m b/test/Index/Core/index-with-module.m
index e50b247..c83de63 100644
--- a/test/Index/Core/index-with-module.m
+++ b/test/Index/Core/index-with-module.m
@@ -1,5 +1,5 @@
 // RUN: rm -rf %t.mcp
-// RUN: c-index-test core -print-source-symbols -- %s -I %S/Inputs/module -fmodules -fmodules-cache-path=%t.mcp | FileCheck %s
+// RUN: c-index-test core -print-source-symbols -dump-imported-module-files -- %s -I %S/Inputs/module -fmodules -fmodules-cache-path=%t.mcp | FileCheck %s
 
 // CHECK: [[@LINE+1]]:9 | module/C | ModA | Decl |
 @import ModA;
@@ -10,3 +10,9 @@
   // CHECK: [[@LINE+1]]:3 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Ref,Call,RelCall,RelCont | rel: 1
   ModA_func();
 }
+
+// CHECK: ==== Module ModA ====
+// CHECK: 2:6 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Decl | rel: 0
+// CHECK: ---- Module Inputs ----
+// CHECK: user | {{.*}}ModA.h
+// CHECK: user | {{.*}}module.modulemap
diff --git a/test/Index/complete-cached-globals.cpp b/test/Index/complete-cached-globals.cpp
new file mode 100644
index 0000000..791faf2
--- /dev/null
+++ b/test/Index/complete-cached-globals.cpp
@@ -0,0 +1,25 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+namespace SomeNamespace {
+    class SomeClass {
+    };
+    void SomeFunction();
+}
+
+using SomeNamespace::SomeClass;
+using SomeNamespace::SomeFunction;
+
+static void foo() {
+  return;
+}
+
+// rdar://23454249
+
+// RUN: c-index-test -code-completion-at=%s:14:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+
+// CHECK-CC1: ClassDecl:{TypedText SomeClass} (50)
+// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText SomeFunction}{LeftParen (}{RightParen )} (50)
+// CHECK-CC1-NOT: {Text SomeNamespace::}{TypedText SomeClass}
+// CHECK-CC1-NOT: {Text SomeNamespace::}{TypedText SomeFunction}
diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m
index e3fce6b..c2b0670 100644
--- a/test/Index/complete-objc-message.m
+++ b/test/Index/complete-objc-message.m
@@ -346,3 +346,54 @@
 
 // RUN: c-index-test -code-completion-at=%s:197:6 %s | FileCheck -check-prefix=CHECK-NULLABLE %s
 // CHECK-NULLABLE: ObjCInstanceMethodDecl:{ResultType A * _Nonnull}{TypedText method:}{Placeholder (nullable A *)}
+
+// rdar://28012953
+// Code completion results should include instance methods from RootProtocol and
+// RootClass when completing a method invocation for a RootClass object because
+// RootClasses metaclass subclasses from RootClass (i.e. RootClass is actually
+// an instance of RootClass).
+
+@protocol SubRootProtocol
+
+- (void)subProtocolInstanceMethod;
+
+@end
+
+@protocol RootProtocol <SubRootProtocol>
+
+- (void)protocolInstanceMethod;
++ (void)protocolClassMethod;
+
+@end
+
+@interface RootClass <RootProtocol>
+
+- (void)instanceMethod;
++ (void)classMethod;
+
+@end
+
+@protocol RootCategoryProtocol
+
+- (void)categoryProtocolInstanceMethod;
+
+@end
+
+@interface RootClass (Cat) <RootCategoryProtocol>
+
+- (void)categoryInstanceMethod;
+
+@end
+
+void completeAllTheRootThings() {
+  [RootClass classMethod];
+}
+
+// RUN: c-index-test -code-completion-at=%s:389:14 %s | FileCheck -check-prefix=CHECK-ROOT %s
+// CHECK-ROOT: ObjCInstanceMethodDecl:{ResultType void}{TypedText categoryInstanceMethod} (35)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText categoryProtocolInstanceMethod} (37)
+// CHECK-ROOT-NEXT: ObjCClassMethodDecl:{ResultType void}{TypedText classMethod} (35)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText instanceMethod} (35)
+// CHECK-ROOT-NEXT: ObjCClassMethodDecl:{ResultType void}{TypedText protocolClassMethod} (37)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText protocolInstanceMethod} (37)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText subProtocolInstanceMethod} (37)
diff --git a/test/Lexer/cxx-features.cpp b/test/Lexer/cxx-features.cpp
index 5fc1722..0af42dc 100644
--- a/test/Lexer/cxx-features.cpp
+++ b/test/Lexer/cxx-features.cpp
@@ -9,7 +9,6 @@
 
 // expected-no-diagnostics
 
-// FIXME using `defined` in a macro has undefined behavior.
 #if __cplusplus < 201103L
 #define check(macro, cxx98, cxx11, cxx14, cxx1z) cxx98 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx98
 #elif __cplusplus < 201402L
diff --git a/test/Modules/Inputs/diag_pragma.h b/test/Modules/Inputs/diag_pragma.h
index a8f9589..59c73ea 100644
--- a/test/Modules/Inputs/diag_pragma.h
+++ b/test/Modules/Inputs/diag_pragma.h
@@ -1,3 +1,13 @@
 #define DIAG_PRAGMA_MACRO 1
 
 #pragma clang diagnostic ignored "-Wparentheses"
+
+#ifdef __cplusplus
+template<typename T> const char *f(T t) {
+  return "foo" + t;
+}
+#pragma clang diagnostic ignored "-Wstring-plus-int"
+template<typename T> const char *g(T t) {
+  return "foo" + t;
+}
+#endif
diff --git a/test/Modules/Inputs/incomplete-type/A.h b/test/Modules/Inputs/incomplete-type/A.h
new file mode 100644
index 0000000..6943aaf
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/A.h
@@ -0,0 +1 @@
+#define __P(protos)     ()
diff --git a/test/Modules/Inputs/incomplete-type/B.h b/test/Modules/Inputs/incomplete-type/B.h
new file mode 100644
index 0000000..51df71e
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/B.h
@@ -0,0 +1,2 @@
+#import "A.h"
+#import "B2.h"
diff --git a/test/Modules/Inputs/incomplete-type/B2.h b/test/Modules/Inputs/incomplete-type/B2.h
new file mode 100644
index 0000000..def109f
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/B2.h
@@ -0,0 +1,2 @@
+void test(int __P) {
+}
diff --git a/test/Modules/Inputs/incomplete-type/C.h b/test/Modules/Inputs/incomplete-type/C.h
new file mode 100644
index 0000000..ea6a2ee
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/C.h
@@ -0,0 +1,2 @@
+#import "A.h"
+#import "B.h"
diff --git a/test/Modules/Inputs/incomplete-type/module.modulemap b/test/Modules/Inputs/incomplete-type/module.modulemap
new file mode 100644
index 0000000..17c8d7d
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/module.modulemap
@@ -0,0 +1,15 @@
+module X {
+  header "A.h"
+  export *
+}
+
+// Y imports X
+module Y {
+  header "B.h"
+  export *
+}
+
+// Z imports X and Y
+module Z {
+  header "C.h"
+}
diff --git a/test/Modules/Inputs/shadow/A1/A.h b/test/Modules/Inputs/shadow/A1/A.h
new file mode 100644
index 0000000..f07c681
--- /dev/null
+++ b/test/Modules/Inputs/shadow/A1/A.h
@@ -0,0 +1 @@
+#define A1_A_h
diff --git a/test/Modules/Inputs/shadow/A1/module.modulemap b/test/Modules/Inputs/shadow/A1/module.modulemap
new file mode 100644
index 0000000..9439a43
--- /dev/null
+++ b/test/Modules/Inputs/shadow/A1/module.modulemap
@@ -0,0 +1,5 @@
+module A {
+  header "A.h"
+}
+
+module A1 {}
diff --git a/test/Modules/Inputs/shadow/A2/A.h b/test/Modules/Inputs/shadow/A2/A.h
new file mode 100644
index 0000000..9880ed0
--- /dev/null
+++ b/test/Modules/Inputs/shadow/A2/A.h
@@ -0,0 +1 @@
+#define A2_A_h
diff --git a/test/Modules/Inputs/shadow/A2/module.modulemap b/test/Modules/Inputs/shadow/A2/module.modulemap
new file mode 100644
index 0000000..935d89b
--- /dev/null
+++ b/test/Modules/Inputs/shadow/A2/module.modulemap
@@ -0,0 +1,5 @@
+module A {
+  header "A.h"
+}
+
+module A2 {}
diff --git a/test/Modules/Inputs/swift_name/module.modulemap b/test/Modules/Inputs/swift_name/module.modulemap
new file mode 100644
index 0000000..b7ec6b1
--- /dev/null
+++ b/test/Modules/Inputs/swift_name/module.modulemap
@@ -0,0 +1,2 @@
+module SwiftNameInferred [swift_infer_import_as_member] {
+}
\ No newline at end of file
diff --git a/test/Modules/diag-pragma.cpp b/test/Modules/diag-pragma.cpp
new file mode 100644
index 0000000..347401f
--- /dev/null
+++ b/test/Modules/diag-pragma.cpp
@@ -0,0 +1,47 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -fmodules-ts
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -fmodules-ts -o %t/explicit.pcm -Werror=string-plus-int
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DEXPLICIT_FLAG -fmodule-file=%t/explicit.pcm
+
+import diag_pragma;
+
+int foo(int x) {
+  // Diagnostics from templates in the module follow the diagnostic state from
+  // when the module was built.
+#ifdef EXPLICIT_FLAG
+  // expected-error@diag_pragma.h:7 {{adding 'int' to a string}}
+#else
+  // expected-warning@diag_pragma.h:7 {{adding 'int' to a string}}
+#endif
+  // expected-note@diag_pragma.h:7 {{use array indexing}}
+  f(0); // expected-note {{instantiation of}}
+
+  g(0); // ok, warning was ignored when building module
+
+  // Diagnostics from this source file ignore the diagnostic state from the
+  // module.
+  void("foo" + x); // expected-warning {{adding 'int' to a string}}
+  // expected-note@-1 {{use array indexing}}
+
+#pragma clang diagnostic ignored "-Wstring-plus-int"
+
+  // Diagnostics from the module ignore diagnostic state changes from this
+  // source file.
+#ifdef EXPLICIT_FLAG
+  // expected-error@diag_pragma.h:7 {{adding 'long' to a string}}
+#else
+  // expected-warning@diag_pragma.h:7 {{adding 'long' to a string}}
+#endif
+  // expected-note@diag_pragma.h:7 {{use array indexing}}
+  f(0L); // expected-note {{instantiation of}}
+
+  g(0L);
+
+  void("bar" + x);
+
+  if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                             // expected-note {{place parentheses}} expected-note {{use '=='}}
+    return 0;
+  return 1;
+}
diff --git a/test/Modules/incomplete-type-void.c b/test/Modules/incomplete-type-void.c
new file mode 100644
index 0000000..2ce00f7
--- /dev/null
+++ b/test/Modules/incomplete-type-void.c
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 -fmodules %s -fmodules-cache-path=%t.cache \
+// RUN:     -fsyntax-only -I %S/Inputs/incomplete-type -verify
+
+// expected-no-diagnostics
+
+#import "C.h"
+#import "A.h"
+void foo __P(());
diff --git a/test/Modules/infer_swift_name.m b/test/Modules/infer_swift_name.m
new file mode 100644
index 0000000..d4b4a5d
--- /dev/null
+++ b/test/Modules/infer_swift_name.m
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/swift_name %s -verify
+// REQUIRES: shell
+
+@import SwiftNameInferred; // ok
+@import SwiftName; // expected-error{{module 'SwiftName' not found}}
diff --git a/test/Modules/minimal-identifier-tables.cpp b/test/Modules/minimal-identifier-tables.cpp
deleted file mode 100644
index 0674746..0000000
--- a/test/Modules/minimal-identifier-tables.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir %t
-// RUN: echo 'extern int some_long_variable_name;' > %t/x.h
-// RUN: echo 'extern int some_long_variable_name;' > %t/y.h
-// RUN: echo 'module X { header "x.h" } module Y { header "y.h" }' > %t/map
-// RUN: %clang_cc1 -fmodules -x c++ -fmodule-name=X %t/map -emit-module -o %t/x.pcm
-// RUN: %clang_cc1 -fmodules -x c++ -fmodule-name=Y %t/map -fmodule-file=%t/x.pcm -emit-module -o %t/y.pcm
-// RUN: cat %t/y.pcm | FileCheck %s
-//
-// CHECK-NOT: some_long_variable_name
diff --git a/test/Modules/shadow.m b/test/Modules/shadow.m
new file mode 100644
index 0000000..44320af
--- /dev/null
+++ b/test/Modules/shadow.m
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/shadow/A1 -I %S/Inputs/shadow/A2 %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -fmodule-map-file=%S/Inputs/shadow/A2/module.modulemap %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION
+// REDEFINITION: error: redefinition of module 'A'
+// REDEFINITION: note: previously defined
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -I %S/Inputs/shadow %s -verify
+
+@import A1;
+@import A2;
+@import A;
+
+#import "A2/A.h" // expected-note {{implicitly imported}}
+// expected-error@A2/module.modulemap:1 {{import of shadowed module 'A'}}
+// expected-note@A1/module.modulemap:1 {{previous definition}}
+
+#if defined(A2_A_h)
+#error got the wrong definition of module A
+#elif !defined(A1_A_h)
+#error missing definition from A1
+#endif
diff --git a/test/Preprocessor/expr_define_expansion.c b/test/Preprocessor/expr_define_expansion.c
index 23cb435..3e5a2c4 100644
--- a/test/Preprocessor/expr_define_expansion.c
+++ b/test/Preprocessor/expr_define_expansion.c
@@ -1,28 +1,6 @@
-// RUN: %clang_cc1 %s -E -CC -verify
-// RUN: %clang_cc1 %s -E -CC -DPEDANTIC -pedantic -verify
+// RUN: %clang_cc1 %s -E -CC -pedantic -verify
+// expected-no-diagnostics
 
 #define FOO && 1
 #if defined FOO FOO
 #endif
-
-#define A
-#define B defined(A)
-#if B // expected-warning{{macro expansion producing 'defined' has undefined behavior}}
-#endif
-
-#define m_foo
-#define TEST(a) (defined(m_##a) && a)
-
-#if defined(PEDANTIC)
-// expected-warning@+4{{macro expansion producing 'defined' has undefined behavior}}
-#endif
-
-// This shouldn't warn by default, only with pedantic:
-#if TEST(foo)
-#endif
-
-
-// Only one diagnostic for this case:
-#define INVALID defined(
-#if INVALID // expected-error{{macro name missing}}
-#endif
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 8b89019..1d3e9fb 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -8705,6 +8705,7 @@
 // WEBASSEMBLY32-NEXT:#define __LONG_MAX__ 2147483647L
 // WEBASSEMBLY32-NOT:#define __LP64__
 // WEBASSEMBLY32-NEXT:#define __NO_INLINE__ 1
+// WEBASSEMBLY32-NEXT:#define __OBJC_BOOL_IS_BOOL 0
 // WEBASSEMBLY32-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
 // WEBASSEMBLY32-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
 // WEBASSEMBLY32-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
@@ -9020,6 +9021,7 @@
 // WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L
 // WEBASSEMBLY64-NEXT:#define __LP64__ 1
 // WEBASSEMBLY64-NEXT:#define __NO_INLINE__ 1
+// WEBASSEMBLY64-NEXT:#define __OBJC_BOOL_IS_BOOL 0
 // WEBASSEMBLY64-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
 // WEBASSEMBLY64-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
 // WEBASSEMBLY64-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
diff --git a/test/Sema/attr-availability-swift.c b/test/Sema/attr-availability-swift.c
new file mode 100644
index 0000000..42e7524
--- /dev/null
+++ b/test/Sema/attr-availability-swift.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -ast-dump %s | FileCheck %s
+//
+
+#if !__has_feature(attribute_availability_with_message)
+# error "Missing __has_feature"
+#endif
+
+#if __has_feature(attribute_availability_swift)
+# warning "okay"
+// expected-warning@-1{{okay}}
+#else
+# error "Missing __has_feature"
+#endif
+
+extern int noSwiftGlobal1 __attribute__((availability(swift, unavailable)));
+// CHECK: AvailabilityAttr {{.*}}swift 0 0 0 Unavailable "" ""
+extern int noSwiftGlobal1 __attribute__((availability(macosx, introduced=10.1))); // okay
+// CHECK: AvailabilityAttr {{.*}}macos 10.1 0 0 "" ""
+// CHECK: AvailabilityAttr {{.*}}Inherited swift 0 0 0 Unavailable "" ""
+extern int noSwiftGlobal1 __attribute__((availability(swift, unavailable, message="and this one has a message"))); // okay
+// CHECK: AvailabilityAttr {{.*}}swift 0 0 0 Unavailable "and this one has a message" ""
+// CHECK: AvailabilityAttr {{.*}}Inherited macos 10.1 0 0 "" ""
+extern int noSwiftGlobal2 __attribute__((availability(swift, introduced=5))); // expected-warning{{only 'unavailable' and 'deprecated' are supported for Swift availability}}
+// CHECK: VarDecl
+// CHECK-NOT: AvailabilityAttr
+extern int noSwiftGlobal3 __attribute__((availability(swift, deprecated, message="t")));
+// CHECK: VarDecl
+// CHECK: AvailabilityAttr {{.*}}swift 0 1 0 "t" ""
diff --git a/test/Sema/attr-availability.c b/test/Sema/attr-availability.c
index a4b40ff..e7a800f 100644
--- a/test/Sema/attr-availability.c
+++ b/test/Sema/attr-availability.c
@@ -80,7 +80,6 @@
 extern int x2 __attribute__((availability(macosx,introduced=10.2))); // expected-note {{previous attribute is here}}
 extern int x2 __attribute__((availability(macosx,introduced=10.5))); // expected-warning {{availability does not match previous declaration}}
 
-
 enum Original {
   OriginalDeprecated __attribute__((availability(macosx, deprecated=10.2))), // expected-note + {{'OriginalDeprecated' has been explicitly marked deprecated here}}
   OriginalUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'OriginalUnavailable' has been explicitly marked unavailable here}}
diff --git a/test/Sema/attr-noescape.c b/test/Sema/attr-noescape.c
new file mode 100644
index 0000000..ec367b6
--- /dev/null
+++ b/test/Sema/attr-noescape.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -fblocks -verify -fsyntax-only
+
+#if !__has_attribute(noescape)
+#  error "missing noescape attribute"
+#endif
+
+int *global_var __attribute((noescape)); // expected-warning{{'noescape' attribute only applies to parameters}}
+
+void foo(__attribute__((noescape)) int *int_ptr,
+         __attribute__((noescape)) int (^block)(int),
+         __attribute((noescape)) int integer) { // expected-warning{{'noescape' attribute ignored on parameter of non-pointer type 'int'}}
+}
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index 5465122..ca3132e 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -653,6 +653,33 @@
 }
 #pragma GCC diagnostic warning "-Wformat-nonliteral"
 
+void test_os_log_format(char c, const char *pc, int i, int *pi, void *p, void *buf) {
+  __builtin_os_log_format(buf, "");
+  __builtin_os_log_format(buf, "%d"); // expected-warning {{more '%' conversions than data arguments}}
+  __builtin_os_log_format(buf, "%d", i);
+  __builtin_os_log_format(buf, "%P", p); // expected-warning {{using '%P' format specifier without precision}}
+  __builtin_os_log_format(buf, "%.10P", p);
+  __builtin_os_log_format(buf, "%.*P", p); // expected-warning {{field precision should have type 'int', but argument has type 'void *'}}
+  __builtin_os_log_format(buf, "%.*P", i, p);
+  __builtin_os_log_format(buf, "%.*P", i, i); // expected-warning {{format specifies type 'void *' but the argument has type 'int'}}
+  __builtin_os_log_format(buf, pc); // expected-error {{os_log() format argument is not a string constant}}
+
+  printf("%{private}s", pc); // expected-warning {{using 'private' format specifier annotation outside of os_log()/os_trace()}}
+  __builtin_os_log_format(buf, "%{private}s", pc);
+
+  // <rdar://problem/23835805>
+  __builtin_os_log_format_buffer_size("no-args");
+  __builtin_os_log_format(buf, "%s", "hi");
+
+  // <rdar://problem/24828090>
+  wchar_t wc = 'a';
+  __builtin_os_log_format(buf, "%C", wc);
+  printf("%C", wc);
+  wchar_t wcs[] = {'a', 0};
+  __builtin_os_log_format(buf, "%S", wcs);
+  printf("%S", wcs);
+}
+
 void test_char_pointer_arithmetic(int b) {
   const char s1[] = "string";
   const char s2[] = "%s string";
diff --git a/test/Sema/vector-cast.c b/test/Sema/vector-cast.c
index ea4acfa..03db540 100644
--- a/test/Sema/vector-cast.c
+++ b/test/Sema/vector-cast.c
@@ -45,24 +45,12 @@
 }
 
 typedef float float2 __attribute__ ((vector_size (8)));
-typedef __attribute__((vector_size(8))) double float64x1_t;
-typedef __attribute__((vector_size(16))) double float64x2_t;
-float64x1_t vget_low_f64(float64x2_t __p0);
 
 void f4() {
   float2 f2;
-  double d, a, b, c;
-  float64x2_t v = {0.0, 1.0};
-  // FIXME: These diagnostics are inaccurate: should complain that 'double' to vector 'float2' involves truncation
-  f2 += d; // expected-error {{cannot convert between vector values of different size ('float2' (vector of 2 'float' values) and 'double')}}
-  d += f2; // expected-error {{cannot convert between vector values of different size}}
-  a = 3.0 + vget_low_f64(v);
-  b = vget_low_f64(v) + 3.0;
-  c = vget_low_f64(v);
-  c -= vget_low_f64(v);
-  // LAX conversions between scalar and vector types require same size and one element sized vectors.
-  d = f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}}
-  d = d + f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}}
+  double d;
+  f2 += d;
+  d += f2;
 }
 
 // rdar://15931426
diff --git a/test/Sema/vector-compound-assign-lax.cpp b/test/Sema/vector-compound-assign-lax.cpp
new file mode 100644
index 0000000..296cfb7
--- /dev/null
+++ b/test/Sema/vector-compound-assign-lax.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -ffreestanding -triple armv7 -target-feature +neon -fsyntax-only %s -verify -Wvector-conversion -DNEON
+// RUN: %clang_cc1 -ffreestanding -triple=x86_64-apple-darwin -target-feature +sse2 -fsyntax-only %s -verify -Wvector-conversion -DSSE2
+
+// Test that there are no diagnostics for vector compound assignments where we
+// support lax conversions from the RHS type to the LHS type. For context, see:
+//
+//   <rdar://problem/30112602> cannot convert between vector values ...
+//   <rdar://problem/28639522> Cannot create binary operator with two ...
+//   <rdar://problem/30110333> Invalid conversion from int64x2 to uint32x4 ...
+
+// expected-no-diagnostics
+
+#include <stdint.h>
+
+typedef int v_int32x4_t __attribute__((__vector_size__(16)));
+typedef unsigned v_uint32x4_t __attribute__((__vector_size__(16)));
+
+#ifdef NEON
+typedef __attribute__((neon_vector_type(8))) int16_t n_int16x8_t;
+typedef __attribute__((neon_vector_type(8))) uint16_t n_uint16x8_t;
+
+void fn1() {
+  n_int16x8_t i;
+  n_uint16x8_t u;
+  i += u;
+}
+#endif
+
+void fn2() {
+  v_int32x4_t i;
+  v_uint32x4_t u;
+  i += u;
+}
+
+#ifdef SSE2
+#include <x86intrin.h>
+
+typedef __attribute__((__ext_vector_type__(4))) unsigned int ev_uint32x4_t;
+
+void fn3() {
+  __m128i i;
+  ev_uint32x4_t u;
+  i += u; // FIXME: Converting uint32x4 to int64x2 should *not* be allowed.
+}
+#endif
diff --git a/test/SemaCXX/designated-initializers-base-class.cpp b/test/SemaCXX/designated-initializers-base-class.cpp
new file mode 100644
index 0000000..9c2e61e
--- /dev/null
+++ b/test/SemaCXX/designated-initializers-base-class.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -Winitializer-overrides
+// expected-no-diagnostics
+
+struct B {
+  int x;
+};
+
+struct D : B {
+  int y;
+};
+
+void test() { D d = {1, .y = 2}; }
diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp
index 45f1eaf..bc0d7b2 100644
--- a/test/SemaCXX/pseudo-destructors.cpp
+++ b/test/SemaCXX/pseudo-destructors.cpp
@@ -89,3 +89,26 @@
 void AliasTemplate(int *p) {
   p->~Id<int>();
 }
+
+namespace dotPointerAccess {
+struct Base {
+  virtual ~Base() {}
+};
+
+struct Derived : Base {
+  ~Derived() {}
+};
+
+void test() {
+  Derived d;
+  static_cast<Base *>(&d).~Base(); // expected-error {{member reference type 'dotPointerAccess::Base *' is a pointer; did you mean to use '->'}}
+  d->~Derived(); // expected-error {{member reference type 'dotPointerAccess::Derived' is not a pointer; did you mean to use '.'}}
+}
+
+typedef Derived *Foo;
+
+void test2(Foo d) {
+  d.~Foo(); // This is ok
+  d.~Derived(); // expected-error {{member reference type 'Foo' (aka 'dotPointerAccess::Derived *') is a pointer; did you mean to use '->'}}
+}
+}
diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm
index 11161a0..8e2828f 100644
--- a/test/SemaObjC/arc-repeated-weak.mm
+++ b/test/SemaObjC/arc-repeated-weak.mm
@@ -462,3 +462,16 @@
   use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
   use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}
 }
+
+// This used to crash in the constructor of WeakObjectProfileTy when a
+// DeclRefExpr was passed that didn't reference a VarDecl.
+
+typedef INTF * INTFPtrTy;
+
+enum E {
+  e1
+};
+
+void foo1() {
+  INTFPtrTy tmp = (INTFPtrTy)e1; // expected-error{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}
+}
diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m
index f463bb0..72c07a9 100644
--- a/test/SemaObjC/arc.m
+++ b/test/SemaObjC/arc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class -Wblock-capture-autoreleasing %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s
 
 typedef unsigned long NSUInteger;
 typedef const void * CFTypeRef;
@@ -809,9 +809,30 @@
   TKAssertEqual(object, (id)nil);
 }
 
-void block_capture_autoreleasing(A * __autoreleasing *a, A **b) { // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+void block_capture_autoreleasing(A * __autoreleasing *a,
+                                 A **b, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * _Nullable *c, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * _Nullable __autoreleasing *d,
+                                 A ** _Nullable e, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * __autoreleasing * _Nullable f,
+                                 id __autoreleasing *g,
+                                 id *h, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id _Nullable *i, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id _Nullable __autoreleasing *j,
+                                 id * _Nullable k, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id __autoreleasing * _Nullable l) {
   ^{
     (void)*a;
     (void)*b; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*c; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*d;
+    (void)*e; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*f;
+    (void)*g;
+    (void)*h; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*i; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*j;
+    (void)*k; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*l;
   }();
 }
diff --git a/test/SemaObjC/attr-swift.m b/test/SemaObjC/attr-swift.m
new file mode 100644
index 0000000..bdcbbd0
--- /dev/null
+++ b/test/SemaObjC/attr-swift.m
@@ -0,0 +1,217 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc -fblocks %s
+
+// --- swift_private ---
+
+__attribute__((swift_private))
+@protocol FooProto
+@end
+
+__attribute__((swift_private))
+@interface Foo
+@end
+
+@interface Bar
+@property id prop __attribute__((swift_private));
+- (void)instMethod __attribute__((swift_private));
++ (instancetype)bar __attribute__((swift_private));
+@end
+
+void function(id) __attribute__((swift_private));
+
+struct __attribute__((swift_private)) Point {
+  int x;
+  int y;
+};
+
+enum __attribute__((swift_private)) Colors {
+  Red, Green, Blue
+};
+
+typedef struct {
+  float x, y, z;
+} Point3D __attribute__((swift_private));
+
+
+// --- swift_name ---
+
+__attribute__((swift_name("SNFooType")))
+@protocol SNFoo
+@end
+
+__attribute__((swift_name("SNFooClass")))
+@interface SNFoo <SNFoo>
+- (instancetype)init __attribute__((swift_name("init()")));
+- (instancetype)initWithValue:(int)value __attribute__((swift_name("fooWithValue(_:)")));
+
++ (void)refresh __attribute__((swift_name("refresh()")));
+
++ (instancetype)foo __attribute__((swift_name("foo()")));
++ (SNFoo *)fooWithValue:(int)value __attribute__((swift_name("foo(value:)")));
++ (SNFoo *)fooWithValue:(int)value value:(int)value2 __attribute__((swift_name("foo(value:extra:)")));
++ (SNFoo *)fooWithConvertingValue:(int)value value:(int)value2 __attribute__((swift_name("init(_:extra:)")));
+
++ (SNFoo *)fooWithOtherValue:(int)value __attribute__((swift_name("init"))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
++ (SNFoo *)fooWithAnotherValue:(int)value __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
++ (SNFoo *)fooWithYetAnotherValue:(int)value __attribute__((swift_name("foo(value:extra:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 1; got 2)}}
+
++ (SNFoo *)fooAndReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo()"))); // no-warning
++ (SNFoo *)fooWithValue:(int)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(value:)"))); // no-warning
++ (SNFoo *)fooFromErrorCode:(const int *)errorCode __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
++ (SNFoo *)fooWithValue:(int)value fromErrorCode:(const int *)errorCode __attribute__((swift_name("foo(value:)"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 2; got 1)}}
++ (SNFoo *)fooWithPointerA:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo()"))); // no-warning
++ (SNFoo *)fooWithPointerB:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(pointer:)"))); // no-warning
++ (SNFoo *)fooWithPointerC:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(pointer:errorCode:)"))); // no-warning
++ (SNFoo *)fooWithOtherFoo:(SNFoo *)other __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
+
++ (instancetype)specialFoo __attribute__((swift_name("init(options:)")));
++ (instancetype)specialBar __attribute__((swift_name("init(options:extra:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 2)}}
++ (instancetype)specialBaz __attribute__((swift_name("init(_:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 1)}}
++ (instancetype)specialGarply __attribute__((swift_name("foo(options:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 1)}}
+
++ (instancetype)trailingParen __attribute__((swift_name("foo("))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
++ (instancetype)trailingColon:(int)value __attribute__((swift_name("foo(value)"))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
++ (instancetype)initialIgnore:(int)value __attribute__((swift_name("_(value:)"))); // expected-warning {{'swift_name' attribute has invalid identifier for base name}}
++ (instancetype)middleOmitted:(int)value __attribute__((swift_name("foo(:)"))); // expected-warning {{'swift_name' attribute has invalid identifier for parameter name}}
+
+@property(strong) id someProp __attribute__((swift_name("prop")));
+@end
+
+enum __attribute__((swift_name("MoreColors"))) MoreColors {
+  Cyan,
+  Magenta,
+  Yellow __attribute__((swift_name("RoseGold"))),
+  Black __attribute__((swift_name("SpaceGrey()"))) // expected-warning {{'swift_name' attribute has invalid identifier for base name}}
+};
+
+struct __attribute__((swift_name("FooStruct"))) BarStruct {
+  int x, y, z __attribute__((swift_name("zed")));
+};
+
+int global_int __attribute__((swift_name("GlobalInt")));
+
+void foo1(int i) __attribute__((swift_name("foo"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+void foo2(int i) __attribute__((swift_name("foo()"))); // expected-warning{{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
+void foo2(int i) __attribute__((swift_name("foo(a:b:)"))); // expected-warning{{too many parameters in 'swift_name' attribute (expected 1; got 2)}}
+void foo3(int i, int j) __attribute__((swift_name("fooWithX(_:y:)"))); // okay
+void foo4(int i, int *error) __attribute__((swift_name("fooWithA(_:)"))); // okay
+
+typedef int some_int_type __attribute__((swift_name("SomeInt")));
+
+struct Point3D createPoint3D(float x, float y, float z) __attribute__((swift_name("Point3D.init(x:y:z:)")));
+struct Point3D rotatePoint3D(Point3D point, float radians) __attribute__((swift_name("Point3D.rotate(self:radians:)")));
+struct Point3D badRotatePoint3D(Point3D point, float radians) __attribute__((swift_name("Point3D.rotate(radians:)"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 2; got 1)}}
+
+extern struct Point3D identityPoint __attribute__((swift_name("Point3D.identity")));
+
+// Getters and setters.
+float Point3DGetMagnitude(Point3D point) __attribute__((swift_name("getter:Point3D.magnitude(self:)")));
+
+float Point3DGetMagnitudeAndSomethingElse(Point3D point, float wat) __attribute__((swift_name("getter:Point3D.magnitude(self:wat:)"))); // expected-warning {{'swift_name' attribute for getter must not take any parameters besides 'self:'}}
+
+float Point3DGetRadius(Point3D point) __attribute__((swift_name("getter:Point3D.radius(self:)")));
+void Point3DSetRadius(Point3D point, float radius) __attribute__((swift_name("setter:Point3D.radius(self:newValue:)")));
+
+float Point3DPreGetRadius(Point3D point) __attribute__((swift_name("getter:Point3D.preRadius(self:)")));
+void Point3DPreSetRadius(float radius, Point3D point) __attribute__((swift_name("setter:Point3D.preRadius(newValue:self:)")));
+
+void Point3DSetRadiusAndSomethingElse(Point3D point, float radius, float wat) __attribute__((swift_name("setter:Point3D.radius(self:newValue:wat:)"))); // expected-warning {{'swift_name' attribute for setter must take one parameter for new value}}
+
+float Point3DGetComponent(Point3D point, unsigned index) __attribute__((swift_name("getter:Point3D.subscript(self:_:)")));
+float Point3DSetComponent(Point3D point, unsigned index, float value) __attribute__((swift_name("setter:Point3D.subscript(self:_:newValue:)")));
+
+float Point3DGetMatrixComponent(Point3D point, unsigned x, unsigned y) __attribute__((swift_name("getter:Point3D.subscript(self:x:y:)")));
+void Point3DSetMatrixComponent(Point3D point, unsigned x, float value, unsigned y) __attribute__((swift_name("setter:Point3D.subscript(self:x:newValue:y:)")));
+
+float Point3DSetWithoutNewValue(Point3D point, unsigned x, unsigned y) __attribute__((swift_name("setter:Point3D.subscript(self:x:y:)"))); // expected-warning {{'swift_name' attribute for 'subscript' setter must take a 'newValue:' parameter}}
+
+float Point3DSubscriptButNotGetterSetter(Point3D point, unsigned x) __attribute__((swift_name("Point3D.subscript(self:_:)"))); // expected-warning {{'swift_name' attribute for 'subscript' must be a getter or setter}}
+
+void Point3DSubscriptSetterTwoNewValues(Point3D point, unsigned x, float a, float b) __attribute__((swift_name("setter:Point3D.subscript(self:_:newValue:newValue:)"))); // expected-warning {{'swift_name' attribute for 'subscript' setter cannot take multiple 'newValue:' parameters}}
+float Point3DSubscriptGetterNewValue(Point3D point, unsigned x, float a, float b) __attribute__((swift_name("getter:Point3D.subscript(self:_:newValue:newValue:)"))); // expected-warning {{'swift_name' attribute for 'subscript' getter cannot take a 'newValue:' parameter}}
+
+void Point3DMethodWithNewValue(Point3D point, float newValue) __attribute__((swift_name("Point3D.method(self:newValue:)")));
+void Point3DMethodWithNewValues(Point3D point, float newValue, float newValueB) __attribute__((swift_name("Point3D.method(self:newValue:newValue:)")));
+
+float Point3DStaticSubscript(unsigned x) __attribute__((swift_name("getter:Point3D.subscript(_:)"))); // expected-warning {{'swift_name' attribute for 'subscript' must take a 'self:' parameter}}
+float Point3DStaticSubscriptNoArgs(void) __attribute__((swift_name("getter:Point3D.subscript()"))); // expected-warning {{'swift_name' attribute for 'subscript' must take at least one parameter}}
+
+float Point3DPreGetComponent(Point3D point, unsigned index) __attribute__((swift_name("getter:Point3D.subscript(self:_:)")));
+
+Point3D getCurrentPoint3D(void) __attribute__((swift_name("getter:currentPoint3D()")));
+
+void setCurrentPoint3D(Point3D point) __attribute__((swift_name("setter:currentPoint3D(newValue:)")));
+
+Point3D getLastPoint3D(void) __attribute__((swift_name("getter:lastPoint3D()")));
+
+void setLastPoint3D(Point3D point) __attribute__((swift_name("setter:lastPoint3D(newValue:)")));
+
+Point3D getZeroPoint(void) __attribute__((swift_name("getter:Point3D.zero()")));
+Point3D getZeroPointNoPrototype() __attribute__((swift_name("getter:Point3D.zeroNoPrototype()"))); // expected-warning{{'swift_name' attribute can only be applied to function declarations with prototypes}}
+void setZeroPoint(Point3D point) __attribute__((swift_name("setter:Point3D.zero(newValue:)")));
+
+Point3D badGetter1(int x) __attribute__((swift_name("getter:bad1(_:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+void badSetter1(void) __attribute__((swift_name("getter:bad1())"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+
+Point3D badGetter2(Point3D point) __attribute__((swift_name("getter:bad2(_:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+
+void badSetter2(Point3D point) __attribute__((swift_name("setter:bad2(self:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+
+// --- swift_error ---
+
+@class NSError;
+
+typedef struct __attribute__((objc_bridge(NSError))) __CFError *CFErrorRef;
+
+@interface Erroneous
+- (_Bool) tom0: (NSError**) err __attribute__((swift_error(none)));
+- (_Bool) tom1: (NSError**) err __attribute__((swift_error(nonnull_error)));
+- (_Bool) tom2: (NSError**) err __attribute__((swift_error(null_result))); // expected-error {{'swift_error' attribute with 'null_result' convention can only be applied to a method returning a pointer}}
+- (_Bool) tom3: (NSError**) err __attribute__((swift_error(nonzero_result)));
+- (_Bool) tom4: (NSError**) err __attribute__((swift_error(zero_result)));
+
+- (Undeclared) richard0: (NSError**) err __attribute__((swift_error(none))); // expected-error {{expected a type}}
+- (Undeclared) richard1: (NSError**) err __attribute__((swift_error(nonnull_error))); // expected-error {{expected a type}}
+- (Undeclared) richard2: (NSError**) err __attribute__((swift_error(null_result))); // expected-error {{expected a type}}
+// FIXME: the follow-on warnings should really be suppressed, but apparently having an ill-formed return type doesn't mark anything as invalid
+- (Undeclared) richard3: (NSError**) err __attribute__((swift_error(nonzero_result))); // expected-error {{expected a type}} expected-error {{can only be applied}}
+- (Undeclared) richard4: (NSError**) err __attribute__((swift_error(zero_result))); // expected-error {{expected a type}} expected-error {{can only be applied}}
+
+- (instancetype) harry0: (NSError**) err __attribute__((swift_error(none)));
+- (instancetype) harry1: (NSError**) err __attribute__((swift_error(nonnull_error)));
+- (instancetype) harry2: (NSError**) err __attribute__((swift_error(null_result)));
+- (instancetype) harry3: (NSError**) err __attribute__((swift_error(nonzero_result))); // expected-error {{'swift_error' attribute with 'nonzero_result' convention can only be applied to a method returning an integral type}}
+- (instancetype) harry4: (NSError**) err __attribute__((swift_error(zero_result))); // expected-error {{'swift_error' attribute with 'zero_result' convention can only be applied to a method returning an integral type}}
+
+- (instancetype) harry0 __attribute__((swift_error(none)));
+- (instancetype) harry1 __attribute__((swift_error(nonnull_error))); // expected-error {{'swift_error' attribute can only be applied to a method with an error parameter}}
+- (instancetype) harry2 __attribute__((swift_error(null_result))); // expected-error {{'swift_error' attribute can only be applied to a method with an error parameter}}
+- (instancetype) harry3 __attribute__((swift_error(nonzero_result))); // expected-error {{'swift_error' attribute can only be applied to a method with an error parameter}}
+- (instancetype) harry4 __attribute__((swift_error(zero_result))); // expected-error {{'swift_error' attribute can only be applied to a method with an error parameter}}
+@end
+
+extern _Bool tom0(CFErrorRef *) __attribute__((swift_error(none)));
+extern _Bool tom1(CFErrorRef *) __attribute__((swift_error(nonnull_error)));
+extern _Bool tom2(CFErrorRef *) __attribute__((swift_error(null_result))); // expected-error {{'swift_error' attribute with 'null_result' convention can only be applied to a function returning a pointer}}
+extern _Bool tom3(CFErrorRef *) __attribute__((swift_error(nonzero_result)));
+extern _Bool tom4(CFErrorRef *) __attribute__((swift_error(zero_result)));
+
+extern Undeclared richard0(CFErrorRef *) __attribute__((swift_error(none))); // expected-error {{unknown type name 'Undeclared'}}
+extern Undeclared richard1(CFErrorRef *) __attribute__((swift_error(nonnull_error))); // expected-error {{unknown type name 'Undeclared'}}
+extern Undeclared richard2(CFErrorRef *) __attribute__((swift_error(null_result))); // expected-error {{unknown type name 'Undeclared'}}
+extern Undeclared richard3(CFErrorRef *) __attribute__((swift_error(nonzero_result))); // expected-error {{unknown type name 'Undeclared'}}
+extern Undeclared richard4(CFErrorRef *) __attribute__((swift_error(zero_result))); // expected-error {{unknown type name 'Undeclared'}}
+
+extern void *harry0(CFErrorRef *) __attribute__((swift_error(none)));
+extern void *harry1(CFErrorRef *) __attribute__((swift_error(nonnull_error)));
+extern void *harry2(CFErrorRef *) __attribute__((swift_error(null_result)));
+extern void *harry3(CFErrorRef *) __attribute__((swift_error(nonzero_result))); // expected-error {{'swift_error' attribute with 'nonzero_result' convention can only be applied to a function returning an integral type}}
+extern void *harry4(CFErrorRef *) __attribute__((swift_error(zero_result))); // expected-error {{'swift_error' attribute with 'zero_result' convention can only be applied to a function returning an integral type}}
+
+extern void *wilma0(void) __attribute__((swift_error(none)));
+extern void *wilma1(void) __attribute__((swift_error(nonnull_error))); // expected-error {{'swift_error' attribute can only be applied to a function with an error parameter}}
+extern void *wilma2(void) __attribute__((swift_error(null_result))); // expected-error {{'swift_error' attribute can only be applied to a function with an error parameter}}
+extern void *wilma3(void) __attribute__((swift_error(nonzero_result))); // expected-error {{'swift_error' attribute can only be applied to a function with an error parameter}}
+extern void *wilma4(void) __attribute__((swift_error(zero_result))); // expected-error {{'swift_error' attribute can only be applied to a function with an error parameter}}
+
+
+extern _Bool suzanne __attribute__((swift_error(none))); // expected-error {{'swift_error' attribute only applies to functions and methods}}
diff --git a/test/SemaObjC/attr-swift_newtype.c b/test/SemaObjC/attr-swift_newtype.c
new file mode 100644
index 0000000..61e4d89
--- /dev/null
+++ b/test/SemaObjC/attr-swift_newtype.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+typedef int T1 __attribute__((swift_newtype(struct)));
+typedef int T2 __attribute__((swift_newtype(enum)));
+
+typedef int T3 __attribute__((swift_wrapper(struct)));
+typedef int T4 __attribute__((swift_wrapper(enum)));
+
+
+typedef int Bad1 __attribute__((swift_newtype(bad))); // expected-warning{{'swift_newtype' attribute argument not supported: 'bad'}}
+typedef int Bad2 __attribute__((swift_newtype())); // expected-error{{argument required after attribute}}
+typedef int Bad3 __attribute__((swift_newtype(bad, badder)));
+  // expected-error@-1{{expected ')'}}
+  // expected-note@-2{{to match this '('}}
+  // expected-warning@-3{{'swift_newtype' attribute argument not supported: 'bad'}}
+
+
+// TODO: better error message below
+// FIXME: why is this a parse error, rather than Sema error triggering?
+struct Bad4 __attribute__((swift_newtype(struct))) { }; // expected-error{{expected identifier or '('}}
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index 767d5ac..d5e3220 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -265,40 +265,17 @@
   NSLog(@"%2$[tt]@ %1$[tt]s", @"Foo", @"Bar"); // expected-warning {{object format flags cannot be used with 's' conversion specifier}}
 }
 
-// rdar://23622446
-@interface RD23622446_Tester: NSObject
+// Test os_log_format primitive with ObjC string literal format argument.
+void test_os_log_format(char c, const char *pc, int i, int *pi, void *p, void *buf, NSString *nss) {
+  __builtin_os_log_format(buf, @"");
+  __builtin_os_log_format(buf, @"%d"); // expected-warning {{more '%' conversions than data arguments}}
+  __builtin_os_log_format(buf, @"%d", i);
+  __builtin_os_log_format(buf, @"%P", p); // expected-warning {{using '%P' format specifier without precision}}
+  __builtin_os_log_format(buf, @"%.10P", p);
+  __builtin_os_log_format(buf, @"%.*P", p); // expected-warning {{field precision should have type 'int', but argument has type 'void *'}}
+  __builtin_os_log_format(buf, @"%.*P", i, p);
+  __builtin_os_log_format(buf, @"%.*P", i, i); // expected-warning {{format specifies type 'void *' but the argument has type 'int'}}
 
-+ (void)stringWithFormat:(const char *)format, ... __attribute__((format(__printf__, 1, 2)));
-
-@end
-
-@implementation RD23622446_Tester
-
-__attribute__ ((format_arg(1)))
-const char *rd23622446(const char *format) {
-  return format;
+  __builtin_os_log_format(buf, @"%{private}s", pc);
+  __builtin_os_log_format(buf, @"%@", nss);
 }
-
-+ (void)stringWithFormat:(const char *)format, ... {
-  return;
-}
-
-- (const char *)test:(const char *)format __attribute__ ((format_arg(1))) {
-  return format;
-}
-
-- (NSString *)str:(NSString *)format __attribute__ ((format_arg(1))) {
-  return format;
-}
-
-- (void)foo {
-  [RD23622446_Tester stringWithFormat:rd23622446("%u"), 1, 2]; // expected-warning {{data argument not used by format string}}
-  [RD23622446_Tester stringWithFormat:[self test: "%u"], 1, 2]; // expected-warning {{data argument not used by format string}}
-  [RD23622446_Tester stringWithFormat:[self test: "%s %s"], "name"]; // expected-warning {{more '%' conversions than data arguments}}
-  NSLog([self str: @"%@ %@"], @"name"); // expected-warning {{more '%' conversions than data arguments}}
-  [RD23622446_Tester stringWithFormat:rd23622446("%d"), 1]; // ok
-  [RD23622446_Tester stringWithFormat:[self test: "%d %d"], 1, 2]; // ok
-  NSLog([self str: @"%@"], @"string"); // ok
-}
-
-@end
diff --git a/test/SemaObjC/kindof.m b/test/SemaObjC/kindof.m
index 9d758d3..63ba18f 100644
--- a/test/SemaObjC/kindof.m
+++ b/test/SemaObjC/kindof.m
@@ -385,7 +385,7 @@
 @end
 
 @interface NSGeneric<ObjectType> : NSObject
-- (void)test:(__kindof ObjectType)T; // expected-note{{passing argument to parameter 'T' here}}
+- (void)test:(__kindof ObjectType)T;
 - (void)mapUsingBlock:(id (^)(__kindof ObjectType))block;
 @end
 @implementation NSGeneric
@@ -395,14 +395,6 @@
 }
 @end
 
-void testGeneric(NSGeneric<NSString*> *generic) {
-  NSObject *NSObject_obj;
-  // Assign from NSObject_obj to __kindof NSString*.
-  [generic test:NSObject_obj]; // expected-warning{{incompatible pointer types sending 'NSObject *' to parameter of type '__kindof NSString *'}}
-  NSString *NSString_str;
-  [generic test:NSString_str];
-}
-
 // Check that clang doesn't crash when a type parameter is illegal.
 @interface Array1<T> : NSObject
 @end
diff --git a/test/SemaObjC/parameterized_classes_subst.m b/test/SemaObjC/parameterized_classes_subst.m
index da2d56f..f90ee90 100644
--- a/test/SemaObjC/parameterized_classes_subst.m
+++ b/test/SemaObjC/parameterized_classes_subst.m
@@ -426,36 +426,3 @@
 // warning about likely protocol/class name typos.
 // --------------------------------------------------------------------------
 typedef NSArray<NSObject> ArrayOfNSObjectWarning; // expected-warning{{parameterized class 'NSArray' already conforms to the protocols listed; did you forget a '*'?}}
-
-// rdar://25060179
-@interface MyMutableDictionary<KeyType, ObjectType> : NSObject
-- (void)setObject:(ObjectType)obj forKeyedSubscript:(KeyType <NSCopying>)key; // expected-note{{passing argument to parameter 'obj' here}} \
-    // expected-note{{passing argument to parameter 'key' here}}
-@end
-
-void bar(MyMutableDictionary<NSString *, NSString *> *stringsByString,
-                             NSNumber *n1, NSNumber *n2) {
-  // We warn here when the key types do not match.
-  stringsByString[n1] = n2; // expected-warning{{incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'}} \
-    // expected-warning{{incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString<NSCopying> *'}}
-}
-
-@interface MyTest<K, V> : NSObject <NSCopying>
-- (V)test:(K)key;
-- (V)test2:(K)key; // expected-note{{previous definition is here}}
-- (void)mapUsingBlock:(id (^)(V))block;
-- (void)mapUsingBlock2:(id (^)(V))block; // expected-note{{previous definition is here}}
-@end
-
-@implementation MyTest
-- (id)test:(id)key {
-  return key;
-}
-- (int)test2:(id)key{ // expected-warning{{conflicting return type in implementation}}
-  return 0;
-}
-- (void)mapUsingBlock:(id (^)(id))block {
-}
-- (void)mapUsingBlock2:(id)block { // expected-warning{{conflicting parameter types in implementation}}
-}
-@end
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index e0df503..7244e2c 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -24,8 +24,10 @@
     libclang
     clangAST
     clangBasic
+    clangCodeGen
     clangFrontend
     clangIndex
+    clangSerialization
   )
 endif()
 
diff --git a/tools/c-index-test/core_main.cpp b/tools/c-index-test/core_main.cpp
index 0ab24fb..f371870 100644
--- a/tools/c-index-test/core_main.cpp
+++ b/tools/c-index-test/core_main.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
@@ -15,6 +16,7 @@
 #include "clang/Index/IndexDataConsumer.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Index/CodegenNameGenerator.h"
+#include "clang/Serialization/ASTReader.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
@@ -49,6 +51,17 @@
   "invocation\n"
 );
 
+static cl::opt<bool>
+DumpModuleImports("dump-imported-module-files",
+               cl::desc("Print symbols and input files from imported modules"));
+
+static cl::opt<std::string>
+ModuleFilePath("module-file",
+               cl::desc("Path to module file to print symbols from"));
+static cl::opt<std::string>
+  ModuleFormat("fmodule-format", cl::init("raw"),
+        cl::desc("Container format for clang modules and PCH, 'raw' or 'obj'"));
+
 }
 } // anonymous namespace
 
@@ -134,7 +147,19 @@
 // Print Source Symbols
 //===----------------------------------------------------------------------===//
 
-static bool printSourceSymbols(ArrayRef<const char *> Args) {
+static void dumpModuleFileInputs(serialization::ModuleFile &Mod,
+                                 ASTReader &Reader,
+                                 raw_ostream &OS) {
+  OS << "---- Module Inputs ----\n";
+  Reader.visitInputFiles(Mod, /*IncludeSystem=*/true, /*Complain=*/false,
+                        [&](const serialization::InputFile &IF, bool isSystem) {
+    OS << (isSystem ? "system" : "user") << " | ";
+    OS << IF.getFile()->getName() << '\n';
+  });
+}
+
+static bool printSourceSymbols(ArrayRef<const char *> Args,
+                               bool dumpModuleImports) {
   SmallVector<const char *, 4> ArgsWithProgName;
   ArgsWithProgName.push_back("clang");
   ArgsWithProgName.append(Args.begin(), Args.end());
@@ -144,7 +169,8 @@
   if (!CInvok)
     return true;
 
-  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(outs());
+  raw_ostream &OS = outs();
+  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(OS);
   IndexingOptions IndexOpts;
   std::unique_ptr<FrontendAction> IndexAction;
   IndexAction = createIndexingAction(DataConsumer, IndexOpts,
@@ -157,6 +183,50 @@
   if (!Unit)
     return true;
 
+  if (dumpModuleImports) {
+    if (auto Reader = Unit->getASTReader()) {
+      Reader->getModuleManager().visit([&](serialization::ModuleFile &Mod) -> bool {
+        OS << "==== Module " << Mod.ModuleName << " ====\n";
+        indexModuleFile(Mod, *Reader, DataConsumer, IndexOpts);
+        dumpModuleFileInputs(Mod, *Reader, OS);
+        return true; // skip module dependencies.
+      });
+    }
+  }
+
+  return false;
+}
+
+static bool printSourceSymbolsFromModule(StringRef modulePath,
+                                         StringRef format) {
+  FileSystemOptions FileSystemOpts;
+  auto pchContOps = std::make_shared<PCHContainerOperations>();
+  // Register the support for object-file-wrapped Clang modules.
+  pchContOps->registerReader(llvm::make_unique<ObjectFilePCHContainerReader>());
+  auto pchRdr = pchContOps->getReaderOrNull(format);
+  if (!pchRdr) {
+    errs() << "unknown module format: " << format << '\n';
+    return true;
+  }
+
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+      CompilerInstance::createDiagnostics(new DiagnosticOptions());
+  std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
+      modulePath, *pchRdr, Diags,
+      FileSystemOpts, /*UseDebugInfo=*/false,
+      /*OnlyLocalDecls=*/true, None,
+      /*CaptureDiagnostics=*/false,
+      /*AllowPCHWithCompilerErrors=*/true,
+      /*UserFilesAreVolatile=*/false);
+  if (!AU) {
+    errs() << "failed to create TU for: " << modulePath << '\n';
+    return true;
+  }
+
+  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(outs());
+  IndexingOptions IndexOpts;
+  indexASTUnit(*AU, DataConsumer, IndexOpts);
+
   return false;
 }
 
@@ -219,11 +289,15 @@
   }
 
   if (options::Action == ActionType::PrintSourceSymbols) {
+    if (!options::ModuleFilePath.empty()) {
+      return printSourceSymbolsFromModule(options::ModuleFilePath,
+                                          options::ModuleFormat);
+    }
     if (CompArgs.empty()) {
       errs() << "error: missing compiler args; pass '-- <compiler arguments>'\n";
       return 1;
     }
-    return printSourceSymbols(CompArgs);
+    return printSourceSymbols(CompArgs, options::DumpModuleImports);
   }
 
   return 0;
diff --git a/tools/clang-check/CMakeLists.txt b/tools/clang-check/CMakeLists.txt
index 04151a8..233f981 100644
--- a/tools/clang-check/CMakeLists.txt
+++ b/tools/clang-check/CMakeLists.txt
@@ -9,6 +9,7 @@
   )
 
 target_link_libraries(clang-check
+  clangAPINotes
   clangAST
   clangBasic
   clangDriver
diff --git a/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/tools/clang-offload-bundler/ClangOffloadBundler.cpp
index 20988b4..f37868f 100644
--- a/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ b/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -514,7 +514,10 @@
     // Dump the contents of the temporary file if that was requested.
     if (DumpTemporaryFiles) {
       errs() << ";\n; Object file bundler IR file.\n;\n";
-      AuxModule.get()->dump();
+      AuxModule.get()->print(errs(), nullptr,
+                             /*ShouldPreserveUseListOrder=*/false,
+                             /*IsForDebug=*/true);
+      errs() << '\n';
     }
 
     // Find clang in order to create the bundle binary.
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index f6e26fa..9dfe8cf 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -32,6 +32,7 @@
   driver.cpp
   cc1_main.cpp
   cc1as_main.cpp
+  apinotes_main.cpp
 
   DEPENDS
   ${tablegen_deps}
@@ -39,6 +40,7 @@
 
 target_link_libraries(clang
   clangBasic
+  clangAPINotes
   clangCodeGen
   clangDriver
   clangFrontend
diff --git a/tools/driver/apinotes_main.cpp b/tools/driver/apinotes_main.cpp
new file mode 100644
index 0000000..930dc39
--- /dev/null
+++ b/tools/driver/apinotes_main.cpp
@@ -0,0 +1,154 @@
+//===-- api_notes.cpp - API Notes Driver ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file 
+/// This file provides conversion between the YAML (source) and binary forms 
+/// of API notes.
+///
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/APINotesYAMLCompiler.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Triple.h"
+
+using namespace llvm;
+namespace api_notes = clang::api_notes;
+
+int cc1apinotes_main(ArrayRef<const char *> Argv, const char *Argv0,
+                     void *MainAddr) {
+
+  // Mark all our options with this category, everything else (except for
+  // -version and -help) will be hidden.
+  static cl::OptionCategory APINotesCategory("API Notes options");
+
+  static cl::opt<api_notes::ActionType>
+  Action(cl::desc("Mode:"), cl::init(api_notes::ActionType::None),
+         cl::values(
+                    clEnumValN(api_notes::ActionType::YAMLToBinary,
+                               "yaml-to-binary", 
+                               "Convert YAML to binary format"),
+                    clEnumValN(api_notes::ActionType::BinaryToYAML,
+                               "binary-to-yaml",
+                               "Convert binary format to YAML"),
+                    clEnumValN(api_notes::ActionType::Dump,
+                               "dump", 
+                               "Parse and dump the output")),
+         cl::cat(APINotesCategory));
+
+  static cl::opt<std::string>
+  InputFilename(cl::Positional, cl::desc("<input file>"),
+                cl::Required, cl::cat(APINotesCategory));
+
+  static cl::opt<std::string>
+  Target("target", cl::desc("Generate binary format for the given target"),
+                   cl::cat(APINotesCategory));
+
+  static cl::opt<std::string>
+  OutputFilename("o", cl::desc("Output file name"), cl::cat(APINotesCategory));
+
+  cl::HideUnrelatedOptions(APINotesCategory);
+
+  SmallVector<const char *, 4> Args;
+  Args.push_back(Argv0);
+  Args.append(Argv.begin(), Argv.end());
+  cl::ParseCommandLineOptions(Args.size(),
+                              Args.data(),
+                              "Clang API Notes Tool\n");
+
+  if (Action == clang::api_notes::ActionType::None) {
+    errs() << "action required\n";
+    cl::PrintHelpMessage();
+    return 1;
+  }
+
+  auto fileBufOrErr = MemoryBuffer::getFile(InputFilename);
+  if (std::error_code EC = fileBufOrErr.getError()) {
+    llvm::errs() << "\n Could not open input file: " + EC.message() << '\n';
+    return true;
+  }
+  StringRef input = fileBufOrErr.get()->getBuffer();
+
+  switch (Action) {
+  case api_notes::ActionType::None:
+    llvm_unreachable("handled above");
+
+  case api_notes::ActionType::YAMLToBinary: {
+    if (OutputFilename.empty()) {
+      errs() << "output file is required\n";
+      cl::PrintHelpMessage();
+      return 1;
+    }
+
+    api_notes::OSType targetOS = api_notes::OSType::Absent;
+    // TODO: Check that we've specified the target.
+    if (!Target.empty()) {
+      llvm::Triple target(llvm::Triple::normalize(Target));
+      switch (target.getOS()) {
+        case llvm::Triple::Darwin:
+        case llvm::Triple::MacOSX:
+          targetOS = api_notes::OSType::OSX;
+          break;
+        case llvm::Triple::IOS:
+          targetOS = api_notes::OSType::IOS;
+          break;
+        case llvm::Triple::WatchOS:
+          targetOS = api_notes::OSType::WatchOS;
+          break;
+        case llvm::Triple::TvOS:
+          targetOS = api_notes::OSType::TvOS;
+          break;
+        default:
+          errs() << "target is not supported\n";
+          return 1;
+      }
+    }
+    std::error_code EC;
+    llvm::raw_fd_ostream os(OutputFilename, EC,
+                            llvm::sys::fs::OpenFlags::F_None);
+
+    if (api_notes::compileAPINotes(input, /*sourceFile=*/nullptr, os, targetOS))
+      return 1;
+    
+    os.flush();
+
+    return os.has_error();
+  }
+
+  case api_notes::ActionType::BinaryToYAML: {
+    if (OutputFilename.empty()) {
+      errs() << "output file required\n";
+      cl::PrintHelpMessage();
+      return 1;
+    }
+
+    std::error_code EC;
+    llvm::raw_fd_ostream os(OutputFilename, EC,
+                            llvm::sys::fs::OpenFlags::F_None);
+
+    if (api_notes::decompileAPINotes(std::move(fileBufOrErr.get()), os))
+      return 1;
+    
+    os.flush();
+
+    return os.has_error();
+  }
+
+  case api_notes::ActionType::Dump:
+    return api_notes::parseAndDumpAPINotes(input);
+  }
+
+  return 1;
+}
+
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 6161302..45b1ad3 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -198,6 +198,8 @@
                     void *MainAddr);
 extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
                       void *MainAddr);
+extern int cc1apinotes_main(ArrayRef<const char *> Argv, const char *Argv0,
+                            void *MainAddr);
 
 static void insertTargetAndModeArgs(StringRef Target, StringRef Mode,
                                     SmallVectorImpl<const char *> &ArgVector,
@@ -299,6 +301,8 @@
     return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
   if (Tool == "as")
     return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);
+  if (Tool == "apinotes")
+    return cc1apinotes_main(argv.slice(2), argv[0], GetExecutablePathVP);
 
   // Reject unknown tools.
   llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 2dd6703..5cad9dc 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -35,6 +35,7 @@
 
 set(LIBS
   clangAST
+  clangAPINotes
   clangBasic
   clangFrontend
   clangIndex
diff --git a/tools/libclang/CXIndexDataConsumer.cpp b/tools/libclang/CXIndexDataConsumer.cpp
index cb8aebf..6231742 100644
--- a/tools/libclang/CXIndexDataConsumer.cpp
+++ b/tools/libclang/CXIndexDataConsumer.cpp
@@ -1314,6 +1314,7 @@
   case SymbolLanguage::C: return CXIdxEntityLang_C;
   case SymbolLanguage::ObjC: return CXIdxEntityLang_ObjC;
   case SymbolLanguage::CXX: return CXIdxEntityLang_CXX;
+  case SymbolLanguage::Swift: llvm_unreachable("unexpected Swift symbol language");;
   }
   llvm_unreachable("invalid symbol language");
 }
diff --git a/unittests/AST/DeclTest.cpp b/unittests/AST/DeclTest.cpp
index 87aeef4..67b80ac 100644
--- a/unittests/AST/DeclTest.cpp
+++ b/unittests/AST/DeclTest.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "MatchVerifier.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
@@ -57,3 +58,53 @@
       "constexpr _Complex __uint128_t c = 0xffffffffffffffff;",
       Args));
 }
+
+TEST(Decl, Availability) {
+  const char *CodeStr = "int x __attribute__((availability(macosx, "
+        "introduced=10.2, deprecated=10.8, obsoleted=10.10)));";
+  auto Matcher = varDecl(hasName("x"));
+  std::vector<std::string> Args = {"-target", "x86_64-apple-macosx10.9"};
+
+  class AvailabilityVerifier : public MatchVerifier<clang::VarDecl> {
+  public:
+    void verify(const MatchFinder::MatchResult &Result,
+                const clang::VarDecl &Node) override {
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 1)) !=
+          clang::AR_NotYetIntroduced) {
+        setFailure("failed introduced");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 2)) !=
+          clang::AR_Available) {
+        setFailure("failed available (exact)");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 3)) !=
+          clang::AR_Available) {
+        setFailure("failed available");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 8)) !=
+          clang::AR_Deprecated) {
+        setFailure("failed deprecated (exact)");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 9)) !=
+          clang::AR_Deprecated) {
+        setFailure("failed deprecated");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 10)) !=
+          clang::AR_Unavailable) {
+        setFailure("failed obsoleted (exact)");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 11)) !=
+          clang::AR_Unavailable) {
+        setFailure("failed obsoleted");
+      }
+
+      if (Node.getAvailability() != clang::AR_Deprecated)
+        setFailure("did not default to target OS version");
+
+      setSuccess();
+    }
+  };
+
+  AvailabilityVerifier Verifier;
+  EXPECT_TRUE(Verifier.match(CodeStr, Matcher, Args, Lang_C));
+}
diff --git a/unittests/Lex/CMakeLists.txt b/unittests/Lex/CMakeLists.txt
index ef0f06c..2002fbf 100644
--- a/unittests/Lex/CMakeLists.txt
+++ b/unittests/Lex/CMakeLists.txt
@@ -13,6 +13,7 @@
   clangAST
   clangBasic
   clangLex
+  clangAPINotes
   clangParse
   clangSema
   )
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 27ab34c..8ba2ebc 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -1160,6 +1160,32 @@
     }
   };
 
+  class AttrArgument : public SimpleArgument {
+  public:
+    AttrArgument(const Record &Arg, StringRef Attr)
+      : SimpleArgument(Arg, Attr, "Attr *")
+    {}
+
+    void writePCHReadDecls(raw_ostream &OS) const override {
+      OS << "    AttrVec vec;\n"
+            "    ReadAttributes(F, vec, Record, Idx);\n"
+            "    assert(vec.size() == 1);\n"
+            "    Attr *" << getLowerName() << " = vec.front();";
+    }
+
+    void writePCHWrite(raw_ostream &OS) const override {
+      OS << "    AddAttributes(SA->get" << getUpperName() << "());";
+    }
+
+    void writeDump(raw_ostream &OS) const override {}
+  
+    void writeDumpChildren(raw_ostream &OS) const override {
+      OS << "    dumpAttr(SA->get" << getUpperName() << "());\n";
+    }
+
+    void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
+  };
+
 } // end anonymous namespace
 
 static std::unique_ptr<Argument>
@@ -1207,6 +1233,8 @@
     Ptr = llvm::make_unique<VariadicExprArgument>(Arg, Attr);
   else if (ArgName == "VersionArgument")
     Ptr = llvm::make_unique<VersionArgument>(Arg, Attr);
+  else if (ArgName == "AttrArgument")
+    Ptr = llvm::make_unique<AttrArgument>(Arg, Attr);
 
   if (!Ptr) {
     // Search in reverse order so that the most-derived type is handled first.
diff --git a/utils/perf-training/lit.cfg b/utils/perf-training/lit.cfg
index edae551..16c9367 100644
--- a/utils/perf-training/lit.cfg
+++ b/utils/perf-training/lit.cfg
@@ -7,7 +7,7 @@
 def getSysrootFlagsOnDarwin(config, lit_config):
     # On Darwin, support relocatable SDKs by providing Clang with a
     # default system root path.
-    if 'darwin' in config.target_triple:
+    if lit.util.isMacOSTriple(config.target_triple):
         try:
             out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
             res = 0
diff --git a/utils/perf-training/order-files.lit.cfg b/utils/perf-training/order-files.lit.cfg
index a4fd812..3ea3c9e 100644
--- a/utils/perf-training/order-files.lit.cfg
+++ b/utils/perf-training/order-files.lit.cfg
@@ -8,7 +8,7 @@
 def getSysrootFlagsOnDarwin(config, lit_config):
     # On Darwin, support relocatable SDKs by providing Clang with a
     # default system root path.
-    if 'darwin' in config.target_triple:
+    if lit.util.isMacOSTriple(config.target_triple):
         try:
             out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
             res = 0