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/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 2e99f39..127c324 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
 #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
 
+#include "clang/Basic/Module.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclBase.h"
 #include "llvm/ADT/DenseMap.h"
@@ -149,20 +150,20 @@
     StringRef PCHModuleName;
     StringRef Path;
     StringRef ASTFile;
-    uint64_t Signature = 0;
+    ASTFileSignature Signature;
     const Module *ClangModule = nullptr;
 
   public:
     ASTSourceDescriptor(){};
     ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
-                        uint64_t Signature)
+                        ASTFileSignature Signature)
         : PCHModuleName(std::move(Name)), Path(std::move(Path)),
           ASTFile(std::move(ASTFile)), Signature(Signature){};
     ASTSourceDescriptor(const Module &M);
     std::string getModuleName() const;
     StringRef getPath() const { return Path; }
     StringRef getASTFile() const { return ASTFile; }
-    uint64_t getSignature() const { return Signature; }
+    ASTFileSignature getSignature() const { return Signature; }
     const Module *getModuleOrNull() const { return ClangModule; }
   };
 
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..aeaa824 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -88,10 +88,12 @@
   "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_lock_failure : Error<
-  "could not acquire lock file for module '%0': %1">, DefaultFatal;
-def err_module_lock_timeout : Error<
-  "timed out waiting to acquire lock file for module '%0'">, DefaultFatal;
+def err_module_shadowed : Error<
+  "import of shadowed module '%0'">;
+def remark_module_lock_failure : Remark<
+  "could not acquire lock file for module '%0': %1">, InGroup<ModuleBuild>;
+def remark_module_lock_timeout : Remark<
+  "timed out waiting to acquire lock file for module '%0'">, InGroup<ModuleBuild>;
 def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, 
   DefaultFatal;
 def err_module_prebuilt : 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/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 066a1f5..46adf2c 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -125,6 +125,11 @@
   "duplicate module file extension block name '%0'">,
   InGroup<ModuleFileExtension>;
 
+def warn_module_system_bit_conflict : Warning<
+  "module file '%0' was validated as a system module and is now being imported "
+  "as a non-system module; any difference in diagnostic options will be ignored">,
+  InGroup<ModuleConflict>;
+
 } // let CategoryName
 } // let Component
 
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/MemoryBufferCache.h b/include/clang/Basic/MemoryBufferCache.h
new file mode 100644
index 0000000..c79c3c4
--- /dev/null
+++ b/include/clang/Basic/MemoryBufferCache.h
@@ -0,0 +1,80 @@
+//===- MemoryBufferCache.h - Cache for loaded memory buffers ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
+#define LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include <memory>
+
+namespace llvm {
+class MemoryBuffer;
+} // end namespace llvm
+
+namespace clang {
+
+/// Manage memory buffers across multiple users.
+///
+/// Ensures that multiple users have a consistent view of each buffer.  This is
+/// used by \a CompilerInstance when building PCMs to ensure that each \a
+/// ModuleManager sees the same files.
+///
+/// \a finalizeCurrentBuffers() should be called before creating a new user.
+/// This locks in the current buffers, ensuring that no buffer that has already
+/// been accessed can be purged, preventing use-after-frees.
+class MemoryBufferCache : public llvm::RefCountedBase<MemoryBufferCache> {
+  struct BufferEntry {
+    std::unique_ptr<llvm::MemoryBuffer> Buffer;
+
+    /// Track the timeline of when this was added to the cache.
+    unsigned Index;
+  };
+
+  /// Cache of buffers.
+  llvm::StringMap<BufferEntry> Buffers;
+
+  /// Monotonically increasing index.
+  unsigned NextIndex = 0;
+
+  /// Bumped to prevent "older" buffers from being removed.
+  unsigned FirstRemovableIndex = 0;
+
+public:
+  /// Store the Buffer under the Filename.
+  ///
+  /// \pre There is not already buffer is not already in the cache.
+  /// \return a reference to the buffer as a convenience.
+  llvm::MemoryBuffer &addBuffer(llvm::StringRef Filename,
+                                std::unique_ptr<llvm::MemoryBuffer> Buffer);
+
+  /// Try to remove a buffer from the cache.
+  ///
+  /// \return false on success, iff \c !isBufferFinal().
+  bool tryToRemoveBuffer(llvm::StringRef Filename);
+
+  /// Get a pointer to the buffer if it exists; else nullptr.
+  llvm::MemoryBuffer *lookupBuffer(llvm::StringRef Filename);
+
+  /// Check whether the buffer is final.
+  ///
+  /// \return true iff \a finalizeCurrentBuffers() has been called since the
+  /// buffer was added.  This prevents buffers from being removed.
+  bool isBufferFinal(llvm::StringRef Filename);
+
+  /// Finalize the current buffers in the cache.
+  ///
+  /// Should be called when creating a new user to ensure previous uses aren't
+  /// invalidated.
+  void finalizeCurrentBuffers();
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 31c5c7e..38004fc 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -42,7 +42,17 @@
   
 /// \brief Describes the name of a module.
 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
-  
+
+/// The signature of a module, which is a hash of the AST content.
+struct ASTFileSignature : std::array<uint32_t, 5> {
+  ASTFileSignature(std::array<uint32_t, 5> S = {{0}})
+      : std::array<uint32_t, 5>(std::move(S)) {}
+
+  explicit operator bool() const {
+    return *this != std::array<uint32_t, 5>({{0}});
+  }
+};
+
 /// \brief Describes a module or submodule.
 class Module {
 public:
@@ -65,7 +75,7 @@
   llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
 
   /// \brief The module signature.
-  uint64_t Signature;
+  ASTFileSignature Signature;
 
   /// \brief The name of the umbrella entry, as written in the module map.
   std::string UmbrellaAsWritten;
@@ -147,6 +157,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 +193,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 +341,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/CC1Options.td b/include/clang/Driver/CC1Options.td
index ab296eb..cd446ec 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -658,6 +658,8 @@
   HelpText<"Disable standard system #include directories">;
 def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">,
   HelpText<"Disable the module hash">;
+def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">,
+  HelpText<"Enable hashing the content of a module file">;
 def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
   HelpText<"Add directory to the C SYSTEM include search path">;
 def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
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/Format/Format.h b/include/clang/Format/Format.h
index 6c6458b..d34ca2f 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -465,8 +465,6 @@
     LK_Java,
     /// Should be used for JavaScript.
     LK_JavaScript,
-    /// Should be used for ObjC code.
-    LK_ObjC,
     /// Should be used for Protocol Buffers
     /// (https://developers.google.com/protocol-buffers/).
     LK_Proto,
@@ -854,16 +852,13 @@
 /// == "file".
 /// \param[in] FallbackStyle The name of a predefined style used to fallback to
 /// in case the style can't be determined from \p StyleName.
-/// \param[in] Code The actual code to be formatted. Used to determine the
-/// language if the filename isn't sufficient.
 /// \param[in] FS The underlying file system, in which the file resides. By
 /// default, the file system is the real file system.
 ///
 /// \returns FormatStyle as specified by ``StyleName``. If no style could be
 /// determined, the default is LLVM Style (see ``getLLVMStyle()``).
 FormatStyle getStyle(StringRef StyleName, StringRef FileName,
-                     StringRef FallbackStyle, StringRef Code = "",
-                     vfs::FileSystem *FS = nullptr);
+                     StringRef FallbackStyle, vfs::FileSystem *FS = nullptr);
 
 // \brief Returns a string representation of ``Language``.
 inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index b1cdb46..2a8df1b 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -51,6 +51,7 @@
 class FileEntry;
 class FileManager;
 class HeaderSearch;
+class MemoryBufferCache;
 class Preprocessor;
 class PCHContainerOperations;
 class PCHContainerReader;
@@ -84,6 +85,7 @@
   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
   IntrusiveRefCntPtr<FileManager>         FileMgr;
   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
+  IntrusiveRefCntPtr<MemoryBufferCache>   PCMCache;
   std::unique_ptr<HeaderSearch>           HeaderInfo;
   IntrusiveRefCntPtr<TargetInfo>          Target;
   std::shared_ptr<Preprocessor>           PP;
@@ -519,6 +521,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..62a5fd2 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -44,6 +44,7 @@
 class FileEntry;
 class FileManager;
 class FrontendAction;
+class MemoryBufferCache;
 class Module;
 class Preprocessor;
 class Sema;
@@ -90,6 +91,9 @@
   /// The source manager.
   IntrusiveRefCntPtr<SourceManager> SourceMgr;
 
+  /// The cache of PCM files.
+  IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+
   /// The preprocessor.
   std::shared_ptr<Preprocessor> PP;
 
@@ -142,13 +146,13 @@
 
   /// \brief Whether we should (re)build the global module index once we
   /// have finished with this translation unit.
-  bool BuildGlobalModuleIndex;
+  bool BuildGlobalModuleIndex = false;
 
   /// \brief We have a full global module index, with all modules.
-  bool HaveFullGlobalModuleIndex;
+  bool HaveFullGlobalModuleIndex = false;
 
   /// \brief One or more modules failed to build.
-  bool ModuleBuildFailed;
+  bool ModuleBuildFailed = false;
 
   /// \brief Holds information about the output file.
   ///
@@ -178,7 +182,7 @@
   explicit CompilerInstance(
       std::shared_ptr<PCHContainerOperations> PCHContainerOps =
           std::make_shared<PCHContainerOperations>(),
-      bool BuildingModule = false);
+      MemoryBufferCache *SharedPCMCache = nullptr);
   ~CompilerInstance() override;
 
   /// @name High-Level Operations
@@ -292,6 +296,13 @@
     return Invocation->getHeaderSearchOptsPtr();
   }
 
+  APINotesOptions &getAPINotesOpts() {
+    return Invocation->getAPINotesOpts();
+  }
+  const APINotesOptions &getAPINotesOpts() const {
+    return Invocation->getAPINotesOpts();
+  }
+
   LangOptions &getLangOpts() {
     return *Invocation->getLangOpts();
   }
@@ -783,6 +794,8 @@
   }
 
   void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
+
+  MemoryBufferCache &getPCMCache() const { return *PCMCache; }
 };
 
 } // end namespace clang
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/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h
index d323fb3..f9a7350 100644
--- a/include/clang/Frontend/PCHContainerOperations.h
+++ b/include/clang/Frontend/PCHContainerOperations.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
 #define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
 
+#include "clang/Basic/Module.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -29,7 +30,7 @@
 class CompilerInstance;
 
 struct PCHBuffer {
-  uint64_t Signature;
+  ASTFileSignature Signature;
   llvm::SmallVector<char, 0> Data;
   bool IsComplete;
 };
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/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 51983b9..4df3e78 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -406,8 +406,7 @@
   /// \return false if \#including the file will have no effect or true
   /// if we should include it.
   bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
-                              bool isImport, bool ModulesEnabled,
-                              Module *CorrespondingModule);
+                              bool isImport, Module *CorrespondingModule);
 
   /// \brief Return whether the specified file is a normal header,
   /// a system header, or a C++ friendly system header.
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index e999805..ca3a84e 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -178,6 +178,8 @@
 
   unsigned ModulesValidateDiagnosticOptions : 1;
 
+  unsigned ModulesHashContent : 1;
+
   HeaderSearchOptions(StringRef _Sysroot = "/")
       : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
         ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
@@ -186,8 +188,8 @@
         UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
         UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
         ModulesValidateOncePerBuildSession(false),
-        ModulesValidateSystemHeaders(false),
-        UseDebugInfo(false), ModulesValidateDiagnosticOptions(true) {}
+        ModulesValidateSystemHeaders(false), UseDebugInfo(false),
+        ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {}
 
   /// AddPath - Add the \p Path path to the specified \p Group list.
   void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
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..e5400c6 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;
@@ -316,14 +328,6 @@
     BuiltinIncludeDir = Dir;
   }
 
-  /// \brief Get the directory that contains Clang-supplied include files.
-  const DirectoryEntry *getBuiltinDir() const {
-    return BuiltinIncludeDir;
-  }
-
-  /// \brief Is this a compiler builtin header?
-  static bool isBuiltinHeader(StringRef FileName);
-
   /// \brief Add a module map callback.
   void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) {
     Callbacks.push_back(std::move(Callback));
@@ -440,6 +444,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/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 7ce1aad..ee4b3c8 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -47,6 +47,7 @@
 class FileManager;
 class FileEntry;
 class HeaderSearch;
+class MemoryBufferCache;
 class PragmaNamespace;
 class PragmaHandler;
 class CommentHandler;
@@ -102,6 +103,7 @@
   const TargetInfo  *AuxTarget;
   FileManager       &FileMgr;
   SourceManager     &SourceMgr;
+  MemoryBufferCache &PCMCache;
   std::unique_ptr<ScratchBuffer> ScratchBuf;
   HeaderSearch      &HeaderInfo;
   ModuleLoader      &TheModuleLoader;
@@ -652,6 +654,7 @@
 public:
   Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
                DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
+               MemoryBufferCache &PCMCache,
                HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
                IdentifierInfoLookup *IILookup = nullptr,
                bool OwnsHeaderSearch = false,
@@ -691,6 +694,7 @@
   const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
   FileManager &getFileManager() const { return FileMgr; }
   SourceManager &getSourceManager() const { return SourceMgr; }
+  MemoryBufferCache &getPCMCache() const { return PCMCache; }
   HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
 
   IdentifierTable &getIdentifierTable() { return Identifiers; }
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index fe15902..5fae263 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,
@@ -2365,10 +2373,10 @@
                                 AR_DeclspecAttributesParsed
   };
 
-  void ParseTypeQualifierListOpt(DeclSpec &DS,
-                                 unsigned AttrReqs = AR_AllAttributesParsed,
-                                 bool AtomicAllowed = true,
-                                 bool IdentifierRequired = false);
+  void ParseTypeQualifierListOpt(
+      DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
+      bool AtomicAllowed = true, bool IdentifierRequired = false,
+      Optional<llvm::function_ref<void()>> CodeCompletionHandler = None);
   void ParseDirectDeclarator(Declarator &D);
   void ParseDecompositionDeclarator(Declarator &D);
   void ParseParenDeclarator(Declarator &D);
@@ -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..4f46fbf 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);
@@ -9777,6 +9824,8 @@
   void CodeCompletePostfixExpression(Scope *S, ExprResult LHS);
   void CodeCompleteTag(Scope *S, unsigned TagSpec);
   void CodeCompleteTypeQualifiers(DeclSpec &DS);
+  void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
+                                      const VirtSpecifiers *VS = nullptr);
   void CodeCompleteBracketDeclarator(Scope *S);
   void CodeCompleteCase(Scope *S);
   void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args);
@@ -10107,6 +10156,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/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index acbd6d1..d431c15 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -226,7 +226,7 @@
 
       /// \brief The block containing the detailed preprocessing record.
       PREPROCESSOR_DETAIL_BLOCK_ID,
-      
+
       /// \brief The block containing the submodule structure.
       SUBMODULE_BLOCK_ID,
 
@@ -253,6 +253,10 @@
 
       /// \brief A block containing a module file extension.
       EXTENSION_BLOCK_ID,
+
+      /// A block containing unhashed contents. It currently holds Diagnostic
+      /// Options and Signature.
+      UNHASHED_CONTROL_BLOCK_ID,
     };
 
     /// \brief Record types that occur within the control block.
@@ -288,9 +292,6 @@
       /// AST file.
       MODULE_MAP_FILE,
 
-      /// \brief Record code for the signature that identifiers this AST file.
-      SIGNATURE,
-
       /// \brief Record code for the module build directory.
       MODULE_DIRECTORY,
     };
@@ -309,9 +310,6 @@
       /// \brief Record code for the target options table.
       TARGET_OPTIONS,
 
-      /// \brief Record code for the diagnostic options table.
-      DIAGNOSTIC_OPTIONS,
-
       /// \brief Record code for the filesystem options table.
       FILE_SYSTEM_OPTIONS,
 
@@ -322,6 +320,18 @@
       PREPROCESSOR_OPTIONS,
     };
 
+    /// Record codes for the unhashed control block.
+    enum UnhashedControlBlockRecordTypes {
+      /// Record code for the signature that identifiers this AST file.
+      SIGNATURE = 1,
+
+      /// Record code for the diagnostic options table.
+      DIAGNOSTIC_OPTIONS,
+
+      /// Record code for \#pragma diagnostic mappings.
+      DIAG_PRAGMA_MAPPINGS,
+    };
+
     /// \brief Record code for extension blocks.
     enum ExtensionBlockRecordTypes {
       /// Metadata describing this particular extension.
@@ -493,8 +503,7 @@
 
       // ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records.
 
-      /// \brief Record code for \#pragma diagnostic mappings.
-      DIAG_PRAGMA_MAPPINGS = 32,
+      // ID 32 used to be the code for \#pragma diagnostic mappings.
 
       /// \brief Record code for special CUDA declarations.
       CUDA_SPECIAL_DECL_REFS = 33,
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..e174517 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -408,6 +408,9 @@
   /// \brief The module manager which manages modules and their dependencies
   ModuleManager ModuleMgr;
 
+  /// The cache that manages memory buffers for PCM files.
+  MemoryBufferCache &PCMCache;
+
   /// \brief A dummy identifier resolver used to merge TU-scope declarations in
   /// C, for the cases where we don't have a Sema object to provide a real
   /// identifier resolver.
@@ -1174,7 +1177,7 @@
                             SourceLocation ImportLoc, ModuleFile *ImportedBy,
                             SmallVectorImpl<ImportedModule> &Loaded,
                             off_t ExpectedSize, time_t ExpectedModTime,
-                            serialization::ASTFileSignature ExpectedSignature,
+                            ASTFileSignature ExpectedSignature,
                             unsigned ClientLoadCapabilities);
   ASTReadResult ReadControlBlock(ModuleFile &F,
                                  SmallVectorImpl<ImportedModule> &Loaded,
@@ -1183,7 +1186,22 @@
   static ASTReadResult ReadOptionsBlock(
       llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
       bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
-      std::string &SuggestedPredefines, bool ValidateDiagnosticOptions);
+      std::string &SuggestedPredefines);
+
+  /// Read the unhashed control block.
+  ///
+  /// This has no effect on \c F.Stream, instead creating a fresh cursor from
+  /// \c F.Data and reading ahead.
+  ASTReadResult readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
+                                         unsigned ClientLoadCapabilities);
+
+  static ASTReadResult
+  readUnhashedControlBlockImpl(ModuleFile *F, llvm::StringRef StreamData,
+                               unsigned ClientLoadCapabilities,
+                               bool AllowCompatibleConfigurationMismatch,
+                               ASTReaderListener *Listener,
+                               bool ValidateDiagnosticOptions);
+
   ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
   ASTReadResult ReadExtensionBlock(ModuleFile &F);
   bool ParseLineTable(ModuleFile &F, const RecordData &Record);
@@ -1268,6 +1286,7 @@
   llvm::iterator_range<PreprocessingRecord::iterator>
   getModulePreprocessedEntities(ModuleFile &Mod) const;
 
+public:
   class ModuleDeclIterator
       : public llvm::iterator_adaptor_base<
             ModuleDeclIterator, const serialization::LocalDeclID *,
@@ -1298,6 +1317,7 @@
   llvm::iterator_range<ModuleDeclIterator>
   getModuleFileLevelDecls(ModuleFile &Mod);
 
+private:
   void PassInterestingDeclsToConsumer();
   void PassInterestingDeclToConsumer(Decl *D);
 
@@ -1633,7 +1653,7 @@
     unsigned Result = 0;
     for (ModuleConstIterator I = ModuleMgr.begin(),
         E = ModuleMgr.end(); I != E; ++I) {
-      Result += (*I)->NumPreprocessedEntities;
+      Result += I->NumPreprocessedEntities;
     }
 
     return Result;
@@ -2189,6 +2209,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/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 0d6b026..57b0a65 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -54,6 +54,7 @@
 class OpaqueValueExpr;
 class OpenCLOptions;
 class ASTReader;
+class MemoryBufferCache;
 class Module;
 class ModuleFileExtension;
 class ModuleFileExtensionWriter;
@@ -106,6 +107,12 @@
   /// \brief The bitstream writer used to emit this precompiled header.
   llvm::BitstreamWriter &Stream;
 
+  /// The buffer associated with the bitstream.
+  const SmallVectorImpl<char> &Buffer;
+
+  /// \brief The PCM manager which manages memory buffers for pcm files.
+  MemoryBufferCache &PCMCache;
+
   /// \brief The ASTContext we're writing.
   ASTContext *Context = nullptr;
 
@@ -424,8 +431,16 @@
   void WriteSubStmt(Stmt *S);
 
   void WriteBlockInfoBlock();
-  uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context,
-                             StringRef isysroot, const std::string &OutputFile);
+  void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+                         StringRef isysroot, const std::string &OutputFile);
+
+  /// Write out the signature and diagnostic options, and return the signature.
+  ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP,
+                                             ASTContext &Context);
+
+  /// Calculate hash of the pcm content.
+  static ASTFileSignature createSignature(StringRef Bytes);
+
   void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts,
                        bool Modules);
   void WriteSourceManagerBlock(SourceManager &SourceMgr,
@@ -492,14 +507,15 @@
   void WriteDeclAbbrevs();
   void WriteDecl(ASTContext &Context, Decl *D);
 
-  uint64_t WriteASTCore(Sema &SemaRef,
-                        StringRef isysroot, const std::string &OutputFile,
-                        Module *WritingModule);
+  ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot,
+                                const std::string &OutputFile,
+                                Module *WritingModule);
 
 public:
   /// \brief Create a new precompiled header writer that outputs to
   /// the given bitstream.
-  ASTWriter(llvm::BitstreamWriter &Stream,
+  ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
+            MemoryBufferCache &PCMCache,
             ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
             bool IncludeTimestamps = true);
   ~ASTWriter() override;
@@ -525,9 +541,9 @@
   ///
   /// \return the module signature, which eventually will be a hash of
   /// the module but currently is merely a random 32-bit number.
-  uint64_t WriteAST(Sema &SemaRef, const std::string &OutputFile,
-                    Module *WritingModule, StringRef isysroot,
-                    bool hasErrors = false);
+  ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile,
+                            Module *WritingModule, StringRef isysroot,
+                            bool hasErrors = false);
 
   /// \brief Emit a token.
   void AddToken(const Token &Tok, RecordDataImpl &Record);
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 58b3149..d28a2f3 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_SERIALIZATION_MODULE_H
 
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/Module.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "clang/Serialization/ContinuousRangeMap.h"
@@ -89,8 +90,6 @@
   bool isNotFound() const { return Val.getInt() == NotFound; }
 };
 
-typedef unsigned ASTFileSignature;
-
 /// \brief Information about a module that has been loaded by the ASTReader.
 ///
 /// Each instance of the Module class corresponds to a single AST file, which
@@ -100,13 +99,14 @@
 /// other modules.
 class ModuleFile {
 public:
-  ModuleFile(ModuleKind Kind, unsigned Generation);
+  ModuleFile(ModuleKind Kind, unsigned Generation)
+      : Kind(Kind), Generation(Generation) {}
   ~ModuleFile();
 
   // === General information ===
 
   /// \brief The index of this module in the list of modules.
-  unsigned Index;
+  unsigned Index = 0;
 
   /// \brief The type of this module.
   ModuleKind Kind;
@@ -144,34 +144,34 @@
   std::string ModuleMapPath;
 
   /// \brief Whether this precompiled header is a relocatable PCH file.
-  bool RelocatablePCH;
+  bool RelocatablePCH = false;
 
   /// \brief Whether timestamps are included in this module file.
-  bool HasTimestamps;
+  bool HasTimestamps = false;
 
   /// \brief The file entry for the module file.
-  const FileEntry *File;
+  const FileEntry *File = nullptr;
 
-  /// \brief The signature of the module file, which may be used along with size
+  /// The signature of the module file, which may be used instead of the size
   /// and modification time to identify this particular file.
   ASTFileSignature Signature;
 
   /// \brief Whether this module has been directly imported by the
   /// user.
-  bool DirectlyImported;
+  bool DirectlyImported = false;
 
   /// \brief The generation of which this module file is a part.
   unsigned Generation;
   
-  /// \brief The memory buffer that stores the data associated with
-  /// this AST file.
-  std::unique_ptr<llvm::MemoryBuffer> Buffer;
+  /// The memory buffer that stores the data associated with
+  /// this AST file, owned by the PCMCache in the ModuleManager.
+  llvm::MemoryBuffer *Buffer;
 
   /// \brief The size of this file, in bits.
-  uint64_t SizeInBits;
+  uint64_t SizeInBits = 0;
 
   /// \brief The global bit offset (or base) of this module
-  uint64_t GlobalBitOffset;
+  uint64_t GlobalBitOffset = 0;
 
   /// \brief The serialized bitstream data for this file.
   StringRef Data;
@@ -205,16 +205,20 @@
   llvm::BitstreamCursor InputFilesCursor;
 
   /// \brief Offsets for all of the input file entries in the AST file.
-  const llvm::support::unaligned_uint64_t *InputFileOffsets;
+  const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr;
 
   /// \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.
   ///
   /// The time is specified in seconds since the start of the Epoch.
-  uint64_t InputFilesValidationTimestamp;
+  uint64_t InputFilesValidationTimestamp = 0;
 
   // === Source Locations ===
 
@@ -222,17 +226,17 @@
   llvm::BitstreamCursor SLocEntryCursor;
 
   /// \brief The number of source location entries in this AST file.
-  unsigned LocalNumSLocEntries;
+  unsigned LocalNumSLocEntries = 0;
 
   /// \brief The base ID in the source manager's view of this module.
-  int SLocEntryBaseID;
+  int SLocEntryBaseID = 0;
 
   /// \brief The base offset in the source manager's view of this module.
-  unsigned SLocEntryBaseOffset;
+  unsigned SLocEntryBaseOffset = 0;
 
   /// \brief Offsets for all of the source location entries in the
   /// AST file.
-  const uint32_t *SLocEntryOffsets;
+  const uint32_t *SLocEntryOffsets = nullptr;
 
   /// \brief SLocEntries that we're going to preload.
   SmallVector<uint64_t, 4> PreloadSLocEntries;
@@ -243,17 +247,17 @@
   // === Identifiers ===
 
   /// \brief The number of identifiers in this AST file.
-  unsigned LocalNumIdentifiers;
+  unsigned LocalNumIdentifiers = 0;
 
   /// \brief Offsets into the identifier table data.
   ///
   /// This array is indexed by the identifier ID (-1), and provides
   /// the offset into IdentifierTableData where the string data is
   /// stored.
-  const uint32_t *IdentifierOffsets;
+  const uint32_t *IdentifierOffsets = nullptr;
 
   /// \brief Base identifier ID for identifiers local to this module.
-  serialization::IdentID BaseIdentifierID;
+  serialization::IdentID BaseIdentifierID = 0;
 
   /// \brief Remapping table for identifier IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap;
@@ -262,11 +266,11 @@
   ///
   /// This pointer points into a memory buffer, where the on-disk hash
   /// table for identifiers actually lives.
-  const char *IdentifierTableData;
+  const char *IdentifierTableData = nullptr;
 
   /// \brief A pointer to an on-disk hash table of opaque type
   /// IdentifierHashTable.
-  void *IdentifierLookupTable;
+  void *IdentifierLookupTable = nullptr;
 
   /// \brief Offsets of identifiers that we're going to preload within
   /// IdentifierTableData.
@@ -279,23 +283,23 @@
   llvm::BitstreamCursor MacroCursor;
 
   /// \brief The number of macros in this AST file.
-  unsigned LocalNumMacros;
+  unsigned LocalNumMacros = 0;
 
   /// \brief Offsets of macros in the preprocessor block.
   ///
   /// This array is indexed by the macro ID (-1), and provides
   /// the offset into the preprocessor block where macro definitions are
   /// stored.
-  const uint32_t *MacroOffsets;
+  const uint32_t *MacroOffsets = nullptr;
 
   /// \brief Base macro ID for macros local to this module.
-  serialization::MacroID BaseMacroID;
+  serialization::MacroID BaseMacroID = 0;
 
   /// \brief Remapping table for macro IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> MacroRemap;
 
   /// \brief The offset of the start of the set of defined macros.
-  uint64_t MacroStartOffset;
+  uint64_t MacroStartOffset = 0;
 
   // === Detailed PreprocessingRecord ===
 
@@ -304,40 +308,40 @@
   llvm::BitstreamCursor PreprocessorDetailCursor;
 
   /// \brief The offset of the start of the preprocessor detail cursor.
-  uint64_t PreprocessorDetailStartOffset;
+  uint64_t PreprocessorDetailStartOffset = 0;
 
   /// \brief Base preprocessed entity ID for preprocessed entities local to
   /// this module.
-  serialization::PreprocessedEntityID BasePreprocessedEntityID;
+  serialization::PreprocessedEntityID BasePreprocessedEntityID = 0;
 
   /// \brief Remapping table for preprocessed entity IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
 
-  const PPEntityOffset *PreprocessedEntityOffsets;
-  unsigned NumPreprocessedEntities;
+  const PPEntityOffset *PreprocessedEntityOffsets = nullptr;
+  unsigned NumPreprocessedEntities = 0;
 
   // === Header search information ===
 
   /// \brief The number of local HeaderFileInfo structures.
-  unsigned LocalNumHeaderFileInfos;
+  unsigned LocalNumHeaderFileInfos = 0;
 
   /// \brief Actual data for the on-disk hash table of header file
   /// information.
   ///
   /// This pointer points into a memory buffer, where the on-disk hash
   /// table for header file information actually lives.
-  const char *HeaderFileInfoTableData;
+  const char *HeaderFileInfoTableData = nullptr;
 
   /// \brief The on-disk hash table that contains information about each of
   /// the header files.
-  void *HeaderFileInfoTable;
+  void *HeaderFileInfoTable = nullptr;
 
   // === Submodule information ===  
   /// \brief The number of submodules in this module.
-  unsigned LocalNumSubmodules;
+  unsigned LocalNumSubmodules = 0;
   
   /// \brief Base submodule ID for submodules local to this module.
-  serialization::SubmoduleID BaseSubmoduleID;
+  serialization::SubmoduleID BaseSubmoduleID = 0;
   
   /// \brief Remapping table for submodule IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap;
@@ -347,14 +351,14 @@
   /// \brief The number of selectors new to this file.
   ///
   /// This is the number of entries in SelectorOffsets.
-  unsigned LocalNumSelectors;
+  unsigned LocalNumSelectors = 0;
 
   /// \brief Offsets into the selector lookup table's data array
   /// where each selector resides.
-  const uint32_t *SelectorOffsets;
+  const uint32_t *SelectorOffsets = nullptr;
 
   /// \brief Base selector ID for selectors local to this module.
-  serialization::SelectorID BaseSelectorID;
+  serialization::SelectorID BaseSelectorID = 0;
 
   /// \brief Remapping table for selector IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> SelectorRemap;
@@ -362,14 +366,14 @@
   /// \brief A pointer to the character data that comprises the selector table
   ///
   /// The SelectorOffsets table refers into this memory.
-  const unsigned char *SelectorLookupTableData;
+  const unsigned char *SelectorLookupTableData = nullptr;
 
   /// \brief A pointer to an on-disk hash table of opaque type
   /// ASTSelectorLookupTable.
   ///
   /// This hash table provides the IDs of all selectors, and the associated
   /// instance and factory methods.
-  void *SelectorLookupTable;
+  void *SelectorLookupTable = nullptr;
 
   // === Declarations ===
 
@@ -379,14 +383,14 @@
   llvm::BitstreamCursor DeclsCursor;
 
   /// \brief The number of declarations in this AST file.
-  unsigned LocalNumDecls;
+  unsigned LocalNumDecls = 0;
 
   /// \brief Offset of each declaration within the bitstream, indexed
   /// by the declaration ID (-1).
-  const DeclOffset *DeclOffsets;
+  const DeclOffset *DeclOffsets = nullptr;
 
   /// \brief Base declaration ID for declarations local to this module.
-  serialization::DeclID BaseDeclID;
+  serialization::DeclID BaseDeclID = 0;
 
   /// \brief Remapping table for declaration IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> DeclRemap;
@@ -401,15 +405,15 @@
   llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
 
   /// \brief Array of file-level DeclIDs sorted by file.
-  const serialization::DeclID *FileSortedDecls;
-  unsigned NumFileSortedDecls;
+  const serialization::DeclID *FileSortedDecls = nullptr;
+  unsigned NumFileSortedDecls = 0;
 
   /// \brief Array of category list location information within this 
   /// module file, sorted by the definition ID.
-  const serialization::ObjCCategoriesInfo *ObjCCategoriesMap;
+  const serialization::ObjCCategoriesInfo *ObjCCategoriesMap = nullptr;
   
   /// \brief The number of redeclaration info entries in ObjCCategoriesMap.
-  unsigned LocalNumObjCCategoriesInMap;
+  unsigned LocalNumObjCCategoriesInMap = 0;
   
   /// \brief The Objective-C category lists for categories known to this
   /// module.
@@ -418,15 +422,15 @@
   // === Types ===
 
   /// \brief The number of types in this AST file.
-  unsigned LocalNumTypes;
+  unsigned LocalNumTypes = 0;
 
   /// \brief Offset of each type within the bitstream, indexed by the
   /// type ID, or the representation of a Type*.
-  const uint32_t *TypeOffsets;
+  const uint32_t *TypeOffsets = nullptr;
 
   /// \brief Base type ID for types local to this module as represented in
   /// the global type ID space.
-  serialization::TypeID BaseTypeIndex;
+  serialization::TypeID BaseTypeIndex = 0;
 
   /// \brief Remapping table for type IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> TypeRemap;
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 1c4d88e..da6bedc 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -19,10 +19,12 @@
 #include "clang/Serialization/Module.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/iterator.h"
 
 namespace clang { 
 
 class GlobalModuleIndex;
+class MemoryBufferCache;
 class ModuleMap;
 class PCHContainerReader;
 
@@ -32,7 +34,7 @@
 class ModuleManager {
   /// \brief The chain of AST files, in the order in which we started to load
   /// them (this order isn't really useful for anything).
-  SmallVector<ModuleFile *, 2> Chain;
+  SmallVector<std::unique_ptr<ModuleFile>, 2> Chain;
 
   /// \brief The chain of non-module PCH files. The first entry is the one named
   /// by the user, the last one is the one that doesn't depend on anything
@@ -50,6 +52,9 @@
   /// FileEntry *.
   FileManager &FileMgr;
 
+  /// Cache of PCM files.
+  IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+
   /// \brief Knows how to unwrap module containers.
   const PCHContainerReader &PCHContainerRdr;
 
@@ -111,12 +116,18 @@
   void returnVisitState(VisitState *State);
 
 public:
-  typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator;
-  typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator;
-  typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>
+      ModuleIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>
+      ModuleConstIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>
+      ModuleReverseIterator;
   typedef std::pair<uint32_t, StringRef> ModuleOffset;
 
-  explicit ModuleManager(FileManager &FileMgr,
+  explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
                          const PCHContainerReader &PCHContainerRdr);
   ~ModuleManager();
 
@@ -136,7 +147,8 @@
   ModuleReverseIterator rend() { return Chain.rend(); }
 
   /// \brief A range covering the PCH and preamble module files loaded.
-  llvm::iterator_range<ModuleConstIterator> pch_modules() const {
+  llvm::iterator_range<SmallVectorImpl<ModuleFile *>::const_iterator>
+  pch_modules() const {
     return llvm::make_range(PCHChain.begin(), PCHChain.end());
   }
 
@@ -220,8 +232,8 @@
                             ModuleFile *&Module,
                             std::string &ErrorStr);
 
-  /// \brief Remove the given set of modules.
-  void removeModules(ModuleIterator first, ModuleIterator last,
+  /// \brief Remove the modules starting from First (to the end).
+  void removeModules(ModuleIterator First,
                      llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
                      ModuleMap *modMap);
 
@@ -282,6 +294,8 @@
 
   /// \brief View the graphviz representation of the module graph.
   void viewGraph();
+
+  MemoryBufferCache &getPCMCache() const { return *PCMCache; }
 };
 
 } } // end namespace clang::serialization
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index dd7a6c8..f947776 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -321,9 +321,11 @@
                       const InvalidatedSymbols *invalidated,
                       ArrayRef<const MemRegion *> Explicits,
                       ArrayRef<const MemRegion *> Regions,
+                      const LocationContext *LCtx,
                       const CallEvent *Call) {
-    return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
-                                                      Explicits, Regions, Call);
+    return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
+                                                           Explicits, Regions,
+                                                           LCtx, Call);
   }
 
 public:
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 0316c8f..52ed260 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -338,6 +338,7 @@
                               const InvalidatedSymbols *invalidated,
                               ArrayRef<const MemRegion *> ExplicitRegions,
                               ArrayRef<const MemRegion *> Regions,
+                              const LocationContext *LCtx,
                               const CallEvent *Call);
 
   /// \brief Run checkers when pointers escape.
@@ -443,10 +444,11 @@
   typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
-                                const InvalidatedSymbols *symbols,
-                                ArrayRef<const MemRegion *> ExplicitRegions,
-                                ArrayRef<const MemRegion *> Regions,
-                                const CallEvent *Call)>
+                                     const InvalidatedSymbols *symbols,
+                                     ArrayRef<const MemRegion *> ExplicitRegions,
+                                     ArrayRef<const MemRegion *> Regions,
+                                     const LocationContext *LCtx,
+                                     const CallEvent *Call)>
       CheckRegionChangesFunc;
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 89610ef..aaecf38 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -55,6 +55,7 @@
 class CallDescription {
   friend CallEvent;
   mutable IdentifierInfo *II;
+  mutable bool IsLookupDone;
   StringRef FuncName;
   unsigned RequiredArgs;
 
@@ -68,7 +69,8 @@
   /// call. Omit this parameter to match every occurance of call with a given
   /// name regardless the number of arguments.
   CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
-      : II(nullptr), FuncName(FuncName), RequiredArgs(RequiredArgs) {}
+      : II(nullptr), IsLookupDone(false), FuncName(FuncName),
+        RequiredArgs(RequiredArgs) {}
 
   /// \brief Get the name of the function that this object matches.
   StringRef getFunctionName() const { return FuncName; }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 591b112..fa7769b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -293,6 +293,7 @@
                        const InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) override;
 
   /// printState - Called by ProgramStateManager to print checker-specific data.
@@ -522,7 +523,9 @@
 
   /// Call PointerEscape callback when a value escapes as a result of bind.
   ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
-                                              SVal Loc, SVal Val) override;
+                                              SVal Loc,
+                                              SVal Val,
+                                              const LocationContext *LCtx) override;
   /// Call PointerEscape callback when a value escapes as a result of
   /// region invalidation.
   /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 463b375..2910ef4 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -229,11 +229,12 @@
 
   ProgramStateRef bindLoc(Loc location,
                           SVal V,
+                          const LocationContext *LCtx,
                           bool notifyChanges = true) const;
 
-  ProgramStateRef bindLoc(SVal location, SVal V) const;
+  ProgramStateRef bindLoc(SVal location, SVal V, const LocationContext *LCtx) const;
 
-  ProgramStateRef bindDefault(SVal loc, SVal V) const;
+  ProgramStateRef bindDefault(SVal loc, SVal V, const LocationContext *LCtx) const;
 
   ProgramStateRef killBinding(Loc LV) const;
 
@@ -681,9 +682,9 @@
       this, Val.castAs<NonLoc>(), From, To);
 }
 
-inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
+inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V, const LocationContext *LCtx) const {
   if (Optional<Loc> L = LV.getAs<Loc>())
-    return bindLoc(*L, V);
+    return bindLoc(*L, V, LCtx);
   return this;
 }
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index 581ef20..e16df13 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -131,17 +131,19 @@
                        const InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) = 0;
 
 
   inline ProgramStateRef 
   processRegionChange(ProgramStateRef state,
-                      const MemRegion* MR) {
-    return processRegionChanges(state, nullptr, MR, MR, nullptr);
+                      const MemRegion* MR,
+                      const LocationContext *LCtx) {
+    return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
   }
 
   virtual ProgramStateRef
-  processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0;
+  processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) = 0;
 
   virtual ProgramStateRef
   notifyCheckersOfPointerEscape(ProgramStateRef State,
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/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp
index 8c126b0..6d9530b 100644
--- a/lib/Analysis/CallGraph.cpp
+++ b/lib/Analysis/CallGraph.cpp
@@ -62,6 +62,7 @@
   void VisitCallExpr(CallExpr *CE) {
     if (Decl *D = getDeclFromCall(CE))
       addCalledDecl(D);
+    VisitChildren(CE);
   }
 
   // Adds may-call edges for the ObjC message sends.
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 8929ec3..b6a289a 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -74,6 +74,7 @@
   FileSystemStatCache.cpp
   IdentifierTable.cpp
   LangOptions.cpp
+  MemoryBufferCache.cpp
   Module.cpp
   ObjCRuntime.cpp
   OpenMPKinds.cpp
@@ -82,6 +83,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/MemoryBufferCache.cpp b/lib/Basic/MemoryBufferCache.cpp
new file mode 100644
index 0000000..f4b751c
--- /dev/null
+++ b/lib/Basic/MemoryBufferCache.cpp
@@ -0,0 +1,48 @@
+//===- MemoryBufferCache.cpp - Cache for loaded memory buffers ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/MemoryBufferCache.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace clang;
+
+llvm::MemoryBuffer &
+MemoryBufferCache::addBuffer(llvm::StringRef Filename,
+                             std::unique_ptr<llvm::MemoryBuffer> Buffer) {
+  auto Insertion = Buffers.insert(std::make_pair(
+      Filename, BufferEntry{std::move(Buffer), NextIndex++}));
+  assert(Insertion.second && "Already has a buffer");
+  return *Insertion.first->second.Buffer;
+}
+
+llvm::MemoryBuffer *MemoryBufferCache::lookupBuffer(llvm::StringRef Filename) {
+  auto I = Buffers.find(Filename);
+  if (I == Buffers.end())
+    return nullptr;
+  return I->second.Buffer.get();
+}
+
+bool MemoryBufferCache::isBufferFinal(llvm::StringRef Filename) {
+  auto I = Buffers.find(Filename);
+  if (I == Buffers.end())
+    return false;
+  return I->second.Index < FirstRemovableIndex;
+}
+
+bool MemoryBufferCache::tryToRemoveBuffer(llvm::StringRef Filename) {
+  auto I = Buffers.find(Filename);
+  assert(I != Buffers.end() && "No buffer to remove...");
+  if (I->second.Index < FirstRemovableIndex)
+    return true;
+
+  Buffers.erase(I);
+  return false;
+}
+
+void MemoryBufferCache::finalizeCurrentBuffers() { FirstRemovableIndex = NextIndex; }
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index 80bbc24..a410a72 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -27,11 +27,12 @@
 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
-      Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID),
+      Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID),
       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/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 12a6803..c82e778 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -2009,7 +2009,11 @@
   if (CreateSkeletonCU && IsRootModule) {
     // PCH files don't have a signature field in the control block,
     // but LLVM detects skeleton CUs by looking for a non-zero DWO id.
-    uint64_t Signature = Mod.getSignature() ? Mod.getSignature() : ~1ULL;
+    // We use the lower 64 bits for debug info.
+    uint64_t Signature =
+        Mod.getSignature()
+            ? (uint64_t)Mod.getSignature()[1] << 32 | Mod.getSignature()[0]
+            : ~1ULL;
     llvm::DIBuilder DIB(CGM.getModule());
     DIB.createCompileUnit(TheCU->getSourceLanguage(),
                           DIB.createFile(Mod.getModuleName(), Mod.getPath()),
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.cpp b/lib/CodeGen/CodeGenFunction.cpp
index e142a21..798d5b4 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -707,6 +707,11 @@
   return false;
 }
 
+static void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) {
+  Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
+  Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
+}
+
 void CodeGenFunction::StartFunction(GlobalDecl GD,
                                     QualType RetTy,
                                     llvm::Function *Fn,
@@ -750,16 +755,19 @@
     Fn->addFnAttr(llvm::Attribute::SafeStack);
 
   // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize,
-  // .cxx_destruct and all of their calees at run time.
+  // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time.
   if (SanOpts.has(SanitizerKind::Thread)) {
     if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
       IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
       if (OMD->getMethodFamily() == OMF_dealloc ||
           OMD->getMethodFamily() == OMF_initialize ||
           (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) {
-        Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
-        Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
+        markAsIgnoreThreadCheckingAtRuntime(Fn);
       }
+    } else if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+      IdentifierInfo *II = FD->getIdentifier();
+      if (II && II->isStr("__destroy_helper_block_"))
+        markAsIgnoreThreadCheckingAtRuntime(Fn);
     }
   }
 
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/CodeGen/ObjectFilePCHContainerOperations.cpp b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
index 754f996..37ecc05a 100644
--- a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -171,7 +171,8 @@
     // Prepare CGDebugInfo to emit debug info for a clang module.
     auto *DI = Builder->getModuleDebugInfo();
     StringRef ModuleName = llvm::sys::path::filename(MainFileName);
-    DI->setPCHDescriptor({ModuleName, "", OutputFileName, ~1ULL});
+    DI->setPCHDescriptor({ModuleName, "", OutputFileName,
+                          ASTFileSignature{{{~0U, ~0U, ~0U, ~0U, ~1U}}}});
     DI->setModuleMap(MMap);
   }
 
@@ -241,7 +242,11 @@
 
     // PCH files don't have a signature field in the control block,
     // but LLVM detects DWO CUs by looking for a non-zero DWO id.
-    uint64_t Signature = Buffer->Signature ? Buffer->Signature : ~1ULL;
+    // We use the lower 64 bits for debug info.
+    uint64_t Signature =
+        Buffer->Signature
+            ? (uint64_t)Buffer->Signature[1] << 32 | Buffer->Signature[0]
+            : ~1ULL;
     Builder->getModuleDebugInfo()->setDwoId(Signature);
 
     // Finalize the Builder.
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/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 6bb6fb3..2f8446e 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -560,7 +560,6 @@
   // and we need to avoid bin packing there.
   bool NestedBlockSpecialCase =
       Style.Language != FormatStyle::LK_Cpp &&
-      Style.Language != FormatStyle::LK_ObjC &&
       Current.is(tok::r_brace) && State.Stack.size() > 1 &&
       State.Stack[State.Stack.size() - 2].NestedBlockInlined;
   if (!NestedBlockSpecialCase)
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 389761d..f08b386 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -52,7 +52,6 @@
     IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
     IO.enumCase(Value, "Java", FormatStyle::LK_Java);
     IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
-    IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
     IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
     IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
   }
@@ -624,8 +623,6 @@
   } else if (Language == FormatStyle::LK_Proto) {
     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
     GoogleStyle.SpacesInContainerLiterals = false;
-  } else if (Language == FormatStyle::LK_ObjC) {
-    GoogleStyle.ColumnLimit = 100;
   }
 
   return GoogleStyle;
@@ -1872,8 +1869,6 @@
     return FormatStyle::LK_Java;
   if (FileName.endswith_lower(".js") || FileName.endswith_lower(".ts"))
     return FormatStyle::LK_JavaScript; // JavaScript or TypeScript.
-  if (FileName.endswith(".m") || FileName.endswith(".mm"))
-    return FormatStyle::LK_ObjC;
   if (FileName.endswith_lower(".proto") ||
       FileName.endswith_lower(".protodevel"))
     return FormatStyle::LK_Proto;
@@ -1883,21 +1878,12 @@
 }
 
 FormatStyle getStyle(StringRef StyleName, StringRef FileName,
-                     StringRef FallbackStyle, StringRef Code,
-                     vfs::FileSystem *FS) {
+                     StringRef FallbackStyle, vfs::FileSystem *FS) {
   if (!FS) {
     FS = vfs::getRealFileSystem().get();
   }
   FormatStyle Style = getLLVMStyle();
   Style.Language = getLanguageByFileName(FileName);
-
-  // This is a very crude detection of whether a header contains ObjC code that
-  // should be improved over time and probably be done on tokens, not one the
-  // bare content of the file.
-  if (Style.Language == FormatStyle::LK_Cpp && FileName.endswith(".h") &&
-      (Code.contains("\n- (") || Code.contains("\n+ (")))
-    Style.Language = FormatStyle::LK_ObjC;
-
   if (!getPredefinedStyle(FallbackStyle, Style.Language, &Style)) {
     llvm::errs() << "Invalid fallback style \"" << FallbackStyle
                  << "\" using LLVM style\n";
diff --git a/lib/Format/FormatTokenLexer.cpp b/lib/Format/FormatTokenLexer.cpp
index 46a32a9..2aa48e3 100644
--- a/lib/Format/FormatTokenLexer.cpp
+++ b/lib/Format/FormatTokenLexer.cpp
@@ -558,8 +558,7 @@
     Column = FormatTok->LastLineColumnWidth;
   }
 
-  if (Style.Language == FormatStyle::LK_Cpp ||
-      Style.Language == FormatStyle::LK_ObjC) {
+  if (Style.Language == FormatStyle::LK_Cpp) {
     if (!(Tokens.size() > 0 && Tokens.back()->Tok.getIdentifierInfo() &&
           Tokens.back()->Tok.getIdentifierInfo()->getPPKeywordID() ==
               tok::pp_define) &&
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index b5f7de2..d1a3952 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -317,8 +317,7 @@
          Contexts.back().InTemplateArgument);
 
     bool StartsObjCMethodExpr =
-        !CppArrayTemplates && (Style.Language == FormatStyle::LK_Cpp ||
-                               Style.Language == FormatStyle::LK_ObjC) &&
+        !CppArrayTemplates && Style.Language == FormatStyle::LK_Cpp &&
         Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
         CurrentToken->isNot(tok::l_brace) &&
         (!Parent ||
@@ -434,8 +433,7 @@
           FormatToken *Previous = CurrentToken->getPreviousNonComment();
           if (((CurrentToken->is(tok::colon) &&
                 (!Contexts.back().ColonIsDictLiteral ||
-                 (Style.Language != FormatStyle::LK_Cpp &&
-                  Style.Language != FormatStyle::LK_ObjC))) ||
+                 Style.Language != FormatStyle::LK_Cpp)) ||
                Style.Language == FormatStyle::LK_Proto) &&
               (Previous->Tok.getIdentifierInfo() ||
                Previous->is(tok::string_literal)))
@@ -1176,7 +1174,6 @@
   bool rParenEndsCast(const FormatToken &Tok) {
     // C-style casts are only used in C++ and Java.
     if (Style.Language != FormatStyle::LK_Cpp &&
-        Style.Language != FormatStyle::LK_ObjC &&
         Style.Language != FormatStyle::LK_Java)
       return false;
 
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index d892996..aba662b 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/VirtualFileSystem.h"
@@ -185,7 +186,8 @@
   llvm::BitstreamWriter Stream;
   ASTWriter Writer;
 
-  ASTWriterData() : Stream(Buffer), Writer(Stream, { }) { }
+  ASTWriterData(MemoryBufferCache &PCMCache)
+      : Stream(Buffer), Writer(Stream, Buffer, PCMCache, {}) {}
 };
 
 void ASTUnit::clearFileLevelDecls() {
@@ -619,6 +621,10 @@
     StoredDiags.emplace_back(Level, Info);
 }
 
+IntrusiveRefCntPtr<ASTReader> ASTUnit::getASTReader() const {
+  return Reader;
+}
+
 ASTMutationListener *ASTUnit::getASTMutationListener() {
   if (WriterData)
     return &WriterData->Writer;
@@ -677,6 +683,7 @@
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
                                      AST->getFileManager(),
                                      UserFilesAreVolatile);
+  AST->PCMCache = new MemoryBufferCache;
   AST->HSOpts = std::make_shared<HeaderSearchOptions>();
   AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat();
   AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
@@ -697,7 +704,7 @@
 
   AST->PP = std::make_shared<Preprocessor>(
       std::move(PPOpts), AST->getDiagnostics(), AST->ASTFileLangOpts,
-      AST->getSourceManager(), HeaderInfo, *AST,
+      AST->getSourceManager(), *AST->PCMCache, HeaderInfo, *AST,
       /*IILookup=*/nullptr,
       /*OwnsHeaderSearch=*/false);
   Preprocessor &PP = *AST->PP;
@@ -1723,6 +1730,7 @@
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
                                      UserFilesAreVolatile);
+  AST->PCMCache = new MemoryBufferCache;
 
   return AST;
 }
@@ -1990,6 +1998,7 @@
   if (!VFS)
     return nullptr;
   AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
+  AST->PCMCache = new MemoryBufferCache;
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->TUKind = TUKind;
@@ -2001,7 +2010,7 @@
   AST->StoredDiagnostics.swap(StoredDiagnostics);
   AST->Invocation = CI;
   if (ForSerialization)
-    AST->WriterData.reset(new ASTWriterData());
+    AST->WriterData.reset(new ASTWriterData(*AST->PCMCache));
   // Zero out now to ease cleanup during crash recovery.
   CI = nullptr;
   Diags = nullptr;
@@ -2516,7 +2525,8 @@
 
   SmallString<128> Buffer;
   llvm::BitstreamWriter Stream(Buffer);
-  ASTWriter Writer(Stream, { });
+  MemoryBufferCache PCMCache;
+  ASTWriter Writer(Stream, Buffer, PCMCache, {});
   return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
 }
 
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index afcaa6e..af0f94b 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -8,11 +8,13 @@
 //===----------------------------------------------------------------------===//
 
 #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"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Version.h"
@@ -55,12 +57,15 @@
 
 CompilerInstance::CompilerInstance(
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
-    bool BuildingModule)
-    : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()),
-      ModuleManager(nullptr),
-      ThePCHContainerOperations(std::move(PCHContainerOps)),
-      BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false),
-      ModuleBuildFailed(false) {}
+    MemoryBufferCache *SharedPCMCache)
+    : ModuleLoader(/* BuildingModule = */ SharedPCMCache),
+      Invocation(new CompilerInvocation()),
+      PCMCache(SharedPCMCache ? SharedPCMCache : new MemoryBufferCache),
+      ThePCHContainerOperations(std::move(PCHContainerOps)) {
+  // Don't allow this to invalidate buffers in use by others.
+  if (SharedPCMCache)
+    getPCMCache().finalizeCurrentBuffers();
+}
 
 CompilerInstance::~CompilerInstance() {
   assert(OutputFiles.empty() && "Still output files in flight?");
@@ -131,6 +136,8 @@
   return ModuleManager;
 }
 void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) {
+  assert(PCMCache.get() == &Reader->getModuleManager().getPCMCache() &&
+         "Expected ASTReader to use the same PCM cache");
   ModuleManager = std::move(Reader);
 }
 
@@ -373,7 +380,7 @@
                        getDiagnostics(), getLangOpts(), &getTarget());
   PP = std::make_shared<Preprocessor>(
       Invocation->getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(),
-      getSourceManager(), *HeaderInfo, *this, PTHMgr,
+      getSourceManager(), getPCMCache(), *HeaderInfo, *this, PTHMgr,
       /*OwnsHeaderSearch=*/true, TUKind);
   PP->Initialize(getTarget(), getAuxTarget());
 
@@ -615,6 +622,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 +1044,7 @@
                               SourceLocation ImportLoc,
                               Module *Module,
                               StringRef ModuleFileName) {
-  ModuleMap &ModMap 
+  ModuleMap &ModMap
     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
     
   // Construct a compiler invocation for creating this module.
@@ -1032,7 +1060,7 @@
 
   // Remove any macro definitions that are explicitly ignored by the module.
   // They aren't supposed to affect how the module is built anyway.
-  const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
+  HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
   PPOpts.Macros.erase(
       std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
                      [&HSOpts](const std::pair<std::string, bool> &def) {
@@ -1063,6 +1091,8 @@
   FrontendOpts.DisableFree = false;
   FrontendOpts.GenerateGlobalModuleIndex = false;
   FrontendOpts.BuildingImplicitModule = true;
+  // Force implicitly-built modules to hash the content of the module file.
+  HSOpts.ModulesHashContent = true;
   FrontendOpts.Inputs.clear();
   InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
 
@@ -1074,9 +1104,11 @@
          Invocation->getModuleHash() && "Module hash mismatch!");
   
   // Construct a compiler instance that will be used to actually create the
-  // module.
+  // module.  Since we're sharing a PCMCache,
+  // CompilerInstance::CompilerInstance is responsible for finalizing the
+  // buffers to prevent use-after-frees.
   CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
-                            /*BuildingModule=*/true);
+                            &ImportingInstance.getPreprocessor().getPCMCache());
   auto &Inv = *Invocation;
   Instance.setInvocation(std::move(Invocation));
 
@@ -1180,10 +1212,14 @@
     llvm::LockFileManager Locked(ModuleFileName);
     switch (Locked) {
     case llvm::LockFileManager::LFS_Error:
-      Diags.Report(ModuleNameLoc, diag::err_module_lock_failure)
+      // PCMCache takes care of correctness and locks are only necessary for
+      // performance. If there are errors creating the lock, do not use it
+      // and fallback to building the module ourselves.
+      Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure)
           << Module->Name << Locked.getErrorMessage();
-      return false;
-
+      // Clear the lock file in case there's some leftover around.
+      Locked.unsafeRemoveLockFile();
+      // FALLTHROUGH
     case llvm::LockFileManager::LFS_Owned:
       // We're responsible for building the module ourselves.
       if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
@@ -1203,11 +1239,14 @@
       case llvm::LockFileManager::Res_OwnerDied:
         continue; // try again to get the lock.
       case llvm::LockFileManager::Res_Timeout:
-        Diags.Report(ModuleNameLoc, diag::err_module_lock_timeout)
+        // Since PCMCache takes care of correctness, we try waiting for another
+        // process to complete the build so that this isn't done twice. If we
+        // reach a timeout, it's not a problem, try to build it ourselves then.
+        Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
             << Module->Name;
         // Clear the lock file so that future invokations can make progress.
         Locked.unsafeRemoveLockFile();
-        return false;
+        continue;
       }
       break;
     }
@@ -1794,8 +1833,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..f0cf3d4 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
@@ -1407,7 +1408,8 @@
   return P.str();
 }
 
-static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
+static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
+                                  const std::string &WorkingDir) {
   using namespace options;
   Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/");
   Opts.Verbose = Args.hasArg(OPT_v);
@@ -1417,11 +1419,23 @@
   if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
     Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
   Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
-  Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodules_cache_path);
+
+  // Canonicalize -fmodules-cache-path before storing it.
+  SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path));
+  if (!(P.empty() || llvm::sys::path::is_absolute(P))) {
+    if (WorkingDir.empty())
+      llvm::sys::fs::make_absolute(P);
+    else
+      llvm::sys::fs::make_absolute(WorkingDir, P);
+  }
+  llvm::sys::path::remove_dots(P);
+  Opts.ModuleCachePath = P.str();
+
   Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path);
   for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path))
     Opts.AddPrebuiltModulePath(A->getValue());
   Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
+  Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
   Opts.ModulesValidateDiagnosticOptions =
       !Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
   Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
@@ -1525,6 +1539,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 +2057,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
@@ -2440,7 +2468,10 @@
   ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
   Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
                               Res.getTargetOpts());
-  ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args);
+  ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args,
+                        Res.getFileSystemOpts().WorkingDir);
+  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 +2490,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 +2604,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/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index c667f4b..fa2a76e 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -1092,51 +1092,13 @@
 }
 
 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
-                                          const FileEntry *File, bool isImport,
-                                          bool ModulesEnabled, Module *M) {
+                                          const FileEntry *File,
+                                          bool isImport, Module *M) {
   ++NumIncluded; // Count # of attempted #includes.
 
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&](void) -> bool {
-    if (!ModulesEnabled)
-      return false;
-    // Modules with builtins are special; multiple modules use builtins as
-    // modular headers, example:
-    //
-    //    module stddef { header "stddef.h" export * }
-    //
-    // After module map parsing, this expands to:
-    //
-    //    module stddef {
-    //      header "/path_to_builtin_dirs/stddef.h"
-    //      textual "stddef.h"
-    //    }
-    //
-    // It's common that libc++ and system modules will both define such
-    // submodules. Make sure cached results for a builtin header won't
-    // prevent other builtin modules to potentially enter the builtin header.
-    // Note that builtins are header guarded and the decision to actually
-    // enter them is postponed to the controlling macros logic below.
-    bool TryEnterHdr = false;
-    if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
-      TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
-                    ModuleMap::isBuiltinHeader(
-                        llvm::sys::path::filename(File->getName()));
-
-    // Textual headers can be #imported from different modules. Since ObjC
-    // headers find in the wild might rely only on #import and do not contain
-    // controlling macros, be conservative and only try to enter textual headers
-    // if such macro is present.
-    if (!FileInfo.isModuleHeader &&
-        FileInfo.getControllingMacro(ExternalLookup))
-      TryEnterHdr = true;
-    return TryEnterHdr;
-  };
-
   // If this is a #import directive, check that we have not already imported
   // this header.
   if (isImport) {
@@ -1144,12 +1106,11 @@
     FileInfo.isImport = true;
 
     // Has this already been #import'ed or #include'd?
-    if (FileInfo.NumIncludes && !TryEnterImported())
-      return false;
+    if (FileInfo.NumIncludes) return false;
   } else {
     // Otherwise, if this is a #include of a file that was previously #import'd
     // or if this is the second #include of a #pragma once file, ignore it.
-    if (FileInfo.isImport && !TryEnterImported())
+    if (FileInfo.isImport)
       return false;
   }
 
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 1488f62..12dbd6e 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -144,7 +144,7 @@
 /// \brief Determine whether the given file name is the name of a builtin
 /// header, supplied by Clang to replace, override, or augment existing system
 /// headers.
-bool ModuleMap::isBuiltinHeader(StringRef FileName) {
+static bool isBuiltinHeader(StringRef FileName) {
   return llvm::StringSwitch<bool>(FileName)
            .Case("float.h", true)
            .Case("iso646.h", true)
@@ -165,7 +165,7 @@
   HeadersMap::iterator Known = Headers.find(File);
   if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
       Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
-      ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
+      isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
     HeaderInfo.loadTopLevelSystemModules();
     return Headers.find(File);
   }
@@ -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;
@@ -1889,7 +1921,7 @@
       // supplied by Clang. Find that builtin header.
       if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
           BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
-          ModuleMap::isBuiltinHeader(Header.FileName)) {
+          isBuiltinHeader(Header.FileName)) {
         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
         llvm::sys::path::append(BuiltinPathName, Header.FileName);
         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
@@ -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..7b65f64 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;
@@ -1999,7 +2003,6 @@
   bool SkipHeader = false;
   if (ShouldEnter &&
       !HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
-                                         getLangOpts().Modules,
                                          SuggestedModule.getModule())) {
     ShouldEnter = false;
     SkipHeader = true;
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/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 91319be..babef5d 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -70,15 +70,15 @@
 
 Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
                            DiagnosticsEngine &diags, LangOptions &opts,
-                           SourceManager &SM, HeaderSearch &Headers,
-                           ModuleLoader &TheModuleLoader,
+                           SourceManager &SM, MemoryBufferCache &PCMCache,
+                           HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
                            IdentifierInfoLookup *IILookup, bool OwnsHeaders,
                            TranslationUnitKind TUKind)
     : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), Target(nullptr),
       AuxTarget(nullptr), FileMgr(Headers.getFileMgr()), SourceMgr(SM),
-      ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers),
-      TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),
-      Identifiers(opts, IILookup),
+      PCMCache(PCMCache), ScratchBuf(new ScratchBuffer(SourceMgr)),
+      HeaderInfo(Headers), TheModuleLoader(TheModuleLoader),
+      ExternalSource(nullptr), Identifiers(opts, IILookup),
       PragmaHandlers(new PragmaNamespace(StringRef())),
       IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr),
       CodeCompletionFile(nullptr), CodeCompletionOffset(0),
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..b89419d 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);
@@ -4806,9 +4857,10 @@
 ///              [ only if AttReqs & AR_CXX11AttributesParsed ]
 /// Note: vendor can be GNU, MS, etc and can be explicitly controlled via
 /// AttrRequirements bitmask values.
-void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,
-                                       bool AtomicAllowed,
-                                       bool IdentifierRequired) {
+void Parser::ParseTypeQualifierListOpt(
+    DeclSpec &DS, unsigned AttrReqs, bool AtomicAllowed,
+    bool IdentifierRequired,
+    Optional<llvm::function_ref<void()>> CodeCompletionHandler) {
   if (getLangOpts().CPlusPlus11 && (AttrReqs & AR_CXX11AttributesParsed) &&
       isCXX11AttributeSpecifier()) {
     ParsedAttributesWithRange attrs(AttrFactory);
@@ -4826,7 +4878,10 @@
 
     switch (Tok.getKind()) {
     case tok::code_completion:
-      Actions.CodeCompleteTypeQualifiers(DS);
+      if (CodeCompletionHandler)
+        (*CodeCompletionHandler)();
+      else
+        Actions.CodeCompleteTypeQualifiers(DS);
       return cutOffParsing();
 
     case tok::kw_const:
@@ -5744,7 +5799,11 @@
 
       // Parse cv-qualifier-seq[opt].
       ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
-                                /*AtomicAllowed*/ false);
+                                /*AtomicAllowed*/ false,
+                                /*IdentifierRequired=*/false,
+                                llvm::function_ref<void()>([&]() {
+                                  Actions.CodeCompleteFunctionQualifiers(DS, D);
+                                }));
       if (!DS.getSourceRange().getEnd().isInvalid()) {
         EndLoc = DS.getSourceRange().getEnd();
         ConstQualifierLoc = DS.getConstSpecLoc();
@@ -6553,3 +6612,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..d2165d8 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -2283,7 +2283,11 @@
 
   // GNU-style and C++11 attributes are not allowed here, but they will be
   // handled by the caller.  Diagnose everything else.
-  ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed, false);
+  ParseTypeQualifierListOpt(
+      DS, AR_NoAttributesParsed, false,
+      /*IdentifierRequired=*/false, llvm::function_ref<void()>([&]() {
+        Actions.CodeCompleteFunctionQualifiers(DS, D, &VS);
+      }));
   D.ExtendWithDeclSpec(DS);
 
   if (D.isFunctionDeclarator()) {
@@ -2724,8 +2728,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..c85fda0 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1334,8 +1334,9 @@
       Builder.AddChunk(CodeCompletionString::CK_RightParen);
       Results.AddResult(Result(Builder.TakeString()));
     }
-  }
-  
+  } else
+    Results.AddResult(Result("__auto_type", CCP_Type));
+
   // GNU extensions
   if (LangOpts.GNUMode) {
     // FIXME: Enable when we actually support decimal floating point.
@@ -1370,6 +1371,21 @@
   // in C++0x as a type specifier.
   Results.AddResult(Result("extern"));
   Results.AddResult(Result("static"));
+
+  if (LangOpts.CPlusPlus11) {
+    CodeCompletionAllocator &Allocator = Results.getAllocator();
+    CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
+
+    // alignas
+    Builder.AddTypedTextChunk("alignas");
+    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
+    Builder.AddPlaceholderChunk("expression");
+    Builder.AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(Result(Builder.TakeString()));
+
+    Results.AddResult(Result("constexpr"));
+    Results.AddResult(Result("thread_local"));
+  }
 }
 
 static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
@@ -1527,6 +1543,21 @@
   Results.AddResult(CodeCompletionResult(Builder.TakeString()));
 }
 
+static void AddStaticAssertResult(CodeCompletionBuilder &Builder,
+                                  ResultBuilder &Results,
+                                  const LangOptions &LangOpts) {
+  if (!LangOpts.CPlusPlus11)
+    return;
+
+  Builder.AddTypedTextChunk("static_assert");
+  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
+  Builder.AddPlaceholderChunk("expression");
+  Builder.AddChunk(CodeCompletionString::CK_Comma);
+  Builder.AddPlaceholderChunk("message");
+  Builder.AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(CodeCompletionResult(Builder.TakeString()));
+}
+
 /// \brief Add language constructs that show up for "ordinary" names.
 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
                                    Scope *S,
@@ -1611,6 +1642,8 @@
         Results.AddResult(Result(Builder.TakeString()));
       }
 
+      AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
+
       if (CCC == Sema::PCC_Class) {
         AddTypedefResult(Results);
 
@@ -1824,6 +1857,8 @@
     Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
     Builder.AddPlaceholderChunk("identifier");
     Results.AddResult(Result(Builder.TakeString()));
+
+    AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
   }
 
   // Fall through (for statement expressions).
@@ -3482,6 +3517,11 @@
     Results.AddResult(Result("restrict"));
 
   if (getLangOpts().CPlusPlus) {
+    if (getLangOpts().CPlusPlus11 &&
+        (DS.getTypeSpecType() == DeclSpec::TST_class ||
+         DS.getTypeSpecType() == DeclSpec::TST_struct))
+      Results.AddResult("final");
+
     if (AllowNonIdentifiers) {
       Results.AddResult(Result("operator")); 
     }
@@ -4012,30 +4052,54 @@
                             Results.data(),Results.size());
 }
 
+static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results,
+                                    const LangOptions &LangOpts) {
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
+    Results.AddResult("const");
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
+    Results.AddResult("volatile");
+  if (LangOpts.C99 && !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
+    Results.AddResult("restrict");
+  if (LangOpts.C11 && !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
+    Results.AddResult("_Atomic");
+  if (LangOpts.MSVCCompat && !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
+    Results.AddResult("__unaligned");
+}
+
 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
                         CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_TypeQualifiers);
   Results.EnterNewScope();
-  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
-    Results.AddResult("const");
-  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
-    Results.AddResult("volatile");
-  if (getLangOpts().C99 &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
-    Results.AddResult("restrict");
-  if (getLangOpts().C11 &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
-    Results.AddResult("_Atomic");
-  if (getLangOpts().MSVCCompat &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
-    Results.AddResult("__unaligned");
+  AddTypeQualifierResults(DS, Results, LangOpts);
   Results.ExitScope();
   HandleCodeCompleteResults(this, CodeCompleter, 
                             Results.getCompletionContext(),
                             Results.data(), Results.size());
 }
 
+void Sema::CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
+                                          const VirtSpecifiers *VS) {
+  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
+                        CodeCompletionContext::CCC_TypeQualifiers);
+  Results.EnterNewScope();
+  AddTypeQualifierResults(DS, Results, LangOpts);
+  if (LangOpts.CPlusPlus11) {
+    Results.AddResult("noexcept");
+    if (D.getContext() == Declarator::MemberContext && !D.isCtorOrDtor() &&
+        !D.isStaticMember()) {
+      if (!VS || !VS->isFinalSpecified())
+        Results.AddResult("final");
+      if (!VS || !VS->isOverrideSpecified())
+        Results.AddResult("override");
+    }
+  }
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
+}
+
 void Sema::CodeCompleteBracketDeclarator(Scope *S) {
   CodeCompleteExpression(S, QualType(getASTContext().getSizeType()));
 }
@@ -5230,24 +5294,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 +5335,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 +5345,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..e5d368f 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;
@@ -3977,6 +3981,8 @@
       ImplicitConversionSequence ICS;
       ICS.setStandard();
       ICS.Standard.setAsIdentityConversion();
+      if (!E->isRValue())
+        ICS.Standard.First = ICK_Lvalue_To_Rvalue;
       // If E is of a floating-point type, then the conversion is ill-formed
       // due to narrowing, but go through the motions in order to produce the
       // right diagnostic.
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index e2cb2c8..f751d8b 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -3430,6 +3430,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..3061aed 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -36,6 +36,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/Sanitizers.h"
@@ -461,6 +462,30 @@
   return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain);
 }
 
+/// Return the top import module if it is implicit, nullptr otherwise.
+static Module *getTopImportImplicitModule(ModuleManager &ModuleMgr,
+                                          Preprocessor &PP) {
+  // If the original import came from a file explicitly generated by the user,
+  // don't check the diagnostic mappings.
+  // FIXME: currently this is approximated by checking whether this is not a
+  // module import of an implicitly-loaded module file.
+  // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
+  // the transitive closure of its imports, since unrelated modules cannot be
+  // imported until after this module finishes validation.
+  ModuleFile *TopImport = &*ModuleMgr.rbegin();
+  while (!TopImport->ImportedBy.empty())
+    TopImport = TopImport->ImportedBy[0];
+  if (TopImport->Kind != MK_ImplicitModule)
+    return nullptr;
+
+  StringRef ModuleName = TopImport->ModuleName;
+  assert(!ModuleName.empty() && "diagnostic options read before module name");
+
+  Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
+  assert(M && "missing module");
+  return M;
+}
+
 bool PCHValidator::ReadDiagnosticOptions(
     IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
   DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
@@ -474,28 +499,14 @@
   ModuleManager &ModuleMgr = Reader.getModuleManager();
   assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");
 
-  // If the original import came from a file explicitly generated by the user,
-  // don't check the diagnostic mappings.
-  // FIXME: currently this is approximated by checking whether this is not a
-  // module import of an implicitly-loaded module file.
-  // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
-  // the transitive closure of its imports, since unrelated modules cannot be
-  // imported until after this module finishes validation.
-  ModuleFile *TopImport = *ModuleMgr.rbegin();
-  while (!TopImport->ImportedBy.empty())
-    TopImport = TopImport->ImportedBy[0];
-  if (TopImport->Kind != MK_ImplicitModule)
+  Module *TopM = getTopImportImplicitModule(ModuleMgr, PP);
+  if (!TopM)
     return false;
 
-  StringRef ModuleName = TopImport->ModuleName;
-  assert(!ModuleName.empty() && "diagnostic options read before module name");
-
-  Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
-  assert(M && "missing module");
-
   // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
   // contains the union of their flags.
-  return checkDiagnosticMappings(*Diags, ExistingDiags, M->IsSystem, Complain);
+  return checkDiagnosticMappings(*Diags, ExistingDiags, TopM->IsSystem,
+                                 Complain);
 }
 
 /// \brief Collect the macro definitions provided by the given preprocessor
@@ -1707,15 +1718,15 @@
   // Note that we are loading defined macros.
   Deserializing Macros(this);
 
-  for (auto &I : llvm::reverse(ModuleMgr)) {
-    BitstreamCursor &MacroCursor = I->MacroCursor;
+  for (ModuleFile &I : llvm::reverse(ModuleMgr)) {
+    BitstreamCursor &MacroCursor = I.MacroCursor;
 
     // If there was no preprocessor block, skip this file.
     if (MacroCursor.getBitcodeBytes().empty())
       continue;
 
     BitstreamCursor Cursor = MacroCursor;
-    Cursor.JumpToBit(I->MacroStartOffset);
+    Cursor.JumpToBit(I.MacroStartOffset);
 
     RecordData Record;
     while (true) {
@@ -1737,7 +1748,7 @@
 
         case PP_MACRO_OBJECT_LIKE:
         case PP_MACRO_FUNCTION_LIKE: {
-          IdentifierInfo *II = getLocalIdentifier(*I, Record[0]);
+          IdentifierInfo *II = getLocalIdentifier(I, Record[0]);
           if (II->isOutOfDate())
             updateOutOfDateIdentifier(*II);
           break;
@@ -2149,7 +2160,7 @@
 ASTReader::ASTReadResult ASTReader::ReadOptionsBlock(
     BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
     bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
-    std::string &SuggestedPredefines, bool ValidateDiagnosticOptions) {
+    std::string &SuggestedPredefines) {
   if (Stream.EnterSubBlock(OPTIONS_BLOCK_ID))
     return Failure;
 
@@ -2191,15 +2202,6 @@
       break;
     }
 
-    case DIAGNOSTIC_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
-      if (ValidateDiagnosticOptions &&
-          !AllowCompatibleConfigurationMismatch &&
-          ParseDiagnosticOptions(Record, Complain, Listener))
-        return OutOfDate;
-      break;
-    }
-
     case FILE_SYSTEM_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
       if (!AllowCompatibleConfigurationMismatch &&
@@ -2240,6 +2242,18 @@
     return Failure;
   }
 
+  // Lambda to read the unhashed control block the first time it's called.
+  bool HasReadUnhashedControlBlock = false;
+  auto readUnhashedControlBlockOnce = [&]() {
+    if (!HasReadUnhashedControlBlock) {
+      HasReadUnhashedControlBlock = true;
+      if (ASTReadResult Result =
+              readUnhashedControlBlock(F, ImportedBy, ClientLoadCapabilities))
+        return Result;
+    }
+    return Success;
+  };
+
   // Read all of the records and blocks in the control block.
   RecordData Record;
   unsigned NumInputs = 0;
@@ -2252,6 +2266,11 @@
       Error("malformed block record in AST file");
       return Failure;
     case llvm::BitstreamEntry::EndBlock: {
+      // Validate the module before returning.  This call catches an AST with
+      // no module name and no imports.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
       // Validate input files.
       const HeaderSearchOptions &HSOpts =
           PP.getHeaderSearchInfo().getHeaderSearchOpts();
@@ -2323,13 +2342,10 @@
           // FIXME: Allow this for files explicitly specified with -include-pch.
           bool AllowCompatibleConfigurationMismatch =
               F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
-          const HeaderSearchOptions &HSOpts =
-              PP.getHeaderSearchInfo().getHeaderSearchOpts();
 
           Result = ReadOptionsBlock(Stream, ClientLoadCapabilities,
                                     AllowCompatibleConfigurationMismatch,
-                                    *Listener, SuggestedPredefines,
-                                    HSOpts.ModulesValidateDiagnosticOptions);
+                                    *Listener, SuggestedPredefines);
           if (Result == Failure) {
             Error("malformed block record in AST file");
             return Result;
@@ -2403,12 +2419,13 @@
       break;
     }
 
-    case SIGNATURE:
-      assert((!F.Signature || F.Signature == Record[0]) && "signature changed");
-      F.Signature = Record[0];
-      break;
-
     case IMPORTS: {
+      // Validate the AST before processing any imports (otherwise, untangling
+      // them can be error-prone and expensive).  A module will have a name and
+      // will already have been validated, but this catches the PCH case.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
       // Load each of the imported PCH files.
       unsigned Idx = 0, N = Record.size();
       while (Idx < N) {
@@ -2421,7 +2438,10 @@
             ReadUntranslatedSourceLocation(Record[Idx++]);
         off_t StoredSize = (off_t)Record[Idx++];
         time_t StoredModTime = (time_t)Record[Idx++];
-        ASTFileSignature StoredSignature = Record[Idx++];
+        ASTFileSignature StoredSignature = {
+            {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++]}}};
         auto ImportedFile = ReadPath(F, Record, Idx);
 
         // If our client can't cope with us being out of date, we can't cope with
@@ -2473,6 +2493,12 @@
       F.ModuleName = Blob;
       if (Listener)
         Listener->ReadModuleName(F.ModuleName);
+
+      // Validate the AST as soon as we have a name so we can exit early on
+      // failure.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
       break;
 
     case MODULE_DIRECTORY: {
@@ -2513,6 +2539,7 @@
       F.InputFileOffsets =
           (const llvm::support::unaligned_uint64_t *)Blob.data();
       F.InputFilesLoaded.resize(NumInputs);
+      F.NumUserInputFiles = NumUserInputs;
       break;
     }
   }
@@ -3123,14 +3150,6 @@
       F.ObjCCategories.swap(Record);
       break;
 
-    case DIAG_PRAGMA_MAPPINGS:
-      if (F.PragmaDiagMappings.empty())
-        F.PragmaDiagMappings.swap(Record);
-      else
-        F.PragmaDiagMappings.insert(F.PragmaDiagMappings.end(),
-                                    Record.begin(), Record.end());
-      break;
-
     case CUDA_SPECIAL_DECL_REFS:
       // Later tables overwrite earlier ones.
       // FIXME: Modules will have trouble with this.
@@ -3245,8 +3264,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;
@@ -3342,8 +3364,7 @@
   // usable header search context.
   assert(!F.ModuleName.empty() &&
          "MODULE_NAME should come before MODULE_MAP_FILE");
-  if (F.Kind == MK_ImplicitModule &&
-      (*ModuleMgr.begin())->Kind != MK_MainFile) {
+  if (F.Kind == MK_ImplicitModule && ModuleMgr.begin()->Kind != MK_MainFile) {
     // An implicitly-loaded module file should have its module listed in some
     // module map file that we've already loaded.
     Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
@@ -3621,10 +3642,10 @@
 
   unsigned NumModules = ModuleMgr.size();
   SmallVector<ImportedModule, 4> Loaded;
-  switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,
-                                                /*ImportedBy=*/nullptr, Loaded,
-                                                0, 0, 0,
-                                                ClientLoadCapabilities)) {
+  switch (ASTReadResult ReadResult =
+              ReadASTCore(FileName, Type, ImportLoc,
+                          /*ImportedBy=*/nullptr, Loaded, 0, 0,
+                          ASTFileSignature(), ClientLoadCapabilities)) {
   case Failure:
   case Missing:
   case OutOfDate:
@@ -3635,11 +3656,10 @@
     for (const ImportedModule &IM : Loaded)
       LoadedSet.insert(IM.Mod);
 
-    ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end(),
-                            LoadedSet,
+    ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, LoadedSet,
                             Context.getLangOpts().Modules
-                              ? &PP.getHeaderSearchInfo().getModuleMap()
-                              : nullptr);
+                                ? &PP.getHeaderSearchInfo().getModuleMap()
+                                : nullptr);
 
     // If we find that any modules are unusable, the global index is going
     // to be out-of-date. Just remove it.
@@ -3986,6 +4006,11 @@
       Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc));
       return Success;
 
+    case UNHASHED_CONTROL_BLOCK_ID:
+      // This block is handled using look-ahead during ReadControlBlock.  We
+      // shouldn't get here!
+      return Failure;
+
     default:
       if (Stream.SkipBlock()) {
         Error("malformed block record in AST file");
@@ -3998,6 +4023,122 @@
   return Success;
 }
 
+ASTReader::ASTReadResult
+ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
+                                    unsigned ClientLoadCapabilities) {
+  const HeaderSearchOptions &HSOpts =
+      PP.getHeaderSearchInfo().getHeaderSearchOpts();
+  bool AllowCompatibleConfigurationMismatch =
+      F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
+
+  ASTReadResult Result = readUnhashedControlBlockImpl(
+      &F, F.Data, ClientLoadCapabilities, AllowCompatibleConfigurationMismatch,
+      Listener.get(),
+      WasImportedBy ? false : HSOpts.ModulesValidateDiagnosticOptions);
+
+  // If F was directly imported by another module, it's implicitly validated by
+  // the importing module.
+  if (DisableValidation || WasImportedBy ||
+      (AllowConfigurationMismatch && Result == ConfigurationMismatch))
+    return Success;
+
+  if (Result == Failure) {
+    Error("malformed block record in AST file");
+    return Failure;
+  }
+
+  if (Result == OutOfDate && F.Kind == MK_ImplicitModule) {
+    // If this module has already been finalized in the PCMCache, we're stuck
+    // with it; we can only load a single version of each module.
+    //
+    // This can happen when a module is imported in two contexts: in one, as a
+    // user module; in another, as a system module (due to an import from
+    // another module marked with the [system] flag).  It usually indicates a
+    // bug in the module map: this module should also be marked with [system].
+    //
+    // If -Wno-system-headers (the default), and the first import is as a
+    // system module, then validation will fail during the as-user import,
+    // since -Werror flags won't have been validated.  However, it's reasonable
+    // to treat this consistently as a system module.
+    //
+    // If -Wsystem-headers, the PCM on disk was built with
+    // -Wno-system-headers, and the first import is as a user module, then
+    // validation will fail during the as-system import since the PCM on disk
+    // doesn't guarantee that -Werror was respected.  However, the -Werror
+    // flags were checked during the initial as-user import.
+    if (PCMCache.isBufferFinal(F.FileName)) {
+      Diag(diag::warn_module_system_bit_conflict) << F.FileName;
+      return Success;
+    }
+  }
+
+  return Result;
+}
+
+ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
+    ModuleFile *F, llvm::StringRef StreamData, unsigned ClientLoadCapabilities,
+    bool AllowCompatibleConfigurationMismatch, ASTReaderListener *Listener,
+    bool ValidateDiagnosticOptions) {
+  // Initialize a stream.
+  BitstreamCursor Stream(StreamData);
+
+  // Sniff for the signature.
+  if (!startsWithASTFileMagic(Stream))
+    return Failure;
+
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
+    return Failure;
+
+  // Read all of the records in the options block.
+  RecordData Record;
+  ASTReadResult Result = Success;
+  while (1) {
+    llvm::BitstreamEntry Entry = Stream.advance();
+
+    switch (Entry.Kind) {
+    case llvm::BitstreamEntry::Error:
+    case llvm::BitstreamEntry::SubBlock:
+      return Failure;
+
+    case llvm::BitstreamEntry::EndBlock:
+      return Result;
+
+    case llvm::BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read and process a record.
+    Record.clear();
+    switch (
+        (UnhashedControlBlockRecordTypes)Stream.readRecord(Entry.ID, Record)) {
+    case SIGNATURE: {
+      if (F)
+        std::copy(Record.begin(), Record.end(), F->Signature.data());
+      break;
+    }
+    case DIAGNOSTIC_OPTIONS: {
+      bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
+      if (Listener && ValidateDiagnosticOptions &&
+          !AllowCompatibleConfigurationMismatch &&
+          ParseDiagnosticOptions(Record, Complain, *Listener))
+        Result = OutOfDate; // Don't return early.  Read the signature.
+      break;
+    }
+    case DIAG_PRAGMA_MAPPINGS:
+      if (!F)
+        break;
+      if (F->PragmaDiagMappings.empty())
+        F->PragmaDiagMappings.swap(Record);
+      else
+        F->PragmaDiagMappings.insert(F->PragmaDiagMappings.end(),
+                                     Record.begin(), Record.end());
+      break;
+    }
+  }
+}
+
 /// Parse a record and blob containing module file extension metadata.
 static bool parseModuleFileExtensionMetadata(
               const SmallVectorImpl<uint64_t> &Record,
@@ -4214,23 +4355,24 @@
 static ASTFileSignature readASTFileSignature(StringRef PCH) {
   BitstreamCursor Stream(PCH);
   if (!startsWithASTFileMagic(Stream))
-    return 0;
+    return ASTFileSignature();
 
-  // Scan for the CONTROL_BLOCK_ID block.
-  if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID))
-    return 0;
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
+    return ASTFileSignature();
 
-  // Scan for SIGNATURE inside the control block.
+  // Scan for SIGNATURE inside the diagnostic options block.
   ASTReader::RecordData Record;
   while (true) {
     llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
     if (Entry.Kind != llvm::BitstreamEntry::Record)
-      return 0;
+      return ASTFileSignature();
 
     Record.clear();
     StringRef Blob;
     if (SIGNATURE == Stream.readRecord(Entry.ID, Record, &Blob))
-      return Record[0];
+      return {{{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
+                (uint32_t)Record[3], (uint32_t)Record[4]}}};
   }
 }
 
@@ -4349,7 +4491,8 @@
   }
 
   // Initialize the stream
-  BitstreamCursor Stream(PCHContainerRdr.ExtractPCH(**Buffer));
+  StringRef Bytes = PCHContainerRdr.ExtractPCH(**Buffer);
+  BitstreamCursor Stream(Bytes);
 
   // Sniff for the signature.
   if (!startsWithASTFileMagic(Stream))
@@ -4377,8 +4520,7 @@
         std::string IgnoredSuggestedPredefines;
         if (ReadOptionsBlock(Stream, ARR_ConfigurationMismatch | ARR_OutOfDate,
                              /*AllowCompatibleConfigurationMismatch*/ false,
-                             Listener, IgnoredSuggestedPredefines,
-                             ValidateDiagnosticOptions) != Success)
+                             Listener, IgnoredSuggestedPredefines) != Success)
           return true;
         break;
       }
@@ -4499,6 +4641,7 @@
 
   // Look for module file extension blocks, if requested.
   if (FindModuleFileExtensions) {
+    BitstreamCursor SavedStream = Stream;
     while (!SkipCursorToBlock(Stream, EXTENSION_BLOCK_ID)) {
       bool DoneWithExtensionBlock = false;
       while (!DoneWithExtensionBlock) {
@@ -4537,8 +4680,16 @@
        }
       }
     }
+    Stream = SavedStream;
   }
 
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (readUnhashedControlBlockImpl(
+          nullptr, Bytes, ARR_ConfigurationMismatch | ARR_OutOfDate,
+          /*AllowCompatibleConfigurationMismatch*/ false, &Listener,
+          ValidateDiagnosticOptions) != Success)
+    return true;
+
   return false;
 }
 
@@ -4617,6 +4768,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 +4813,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 +5441,83 @@
 }
 
 void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
-  // FIXME: Make it work properly with modules.
-  SmallVector<DiagnosticsEngine::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;
-      }
+  using DiagState = DiagnosticsEngine::DiagState;
+  SmallVector<DiagState *, 32> DiagStates;
 
-      assert(DiagStateID == 0);
+  for (ModuleFile &F : ModuleMgr) {
+    unsigned Idx = 0;
+    auto &Record = F.PragmaDiagMappings;
+    if (Record.empty())
+      continue;
+
+    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();
   }
 }
 
@@ -7092,18 +7280,15 @@
                   GlobalPreprocessedEntityMap);
 
   llvm::errs() << "\n*** PCH/Modules Loaded:";
-  for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(),
-                                       MEnd = ModuleMgr.end();
-       M != MEnd; ++M)
-    (*M)->dump();
+  for (ModuleFile &M : ModuleMgr)
+    M.dump();
 }
 
 /// Return the amount of memory used by memory buffers, breaking down
 /// by heap-backed versus mmap'ed memory.
 void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
-  for (ModuleConstIterator I = ModuleMgr.begin(),
-      E = ModuleMgr.end(); I != E; ++I) {
-    if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) {
+  for (ModuleFile &I : ModuleMgr) {
+    if (llvm::MemoryBuffer *buf = I.Buffer) {
       size_t bytes = buf->getBufferSize();
       switch (buf->getBufferKind()) {
         case llvm::MemoryBuffer::MemoryBuffer_Malloc:
@@ -8493,6 +8678,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())
@@ -8905,8 +9105,10 @@
                    : cast<ASTReaderListener>(new PCHValidator(PP, *this))),
       SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
       PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
-      Context(Context), ModuleMgr(PP.getFileManager(), PCHContainerRdr),
-      DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
+      Context(Context),
+      ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr),
+      PCMCache(PP.getPCMCache()), DummyIdResolver(PP),
+      ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
       DisableValidation(DisableValidation),
       AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
       AllowConfigurationMismatch(AllowConfigurationMismatch),
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index c691919..707a924 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -2513,8 +2513,8 @@
 
   // An ImportDecl or VarDecl imported from a module will get emitted when
   // we import the relevant module.
-  if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && Ctx.DeclMustBeEmitted(D) &&
-      D->getImportedOwningModule())
+  if ((isa<ImportDecl>(D) || isa<VarDecl>(D)) && D->getImportedOwningModule() &&
+      Ctx.DeclMustBeEmitted(D))
     return false;
 
   if (isa<FileScopeAsmDecl>(D) || 
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 886523e..a44c9a8 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -18,8 +18,8 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTUnresolvedSet.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/DeclContextInternals.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclContextInternals.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
@@ -33,8 +33,9 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/SourceManager.h"
@@ -64,9 +65,9 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Bitcode/BitCodes.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
@@ -78,6 +79,7 @@
 #include "llvm/Support/OnDiskHashTable.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/SHA1.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
@@ -1001,7 +1003,6 @@
   // Control Block.
   BLOCK(CONTROL_BLOCK);
   RECORD(METADATA);
-  RECORD(SIGNATURE);
   RECORD(MODULE_NAME);
   RECORD(MODULE_DIRECTORY);
   RECORD(MODULE_MAP_FILE);
@@ -1014,7 +1015,6 @@
   BLOCK(OPTIONS_BLOCK);
   RECORD(LANGUAGE_OPTIONS);
   RECORD(TARGET_OPTIONS);
-  RECORD(DIAGNOSTIC_OPTIONS);
   RECORD(FILE_SYSTEM_OPTIONS);
   RECORD(HEADER_SEARCH_OPTIONS);
   RECORD(PREPROCESSOR_OPTIONS);
@@ -1049,7 +1049,6 @@
   RECORD(UPDATE_VISIBLE);
   RECORD(DECL_UPDATE_OFFSETS);
   RECORD(DECL_UPDATES);
-  RECORD(DIAG_PRAGMA_MAPPINGS);
   RECORD(CUDA_SPECIAL_DECL_REFS);
   RECORD(HEADER_SEARCH_TABLE);
   RECORD(FP_PRAGMA_OPTIONS);
@@ -1242,6 +1241,11 @@
   BLOCK(EXTENSION_BLOCK);
   RECORD(EXTENSION_METADATA);
 
+  BLOCK(UNHASHED_CONTROL_BLOCK);
+  RECORD(SIGNATURE);
+  RECORD(DIAGNOSTIC_OPTIONS);
+  RECORD(DIAG_PRAGMA_MAPPINGS);
+
 #undef RECORD
 #undef BLOCK
   Stream.ExitBlock();
@@ -1304,21 +1308,73 @@
   return Filename + Pos;
 }
 
-static ASTFileSignature getSignature() {
-  while (true) {
-    if (ASTFileSignature S = llvm::sys::Process::GetRandomNumber())
-      return S;
-    // Rely on GetRandomNumber to eventually return non-zero...
+ASTFileSignature ASTWriter::createSignature(StringRef Bytes) {
+  // Calculate the hash till start of UNHASHED_CONTROL_BLOCK.
+  llvm::SHA1 Hasher;
+  Hasher.update(ArrayRef<uint8_t>(Bytes.bytes_begin(), Bytes.size()));
+  auto Hash = Hasher.result();
+
+  // Convert to an array [5*i32].
+  ASTFileSignature Signature;
+  auto LShift = [&](unsigned char Val, unsigned Shift) {
+    return (uint32_t)Val << Shift;
+  };
+  for (int I = 0; I != 5; ++I)
+    Signature[I] = LShift(Hash[I * 4 + 0], 24) | LShift(Hash[I * 4 + 1], 16) |
+                   LShift(Hash[I * 4 + 2], 8) | LShift(Hash[I * 4 + 3], 0);
+
+  return Signature;
+}
+
+ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
+                                                      ASTContext &Context) {
+  // Flush first to prepare the PCM hash (signature).
+  Stream.FlushToWord();
+  auto StartOfUnhashedControl = Stream.GetCurrentBitNo() >> 3;
+
+  // Enter the block and prepare to write records.
+  RecordData Record;
+  Stream.EnterSubblock(UNHASHED_CONTROL_BLOCK_ID, 5);
+
+  // For implicit modules, write the hash of the PCM as its signature.
+  ASTFileSignature Signature;
+  if (WritingModule &&
+      PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent) {
+    Signature = createSignature(StringRef(Buffer.begin(), StartOfUnhashedControl));
+    Record.append(Signature.begin(), Signature.end());
+    Stream.EmitRecord(SIGNATURE, Record);
+    Record.clear();
   }
+
+  // Diagnostic options.
+  const auto &Diags = Context.getDiagnostics();
+  const DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();
+#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
+#define ENUM_DIAGOPT(Name, Type, Bits, Default)                                \
+  Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
+#include "clang/Basic/DiagnosticOptions.def"
+  Record.push_back(DiagOpts.Warnings.size());
+  for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
+    AddString(DiagOpts.Warnings[I], Record);
+  Record.push_back(DiagOpts.Remarks.size());
+  for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
+    AddString(DiagOpts.Remarks[I], Record);
+  // Note: we don't serialize the log or serialization file names, because they
+  // are generally transient files and will almost always be overridden.
+  Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
+
+  // Write out the diagnostic/pragma mappings.
+  WritePragmaDiagnosticMappings(Diags, /* IsModule = */ WritingModule);
+
+  // Leave the options block.
+  Stream.ExitBlock();
+  return Signature;
 }
 
 /// \brief Write the control block.
-uint64_t ASTWriter::WriteControlBlock(Preprocessor &PP,
-                                      ASTContext &Context,
-                                      StringRef isysroot,
-                                      const std::string &OutputFile) {
-  ASTFileSignature Signature = 0;
-
+void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+                                  StringRef isysroot,
+                                  const std::string &OutputFile) {
   using namespace llvm;
   Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
   RecordData Record;
@@ -1346,15 +1402,6 @@
                               getClangFullRepositoryVersion());
   }
   if (WritingModule) {
-    // For implicit modules we output a signature that we can use to ensure
-    // duplicate module builds don't collide in the cache as their output order
-    // is non-deterministic.
-    // FIXME: Remove this when output is deterministic.
-    if (Context.getLangOpts().ImplicitModules) {
-      Signature = getSignature();
-      RecordData::value_type Record[] = {Signature};
-      Stream.EmitRecord(SIGNATURE, Record);
-    }
 
     // Module name
     auto Abbrev = std::make_shared<BitCodeAbbrev>();
@@ -1420,17 +1467,23 @@
     serialization::ModuleManager &Mgr = Chain->getModuleManager();
     Record.clear();
 
-    for (auto *M : Mgr) {
+    for (ModuleFile &M : Mgr) {
       // Skip modules that weren't directly imported.
-      if (!M->isDirectlyImported())
+      if (!M.isDirectlyImported())
         continue;
 
-      Record.push_back((unsigned)M->Kind); // FIXME: Stable encoding
-      AddSourceLocation(M->ImportLoc, Record);
-      Record.push_back(M->File->getSize());
-      Record.push_back(getTimestampForOutput(M->File));
-      Record.push_back(M->Signature);
-      AddPath(M->FileName, Record);
+      Record.push_back((unsigned)M.Kind); // FIXME: Stable encoding
+      AddSourceLocation(M.ImportLoc, Record);
+
+      // If we have calculated signature, there is no need to store
+      // the size or timestamp.
+      Record.push_back(M.Signature ? 0 : M.File->getSize());
+      Record.push_back(M.Signature ? 0 : getTimestampForOutput(M.File));
+
+      for (auto I : M.Signature)
+        Record.push_back(I);
+
+      AddPath(M.FileName, Record);
     }
     Stream.EmitRecord(IMPORTS, Record);
   }
@@ -1492,24 +1545,6 @@
   }
   Stream.EmitRecord(TARGET_OPTIONS, Record);
 
-  // Diagnostic options.
-  Record.clear();
-  const DiagnosticOptions &DiagOpts
-    = Context.getDiagnostics().getDiagnosticOptions();
-#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-  Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
-#include "clang/Basic/DiagnosticOptions.def"
-  Record.push_back(DiagOpts.Warnings.size());
-  for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
-    AddString(DiagOpts.Warnings[I], Record);
-  Record.push_back(DiagOpts.Remarks.size());
-  for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
-    AddString(DiagOpts.Remarks[I], Record);
-  // Note: we don't serialize the log or serialization file names, because they
-  // are generally transient files and will almost always be overridden.
-  Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
-
   // File system options.
   Record.clear();
   const FileSystemOptions &FSOpts =
@@ -1623,7 +1658,6 @@
                   PP.getHeaderSearchInfo().getHeaderSearchOpts(),
                   PP.getLangOpts().Modules);
   Stream.ExitBlock();
-  return Signature;
 }
 
 namespace  {
@@ -2516,7 +2550,8 @@
 
   auto *Top = Mod->getTopLevelModule();
   if (Top != WritingModule &&
-      !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule)))
+      (getLangOpts().CompilingPCH ||
+       !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule))))
     return 0;
 
   return SubmoduleIDs[Mod] = NextSubmoduleID++;
@@ -2558,6 +2593,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 +2688,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 +2825,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 +3324,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 +3473,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);
     }
 
@@ -4223,9 +4260,11 @@
 }
 
 ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
+                     SmallVectorImpl<char> &Buffer, MemoryBufferCache &PCMCache,
                      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
                      bool IncludeTimestamps)
-    : Stream(Stream), IncludeTimestamps(IncludeTimestamps) {
+    : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache),
+      IncludeTimestamps(IncludeTimestamps) {
   for (const auto &Ext : Extensions) {
     if (auto Writer = Ext->createExtensionWriter(*this))
       ModuleFileExtensionWriters.push_back(std::move(Writer));
@@ -4245,9 +4284,10 @@
   return IncludeTimestamps ? E->getModificationTime() : 0;
 }
 
-uint64_t ASTWriter::WriteAST(Sema &SemaRef, const std::string &OutputFile,
-                             Module *WritingModule, StringRef isysroot,
-                             bool hasErrors) {
+ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
+                                     const std::string &OutputFile,
+                                     Module *WritingModule, StringRef isysroot,
+                                     bool hasErrors) {
   WritingAST = true;
 
   ASTHasCompilerErrors = hasErrors;
@@ -4271,6 +4311,12 @@
   this->BaseDirectory.clear();
 
   WritingAST = false;
+  if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) {
+    // Construct MemoryBuffer and update buffer manager.
+    PCMCache.addBuffer(OutputFile,
+                       llvm::MemoryBuffer::getMemBufferCopy(
+                           StringRef(Buffer.begin(), Buffer.size())));
+  }
   return Signature;
 }
 
@@ -4283,9 +4329,9 @@
   }
 }
 
-uint64_t ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
-                                 const std::string &OutputFile,
-                                 Module *WritingModule) {
+ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
+                                         const std::string &OutputFile,
+                                         Module *WritingModule) {
   using namespace llvm;
 
   bool isModule = WritingModule != nullptr;
@@ -4433,7 +4479,7 @@
   }
 
   // Write the control block
-  uint64_t Signature = WriteControlBlock(PP, Context, isysroot, OutputFile);
+  WriteControlBlock(PP, Context, isysroot, OutputFile);
 
   // Write the remaining AST contents.
   Stream.EnterSubblock(AST_BLOCK_ID, 5);
@@ -4573,10 +4619,10 @@
     SmallString<2048> Buffer;
     {
       llvm::raw_svector_ostream Out(Buffer);
-      for (ModuleFile *M : Chain->ModuleMgr) {
+      for (ModuleFile &M : Chain->ModuleMgr) {
         using namespace llvm::support;
         endian::Writer<little> LE(Out);
-        StringRef FileName = M->FileName;
+        StringRef FileName = M.FileName;
         LE.write<uint16_t>(FileName.size());
         Out.write(FileName.data(), FileName.size());
 
@@ -4594,15 +4640,15 @@
 
         // These values should be unique within a chain, since they will be read
         // as keys into ContinuousRangeMaps.
-        writeBaseIDOrNone(M->SLocEntryBaseOffset, M->LocalNumSLocEntries);
-        writeBaseIDOrNone(M->BaseIdentifierID, M->LocalNumIdentifiers);
-        writeBaseIDOrNone(M->BaseMacroID, M->LocalNumMacros);
-        writeBaseIDOrNone(M->BasePreprocessedEntityID,
-                          M->NumPreprocessedEntities);
-        writeBaseIDOrNone(M->BaseSubmoduleID, M->LocalNumSubmodules);
-        writeBaseIDOrNone(M->BaseSelectorID, M->LocalNumSelectors);
-        writeBaseIDOrNone(M->BaseDeclID, M->LocalNumDecls);
-        writeBaseIDOrNone(M->BaseTypeIndex, M->LocalNumTypes);
+        writeBaseIDOrNone(M.SLocEntryBaseOffset, M.LocalNumSLocEntries);
+        writeBaseIDOrNone(M.BaseIdentifierID, M.LocalNumIdentifiers);
+        writeBaseIDOrNone(M.BaseMacroID, M.LocalNumMacros);
+        writeBaseIDOrNone(M.BasePreprocessedEntityID,
+                          M.NumPreprocessedEntities);
+        writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
+        writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
+        writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls);
+        writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes);
       }
     }
     RecordData::value_type Record[] = {MODULE_OFFSET_MAP};
@@ -4650,7 +4696,6 @@
   WriteOpenCLExtensionTypes(SemaRef);
   WriteOpenCLExtensionDecls(SemaRef);
   WriteCUDAPragmas(SemaRef);
-  WritePragmaDiagnosticMappings(Context.getDiagnostics(), isModule);
 
   // If we're emitting a module, write out the submodule information.  
   if (WritingModule)
@@ -4776,7 +4821,7 @@
   for (const auto &ExtWriter : ModuleFileExtensionWriters)
     WriteModuleFileExtension(SemaRef, *ExtWriter);
 
-  return Signature;
+  return writeUnhashedControlBlock(PP, Context);
 }
 
 void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index 7f1b750..429ae8e 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -28,7 +28,8 @@
     bool AllowASTWithErrors, bool IncludeTimestamps)
     : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
       SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data),
-      Writer(Stream, Extensions, IncludeTimestamps),
+      Writer(Stream, Buffer->Data, PP.getPCMCache(), Extensions,
+             IncludeTimestamps),
       AllowASTWithErrors(AllowASTWithErrors) {
   Buffer->IsComplete = false;
 }
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index ae5796e..6978e7e 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -376,6 +376,15 @@
     /// \brief The set of modules on which this module depends. Each entry is
     /// a module ID.
     SmallVector<unsigned, 4> Dependencies;
+    ASTFileSignature Signature;
+  };
+
+  struct ImportedModuleFileInfo {
+    off_t StoredSize;
+    time_t StoredModTime;
+    ASTFileSignature StoredSignature;
+    ImportedModuleFileInfo(off_t Size, time_t ModTime, ASTFileSignature Sig)
+        : StoredSize(Size), StoredModTime(ModTime), StoredSignature(Sig) {}
   };
 
   /// \brief Builder that generates the global module index file.
@@ -383,12 +392,20 @@
     FileManager &FileMgr;
     const PCHContainerReader &PCHContainerRdr;
 
-    /// \brief Mapping from files to module file information.
+    /// Mapping from files to module file information.
     typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
 
-    /// \brief Information about each of the known module files.
+    /// Information about each of the known module files.
     ModuleFilesMap ModuleFiles;
 
+    /// \brief Mapping from the imported module file to the imported
+    /// information.
+    typedef std::multimap<const FileEntry *, ImportedModuleFileInfo>
+        ImportedModuleFilesMap;
+
+    /// \brief Information about each importing of a module file.
+    ImportedModuleFilesMap ImportedModuleFiles;
+
     /// \brief Mapping from identifiers to the list of module file IDs that
     /// consider this identifier to be interesting.
     typedef llvm::StringMap<SmallVector<unsigned, 2> > InterestingIdentifierMap;
@@ -424,7 +441,8 @@
     bool loadModuleFile(const FileEntry *File);
 
     /// \brief Write the index to the given bitstream.
-    void writeIndex(llvm::BitstreamWriter &Stream);
+    /// \returns true if an error occurred, false otherwise.
+    bool writeIndex(llvm::BitstreamWriter &Stream);
   };
 }
 
@@ -515,7 +533,7 @@
   unsigned ID = getModuleFileInfo(File).ID;
 
   // Search for the blocks and records we care about.
-  enum { Other, ControlBlock, ASTBlock } State = Other;
+  enum { Other, ControlBlock, ASTBlock, DiagnosticOptionsBlock } State = Other;
   bool Done = false;
   while (!Done) {
     llvm::BitstreamEntry Entry = InStream.advance();
@@ -553,6 +571,15 @@
         continue;
       }
 
+      if (Entry.ID == UNHASHED_CONTROL_BLOCK_ID) {
+        if (InStream.EnterSubBlock(UNHASHED_CONTROL_BLOCK_ID))
+          return true;
+
+        // Found the Diagnostic Options block.
+        State = DiagnosticOptionsBlock;
+        continue;
+      }
+
       if (InStream.SkipBlock())
         return true;
 
@@ -587,7 +614,10 @@
 
         // Skip the stored signature.
         // FIXME: we could read the signature out of the import and validate it.
-        Idx++;
+        ASTFileSignature StoredSignature = {
+            {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++]}}};
 
         // Retrieve the imported file name.
         unsigned Length = Record[Idx++];
@@ -599,11 +629,16 @@
         const FileEntry *DependsOnFile
           = FileMgr.getFile(ImportedFile, /*openFile=*/false,
                             /*cacheFailure=*/false);
-        if (!DependsOnFile ||
-            (StoredSize != DependsOnFile->getSize()) ||
-            (StoredModTime != DependsOnFile->getModificationTime()))
+
+        if (!DependsOnFile)
           return true;
 
+        // Save the information in ImportedModuleFileInfo so we can verify after
+        // loading all pcms.
+        ImportedModuleFiles.insert(std::make_pair(
+            DependsOnFile, ImportedModuleFileInfo(StoredSize, StoredModTime,
+                                                  StoredSignature)));
+
         // Record the dependency.
         unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID;
         getModuleFileInfo(File).Dependencies.push_back(DependsOnID);
@@ -632,6 +667,12 @@
       }
     }
 
+    // Get Signature.
+    if (State == DiagnosticOptionsBlock && Code == SIGNATURE)
+      getModuleFileInfo(File).Signature = {
+          {{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
+            (uint32_t)Record[3], (uint32_t)Record[4]}}};
+
     // We don't care about this record.
   }
 
@@ -680,7 +721,20 @@
 
 }
 
-void GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
+bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
+  for (auto MapEntry : ImportedModuleFiles) {
+    auto *File = MapEntry.first;
+    ImportedModuleFileInfo &Info = MapEntry.second;
+    if (getModuleFileInfo(File).Signature) {
+      if (getModuleFileInfo(File).Signature != Info.StoredSignature)
+        // Verify Signature.
+        return true;
+    } else if (Info.StoredSize != File->getSize() ||
+               Info.StoredModTime != File->getModificationTime())
+      // Verify Size and ModTime.
+      return true;
+  }
+
   using namespace llvm;
   
   // Emit the file header.
@@ -756,6 +810,7 @@
   }
 
   Stream.ExitBlock();
+  return false;
 }
 
 GlobalModuleIndex::ErrorCode
@@ -816,7 +871,8 @@
   SmallVector<char, 16> OutputBuffer;
   {
     llvm::BitstreamWriter OutputStream(OutputBuffer);
-    Builder.writeIndex(OutputStream);
+    if (Builder.writeIndex(OutputStream))
+      return EC_IOError;
   }
 
   // Write the global index file to a temporary file.
diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp
index 72b0861..5a44d26 100644
--- a/lib/Serialization/Module.cpp
+++ b/lib/Serialization/Module.cpp
@@ -19,28 +19,6 @@
 using namespace serialization;
 using namespace reader;
 
-ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
-  : Kind(Kind), File(nullptr), Signature(0), DirectlyImported(false),
-    Generation(Generation), SizeInBits(0),
-    LocalNumSLocEntries(0), SLocEntryBaseID(0),
-    SLocEntryBaseOffset(0), SLocEntryOffsets(nullptr),
-    LocalNumIdentifiers(0),
-    IdentifierOffsets(nullptr), BaseIdentifierID(0),
-    IdentifierTableData(nullptr), IdentifierLookupTable(nullptr),
-    LocalNumMacros(0), MacroOffsets(nullptr),
-    BasePreprocessedEntityID(0),
-    PreprocessedEntityOffsets(nullptr), NumPreprocessedEntities(0),
-    LocalNumHeaderFileInfos(0), 
-    HeaderFileInfoTableData(nullptr), HeaderFileInfoTable(nullptr),
-    LocalNumSubmodules(0), BaseSubmoduleID(0),
-    LocalNumSelectors(0), SelectorOffsets(nullptr), BaseSelectorID(0),
-    SelectorLookupTableData(nullptr), SelectorLookupTable(nullptr),
-    LocalNumDecls(0), DeclOffsets(nullptr), BaseDeclID(0),
-    FileSortedDecls(nullptr), NumFileSortedDecls(0),
-    ObjCCategoriesMap(nullptr), LocalNumObjCCategoriesInMap(0),
-    LocalNumTypes(0), TypeOffsets(nullptr), BaseTypeIndex(0)
-{}
-
 ModuleFile::~ModuleFile() {
   delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
   delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 722b547..e35a44d 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/Serialization/ModuleManager.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/ModuleMap.h"
@@ -52,6 +53,30 @@
   return std::move(InMemoryBuffers[Entry]);
 }
 
+static bool checkSignature(ASTFileSignature Signature,
+                           ASTFileSignature ExpectedSignature,
+                           std::string &ErrorStr) {
+  if (!ExpectedSignature || Signature == ExpectedSignature)
+    return false;
+
+  ErrorStr =
+      Signature ? "signature mismatch" : "could not read module signature";
+  return true;
+}
+
+static void updateModuleImports(ModuleFile &MF, ModuleFile *ImportedBy,
+                                SourceLocation ImportLoc) {
+  if (ImportedBy) {
+    MF.ImportedBy.insert(ImportedBy);
+    ImportedBy->Imports.insert(&MF);
+  } else {
+    if (!MF.DirectlyImported)
+      MF.ImportLoc = ImportLoc;
+
+    MF.DirectlyImported = true;
+  }
+}
+
 ModuleManager::AddModuleResult
 ModuleManager::addModule(StringRef FileName, ModuleKind Type,
                          SourceLocation ImportLoc, ModuleFile *ImportedBy,
@@ -84,141 +109,133 @@
   }
 
   // Check whether we already loaded this module, before
-  ModuleFile *ModuleEntry = Modules[Entry];
-  bool NewModule = false;
-  if (!ModuleEntry) {
-    // Allocate a new module.
-    NewModule = true;
-    ModuleEntry = new ModuleFile(Type, Generation);
-    ModuleEntry->Index = Chain.size();
-    ModuleEntry->FileName = FileName.str();
-    ModuleEntry->File = Entry;
-    ModuleEntry->ImportLoc = ImportLoc;
-    ModuleEntry->InputFilesValidationTimestamp = 0;
-
-    if (ModuleEntry->Kind == MK_ImplicitModule) {
-      std::string TimestampFilename = ModuleEntry->getTimestampFilename();
-      vfs::Status Status;
-      // A cached stat value would be fine as well.
-      if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
-        ModuleEntry->InputFilesValidationTimestamp =
-            llvm::sys::toTimeT(Status.getLastModificationTime());
-    }
-
-    // Load the contents of the module
-    if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
-      // The buffer was already provided for us.
-      ModuleEntry->Buffer = std::move(Buffer);
-    } else {
-      // Open the AST file.
-      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf(
-          (std::error_code()));
-      if (FileName == "-") {
-        Buf = llvm::MemoryBuffer::getSTDIN();
-      } else {
-        // Leave the FileEntry open so if it gets read again by another
-        // ModuleManager it must be the same underlying file.
-        // FIXME: Because FileManager::getFile() doesn't guarantee that it will
-        // give us an open file, this may not be 100% reliable.
-        Buf = FileMgr.getBufferForFile(ModuleEntry->File,
-                                       /*IsVolatile=*/false,
-                                       /*ShouldClose=*/false);
-      }
-
-      if (!Buf) {
-        ErrorStr = Buf.getError().message();
-        delete ModuleEntry;
-        return Missing;
-      }
-
-      ModuleEntry->Buffer = std::move(*Buf);
-    }
-
-    // Initialize the stream.
-    ModuleEntry->Data = PCHContainerRdr.ExtractPCH(*ModuleEntry->Buffer);
-  }
-
-  if (ExpectedSignature) {
-    // If we've not read the control block yet, read the signature eagerly now
-    // so that we can check it.
-    if (!ModuleEntry->Signature)
-      ModuleEntry->Signature = ReadSignature(ModuleEntry->Data);
-
-    if (ModuleEntry->Signature != ExpectedSignature) {
-      ErrorStr = ModuleEntry->Signature ? "signature mismatch"
-                                        : "could not read module signature";
-
-      if (NewModule)
-        delete ModuleEntry;
+  if (ModuleFile *ModuleEntry = Modules.lookup(Entry)) {
+    // Check the stored signature.
+    if (checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr))
       return OutOfDate;
-    }
-  }
 
-  if (ImportedBy) {
-    ModuleEntry->ImportedBy.insert(ImportedBy);
-    ImportedBy->Imports.insert(ModuleEntry);
-  } else {
-    if (!ModuleEntry->DirectlyImported)
-      ModuleEntry->ImportLoc = ImportLoc;
-    
-    ModuleEntry->DirectlyImported = true;
-  }
-
-  Module = ModuleEntry;
-
-  if (!NewModule)
+    Module = ModuleEntry;
+    updateModuleImports(*ModuleEntry, ImportedBy, ImportLoc);
     return AlreadyLoaded;
+  }
 
-  assert(!Modules[Entry] && "module loaded twice");
-  Modules[Entry] = ModuleEntry;
+  // Allocate a new module.
+  auto NewModule = llvm::make_unique<ModuleFile>(Type, Generation);
+  NewModule->Index = Chain.size();
+  NewModule->FileName = FileName.str();
+  NewModule->File = Entry;
+  NewModule->ImportLoc = ImportLoc;
+  NewModule->InputFilesValidationTimestamp = 0;
 
-  Chain.push_back(ModuleEntry);
-  if (!ModuleEntry->isModule())
-    PCHChain.push_back(ModuleEntry);
+  if (NewModule->Kind == MK_ImplicitModule) {
+    std::string TimestampFilename = NewModule->getTimestampFilename();
+    vfs::Status Status;
+    // A cached stat value would be fine as well.
+    if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
+      NewModule->InputFilesValidationTimestamp =
+          llvm::sys::toTimeT(Status.getLastModificationTime());
+  }
+
+  // Load the contents of the module
+  if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
+    // The buffer was already provided for us.
+    NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer));
+  } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) {
+    NewModule->Buffer = Buffer;
+  } else {
+    // Open the AST file.
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code()));
+    if (FileName == "-") {
+      Buf = llvm::MemoryBuffer::getSTDIN();
+    } else {
+      // Leave the FileEntry open so if it gets read again by another
+      // ModuleManager it must be the same underlying file.
+      // FIXME: Because FileManager::getFile() doesn't guarantee that it will
+      // give us an open file, this may not be 100% reliable.
+      Buf = FileMgr.getBufferForFile(NewModule->File,
+                                     /*IsVolatile=*/false,
+                                     /*ShouldClose=*/false);
+    }
+
+    if (!Buf) {
+      ErrorStr = Buf.getError().message();
+      return Missing;
+    }
+
+    NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf));
+  }
+
+  // Initialize the stream.
+  NewModule->Data = PCHContainerRdr.ExtractPCH(*NewModule->Buffer);
+
+  // Read the signature eagerly now so that we can check it.  Avoid calling
+  // ReadSignature unless there's something to check though.
+  if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data),
+                                          ExpectedSignature, ErrorStr)) {
+    // Try to remove the buffer.  If it can't be removed, then it was already
+    // validated by this process.
+    if (!PCMCache->tryToRemoveBuffer(NewModule->FileName))
+      FileMgr.invalidateCache(NewModule->File);
+    return OutOfDate;
+  }
+
+  // We're keeping this module.  Store it everywhere.
+  Module = Modules[Entry] = NewModule.get();
+
+  updateModuleImports(*NewModule, ImportedBy, ImportLoc);
+
+  if (!NewModule->isModule())
+    PCHChain.push_back(NewModule.get());
   if (!ImportedBy)
-    Roots.push_back(ModuleEntry);
+    Roots.push_back(NewModule.get());
 
+  Chain.push_back(std::move(NewModule));
   return NewlyLoaded;
 }
 
 void ModuleManager::removeModules(
-    ModuleIterator first, ModuleIterator last,
+    ModuleIterator First,
     llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
     ModuleMap *modMap) {
-  if (first == last)
+  auto Last = end();
+  if (First == Last)
     return;
 
+
   // Explicitly clear VisitOrder since we might not notice it is stale.
   VisitOrder.clear();
 
   // Collect the set of module file pointers that we'll be removing.
-  llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);
+  llvm::SmallPtrSet<ModuleFile *, 4> victimSet(
+      (llvm::pointer_iterator<ModuleIterator>(First)),
+      (llvm::pointer_iterator<ModuleIterator>(Last)));
 
   auto IsVictim = [&](ModuleFile *MF) {
     return victimSet.count(MF);
   };
   // Remove any references to the now-destroyed modules.
-  for (unsigned i = 0, n = Chain.size(); i != n; ++i) {
-    Chain[i]->ImportedBy.remove_if(IsVictim);
+  for (auto I = begin(); I != First; ++I) {
+    I->Imports.remove_if(IsVictim);
+    I->ImportedBy.remove_if(IsVictim);
   }
   Roots.erase(std::remove_if(Roots.begin(), Roots.end(), IsVictim),
               Roots.end());
 
   // Remove the modules from the PCH chain.
-  for (auto I = first; I != last; ++I) {
-    if (!(*I)->isModule()) {
-      PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), *I),
+  for (auto I = First; I != Last; ++I) {
+    if (!I->isModule()) {
+      PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), &*I),
                      PCHChain.end());
       break;
     }
   }
 
   // Delete the modules and erase them from the various structures.
-  for (ModuleIterator victim = first; victim != last; ++victim) {
-    Modules.erase((*victim)->File);
+  for (ModuleIterator victim = First; victim != Last; ++victim) {
+    Modules.erase(victim->File);
 
     if (modMap) {
-      StringRef ModuleName = (*victim)->ModuleName;
+      StringRef ModuleName = victim->ModuleName;
       if (Module *mod = modMap->findModule(ModuleName)) {
         mod->setASTFile(nullptr);
       }
@@ -227,14 +244,17 @@
     // Files that didn't make it through ReadASTCore successfully will be
     // rebuilt (or there was an error). Invalidate them so that we can load the
     // new files that will be renamed over the old ones.
-    if (LoadedSuccessfully.count(*victim) == 0)
-      FileMgr.invalidateCache((*victim)->File);
-
-    delete *victim;
+    //
+    // The PCMCache tracks whether the module was succesfully loaded in another
+    // thread/context; in that case, it won't need to be rebuilt (and we can't
+    // safely invalidate it anyway).
+    if (LoadedSuccessfully.count(&*victim) == 0 &&
+        !PCMCache->tryToRemoveBuffer(victim->FileName))
+      FileMgr.invalidateCache(victim->File);
   }
 
-  // Remove the modules from the chain.
-  Chain.erase(first, last);
+  // Delete the modules.
+  Chain.erase(Chain.begin() + (First - begin()), Chain.end());
 }
 
 void
@@ -274,11 +294,9 @@
 
   // Notify the global module index about all of the modules we've already
   // loaded.
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
-    if (!GlobalIndex->loadedModuleFile(Chain[I])) {
-      ModulesInCommonWithGlobalIndex.push_back(Chain[I]);
-    }
-  }
+  for (ModuleFile &M : *this)
+    if (!GlobalIndex->loadedModuleFile(&M))
+      ModulesInCommonWithGlobalIndex.push_back(&M);
 }
 
 void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
@@ -288,16 +306,12 @@
   ModulesInCommonWithGlobalIndex.push_back(MF);
 }
 
-ModuleManager::ModuleManager(FileManager &FileMgr,
+ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
                              const PCHContainerReader &PCHContainerRdr)
-    : FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr), GlobalIndex(),
-      FirstVisitState(nullptr) {}
+    : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr),
+      GlobalIndex(), FirstVisitState(nullptr) {}
 
-ModuleManager::~ModuleManager() {
-  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
-    delete Chain[e - i - 1];
-  delete FirstVisitState;
-}
+ModuleManager::~ModuleManager() { delete FirstVisitState; }
 
 void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
                           llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
@@ -314,11 +328,11 @@
     Queue.reserve(N);
     llvm::SmallVector<unsigned, 4> UnusedIncomingEdges;
     UnusedIncomingEdges.resize(size());
-    for (ModuleFile *M : llvm::reverse(*this)) {
-      unsigned Size = M->ImportedBy.size();
-      UnusedIncomingEdges[M->Index] = Size;
+    for (ModuleFile &M : llvm::reverse(*this)) {
+      unsigned Size = M.ImportedBy.size();
+      UnusedIncomingEdges[M.Index] = Size;
       if (!Size)
-        Queue.push_back(M);
+        Queue.push_back(&M);
     }
 
     // Traverse the graph, making sure to visit a module before visiting any
@@ -433,7 +447,7 @@
   struct GraphTraits<ModuleManager> {
     typedef ModuleFile *NodeRef;
     typedef llvm::SetVector<ModuleFile *>::const_iterator ChildIteratorType;
-    typedef ModuleManager::ModuleConstIterator nodes_iterator;
+    typedef pointer_iterator<ModuleManager::ModuleConstIterator> nodes_iterator;
 
     static ChildIteratorType child_begin(NodeRef Node) {
       return Node->Imports.begin();
@@ -444,11 +458,11 @@
     }
     
     static nodes_iterator nodes_begin(const ModuleManager &Manager) {
-      return Manager.begin();
+      return nodes_iterator(Manager.begin());
     }
     
     static nodes_iterator nodes_end(const ModuleManager &Manager) {
-      return Manager.end();
+      return nodes_iterator(Manager.end());
     }
   };
   
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 238032c8..32e3ce9 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -68,6 +68,7 @@
                        const InvalidatedSymbols *,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) const;
 
   typedef void (CStringChecker::*FnCheck)(CheckerContext &,
@@ -1943,8 +1944,12 @@
     // Overwrite the search string pointer. The new value is either an address
     // further along in the same string, or NULL if there are no more tokens.
     State = State->bindLoc(*SearchStrLoc,
-                           SVB.conjureSymbolVal(getTag(), CE, LCtx, CharPtrTy,
-                                                C.blockCount()));
+                           SVB.conjureSymbolVal(getTag(),
+                                                CE,
+                                                LCtx,
+                                                CharPtrTy,
+                                                C.blockCount()),
+                           LCtx);
   } else {
     assert(SearchStrVal.isUnknown());
     // Conjure a symbolic value. It's the best we can do.
@@ -2116,6 +2121,7 @@
                                    const InvalidatedSymbols *,
                                    ArrayRef<const MemRegion *> ExplicitRegions,
                                    ArrayRef<const MemRegion *> Regions,
+                                   const LocationContext *LCtx,
                                    const CallEvent *Call) const {
   CStringLengthTy Entries = state->get<CStringLength>();
   if (Entries.isEmpty())
diff --git a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
index 3db1994..391b843 100644
--- a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
@@ -36,25 +36,24 @@
   AnalysisDeclContext* AC;
 
   /// Check if two expressions refer to the same declaration.
-  inline bool sameDecl(const Expr *A1, const Expr *A2) {
-    if (const DeclRefExpr *D1 = dyn_cast<DeclRefExpr>(A1->IgnoreParenCasts()))
-      if (const DeclRefExpr *D2 = dyn_cast<DeclRefExpr>(A2->IgnoreParenCasts()))
+  bool sameDecl(const Expr *A1, const Expr *A2) {
+    if (const auto *D1 = dyn_cast<DeclRefExpr>(A1->IgnoreParenCasts()))
+      if (const auto *D2 = dyn_cast<DeclRefExpr>(A2->IgnoreParenCasts()))
         return D1->getDecl() == D2->getDecl();
     return false;
   }
 
   /// Check if the expression E is a sizeof(WithArg).
-  inline bool isSizeof(const Expr *E, const Expr *WithArg) {
-    if (const UnaryExprOrTypeTraitExpr *UE =
-    dyn_cast<UnaryExprOrTypeTraitExpr>(E))
-      if (UE->getKind() == UETT_SizeOf)
+  bool isSizeof(const Expr *E, const Expr *WithArg) {
+    if (const auto *UE = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
+      if (UE->getKind() == UETT_SizeOf && !UE->isArgumentType())
         return sameDecl(UE->getArgumentExpr(), WithArg);
     return false;
   }
 
   /// Check if the expression E is a strlen(WithArg).
-  inline bool isStrlen(const Expr *E, const Expr *WithArg) {
-    if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+  bool isStrlen(const Expr *E, const Expr *WithArg) {
+    if (const auto *CE = dyn_cast<CallExpr>(E)) {
       const FunctionDecl *FD = CE->getDirectCallee();
       if (!FD)
         return false;
@@ -65,14 +64,14 @@
   }
 
   /// Check if the expression is an integer literal with value 1.
-  inline bool isOne(const Expr *E) {
-    if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
+  bool isOne(const Expr *E) {
+    if (const auto *IL = dyn_cast<IntegerLiteral>(E))
       return (IL->getValue().isIntN(1));
     return false;
   }
 
-  inline StringRef getPrintableName(const Expr *E) {
-    if (const DeclRefExpr *D = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+  StringRef getPrintableName(const Expr *E) {
+    if (const auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
       return D->getDecl()->getName();
     return StringRef();
   }
@@ -82,8 +81,8 @@
   bool containsBadStrncatPattern(const CallExpr *CE);
 
 public:
-  WalkAST(const CheckerBase *checker, BugReporter &br, AnalysisDeclContext *ac)
-      : Checker(checker), BR(br), AC(ac) {}
+  WalkAST(const CheckerBase *Checker, BugReporter &BR, AnalysisDeclContext *AC)
+      : Checker(Checker), BR(BR), AC(AC) {}
 
   // Statement visitor methods.
   void VisitChildren(Stmt *S);
@@ -108,8 +107,7 @@
   const Expr *LenArg = CE->getArg(2);
 
   // Identify wrong size expressions, which are commonly used instead.
-  if (const BinaryOperator *BE =
-              dyn_cast<BinaryOperator>(LenArg->IgnoreParenCasts())) {
+  if (const auto *BE = dyn_cast<BinaryOperator>(LenArg->IgnoreParenCasts())) {
     // - sizeof(dst) - strlen(dst)
     if (BE->getOpcode() == BO_Sub) {
       const Expr *L = BE->getLHS();
diff --git a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
index 7631322..668e772 100644
--- a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
@@ -51,9 +51,9 @@
       State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));
   auto Param = SVB.makeLoc(State->getRegion(MD->getParamDecl(0), LCtx));
   auto ParamVal = State->getSVal(Param);
-  ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal);
+  ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal, LCtx);
   C.addTransition(SelfAssignState);
-  ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal);
+  ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal, LCtx);
   C.addTransition(NonSelfAssignState);
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
index 86764c9..95b6c4d 100644
--- a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
@@ -231,14 +231,6 @@
   /// check::LiveSymbols
   void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const {}
 
-  /// \brief Called to determine if the checker currently needs to know if when
-  /// contents of any regions change.
-  ///
-  /// Since it is not necessarily cheap to compute which regions are being
-  /// changed, this allows the analyzer core to skip the more expensive
-  /// #checkRegionChanges when no checkers are tracking any state.
-  bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }
-
   /// \brief Called when the contents of one or more regions change.
   ///
   /// This can occur in many different ways: an explicit bind, a blanket
@@ -255,18 +247,18 @@
   ///        by this change. For a simple bind, this list will be the same as
   ///        \p ExplicitRegions, since a bind does not affect the contents of
   ///        anything accessible through the base region.
+  /// \param LCtx LocationContext that is useful for getting various contextual
+  ///        info, like callstack, CFG etc.
   /// \param Call The opaque call triggering this invalidation. Will be 0 if the
   ///        change was not triggered by a call.
   ///
-  /// Note that this callback will not be invoked unless
-  /// #wantsRegionChangeUpdate returns \c true.
-  ///
   /// check::RegionChanges
   ProgramStateRef
     checkRegionChanges(ProgramStateRef State,
                        const InvalidatedSymbols *Invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) const {
     return State;
   }
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/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index 2d5cb60..fe48a94 100644
--- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -13,6 +13,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ScopedPrinter.h"
 
 using namespace clang;
 using namespace ento;
@@ -269,7 +270,7 @@
     unsigned NumTimesReached = Item.second.NumTimesReached;
     ExplodedNode *N = Item.second.ExampleNode;
 
-    reportBug(std::to_string(NumTimesReached), BR, N);
+    reportBug(llvm::to_string(NumTimesReached), BR, N);
   }
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index f1aa163..f8473db 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -28,7 +28,8 @@
 namespace {
 class MacOSKeychainAPIChecker : public Checker<check::PreStmt<CallExpr>,
                                                check::PostStmt<CallExpr>,
-                                               check::DeadSymbols> {
+                                               check::DeadSymbols,
+                                               eval::Assume> {
   mutable std::unique_ptr<BugType> BT;
 
 public:
@@ -57,6 +58,10 @@
   void checkPreStmt(const CallExpr *S, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *S, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
+  ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
+                             bool Assumption) const;
+  void printState(raw_ostream &Out, ProgramStateRef State,
+                  const char *NL, const char *Sep) const;
 
 private:
   typedef std::pair<SymbolRef, const AllocationState*> AllocationPair;
@@ -106,19 +111,6 @@
   std::unique_ptr<BugReport> generateAllocatedDataNotReleasedReport(
       const AllocationPair &AP, ExplodedNode *N, CheckerContext &C) const;
 
-  /// Check if RetSym evaluates to an error value in the current state.
-  bool definitelyReturnedError(SymbolRef RetSym,
-                               ProgramStateRef State,
-                               SValBuilder &Builder,
-                               bool noError = false) const;
-
-  /// Check if RetSym evaluates to a NoErr value in the current state.
-  bool definitelyDidnotReturnError(SymbolRef RetSym,
-                                   ProgramStateRef State,
-                                   SValBuilder &Builder) const {
-    return definitelyReturnedError(RetSym, State, Builder, true);
-  }
-
   /// Mark an AllocationPair interesting for diagnostic reporting.
   void markInteresting(BugReport *R, const AllocationPair &AP) const {
     R->markInteresting(AP.first);
@@ -221,24 +213,6 @@
   return nullptr;
 }
 
-// When checking for error code, we need to consider the following cases:
-// 1) noErr / [0]
-// 2) someErr / [1, inf]
-// 3) unknown
-// If noError, returns true iff (1).
-// If !noError, returns true iff (2).
-bool MacOSKeychainAPIChecker::definitelyReturnedError(SymbolRef RetSym,
-                                                      ProgramStateRef State,
-                                                      SValBuilder &Builder,
-                                                      bool noError) const {
-  DefinedOrUnknownSVal NoErrVal = Builder.makeIntVal(NoErr,
-    Builder.getSymbolManager().getType(RetSym));
-  DefinedOrUnknownSVal NoErr = Builder.evalEQ(State, NoErrVal,
-                                                     nonloc::SymbolVal(RetSym));
-  ProgramStateRef ErrState = State->assume(NoErr, noError);
-  return ErrState == State;
-}
-
 // Report deallocator mismatch. Remove the region from tracking - reporting a
 // missing free error after this one is redundant.
 void MacOSKeychainAPIChecker::
@@ -289,27 +263,25 @@
     const Expr *ArgExpr = CE->getArg(paramIdx);
     if (SymbolRef V = getAsPointeeSymbol(ArgExpr, C))
       if (const AllocationState *AS = State->get<AllocatedData>(V)) {
-        if (!definitelyReturnedError(AS->Region, State, C.getSValBuilder())) {
-          // Remove the value from the state. The new symbol will be added for
-          // tracking when the second allocator is processed in checkPostStmt().
-          State = State->remove<AllocatedData>(V);
-          ExplodedNode *N = C.generateNonFatalErrorNode(State);
-          if (!N)
-            return;
-          initBugType();
-          SmallString<128> sbuf;
-          llvm::raw_svector_ostream os(sbuf);
-          unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx;
-          os << "Allocated data should be released before another call to "
-              << "the allocator: missing a call to '"
-              << FunctionsToTrack[DIdx].Name
-              << "'.";
-          auto Report = llvm::make_unique<BugReport>(*BT, os.str(), N);
-          Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(V));
-          Report->addRange(ArgExpr->getSourceRange());
-          Report->markInteresting(AS->Region);
-          C.emitReport(std::move(Report));
-        }
+        // Remove the value from the state. The new symbol will be added for
+        // tracking when the second allocator is processed in checkPostStmt().
+        State = State->remove<AllocatedData>(V);
+        ExplodedNode *N = C.generateNonFatalErrorNode(State);
+        if (!N)
+          return;
+        initBugType();
+        SmallString<128> sbuf;
+        llvm::raw_svector_ostream os(sbuf);
+        unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx;
+        os << "Allocated data should be released before another call to "
+            << "the allocator: missing a call to '"
+            << FunctionsToTrack[DIdx].Name
+            << "'.";
+        auto Report = llvm::make_unique<BugReport>(*BT, os.str(), N);
+        Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(V));
+        Report->addRange(ArgExpr->getSourceRange());
+        Report->markInteresting(AS->Region);
+        C.emitReport(std::move(Report));
       }
     return;
   }
@@ -344,13 +316,12 @@
 
   // Is the argument to the call being tracked?
   const AllocationState *AS = State->get<AllocatedData>(ArgSM);
-  if (!AS && FunctionsToTrack[idx].Kind != ValidAPI) {
+  if (!AS)
     return;
-  }
-  // If trying to free data which has not been allocated yet, report as a bug.
-  // TODO: We might want a more precise diagnostic for double free
+
+  // TODO: We might want to report double free here.
   // (that would involve tracking all the freed symbols in the checker state).
-  if (!AS || RegionArgIsBad) {
+  if (RegionArgIsBad) {
     // It is possible that this is a false positive - the argument might
     // have entered as an enclosing function parameter.
     if (isEnclosingFunctionParam(ArgExpr))
@@ -418,23 +389,6 @@
     return;
   }
 
-  // If the buffer can be null and the return status can be an error,
-  // report a bad call to free.
-  if (State->assume(ArgSVal.castAs<DefinedSVal>(), false) &&
-      !definitelyDidnotReturnError(AS->Region, State, C.getSValBuilder())) {
-    ExplodedNode *N = C.generateNonFatalErrorNode(State);
-    if (!N)
-      return;
-    initBugType();
-    auto Report = llvm::make_unique<BugReport>(
-        *BT, "Only call free if a valid (non-NULL) buffer was returned.", N);
-    Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(ArgSM));
-    Report->addRange(ArgExpr->getSourceRange());
-    Report->markInteresting(AS->Region);
-    C.emitReport(std::move(Report));
-    return;
-  }
-
   C.addTransition(State);
 }
 
@@ -540,27 +494,63 @@
   return Report;
 }
 
+/// If the return symbol is assumed to be error, remove the allocated info
+/// from consideration.
+ProgramStateRef MacOSKeychainAPIChecker::evalAssume(ProgramStateRef State,
+                                                    SVal Cond,
+                                                    bool Assumption) const {
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+  if (AMap.isEmpty())
+    return State;
+
+  auto *CondBSE = dyn_cast_or_null<BinarySymExpr>(Cond.getAsSymExpr());
+  if (!CondBSE)
+    return State;
+  BinaryOperator::Opcode OpCode = CondBSE->getOpcode();
+  if (OpCode != BO_EQ && OpCode != BO_NE)
+    return State;
+
+  // Match for a restricted set of patterns for cmparison of error codes.
+  // Note, the comparisons of type '0 == st' are transformed into SymIntExpr.
+  SymbolRef ReturnSymbol = nullptr;
+  if (auto *SIE = dyn_cast<SymIntExpr>(CondBSE)) {
+    const llvm::APInt &RHS = SIE->getRHS();
+    bool ErrorIsReturned = (OpCode == BO_EQ && RHS != NoErr) ||
+                           (OpCode == BO_NE && RHS == NoErr);
+    if (!Assumption)
+      ErrorIsReturned = !ErrorIsReturned;
+    if (ErrorIsReturned)
+      ReturnSymbol = SIE->getLHS();
+  }
+
+  if (ReturnSymbol)
+    for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+      if (ReturnSymbol == I->second.Region)
+        State = State->remove<AllocatedData>(I->first);
+    }
+
+  return State;
+}
+
 void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
                                                CheckerContext &C) const {
   ProgramStateRef State = C.getState();
-  AllocatedDataTy ASet = State->get<AllocatedData>();
-  if (ASet.isEmpty())
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+  if (AMap.isEmpty())
     return;
 
   bool Changed = false;
   AllocationPairVec Errors;
-  for (AllocatedDataTy::iterator I = ASet.begin(), E = ASet.end(); I != E; ++I) {
-    if (SR.isLive(I->first))
+  for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+    if (!SR.isDead(I->first))
       continue;
 
     Changed = true;
     State = State->remove<AllocatedData>(I->first);
-    // If the allocated symbol is null or if the allocation call might have
-    // returned an error, do not report.
+    // If the allocated symbol is null do not report.
     ConstraintManager &CMgr = State->getConstraintManager();
     ConditionTruthVal AllocFailed = CMgr.isNull(State, I.getKey());
-    if (AllocFailed.isConstrainedTrue() ||
-        definitelyReturnedError(I->second.Region, State, C.getSValBuilder()))
+    if (AllocFailed.isConstrainedTrue())
       continue;
     Errors.push_back(std::make_pair(I->first, &I->second));
   }
@@ -612,6 +602,22 @@
                                                     "Data is allocated here.");
 }
 
+void MacOSKeychainAPIChecker::printState(raw_ostream &Out,
+                                         ProgramStateRef State,
+                                         const char *NL,
+                                         const char *Sep) const {
+
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+
+  if (!AMap.isEmpty()) {
+    Out << Sep << "KeychainAPIChecker :" << NL;
+    for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+      I.getKey()->dumpToStream(Out);
+    }
+  }
+}
+
+
 void ento::registerMacOSKeychainAPIChecker(CheckerManager &mgr) {
   mgr.registerChecker<MacOSKeychainAPIChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 8e839a1..504d470 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1154,7 +1154,7 @@
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
 
   // Fill the region with the initialization value.
-  State = State->bindDefault(RetVal, Init);
+  State = State->bindDefault(RetVal, Init, LCtx);
 
   // Set the region's extent equal to the Size parameter.
   const SymbolicRegion *R =
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index eb101e1..3f6ae62 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2661,6 +2661,7 @@
                      const InvalidatedSymbols *invalidated,
                      ArrayRef<const MemRegion *> ExplicitRegions,
                      ArrayRef<const MemRegion *> Regions,
+                     const LocationContext* LCtx,
                      const CallEvent *Call) const;
 
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
@@ -3647,7 +3648,7 @@
       // same state.
       SVal StoredVal = state->getSVal(regionLoc->getRegion());
       if (StoredVal != val)
-        escapes = (state == (state->bindLoc(*regionLoc, val)));
+        escapes = (state == (state->bindLoc(*regionLoc, val, C.getLocationContext())));
     }
     if (!escapes) {
       // Case 4: We do not currently model what happens when a symbol is
@@ -3714,10 +3715,11 @@
 
 ProgramStateRef
 RetainCountChecker::checkRegionChanges(ProgramStateRef state,
-                                    const InvalidatedSymbols *invalidated,
-                                    ArrayRef<const MemRegion *> ExplicitRegions,
-                                    ArrayRef<const MemRegion *> Regions,
-                                    const CallEvent *Call) const {
+                                       const InvalidatedSymbols *invalidated,
+                                       ArrayRef<const MemRegion *> ExplicitRegions,
+                                       ArrayRef<const MemRegion *> Regions,
+                                       const LocationContext *LCtx,
+                                       const CallEvent *Call) const {
   if (!invalidated)
     return state;
 
diff --git a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
index 15e8ea3..b47762b 100644
--- a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
@@ -179,7 +179,8 @@
   }
 
   // Get the callee.
-  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CE->getDirectCallee());
+  const CXXMethodDecl *MD =
+      dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee());
   if (MD && MD->isVirtual() && !callIsNonVirtual && !MD->hasAttr<FinalAttr>() &&
       !MD->getParent()->hasAttr<FinalAttr>())
     ReportVirtualCall(CE, MD->isPure());
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 420e2a6..ef824b8 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -212,9 +212,12 @@
 
 bool CallEvent::isCalled(const CallDescription &CD) const {
   assert(getKind() != CE_ObjCMessage && "Obj-C methods are not supported");
-  if (!CD.II)
+  if (!CD.IsLookupDone) {
+    CD.IsLookupDone = true;
     CD.II = &getState()->getStateManager().getContext().Idents.get(CD.FuncName);
-  if (getCalleeIdentifier() != CD.II)
+  }
+  const IdentifierInfo *II = getCalleeIdentifier();
+  if (!II || II != CD.II)
     return false;
   return (CD.RequiredArgs == CallDescription::NoArgRequirement ||
           CD.RequiredArgs == getNumArgs());
@@ -896,6 +899,38 @@
   llvm_unreachable("The while loop should always terminate.");
 }
 
+static const ObjCMethodDecl *findDefiningRedecl(const ObjCMethodDecl *MD) {
+  if (!MD)
+    return MD;
+
+  // Find the redeclaration that defines the method.
+  if (!MD->hasBody()) {
+    for (auto I : MD->redecls())
+      if (I->hasBody())
+        MD = cast<ObjCMethodDecl>(I);
+  }
+  return MD;
+}
+
+static bool isCallToSelfClass(const ObjCMessageExpr *ME) {
+  const Expr* InstRec = ME->getInstanceReceiver();
+  if (!InstRec)
+    return false;
+  const auto *InstRecIg = dyn_cast<DeclRefExpr>(InstRec->IgnoreParenImpCasts());
+
+  // Check that receiver is called 'self'.
+  if (!InstRecIg || !InstRecIg->getFoundDecl() ||
+      !InstRecIg->getFoundDecl()->getName().equals("self"))
+    return false;
+
+  // Check that the method name is 'class'.
+  if (ME->getSelector().getNumArgs() != 0 ||
+      !ME->getSelector().getNameForSlot(0).equals("class"))
+    return false;
+
+  return true;
+}
+
 RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
   const ObjCMessageExpr *E = getOriginExpr();
   assert(E);
@@ -910,6 +945,7 @@
     const MemRegion *Receiver = nullptr;
 
     if (!SupersType.isNull()) {
+      // The receiver is guaranteed to be 'super' in this case.
       // Super always means the type of immediate predecessor to the method
       // where the call occurs.
       ReceiverT = cast<ObjCObjectPointerType>(SupersType);
@@ -921,7 +957,7 @@
       DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
       QualType DynType = DTI.getType();
       CanBeSubClassed = DTI.canBeASubClass();
-      ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType);
+      ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
 
       if (ReceiverT && CanBeSubClassed)
         if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl())
@@ -929,7 +965,32 @@
             CanBeSubClassed = false;
     }
 
-    // Lookup the method implementation.
+    // Handle special cases of '[self classMethod]' and
+    // '[[self class] classMethod]', which are treated by the compiler as
+    // instance (not class) messages. We will statically dispatch to those.
+    if (auto *PT = dyn_cast_or_null<ObjCObjectPointerType>(ReceiverT)) {
+      // For [self classMethod], return the compiler visible declaration.
+      if (PT->getObjectType()->isObjCClass() &&
+          Receiver == getSelfSVal().getAsRegion())
+        return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
+
+      // Similarly, handle [[self class] classMethod].
+      // TODO: We are currently doing a syntactic match for this pattern with is
+      // limiting as the test cases in Analysis/inlining/InlineObjCClassMethod.m
+      // shows. A better way would be to associate the meta type with the symbol
+      // using the dynamic type info tracking and use it here. We can add a new
+      // SVal for ObjC 'Class' values that know what interface declaration they
+      // come from. Then 'self' in a class method would be filled in with
+      // something meaningful in ObjCMethodCall::getReceiverSVal() and we could
+      // do proper dynamic dispatch for class methods just like we do for
+      // instance methods now.
+      if (E->getInstanceReceiver())
+        if (const auto *M = dyn_cast<ObjCMessageExpr>(E->getInstanceReceiver()))
+          if (isCallToSelfClass(M))
+            return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
+    }
+
+    // Lookup the instance method implementation.
     if (ReceiverT)
       if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl()) {
         // Repeatedly calling lookupPrivateMethod() is expensive, especially
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 79e204c..49f3ede 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -521,17 +521,19 @@
 /// \brief Run checkers for region changes.
 ProgramStateRef
 CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
-                                    const InvalidatedSymbols *invalidated,
-                                    ArrayRef<const MemRegion *> ExplicitRegions,
-                                    ArrayRef<const MemRegion *> Regions,
-                                    const CallEvent *Call) {
+                                            const InvalidatedSymbols *invalidated,
+                                            ArrayRef<const MemRegion *> ExplicitRegions,
+                                            ArrayRef<const MemRegion *> Regions,
+                                            const LocationContext *LCtx,
+                                            const CallEvent *Call) {
   for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
     // If any checker declares the state infeasible (or if it starts that way),
     // bail out.
     if (!state)
       return nullptr;
     state = RegionChangesCheckers[i](state, invalidated,
-                                     ExplicitRegions, Regions, Call);
+                                     ExplicitRegions, Regions,
+                                     LCtx, Call);
   }
   return state;
 }
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index d563f8e..7d0c8b4 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -254,7 +254,7 @@
       break;
     case SubobjectAdjustment::MemberPointerAdjustment:
       // FIXME: Unimplemented.
-      State->bindDefault(Reg, UnknownVal());
+      State->bindDefault(Reg, UnknownVal(), LC);
       return State;
     }
   }
@@ -265,7 +265,7 @@
                                           currBldrCtx->blockCount());
   // Bind the value of the expression to the sub-object region, and then bind
   // the sub-object region to our expression.
-  State = State->bindLoc(Reg, V);
+  State = State->bindLoc(Reg, V, LC);
   State = State->BindExpr(Result, LC, Reg);
   return State;
 }
@@ -286,9 +286,11 @@
                                  const InvalidatedSymbols *invalidated,
                                  ArrayRef<const MemRegion *> Explicits,
                                  ArrayRef<const MemRegion *> Regions,
+                                 const LocationContext *LCtx,
                                  const CallEvent *Call) {
   return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
-                                                      Explicits, Regions, Call);
+                                                         Explicits, Regions,
+                                                         LCtx, Call);
 }
 
 void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
@@ -2165,7 +2167,9 @@
 // (3) We are binding to a MemRegion with stack storage that the store
 //     does not understand.
 ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
-                                                        SVal Loc, SVal Val) {
+                                                        SVal Loc,
+                                                        SVal Val,
+                                                        const LocationContext *LCtx) {
   // Are we storing to something that causes the value to "escape"?
   bool escapes = true;
 
@@ -2181,7 +2185,7 @@
       // same state.
       SVal StoredVal = State->getSVal(regionLoc->getRegion());
       if (StoredVal != Val)
-        escapes = (State == (State->bindLoc(*regionLoc, Val)));
+        escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
     }
   }
 
@@ -2278,7 +2282,7 @@
     const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr,
                                      /*tag*/nullptr);
     ProgramStateRef state = Pred->getState();
-    state = processPointerEscapedOnBind(state, location, Val);
+    state = processPointerEscapedOnBind(state, location, Val, LC);
     Bldr.generateNode(L, state, Pred);
     return;
   }
@@ -2288,13 +2292,13 @@
     ExplodedNode *PredI = *I;
     ProgramStateRef state = PredI->getState();
 
-    state = processPointerEscapedOnBind(state, location, Val);
+    state = processPointerEscapedOnBind(state, location, Val, LC);
 
     // When binding the value, pass on the hint that this is a initialization.
     // For initializations, we do not need to inform clients of region
     // changes.
     state = state->bindLoc(location.castAs<Loc>(),
-                           Val, /* notifyChanges = */ !atDeclInit);
+                           Val, LC, /* notifyChanges = */ !atDeclInit);
 
     const MemRegion *LocReg = nullptr;
     if (Optional<loc::MemRegionVal> LocRegVal =
@@ -2520,7 +2524,7 @@
     assert (!X.getAs<NonLoc>());  // Should be an Lval, or unknown, undef.
 
     if (Optional<Loc> LV = X.getAs<Loc>())
-      state = state->bindLoc(*LV, UnknownVal());
+      state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
   }
 
   Bldr.generateNode(A, Pred, state);
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 89fab1d..ea4ff91 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -227,12 +227,13 @@
 
       if (capturedR != originalR) {
         SVal originalV;
+        const LocationContext *LCtx = Pred->getLocationContext();
         if (copyExpr) {
-          originalV = State->getSVal(copyExpr, Pred->getLocationContext());
+          originalV = State->getSVal(copyExpr, LCtx);
         } else {
           originalV = State->getSVal(loc::MemRegionVal(originalR));
         }
-        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV);
+        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
       }
     }
   }
@@ -534,7 +535,7 @@
   } else {
     assert(isa<InitListExpr>(Init));
     Loc CLLoc = State->getLValue(CL, LCtx);
-    State = State->bindLoc(CLLoc, V);
+    State = State->bindLoc(CLLoc, V, LCtx);
 
     if (CL->isGLValue())
       V = CLLoc;
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 7e9b203..ca2e242 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -317,7 +317,7 @@
         // actually make things worse. Placement new makes this tricky as well,
         // since it's then possible to be initializing one part of a multi-
         // dimensional array.
-        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
+        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal, LCtx);
         Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
                           ProgramPoint::PreStmtKind);
       }
@@ -572,7 +572,7 @@
   SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
                                         currBldrCtx->blockCount());
   ProgramStateRef state = Pred->getState();
-  state = state->bindLoc(state->getLValue(VD, LCtx), V);
+  state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
 
   StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   Bldr.generateNode(CS, Pred, state);
@@ -627,7 +627,7 @@
       InitVal = State->getSVal(SizeExpr, LocCtxt);
     }
 
-    State = State->bindLoc(FieldLoc, InitVal);
+    State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
   }
 
   // Decay the Loc into an RValue, because there might be a
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index 92c5fe6..f5e64f4 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -115,11 +115,11 @@
         SymbolRef Sym = SymMgr.conjureSymbol(elem, LCtx, T,
                                              currBldrCtx->blockCount());
         SVal V = svalBuilder.makeLoc(Sym);
-        hasElems = hasElems->bindLoc(elementV, V);
+        hasElems = hasElems->bindLoc(elementV, V, LCtx);
 
         // Bind the location to 'nil' on the false branch.
         SVal nilV = svalBuilder.makeIntVal(0, T);
-        noElems = noElems->bindLoc(elementV, nilV);
+        noElems = noElems->bindLoc(elementV, nilV, LCtx);
       }
 
     // Create the new nodes.
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 03ace35..31556c7 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -111,24 +111,29 @@
   return ConstraintMgr->removeDeadBindings(Result, SymReaper);
 }
 
-ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const {
+ProgramStateRef ProgramState::bindLoc(Loc LV,
+                                      SVal V,
+                                      const LocationContext *LCtx,
+                                      bool notifyChanges) const {
   ProgramStateManager &Mgr = getStateManager();
   ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
                                                              LV, V));
   const MemRegion *MR = LV.getAsRegion();
   if (MR && Mgr.getOwningEngine() && notifyChanges)
-    return Mgr.getOwningEngine()->processRegionChange(newState, MR);
+    return Mgr.getOwningEngine()->processRegionChange(newState, MR, LCtx);
 
   return newState;
 }
 
-ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
+ProgramStateRef ProgramState::bindDefault(SVal loc,
+                                          SVal V,
+                                          const LocationContext *LCtx) const {
   ProgramStateManager &Mgr = getStateManager();
   const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
   const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
   ProgramStateRef new_state = makeWithStore(newStore);
   return Mgr.getOwningEngine() ?
-           Mgr.getOwningEngine()->processRegionChange(new_state, R) :
+           Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) :
            new_state;
 }
 
@@ -202,7 +207,7 @@
     }
 
     return Eng->processRegionChanges(newState, IS, TopLevelInvalidated,
-                                     Invalidated, Call);
+                                     Invalidated, LCtx, Call);
   }
 
   const StoreRef &newStore =
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/cstring-syntax.c b/test/Analysis/cstring-syntax.c
index 4aa88ed..2cde013 100644
--- a/test/Analysis/cstring-syntax.c
+++ b/test/Analysis/cstring-syntax.c
@@ -10,4 +10,6 @@
   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest)); // expected-warning {{Potential buffer overflow. Replace with}}
   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest) - strlen(dest)); // expected-warning {{Potential buffer overflow. Replace with}}
   strncat(dest, src, sizeof(src)); // expected-warning {{Potential buffer overflow. Replace with}}
+  // Should not crash when sizeof has a type argument.
+  strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(char));
 }
diff --git a/test/Analysis/debug-CallGraph.c b/test/Analysis/debug-CallGraph.c
index 64259e2..686abb0 100644
--- a/test/Analysis/debug-CallGraph.c
+++ b/test/Analysis/debug-CallGraph.c
@@ -1,5 +1,17 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s
 
+int get5() {
+  return 5;
+}
+
+int add(int val1, int val2) {
+  return val1 + val2;
+}
+
+int test_add() {
+  return add(10, get5());
+}
+
 static void mmm(int y) {
   if (y != 0)
       y++;
@@ -32,7 +44,7 @@
 void fff() { eee(); }
 
 // CHECK:--- Call graph Dump ---
-// CHECK-NEXT: {{Function: < root > calls: mmm foo aaa < > bbb ccc ddd eee fff $}}
+// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ccc ddd eee fff $}}
 // CHECK-NEXT: {{Function: fff calls: eee $}}
 // CHECK-NEXT: {{Function: eee calls: $}}
 // CHECK-NEXT: {{Function: ddd calls: ccc $}}
@@ -42,3 +54,6 @@
 // CHECK-NEXT: {{Function: aaa calls: foo $}}
 // CHECK-NEXT: {{Function: foo calls: mmm $}}
 // CHECK-NEXT: {{Function: mmm calls: $}}
+// CHECK-NEXT: {{Function: test_add calls: add get5 $}}
+// CHECK-NEXT: {{Function: add calls: $}}
+// CHECK-NEXT: {{Function: get5 calls: $}}
diff --git a/test/Analysis/inlining/InlineObjCClassMethod.m b/test/Analysis/inlining/InlineObjCClassMethod.m
index c9cc90b..2772646 100644
--- a/test/Analysis/inlining/InlineObjCClassMethod.m
+++ b/test/Analysis/inlining/InlineObjCClassMethod.m
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 void clang_analyzer_checkInlined(int);
+void clang_analyzer_eval(int);
 
 // Test inlining of ObjC class methods.
 
@@ -194,7 +195,9 @@
 @implementation SelfUsedInParent
 + (int)getNum {return 5;}
 + (int)foo {
-  return [self getNum];
+  int r = [self getNum];
+  clang_analyzer_eval(r == 5); // expected-warning{{TRUE}}
+  return r;
 }
 @end
 @interface SelfUsedInParentChild : SelfUsedInParent
@@ -229,8 +232,80 @@
 + (void)forwardDeclaredVariadicMethod:(int)x, ... {
   clang_analyzer_checkInlined(0); // no-warning
 }
-
 @end
 
+@interface SelfClassTestParent : NSObject
+-(unsigned)returns10;
++(unsigned)returns20;
++(unsigned)returns30;
+@end
 
+@implementation SelfClassTestParent
+-(unsigned)returns10 { return 100; }
++(unsigned)returns20 { return 100; }
++(unsigned)returns30 { return 100; }
+@end
 
+@interface SelfClassTest : SelfClassTestParent
+-(unsigned)returns10;
++(unsigned)returns20;
++(unsigned)returns30;
+@end
+
+@implementation SelfClassTest
+-(unsigned)returns10 { return 10; }
++(unsigned)returns20 { return 20; }
++(unsigned)returns30 { return 30; }
++(void)classMethod {
+  unsigned result1 = [self returns20];
+  clang_analyzer_eval(result1 == 20); // expected-warning{{TRUE}}
+  unsigned result2 = [[self class] returns30];
+  clang_analyzer_eval(result2 == 30); // expected-warning{{TRUE}}
+  unsigned result3 = [[super class] returns30];
+  clang_analyzer_eval(result3 == 100); // expected-warning{{UNKNOWN}}
+}
+-(void)instanceMethod {
+  unsigned result0 = [self returns10];
+  clang_analyzer_eval(result0 == 10); // expected-warning{{TRUE}}
+  unsigned result2 = [[self class] returns30];
+  clang_analyzer_eval(result2 == 30); // expected-warning{{TRUE}}
+  unsigned result3 = [[super class] returns30];
+  clang_analyzer_eval(result3 == 100); // expected-warning{{UNKNOWN}}
+}
+@end
+
+@interface Parent : NSObject
++ (int)a;
++ (int)b;
+@end
+@interface Child : Parent
+@end
+@interface Other : NSObject
++(void)run;
+@end
+int main(int argc, const char * argv[]) {
+  @autoreleasepool {
+    [Other run];
+  }
+  return 0;
+}
+@implementation Other
++(void)run {
+  int result = [Child a];
+  // TODO: This should return 100.
+  clang_analyzer_eval(result == 12); // expected-warning{{TRUE}}
+}
+@end
+@implementation Parent
++ (int)a; {
+  return [self b];
+}
++ (int)b; {
+  return 12;
+}
+@end
+@implementation Child
++ (int)b; {
+  return 100;
+}
+@end
diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m
index 4fc48c0..618fe53 100644
--- a/test/Analysis/keychainAPI.m
+++ b/test/Analysis/keychainAPI.m
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -verify
+// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI -fblocks %s -verify
+
+#include "Inputs/system-header-simulator-objc.h"
 
 // Fake typedefs.
 typedef unsigned int OSStatus;
@@ -6,8 +8,6 @@
 typedef unsigned int SecKeychainItemRef;
 typedef unsigned int SecItemClass;
 typedef unsigned int UInt32;
-typedef unsigned int CFTypeRef;
-typedef unsigned int UInt16;
 typedef unsigned int SecProtocolType;
 typedef unsigned int SecAuthenticationType;
 typedef unsigned int SecKeychainAttributeInfo;
@@ -77,7 +77,7 @@
   void *outData;
   st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
   if (st == GenericError)
-    SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Only call free if a valid (non-NULL) buffer was returned}}
+    SecKeychainItemFreeContent(ptr, outData);
 } // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
 
 // If null is passed in, the data is not allocated, so no need for the matching free.
@@ -101,14 +101,6 @@
       SecKeychainItemFreeContent(ptr, outData);
 }
 
-void fooOnlyFree() {
-  unsigned int *ptr = 0;
-  OSStatus st = 0;
-  UInt32 length;
-  void *outData = &length;
-  SecKeychainItemFreeContent(ptr, outData);// expected-warning{{Trying to free data which has not been allocated}}
-}
-
 // Do not warn if undefined value is passed to a function.
 void fooOnlyFreeUndef() {
   unsigned int *ptr = 0;
@@ -220,11 +212,27 @@
     if (st == noErr)
       SecKeychainItemFreeContent(ptr, outData[3]);
   }
-  if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
+  if (length) { // TODO: We do not report a warning here since the symbol is no longer live, but it's not marked as dead.
     length++;
   }
   return 0;
-}// no-warning
+}
+
+int testErrorCodeAsLHS(CFTypeRef keychainOrArray, SecProtocolType protocol,
+        SecAuthenticationType authenticationType, SecKeychainItemRef *itemRef) {
+  unsigned int *ptr = 0;
+  OSStatus st = 0;
+  UInt32 length;
+  void *outData;
+  st = SecKeychainFindInternetPassword(keychainOrArray,
+                                       16, "server", 16, "domain", 16, "account",
+                                       16, "path", 222, protocol, authenticationType,
+                                       &length, &outData, itemRef);
+  if (noErr == st)
+    SecKeychainItemFreeContent(ptr, outData);
+
+  return 0;
+}
 
 void free(void *ptr);
 void deallocateWithFree() {
@@ -251,7 +259,6 @@
 extern const CFAllocatorRef kCFAllocatorNull;
 extern const CFAllocatorRef kCFAllocatorUseContext;
 CFStringRef CFStringCreateWithBytesNoCopy(CFAllocatorRef alloc, const uint8_t *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean externalFormat, CFAllocatorRef contentsDeallocator);
-extern void CFRelease(CFStringRef cf);
 
 void DellocWithCFStringCreate1(CFAllocatorRef alloc) {
   unsigned int *ptr = 0;
@@ -333,11 +340,11 @@
     SecKeychainItemFreeContent(0, pwdBytes);
 }
 
-void radar10508828_2() {
+void radar10508828_20092614() {
   UInt32 pwdLen = 0;
   void*  pwdBytes = 0;
   OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0);
-  SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned}}
+  SecKeychainItemFreeContent(0, pwdBytes);
 }
 
 //Example from bug 10797.
@@ -426,3 +433,24 @@
       SecKeychainItemFreeContent(attrList, outData);
 }
 
+typedef struct AuthorizationValue {
+    int length;
+    void *data;
+} AuthorizationValue;
+typedef struct AuthorizationCallback {
+    OSStatus (*SetContextVal)(AuthorizationValue *inValue);
+} AuthorizationCallback;
+static AuthorizationCallback cb;
+int radar_19196494() {
+  @autoreleasepool {
+    AuthorizationValue login_password = {};
+    UInt32 passwordLength;
+    void *passwordData = 0;
+    OSStatus err = SecKeychainFindGenericPassword(0, 0, "", 0, "", (UInt32 *)&login_password.length, (void**)&login_password.data, 0);
+    cb.SetContextVal(&login_password);
+    if (err == noErr) {
+      SecKeychainItemFreeContent(0, login_password.data);
+    }
+  }
+  return 0;
+}
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/Analysis/virtualcall.cpp b/test/Analysis/virtualcall.cpp
index e42b898..311f0a1 100644
--- a/test/Analysis/virtualcall.cpp
+++ b/test/Analysis/virtualcall.cpp
@@ -115,12 +115,23 @@
   int foo() override;
 };
 
+// Regression test: don't crash when there's no direct callee.
+class F {
+public:
+  F() {
+    void (F::* ptr)() = &F::foo;
+    (this->*ptr)();
+  }
+  void foo();
+};
+
 int main() {
   A *a;
   B *b;
   C *c;
   D *d;
   E *e;
+  F *f;
 }
 
 #include "virtualcall.h"
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
index f381ed7..ade3274 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
@@ -150,35 +150,44 @@
 
     void f(T);
     f(T{0});
+
+    char c;
+    auto t3 = T{c};
   }
 #if __cplusplus <= 201402L
-  // expected-error@-15 5{{cannot initialize}}
-  // expected-error@-15 5{{cannot initialize}}
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  //
+  //
+  // expected-error@-18 5{{cannot initialize}}
 #else
-  // expected-error@-29 {{cannot initialize}}
-  // expected-error@-29 {{cannot initialize}}
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  //
+  //
+  // expected-error@-35 {{cannot initialize}}
 #endif
 
   template<typename T> void bad() {
@@ -252,4 +261,12 @@
     (void)B{0.0}; // expected-error {{type 'double' cannot be narrowed}}
 #endif
   }
+
+#if __cplusplus > 201402L
+  enum class F : unsigned {};
+  F f1(unsigned x) { return F{x}; }
+  F f2(const unsigned x) { return F{x}; }
+  F f3(bool x) { return F{x}; }
+  F f4(const bool x) { return F{x}; }
+#endif
 }
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/CodeCompletion/auto_type.c b/test/CodeCompletion/auto_type.c
new file mode 100644
index 0000000..3fcfff0
--- /dev/null
+++ b/test/CodeCompletion/auto_type.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -code-completion-at=%s:3:1 %s | FileCheck %s
+void func() {
+
+}
+// CHECK: COMPLETION: __auto_type
diff --git a/test/CodeCompletion/keywords.cpp b/test/CodeCompletion/keywords.cpp
new file mode 100644
index 0000000..6e5824c
--- /dev/null
+++ b/test/CodeCompletion/keywords.cpp
@@ -0,0 +1,79 @@
+int function(int x) {
+  return x + 1;
+}
+
+int variable = 0;
+
+class Class {
+public:
+  Class() { }
+
+  int method(int x) {
+    return x + 1;
+  }
+
+  virtual void virtualMethod() {
+  }
+
+  static void staticMethod() {
+  }
+
+  static int staticVar;
+};
+
+class SubClass : public Class {
+  void virtualMethod() override final {
+  }
+};
+
+struct Struct {
+};
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:5:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:11:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// CHECK-TOP-LEVEL: alignas(<#expression#>)
+// CHECK-TOP-LEVEL: constexpr
+// CHECK-TOP-LEVEL: static_assert(<#expression#>, <#message#>)
+// CHECK-TOP-LEVEL: thread_local
+// CHECK-TOP-LEVEL-NOT: final
+// CHECK-TOP-LEVEL-NOT: noexcept
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:14 %s | FileCheck --check-prefix=CHECK-PARAM %s
+// CHECK-PARAM-NOT: alignas
+// CHECK-PARAM-NOT: constexpr
+// CHECK-PARAM-NOT: final
+// CHECK-PARAM-NOT: thread_local
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:21:10 %s | FileCheck --check-prefix=CHECK-STATICVAR1 %s
+// CHECK-STATICVAR1: constexpr
+// CHECK-STATICVAR1: thread_local
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:7:13 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:24:16 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:29:15 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// CHECK-CLASS-QUALIFIER: final
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:21 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:9:11 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:18:30 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// CHECK-FUNCTION-QUALIFIER: noexcept
+// CHECK-FUNCTION-QUALIFIER-NOT: final
+// CHECK-FUNCTION-QUALIFIER-NOT: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:11:21 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:15:32 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:24 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// CHECK-METHOD-QUALIFIER: final
+// CHECK-METHOD-QUALIFIER: noexcept
+// CHECK-METHOD-QUALIFIER: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:33 %s | FileCheck --check-prefix=CHECK-OVERRIDE-SPECIFIED %s
+// CHECK-OVERRIDE-SPECIFIED: final
+// CHECK-OVERRIDE-SPECIFIED: noexcept
+// CHECK-OVERRIDE-SPECIFIED-NOT: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:39 %s | FileCheck --check-prefix=CHECK-OVERRIDE-FINAL-SPECIFIED %s
+// CHECK-OVERRIDE-FINAL-SPECIFIED: noexcept
+// CHECK-OVERRIDE-FINAL-SPECIFIED-NOT: final
+// CHECK-OVERRIDE-FINAL-SPECIFIED-NOT: override
diff --git a/test/CodeCompletion/ordinary-name-cxx11.cpp b/test/CodeCompletion/ordinary-name-cxx11.cpp
index 8e6f383..34c3bf9 100644
--- a/test/CodeCompletion/ordinary-name-cxx11.cpp
+++ b/test/CodeCompletion/ordinary-name-cxx11.cpp
@@ -39,10 +39,12 @@
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof...(<#parameter-pack#>)
   // CHECK-CC1-NEXT: COMPLETION: static
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC1-NEXT: COMPLETION: Pattern : static_cast<<#type#>>(<#expression#>)
   // CHECK-CC1-NEXT: COMPLETION: struct
   // CHECK-CC1-NEXT: COMPLETION: Pattern : switch(<#condition#>){
   // CHECK-CC1: COMPLETION: t : t
+  // CHECK-CC1-NEXT: COMPLETION: thread_local
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#void#]throw <#expression#>
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#bool#]true
   // CHECK-CC1-NEXT: COMPLETION: Pattern : try{<#statements#>
@@ -72,6 +74,7 @@
   // CHECK-CC2-NEXT: COMPLETION: char32
   // CHECK-CC2-NEXT: COMPLETION: class
   // CHECK-CC2-NEXT: COMPLETION: const
+  // CHECK-CC2-NEXT: COMPLETION: constexpr
   // CHECK-CC2-NEXT: COMPLETION: Pattern : decltype(<#expression#>)
   // CHECK-CC2-NEXT: COMPLETION: double
   // CHECK-CC2-NEXT: COMPLETION: enum
@@ -86,10 +89,12 @@
   // CHECK-CC2-NEXT: COMPLETION: short
   // CHECK-CC2-NEXT: COMPLETION: signed
   // CHECK-CC2-NEXT: COMPLETION: static
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC2-NEXT: COMPLETION: struct
   // CHECK-CC2-NEXT: COMPLETION: t : t
   // CHECK-CC2-NEXT: COMPLETION: Pattern : template <#declaration#>
   // CHECK-CC2-NEXT: COMPLETION: Pattern : template<<#parameters#>>
+  // CHECK-CC2-NEXT: COMPLETION: thread_local
   // CHECK-CC2-NEXT: COMPLETION: TYPEDEF : TYPEDEF
   // CHECK-CC2-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>
   // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#>
@@ -111,6 +116,7 @@
   // CHECK-CC3-NEXT: COMPLETION: char32_t
   // CHECK-CC3-NEXT: COMPLETION: class
   // CHECK-CC3-NEXT: COMPLETION: const
+  // CHECK-CC3-NEXT: COMPLETION: constexpr
   // CHECK-CC3-NEXT: COMPLETION: Pattern : decltype(<#expression#>)
   // CHECK-CC3-NEXT: COMPLETION: double
   // CHECK-CC3-NEXT: COMPLETION: enum
@@ -129,8 +135,10 @@
   // CHECK-CC3-NEXT: COMPLETION: short
   // CHECK-CC3-NEXT: COMPLETION: signed
   // CHECK-CC3-NEXT: COMPLETION: static
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC3-NEXT: COMPLETION: struct
   // CHECK-CC3-NEXT: COMPLETION: Pattern : template<<#parameters#>>
+  // CHECK-CC3-NEXT: COMPLETION: thread_local
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#>
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof <#expression#>
@@ -227,6 +235,7 @@
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof...(<#parameter-pack#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: static
+  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : static_cast<<#type#>>(<#expression#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: struct
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : switch(<#condition#>){
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/sanitize-thread-no-checking-at-run-time.m b/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
index 098b7cf..3d862c0 100644
--- a/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
+++ b/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -fblocks -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -fblocks -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+
+// WITHOUT-NOT: "sanitize_thread_no_checking_at_run_time"
 
 __attribute__((objc_root_class))
 @interface NSObject
@@ -26,9 +28,14 @@
 }
 @end
 
-// WITHOUT-NOT: "sanitize_thread_no_checking_at_run_time"
-
 // TSAN: initialize{{.*}}) [[ATTR:#[0-9]+]]
 // TSAN: dealloc{{.*}}) [[ATTR:#[0-9]+]]
 // TSAN: cxx_destruct{{.*}}) [[ATTR:#[0-9]+]]
+
+void test2(id x) {
+  extern void test2_helper(id (^)(void));
+  test2_helper(^{ return x; });
+// TSAN: define internal void @__destroy_helper_block_(i8*) [[ATTR:#[0-9]+]]
+}
+
 // TSAN: attributes [[ATTR]] = { noinline nounwind {{.*}} "sanitize_thread_no_checking_at_run_time" {{.*}} }
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/CoverageMapping/unused_names.c b/test/CoverageMapping/unused_names.c
index a03d18b..49fa119 100644
--- a/test/CoverageMapping/unused_names.c
+++ b/test/CoverageMapping/unused_names.c
@@ -2,14 +2,15 @@
 // RUN: FileCheck -input-file %t %s
 // RUN: FileCheck -check-prefix=SYSHEADER -input-file %t %s
 
-// Since foo is never emitted, there should not be a profile name for it.
-
-// CHECK-DAG: @__profn_bar = {{.*}} [3 x i8] c"bar"
-// CHECK-DAG: @__profn_baz = {{.*}} [3 x i8] c"baz"
-// CHECK-DAG: @__profn_unused_names.c_qux = {{.*}} [18 x i8] c"unused_names.c:qux"
+// CHECK-DAG: @__profc_bar
 // CHECK-DAG: @__llvm_prf_nm = private constant {{.*}}, section "{{.*}}__llvm_prf_names"
 
-// SYSHEADER-NOT: @__profn_foo =
+// These are never instantiated, so we shouldn't get counters for them.
+//
+// CHECK-NOT: @__profc_baz
+// CHECK-NOT: @__profc_unused_names.c_qux
+
+// SYSHEADER-NOT: @__profc_foo =
 
 
 #ifdef IS_SYSHEADER
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/import-textual/M/A/A.h b/test/Modules/Inputs/import-textual/M/A/A.h
deleted file mode 100644
index ebe4979..0000000
--- a/test/Modules/Inputs/import-textual/M/A/A.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#import "someheader.h"
-
-typedef myint aint;
diff --git a/test/Modules/Inputs/import-textual/M/B/B.h b/test/Modules/Inputs/import-textual/M/B/B.h
deleted file mode 100644
index ba85071..0000000
--- a/test/Modules/Inputs/import-textual/M/B/B.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#import "someheader.h"
-
-typedef myint bint;
diff --git a/test/Modules/Inputs/import-textual/M/module.modulemap b/test/Modules/Inputs/import-textual/M/module.modulemap
deleted file mode 100644
index f801948..0000000
--- a/test/Modules/Inputs/import-textual/M/module.modulemap
+++ /dev/null
@@ -1,17 +0,0 @@
-
-module M {
-
-  module A {
-    header "A/A.h"
-    textual header "someheader.h"
-    export *
-  }
-
-  module B {
-    header "B/B.h"
-    textual header "someheader.h"
-    export *
-  }
-
-  export *
-}
diff --git a/test/Modules/Inputs/import-textual/M/someheader.h b/test/Modules/Inputs/import-textual/M/someheader.h
deleted file mode 100644
index 16fae40..0000000
--- a/test/Modules/Inputs/import-textual/M/someheader.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef C_GUARD
-#define C_GUARD
-
-typedef int myint;
-
-#endif
diff --git a/test/Modules/Inputs/import-textual/M2/A/A.h b/test/Modules/Inputs/import-textual/M2/A/A.h
deleted file mode 100644
index ebe4979..0000000
--- a/test/Modules/Inputs/import-textual/M2/A/A.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#import "someheader.h"
-
-typedef myint aint;
diff --git a/test/Modules/Inputs/import-textual/M2/B/B.h b/test/Modules/Inputs/import-textual/M2/B/B.h
deleted file mode 100644
index ba85071..0000000
--- a/test/Modules/Inputs/import-textual/M2/B/B.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#import "someheader.h"
-
-typedef myint bint;
diff --git a/test/Modules/Inputs/import-textual/M2/module.modulemap b/test/Modules/Inputs/import-textual/M2/module.modulemap
deleted file mode 100644
index f801948..0000000
--- a/test/Modules/Inputs/import-textual/M2/module.modulemap
+++ /dev/null
@@ -1,17 +0,0 @@
-
-module M {
-
-  module A {
-    header "A/A.h"
-    textual header "someheader.h"
-    export *
-  }
-
-  module B {
-    header "B/B.h"
-    textual header "someheader.h"
-    export *
-  }
-
-  export *
-}
diff --git a/test/Modules/Inputs/import-textual/M2/someheader.h b/test/Modules/Inputs/import-textual/M2/someheader.h
deleted file mode 100644
index df2009a..0000000
--- a/test/Modules/Inputs/import-textual/M2/someheader.h
+++ /dev/null
@@ -1 +0,0 @@
-typedef int myint;
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/invalid-module-id/NC-Prefix.pch b/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch
new file mode 100644
index 0000000..73a9816
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch
@@ -0,0 +1,3 @@
+#ifdef __OBJC__
+  #import <NC/NULog.h>
+#endif
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h
new file mode 100644
index 0000000..3866c88
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h
@@ -0,0 +1 @@
+#import <NC/NUGeometry.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h
new file mode 100644
index 0000000..1e7614c
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h
@@ -0,0 +1 @@
+// NU-Visibility.h
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h
new file mode 100644
index 0000000..8923e04
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h
@@ -0,0 +1 @@
+#import <NC/NU-Visibility.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap
new file mode 100644
index 0000000..475b414
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module NC {
+  umbrella header "NC.h"
+
+  export *
+  module * { export * }
+}
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..80488bd
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap
@@ -0,0 +1,5 @@
+explicit module NC.Private
+{
+	header "NULog.h"
+	header "NUAssert.h"
+}
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h
new file mode 100644
index 0000000..7bf8def
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h
@@ -0,0 +1 @@
+#import <NC/NULog.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h
new file mode 100644
index 0000000..8923e04
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h
@@ -0,0 +1 @@
+#import <NC/NU-Visibility.h>
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef
deleted file mode 100644
index 4898c05..0000000
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _LIBCPP_CSTDDEF
-#define _LIBCPP_CSTDDEF
-
-#include <stddef.h>
-#include <type_traits>
-
-typedef ptrdiff_t my_ptrdiff_t;
-
-#endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
index 9e2b693..f761b91 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
@@ -4,6 +4,4 @@
 #include_next <math.h>
 template<typename T> T abs(T t) { return (t < 0) ? -t : t; }
 
-#include <type_traits>
-
 #endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
index f57c11c..b06142a 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
@@ -6,7 +6,5 @@
   // FIXME: remove "textual" from stdint module below once the issue
   // between umbrella headers and builtins is resolved.
   module stdint { textual header "stdint.h" export * }
-  module type_traits { header "type_traits" export * }
-  module cstddef { header "cstddef" export * }
   module __config { header "__config" export * }
 }
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
index 14167cf..bd42008 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
@@ -2,6 +2,5 @@
 #define LIBCXX_STDDEF_H
 
 #include <__config>
-#include_next <stddef.h>
 
 #endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits
deleted file mode 100644
index a91056e..0000000
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _LIBCPP_TYPE_TRAITS
-#define _LIBCPP_TYPE_TRAITS
-
-#include <cstddef>
-
-#endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
index 25b9468..7244cb0 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
@@ -5,12 +5,4 @@
   module stdint { header "stdint.h" export * }
   module stdio { header "stdio.h" export * }
   module util { header "util.h" export * }
-  module POSIX {
-    module sys {
-      module types {
-        umbrella header "sys/_types/_types.h"
-        export *
-      }
-    }
-  }
 }
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
index b98249f..eca7241 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
@@ -1,6 +1 @@
-#ifndef __STDDEF_H__
-#define __STDDEF_H__
-
-#include "sys/_types/_ptrdiff_t.h"
-
-#endif
+// stddef.h
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h
deleted file mode 100644
index d14110e..0000000
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef int * ptrdiff_t;
-#endif /* _PTRDIFF_T */
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h
deleted file mode 100644
index 33d5e51..0000000
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _SYS_TYPES_UMBRELLA
-#define _SYS_TYPES_UMBRELLA
-
-#include "_ptrdiff_t.h"
-
-#endif
diff --git a/test/Modules/Inputs/outofdate-rebuild/AppKit.h b/test/Modules/Inputs/outofdate-rebuild/AppKit.h
new file mode 100644
index 0000000..e357918
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/AppKit.h
@@ -0,0 +1,3 @@
+// AppKit
+#import "CoreVideo.h" // CoreVideo
+struct B { int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/Cocoa.h b/test/Modules/Inputs/outofdate-rebuild/Cocoa.h
new file mode 100644
index 0000000..d631140
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/Cocoa.h
@@ -0,0 +1,5 @@
+// Cocoa
+#import "Foundation.h"
+#import "AppKit.h"
+
+struct A {  int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/CoreText.h b/test/Modules/Inputs/outofdate-rebuild/CoreText.h
new file mode 100644
index 0000000..7ff0e23
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/CoreText.h
@@ -0,0 +1 @@
+struct C { int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h b/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h
new file mode 100644
index 0000000..bd249dc
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h
@@ -0,0 +1,3 @@
+// CoreVideo
+#import "Foundation.h" // Foundation
+struct E { int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/Foundation.h b/test/Modules/Inputs/outofdate-rebuild/Foundation.h
new file mode 100644
index 0000000..b2d053a
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/Foundation.h
@@ -0,0 +1,3 @@
+// Foundation
+#import "CoreText.h"
+struct D { int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/module.modulemap b/test/Modules/Inputs/outofdate-rebuild/module.modulemap
new file mode 100644
index 0000000..71c99e8
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/module.modulemap
@@ -0,0 +1,19 @@
+module Cocoa {
+  header "Cocoa.h"
+}
+
+module AppKit {
+  header "AppKit.h"
+}
+
+module CoreText {
+  header "CoreText.h"
+}
+
+module Foundation {
+  header "Foundation.h"
+}
+
+module CoreVideo {
+  header "CoreVideo.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/Inputs/system-out-of-date/X.h b/test/Modules/Inputs/system-out-of-date/X.h
new file mode 100644
index 0000000..edcfa18
--- /dev/null
+++ b/test/Modules/Inputs/system-out-of-date/X.h
@@ -0,0 +1 @@
+#import <Y.h>
diff --git a/test/Modules/Inputs/system-out-of-date/Y.h b/test/Modules/Inputs/system-out-of-date/Y.h
new file mode 100644
index 0000000..90fe1bc
--- /dev/null
+++ b/test/Modules/Inputs/system-out-of-date/Y.h
@@ -0,0 +1 @@
+//empty
diff --git a/test/Modules/Inputs/system-out-of-date/Z.h b/test/Modules/Inputs/system-out-of-date/Z.h
new file mode 100644
index 0000000..edcfa18
--- /dev/null
+++ b/test/Modules/Inputs/system-out-of-date/Z.h
@@ -0,0 +1 @@
+#import <Y.h>
diff --git a/test/Modules/Inputs/system-out-of-date/module.map b/test/Modules/Inputs/system-out-of-date/module.map
new file mode 100644
index 0000000..0c0f42a
--- /dev/null
+++ b/test/Modules/Inputs/system-out-of-date/module.map
@@ -0,0 +1,12 @@
+module X [system] {
+  header "X.h" // imports Y
+  export *
+}
+module Y {
+  header "Y.h"
+  export *
+}
+module Z {
+  header "Z.h" // imports Y
+  export *
+}
diff --git a/test/Modules/Inputs/warning-mismatch/Mismatch.h b/test/Modules/Inputs/warning-mismatch/Mismatch.h
new file mode 100644
index 0000000..a07b0ee
--- /dev/null
+++ b/test/Modules/Inputs/warning-mismatch/Mismatch.h
@@ -0,0 +1 @@
+struct Mismatch { int i; };
diff --git a/test/Modules/Inputs/warning-mismatch/System.h b/test/Modules/Inputs/warning-mismatch/System.h
new file mode 100644
index 0000000..8e69e70
--- /dev/null
+++ b/test/Modules/Inputs/warning-mismatch/System.h
@@ -0,0 +1,2 @@
+#import "Mismatch.h"
+struct System { int i; };
diff --git a/test/Modules/Inputs/warning-mismatch/module.modulemap b/test/Modules/Inputs/warning-mismatch/module.modulemap
new file mode 100644
index 0000000..c22cde4
--- /dev/null
+++ b/test/Modules/Inputs/warning-mismatch/module.modulemap
@@ -0,0 +1,7 @@
+module System [system] {
+  header "System.h"
+}
+
+module Mismatch {
+  header "Mismatch.h"
+}
diff --git a/test/Modules/builtin-import.mm b/test/Modules/builtin-import.mm
deleted file mode 100644
index 2536ac5..0000000
--- a/test/Modules/builtin-import.mm
+++ /dev/null
@@ -1,12 +0,0 @@
-// REQUIRES: system-darwin
-
-// RUN: rm -rf %t
-// RUN: %clang -cc1 -fsyntax-only -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s
-
-#include <stdio.h>
-#include <stddef.h>
-#include <cstddef>
-
-typedef ptrdiff_t try1_ptrdiff_t;
-typedef my_ptrdiff_t try2_ptrdiff_t;
-
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/diagnostic-options-out-of-date.m b/test/Modules/diagnostic-options-out-of-date.m
index ed9e8e1..fd98a8f 100644
--- a/test/Modules/diagnostic-options-out-of-date.m
+++ b/test/Modules/diagnostic-options-out-of-date.m
@@ -7,6 +7,16 @@
 // RUN: %clang_cc1 -Werror -Wconversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s -fmodules-disable-diagnostic-validation
 // Make sure we don't error out when using the pch
 // RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify -fmodules-disable-diagnostic-validation
+
+// Build A.pcm
+// RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s
+// Build pch that imports A.pcm
+// RUN: %clang_cc1 -Werror -Wno-conversion -emit-pch -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/pch-import-module-out-of-date.pch
+// We will rebuild A.pcm and overwrite the original A.pcm that the pch imports, but the two versions have the same hash.
+// RUN: %clang_cc1 -Werror -Wconversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s
+// Make sure we don't error out when using the pch
+// RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify
+
 // expected-no-diagnostics
 
 @import DiagOutOfDate;
diff --git a/test/Modules/import-textual-noguard.mm b/test/Modules/import-textual-noguard.mm
deleted file mode 100644
index dd124b6..0000000
--- a/test/Modules/import-textual-noguard.mm
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fmodules -fimplicit-module-maps -I%S/Inputs/import-textual/M2 -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s -verify
-
-#include "A/A.h" // expected-error {{could not build module 'M'}}
-#include "B/B.h"
-
-typedef aint xxx;
-typedef bint yyy;
diff --git a/test/Modules/import-textual.mm b/test/Modules/import-textual.mm
deleted file mode 100644
index 6593239..0000000
--- a/test/Modules/import-textual.mm
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fmodules -fimplicit-module-maps -I%S/Inputs/import-textual/M -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s -verify
-
-// expected-no-diagnostics
-
-#include "A/A.h"
-#include "B/B.h"
-
-typedef aint xxx;
-typedef bint yyy;
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/invalid-pch-module-id.m b/test/Modules/invalid-pch-module-id.m
new file mode 100644
index 0000000..34d9995
--- /dev/null
+++ b/test/Modules/invalid-pch-module-id.m
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t.cache
+//
+// RUN: %clang_cc1 -x objective-c-header -fmodules -F%S/Inputs/invalid-module-id \
+// RUN:  -fmodule-implementation-of NC -fmodules-cache-path=%t.cache \
+// RUN:  -fimplicit-module-maps \
+// RUN:  -emit-pch %S/Inputs/invalid-module-id/NC-Prefix.pch -o %t.pch
+//
+// RUN: %clang_cc1 -x objective-c -fmodules -F%S/Inputs/invalid-module-id \
+// RUN:  -fmodule-implementation-of NC -fmodules-cache-path=%t.cache \
+// RUN:  -fimplicit-module-maps -include-pch %t.pch %s -fsyntax-only
+
+#import <NC/NULog.h>
+#import <NC/NUGeometry.h>
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/module_file_info.m b/test/Modules/module_file_info.m
index fa841b7..c5f47d9 100644
--- a/test/Modules/module_file_info.m
+++ b/test/Modules/module_file_info.m
@@ -29,11 +29,6 @@
 // CHECK:     CPU:
 // CHECK:     ABI:
 
-// CHECK: Diagnostic options:
-// CHECK:   IgnoreWarnings: Yes
-// CHECK:   Diagnostic flags:
-// CHECK:     -Wunused
-
 // CHECK: Header search options:
 // CHECK:   System root [-isysroot=]: '/'
 // CHECK:   Use builtin include directories [-nobuiltininc]: Yes
@@ -47,3 +42,8 @@
 // CHECK:   Predefined macros:
 // CHECK:     -DBLARG
 // CHECK:     -DWIBBLE=WOBBLE
+
+// CHECK: Diagnostic options:
+// CHECK:   IgnoreWarnings: Yes
+// CHECK:   Diagnostic flags:
+// CHECK:     -Wunused
diff --git a/test/Modules/modules-cache-path-canonicalization.m b/test/Modules/modules-cache-path-canonicalization.m
new file mode 100644
index 0000000..7cc7460
--- /dev/null
+++ b/test/Modules/modules-cache-path-canonicalization.m
@@ -0,0 +1,30 @@
+// RUN: rm -rf %t/cache %T/rel
+
+// This testcase reproduces a use-after-free after looking up a PCM in
+// a non-canonical modules-cache-path.
+//
+// Prime the module cache (note the '.' in the path).
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/./cache \
+// RUN:   -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \
+// RUN:   %s -fsyntax-only
+//
+// Force a module to be rebuilt by creating a conflict.
+// RUN: echo "@import CoreText;" > %t.m
+// RUN: %clang_cc1 -DMISMATCH -Werror -fdisable-module-hash \
+// RUN:   -fmodules-cache-path=%t/./cache -fmodules -fimplicit-module-maps \
+// RUN:   -I %S/Inputs/outofdate-rebuild %t.m -fsyntax-only
+//
+// Rebuild.
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/./cache \
+// RUN:   -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \
+// RUN:   %s -fsyntax-only
+
+
+// Unrelated to the above: Check that a relative path is resolved correctly.
+//
+// RUN: %clang_cc1 -working-directory %T/rel -fmodules-cache-path=./cache \
+// RUN:   -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \
+// RUN:   -fdisable-module-hash %t.m -fsyntax-only -Rmodule-build 2>&1 \
+// RUN:   | FileCheck %s
+// CHECK: /rel/cache/CoreText.pcm
+@import Cocoa;
diff --git a/test/Modules/outofdate-rebuild.m b/test/Modules/outofdate-rebuild.m
new file mode 100644
index 0000000..e933dce
--- /dev/null
+++ b/test/Modules/outofdate-rebuild.m
@@ -0,0 +1,12 @@
+// RUN: rm -rf %t.cache
+// RUN: echo "@import CoreText;" > %t.m
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild %s -fsyntax-only -Rmodule-build
+// RUN: echo -----------------------------------------------
+// RUN: %clang_cc1 -DMISMATCH -Werror -fdisable-module-hash -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild %t.m -fsyntax-only -Rmodule-build
+// RUN: echo -----------------------------------------------
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild %s -fsyntax-only -Rmodule-build
+
+// This testcase reproduces a use-after-free in
+// https://reviews.llvm.org/D28299 when ModuleManager removes an entry
+// from the PCMcache without notifying its parent ASTReader.
+@import Cocoa;
diff --git a/test/Modules/rebuild.m b/test/Modules/rebuild.m
index 40f2d47..150c2ce 100644
--- a/test/Modules/rebuild.m
+++ b/test/Modules/rebuild.m
@@ -19,11 +19,10 @@
 // RUN: diff %t/Module.size %t/Module.size.saved
 // RUN: cp %t/Module.pcm %t/Module.pcm.saved.2
 
-// But the signature at least is expected to change, so we rebuild DependsOnModule.
-// NOTE: if we change how the signature is created, this test may need updating.
+// The signature is the hash of the PCM content, we will not rebuild rebuild DependsOnModule.
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -fsyntax-only -F %S/Inputs %s
 // RUN: diff %t/Module.pcm %t/Module.pcm.saved.2
-// RUN: not diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
+// RUN: diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
 
 // Rebuild Module, reset its timestamp, and verify its size hasn't changed
 // RUN: rm %t/Module.pcm
@@ -34,10 +33,9 @@
 // RUN: cp %t/Module.pcm %t/Module.pcm.saved.2
 
 // Verify again with Module pre-imported.
-// NOTE: if we change how the signature is created, this test may need updating.
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -fsyntax-only -F %S/Inputs %s
 // RUN: diff %t/Module.pcm %t/Module.pcm.saved.2
-// RUN: not diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
+// RUN: diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
 
 #ifdef PREIMPORT
 @import Module;
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/Modules/system-out-of-date-test.m b/test/Modules/system-out-of-date-test.m
new file mode 100644
index 0000000..9ce14cc
--- /dev/null
+++ b/test/Modules/system-out-of-date-test.m
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t
+// RUN: echo '@import X;' | \
+// RUN:   %clang_cc1 -fmodules -fimplicit-module-maps \
+// RUN:     -fmodules-cache-path=%t -I %S/Inputs/system-out-of-date \
+// RUN:     -fsyntax-only -x objective-c -
+
+// We have an version built with different diagnostic options.
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/system-out-of-date -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module %s -fsyntax-only 2>&1 | FileCheck %s
+ @import X;
+ 
+ #import <Z.h>
+// CHECK: While building module 'Z' imported from
+// CHECK: {{.*}}Y-{{.*}}pcm' was validated as a system module and is now being imported as a non-system module
diff --git a/test/Modules/warning-mismatch.m b/test/Modules/warning-mismatch.m
new file mode 100644
index 0000000..7c83664
--- /dev/null
+++ b/test/Modules/warning-mismatch.m
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t.cache
+// RUN: echo "@import Mismatch;" >%t.m
+// RUN: %clang_cc1 -Wno-system-headers -fdisable-module-hash -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps -I %S/Inputs/warning-mismatch %t.m -fsyntax-only -Rmodule-build
+// RUN: echo -----------------------------------------------
+// RUN: %clang_cc1 -Wsystem-headers -fdisable-module-hash -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps -I %S/Inputs/warning-mismatch %s -fsyntax-only -Rmodule-build
+
+// This testcase triggers a warning flag mismatch in an already validated header.
+@import Mismatch;
+@import System;
diff --git a/test/PCH/empty-def-fwd-struct.h b/test/PCH/empty-def-fwd-struct.h
new file mode 100644
index 0000000..6a9372c
--- /dev/null
+++ b/test/PCH/empty-def-fwd-struct.h
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-pch -x c++-header %s -std=c++14 -o %t.pch
+// RUN: %clang_cc1 -emit-llvm -x c++ /dev/null -std=c++14 -include-pch %t.pch -o %t.o
+struct FVector;
+struct FVector {};
+struct FBox {
+  FVector Min;
+  FBox(int);
+};
+namespace {
+FBox InvalidBoundingBox(0);
+}
+
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/Profile/cxx-virtual-destructor-calls.cpp b/test/Profile/cxx-virtual-destructor-calls.cpp
index cc3df68..c60fc92 100644
--- a/test/Profile/cxx-virtual-destructor-calls.cpp
+++ b/test/Profile/cxx-virtual-destructor-calls.cpp
@@ -13,15 +13,6 @@
   virtual ~B();
 };
 
-// Base dtor
-// CHECK: @__profn__ZN1BD2Ev = private constant [9 x i8] c"_ZN1BD2Ev"
-
-// Complete dtor must not be instrumented
-// CHECK-NOT: @__profn__ZN1BD1Ev = private constant [9 x i8] c"_ZN1BD1Ev"
-
-// Deleting dtor must not be instrumented
-// CHECK-NOT: @__profn__ZN1BD0Ev = private constant [9 x i8] c"_ZN1BD0Ev"
-
 // Base dtor counters and profile data
 // CHECK: @__profc__ZN1BD2Ev = private global [1 x i64] zeroinitializer
 // CHECK: @__profd__ZN1BD2Ev =
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-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index 6c50daf..c097239 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -249,8 +249,7 @@
   if (fillRanges(Code.get(), Ranges))
     return true;
   StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName;
-  FormatStyle FormatStyle =
-      getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer());
+  FormatStyle FormatStyle = getStyle(Style, AssumedFileName, FallbackStyle);
   if (SortIncludes.getNumOccurrences() != 0)
     FormatStyle.SortIncludes = SortIncludes;
   unsigned CursorPosition = Cursor;
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/Basic/CMakeLists.txt b/unittests/Basic/CMakeLists.txt
index 3cb3cb8..3a9f34f 100644
--- a/unittests/Basic/CMakeLists.txt
+++ b/unittests/Basic/CMakeLists.txt
@@ -6,6 +6,7 @@
   CharInfoTest.cpp
   DiagnosticTest.cpp
   FileManagerTest.cpp
+  MemoryBufferCacheTest.cpp
   SourceManagerTest.cpp
   VirtualFileSystemTest.cpp
   )
diff --git a/unittests/Basic/MemoryBufferCacheTest.cpp b/unittests/Basic/MemoryBufferCacheTest.cpp
new file mode 100644
index 0000000..be243c2
--- /dev/null
+++ b/unittests/Basic/MemoryBufferCacheTest.cpp
@@ -0,0 +1,94 @@
+//===- MemoryBufferCacheTest.cpp - MemoryBufferCache tests ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/MemoryBufferCache.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+
+std::unique_ptr<MemoryBuffer> getBuffer(int I) {
+  SmallVector<char, 8> Bytes;
+  raw_svector_ostream(Bytes) << "data:" << I;
+  return MemoryBuffer::getMemBuffer(StringRef(Bytes.data(), Bytes.size()));
+}
+
+TEST(MemoryBufferCacheTest, addBuffer) {
+  auto B1 = getBuffer(1);
+  auto B2 = getBuffer(2);
+  auto B3 = getBuffer(3);
+  auto *RawB1 = B1.get();
+  auto *RawB2 = B2.get();
+  auto *RawB3 = B3.get();
+
+  // Add a few buffers.
+  MemoryBufferCache Cache;
+  EXPECT_EQ(RawB1, &Cache.addBuffer("1", std::move(B1)));
+  EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));
+  EXPECT_EQ(RawB3, &Cache.addBuffer("3", std::move(B3)));
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
+  EXPECT_EQ(RawB2, Cache.lookupBuffer("2"));
+  EXPECT_EQ(RawB3, Cache.lookupBuffer("3"));
+  EXPECT_FALSE(Cache.isBufferFinal("1"));
+  EXPECT_FALSE(Cache.isBufferFinal("2"));
+  EXPECT_FALSE(Cache.isBufferFinal("3"));
+
+  // Remove the middle buffer.
+  EXPECT_FALSE(Cache.tryToRemoveBuffer("2"));
+  EXPECT_EQ(nullptr, Cache.lookupBuffer("2"));
+  EXPECT_FALSE(Cache.isBufferFinal("2"));
+
+  // Replace the middle buffer.
+  B2 = getBuffer(2);
+  ASSERT_NE(RawB2, B2.get());
+  RawB2 = B2.get();
+  EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));
+
+  // Check that nothing is final.
+  EXPECT_FALSE(Cache.isBufferFinal("1"));
+  EXPECT_FALSE(Cache.isBufferFinal("2"));
+  EXPECT_FALSE(Cache.isBufferFinal("3"));
+}
+
+TEST(MemoryBufferCacheTest, finalizeCurrentBuffers) {
+  // Add a buffer.
+  MemoryBufferCache Cache;
+  auto B1 = getBuffer(1);
+  auto *RawB1 = B1.get();
+  Cache.addBuffer("1", std::move(B1));
+  ASSERT_FALSE(Cache.isBufferFinal("1"));
+
+  // Finalize it.
+  Cache.finalizeCurrentBuffers();
+  EXPECT_TRUE(Cache.isBufferFinal("1"));
+  EXPECT_TRUE(Cache.tryToRemoveBuffer("1"));
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
+  EXPECT_TRUE(Cache.isBufferFinal("1"));
+
+  // Repeat.
+  auto B2 = getBuffer(2);
+  auto *RawB2 = B2.get();
+  Cache.addBuffer("2", std::move(B2));
+  EXPECT_FALSE(Cache.isBufferFinal("2"));
+
+  Cache.finalizeCurrentBuffers();
+  EXPECT_TRUE(Cache.isBufferFinal("1"));
+  EXPECT_TRUE(Cache.isBufferFinal("2"));
+  EXPECT_TRUE(Cache.tryToRemoveBuffer("1"));
+  EXPECT_TRUE(Cache.tryToRemoveBuffer("2"));
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
+  EXPECT_EQ(RawB2, Cache.lookupBuffer("2"));
+  EXPECT_TRUE(Cache.isBufferFinal("1"));
+  EXPECT_TRUE(Cache.isBufferFinal("2"));
+}
+
+} // namespace
diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp
index a967b0e..dddc3f9 100644
--- a/unittests/Basic/SourceManagerTest.cpp
+++ b/unittests/Basic/SourceManagerTest.cpp
@@ -12,6 +12,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Lex/HeaderSearch.h"
@@ -78,10 +79,11 @@
   SourceMgr.setMainFileID(mainFileID);
 
   VoidModuleLoader ModLoader;
+  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, HeaderInfo, ModLoader,
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
@@ -198,10 +200,11 @@
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
 
   VoidModuleLoader ModLoader;
+  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, HeaderInfo, ModLoader,
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
@@ -298,10 +301,11 @@
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
 
   VoidModuleLoader ModLoader;
+  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, HeaderInfo, ModLoader,
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt
index eb7756a..240be6e 100644
--- a/unittests/Format/CMakeLists.txt
+++ b/unittests/Format/CMakeLists.txt
@@ -7,7 +7,6 @@
   FormatTest.cpp
   FormatTestJava.cpp
   FormatTestJS.cpp
-  FormatTestObjC.cpp
   FormatTestProto.cpp
   FormatTestSelective.cpp
   SortImportsTestJS.cpp
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index b402b5c..47e226e 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -2493,6 +2493,42 @@
                Style);
 }
 
+TEST_F(FormatTest, FormatObjCTryCatch) {
+  verifyFormat("@try {\n"
+               "  f();\n"
+               "} @catch (NSException e) {\n"
+               "  @throw;\n"
+               "} @finally {\n"
+               "  exit(42);\n"
+               "}");
+  verifyFormat("DEBUG({\n"
+               "  @try {\n"
+               "  } @finally {\n"
+               "  }\n"
+               "});\n");
+}
+
+TEST_F(FormatTest, FormatObjCAutoreleasepool) {
+  FormatStyle Style = getLLVMStyle();
+  verifyFormat("@autoreleasepool {\n"
+               "  f();\n"
+               "}\n"
+               "@autoreleasepool {\n"
+               "  f();\n"
+               "}\n",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  verifyFormat("@autoreleasepool\n"
+               "{\n"
+               "  f();\n"
+               "}\n"
+               "@autoreleasepool\n"
+               "{\n"
+               "  f();\n"
+               "}\n",
+               Style);
+}
+
 TEST_F(FormatTest, StaticInitializers) {
   verifyFormat("static SomeClass SC = {1, 'a'};");
 
@@ -7355,6 +7391,704 @@
   verifyGoogleFormat("- foo:(int)foo;");
 }
 
+TEST_F(FormatTest, FormatObjCInterface) {
+  verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
+               "@public\n"
+               "  int field1;\n"
+               "@protected\n"
+               "  int field2;\n"
+               "@private\n"
+               "  int field3;\n"
+               "@package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyGoogleFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
+                     " @public\n"
+                     "  int field1;\n"
+                     " @protected\n"
+                     "  int field2;\n"
+                     " @private\n"
+                     "  int field3;\n"
+                     " @package\n"
+                     "  int field4;\n"
+                     "}\n"
+                     "+ (id)init;\n"
+                     "@end");
+
+  verifyFormat("@interface /* wait for it */ Foo\n"
+               "+ (id)init;\n"
+               "// Look, a comment!\n"
+               "- (int)answerWith:(int)i;\n"
+               "@end");
+
+  verifyFormat("@interface Foo\n"
+               "@end\n"
+               "@interface Bar\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : /**/ Bar /**/ <Baz, /**/ Quux>\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyGoogleFormat("@interface Foo : Bar<Baz, Quux>\n"
+                     "+ (id)init;\n"
+                     "@end");
+
+  verifyFormat("@interface Foo (HackStuff)\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo ()\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyGoogleFormat("@interface Foo (HackStuff)<MyProtocol>\n"
+                     "+ (id)init;\n"
+                     "@end");
+
+  verifyFormat("@interface Foo {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar <Baz, Quux> {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo () {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  FormatStyle OnePerLine = getGoogleStyle();
+  OnePerLine.BinPackParameters = false;
+  verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
+               "}",
+               OnePerLine);
+}
+
+TEST_F(FormatTest, FormatObjCImplementation) {
+  verifyFormat("@implementation Foo : NSObject {\n"
+               "@public\n"
+               "  int field1;\n"
+               "@protected\n"
+               "  int field2;\n"
+               "@private\n"
+               "  int field3;\n"
+               "@package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyGoogleFormat("@implementation Foo : NSObject {\n"
+                     " @public\n"
+                     "  int field1;\n"
+                     " @protected\n"
+                     "  int field2;\n"
+                     " @private\n"
+                     "  int field3;\n"
+                     " @package\n"
+                     "  int field4;\n"
+                     "}\n"
+                     "+ (id)init {\n}\n"
+                     "@end");
+
+  verifyFormat("@implementation Foo\n"
+               "+ (id)init {\n"
+               "  if (true)\n"
+               "    return nil;\n"
+               "}\n"
+               "// Look, a comment!\n"
+               "- (int)answerWith:(int)i {\n"
+               "  return i;\n"
+               "}\n"
+               "+ (int)answerWith:(int)i {\n"
+               "  return i;\n"
+               "}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo\n"
+               "@end\n"
+               "@implementation Bar\n"
+               "@end");
+
+  EXPECT_EQ("@implementation Foo : Bar\n"
+            "+ (id)init {\n}\n"
+            "- (void)foo {\n}\n"
+            "@end",
+            format("@implementation Foo : Bar\n"
+                   "+(id)init{}\n"
+                   "-(void)foo{}\n"
+                   "@end"));
+
+  verifyFormat("@implementation Foo {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo : Bar {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo (HackStuff)\n"
+               "+ (id)init {\n}\n"
+               "@end");
+  verifyFormat("@implementation ObjcClass\n"
+               "- (void)method;\n"
+               "{}\n"
+               "@end");
+}
+
+TEST_F(FormatTest, FormatObjCProtocol) {
+  verifyFormat("@protocol Foo\n"
+               "@property(weak) id delegate;\n"
+               "- (NSUInteger)numberOfThings;\n"
+               "@end");
+
+  verifyFormat("@protocol MyProtocol <NSObject>\n"
+               "- (NSUInteger)numberOfThings;\n"
+               "@end");
+
+  verifyGoogleFormat("@protocol MyProtocol<NSObject>\n"
+                     "- (NSUInteger)numberOfThings;\n"
+                     "@end");
+
+  verifyFormat("@protocol Foo;\n"
+               "@protocol Bar;\n");
+
+  verifyFormat("@protocol Foo\n"
+               "@end\n"
+               "@protocol Bar\n"
+               "@end");
+
+  verifyFormat("@protocol myProtocol\n"
+               "- (void)mandatoryWithInt:(int)i;\n"
+               "@optional\n"
+               "- (void)optional;\n"
+               "@required\n"
+               "- (void)required;\n"
+               "@optional\n"
+               "@property(assign) int madProp;\n"
+               "@end\n");
+
+  verifyFormat("@property(nonatomic, assign, readonly)\n"
+               "    int *looooooooooooooooooooooooooooongNumber;\n"
+               "@property(nonatomic, assign, readonly)\n"
+               "    NSString *looooooooooooooooooooooooooooongName;");
+
+  verifyFormat("@implementation PR18406\n"
+               "}\n"
+               "@end");
+}
+
+TEST_F(FormatTest, FormatObjCMethodDeclarations) {
+  verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n"
+               "                   rect:(NSRect)theRect\n"
+               "               interval:(float)theInterval {\n"
+               "}");
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "      longKeyword:(NSRect)theRect\n"
+               "    longerKeyword:(float)theInterval\n"
+               "            error:(NSError **)theError {\n"
+               "}");
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "          longKeyword:(NSRect)theRect\n"
+               "    evenLongerKeyword:(float)theInterval\n"
+               "                error:(NSError **)theError {\n"
+               "}");
+  verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"
+               "                         y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"
+               "    NS_DESIGNATED_INITIALIZER;",
+               getLLVMStyleWithColumns(60));
+
+  // Continuation indent width should win over aligning colons if the function
+  // name is long.
+  FormatStyle continuationStyle = getGoogleStyle();
+  continuationStyle.ColumnLimit = 40;
+  continuationStyle.IndentWrappedFunctionNames = true;
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "    dontAlignNamef:(NSRect)theRect {\n"
+               "}",
+               continuationStyle);
+
+  // Make sure we don't break aligning for short parameter names.
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "       aShortf:(NSRect)theRect {\n"
+               "}",
+               continuationStyle);
+
+  // Format pairs correctly.
+  verifyFormat("- (void)drawRectOn:(id)surface\n"
+               "            ofSize:(aaaaaaaa)height\n"
+               "                  :(size_t)width\n"
+               "          atOrigin:(size_t)x\n"
+               "                  :(size_t)y\n"
+               "             aaaaa:(a)yyy\n"
+               "               bbb:(d)cccc;");
+  verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;");
+  verifyFormat("- (void)drawRectOn:(id)surface\n"
+               "            ofSize:(size_t)height\n"
+               "                  :(size_t)width;",
+               getLLVMStyleWithColumns(60));
+}
+
+TEST_F(FormatTest, FormatObjCMethodExpr) {
+  verifyFormat("[foo bar:baz];");
+  verifyFormat("return [foo bar:baz];");
+  verifyFormat("return (a)[foo bar:baz];");
+  verifyFormat("f([foo bar:baz]);");
+  verifyFormat("f(2, [foo bar:baz]);");
+  verifyFormat("f(2, a ? b : c);");
+  verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");
+
+  // Unary operators.
+  verifyFormat("int a = +[foo bar:baz];");
+  verifyFormat("int a = -[foo bar:baz];");
+  verifyFormat("int a = ![foo bar:baz];");
+  verifyFormat("int a = ~[foo bar:baz];");
+  verifyFormat("int a = ++[foo bar:baz];");
+  verifyFormat("int a = --[foo bar:baz];");
+  verifyFormat("int a = sizeof [foo bar:baz];");
+  verifyFormat("int a = alignof [foo bar:baz];", getGoogleStyle());
+  verifyFormat("int a = &[foo bar:baz];");
+  verifyFormat("int a = *[foo bar:baz];");
+  // FIXME: Make casts work, without breaking f()[4].
+  // verifyFormat("int a = (int)[foo bar:baz];");
+  // verifyFormat("return (int)[foo bar:baz];");
+  // verifyFormat("(void)[foo bar:baz];");
+  verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];");
+
+  // Binary operators.
+  verifyFormat("[foo bar:baz], [foo bar:baz];");
+  verifyFormat("[foo bar:baz] = [foo bar:baz];");
+  verifyFormat("[foo bar:baz] *= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] /= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] %= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] += [foo bar:baz];");
+  verifyFormat("[foo bar:baz] -= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] <<= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >>= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] &= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ^= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] |= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");
+  verifyFormat("[foo bar:baz] || [foo bar:baz];");
+  verifyFormat("[foo bar:baz] && [foo bar:baz];");
+  verifyFormat("[foo bar:baz] | [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ^ [foo bar:baz];");
+  verifyFormat("[foo bar:baz] & [foo bar:baz];");
+  verifyFormat("[foo bar:baz] == [foo bar:baz];");
+  verifyFormat("[foo bar:baz] != [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] <= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] > [foo bar:baz];");
+  verifyFormat("[foo bar:baz] < [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >> [foo bar:baz];");
+  verifyFormat("[foo bar:baz] << [foo bar:baz];");
+  verifyFormat("[foo bar:baz] - [foo bar:baz];");
+  verifyFormat("[foo bar:baz] + [foo bar:baz];");
+  verifyFormat("[foo bar:baz] * [foo bar:baz];");
+  verifyFormat("[foo bar:baz] / [foo bar:baz];");
+  verifyFormat("[foo bar:baz] % [foo bar:baz];");
+  // Whew!
+
+  verifyFormat("return in[42];");
+  verifyFormat("for (auto v : in[1]) {\n}");
+  verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}");
+  verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}");
+  verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}");
+  verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}");
+  verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}");
+  verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
+               "}");
+  verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");
+  verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");
+  verifyFormat("[self aaaaa:(Type)a bbbbb:3];");
+
+  verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
+  verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
+  verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");
+  verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");
+  verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");
+  verifyFormat("[button setAction:@selector(zoomOut:)];");
+  verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];");
+
+  verifyFormat("arr[[self indexForFoo:a]];");
+  verifyFormat("throw [self errorFor:a];");
+  verifyFormat("@throw [self errorFor:a];");
+
+  verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];");
+  verifyFormat("[(id)foo bar:(id) ? baz : quux];");
+  verifyFormat("4 > 4 ? (id)a : (id)baz;");
+
+  // This tests that the formatter doesn't break after "backing" but before ":",
+  // which would be at 80 columns.
+  verifyFormat(
+      "void f() {\n"
+      "  if ((self = [super initWithContentRect:contentRect\n"
+      "                               styleMask:styleMask ?: otherMask\n"
+      "                                 backing:NSBackingStoreBuffered\n"
+      "                                   defer:YES]))");
+
+  verifyFormat(
+      "[foo checkThatBreakingAfterColonWorksOk:\n"
+      "         [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];");
+
+  verifyFormat("[myObj short:arg1 // Force line break\n"
+               "          longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n"
+               "    evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n"
+               "                error:arg4];");
+  verifyFormat(
+      "void f() {\n"
+      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
+      "                                     pos.width(), pos.height())\n"
+      "                styleMask:NSBorderlessWindowMask\n"
+      "                  backing:NSBackingStoreBuffered\n"
+      "                    defer:NO]);\n"
+      "}");
+  verifyFormat(
+      "void f() {\n"
+      "  popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n"
+      "                                 pos.width(), pos.height())\n"
+      "                syeMask:NSBorderlessWindowMask\n"
+      "                  bking:NSBackingStoreBuffered\n"
+      "                    der:NO]);\n"
+      "}",
+      getLLVMStyleWithColumns(70));
+  verifyFormat(
+      "void f() {\n"
+      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
+      "                                     pos.width(), pos.height())\n"
+      "                styleMask:NSBorderlessWindowMask\n"
+      "                  backing:NSBackingStoreBuffered\n"
+      "                    defer:NO]);\n"
+      "}",
+      getChromiumStyle(FormatStyle::LK_Cpp));
+  verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n"
+               "                             with:contentsNativeView];");
+
+  verifyFormat(
+      "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n"
+      "           owner:nillllll];");
+
+  verifyFormat(
+      "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n"
+      "        forType:kBookmarkButtonDragType];");
+
+  verifyFormat("[defaultCenter addObserver:self\n"
+               "                  selector:@selector(willEnterFullscreen)\n"
+               "                      name:kWillEnterFullscreenNotification\n"
+               "                    object:nil];");
+  verifyFormat("[image_rep drawInRect:drawRect\n"
+               "             fromRect:NSZeroRect\n"
+               "            operation:NSCompositeCopy\n"
+               "             fraction:1.0\n"
+               "       respectFlipped:NO\n"
+               "                hints:nil];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n"
+               "    aaaaaaaaaaaaaaaaaaaaaa];");
+  verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n"
+               "        .aaaaaaaa];", // FIXME: Indentation seems off.
+               getLLVMStyleWithColumns(60));
+
+  verifyFormat(
+      "scoped_nsobject<NSTextField> message(\n"
+      "    // The frame will be fixed up when |-setMessageText:| is called.\n"
+      "    [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);");
+  verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n"
+               "    aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n"
+               "         aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n"
+               "          aaaa:bbb];");
+  verifyFormat("[self param:function( //\n"
+               "                parameter)]");
+  verifyFormat(
+      "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
+      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
+      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];");
+
+  // FIXME: This violates the column limit.
+  verifyFormat(
+      "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "    aaaaaaaaaaaaaaaaa:aaaaaaaa\n"
+      "                  aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];",
+      getLLVMStyleWithColumns(60));
+
+  // Variadic parameters.
+  verifyFormat(
+      "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];");
+  verifyFormat(
+      "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
+      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
+      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");
+  verifyFormat("[self // break\n"
+               "      a:a\n"
+               "    aaa:aaa];");
+  verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
+               "          [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
+
+  // Formats pair-parameters.
+  verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
+  verifyFormat("[I drawRectOn:surface //\n"
+               "        ofSize:aa:bbb\n"
+               "      atOrigin:cc:dd];");
+}
+
+TEST_F(FormatTest, ObjCAt) {
+  verifyFormat("@autoreleasepool");
+  verifyFormat("@catch");
+  verifyFormat("@class");
+  verifyFormat("@compatibility_alias");
+  verifyFormat("@defs");
+  verifyFormat("@dynamic");
+  verifyFormat("@encode");
+  verifyFormat("@end");
+  verifyFormat("@finally");
+  verifyFormat("@implementation");
+  verifyFormat("@import");
+  verifyFormat("@interface");
+  verifyFormat("@optional");
+  verifyFormat("@package");
+  verifyFormat("@private");
+  verifyFormat("@property");
+  verifyFormat("@protected");
+  verifyFormat("@protocol");
+  verifyFormat("@public");
+  verifyFormat("@required");
+  verifyFormat("@selector");
+  verifyFormat("@synchronized");
+  verifyFormat("@synthesize");
+  verifyFormat("@throw");
+  verifyFormat("@try");
+
+  EXPECT_EQ("@interface", format("@ interface"));
+
+  // The precise formatting of this doesn't matter, nobody writes code like
+  // this.
+  verifyFormat("@ /*foo*/ interface");
+}
+
+TEST_F(FormatTest, ObjCSnippets) {
+  verifyFormat("@autoreleasepool {\n"
+               "  foo();\n"
+               "}");
+  verifyFormat("@class Foo, Bar;");
+  verifyFormat("@compatibility_alias AliasName ExistingClass;");
+  verifyFormat("@dynamic textColor;");
+  verifyFormat("char *buf1 = @encode(int *);");
+  verifyFormat("char *buf1 = @encode(typeof(4 * 5));");
+  verifyFormat("char *buf1 = @encode(int **);");
+  verifyFormat("Protocol *proto = @protocol(p1);");
+  verifyFormat("SEL s = @selector(foo:);");
+  verifyFormat("@synchronized(self) {\n"
+               "  f();\n"
+               "}");
+
+  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
+  verifyGoogleFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
+
+  verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
+  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
+  verifyGoogleFormat("@property(assign, getter=isEditable) BOOL editable;");
+  verifyFormat("@property (assign, getter=isEditable) BOOL editable;",
+               getMozillaStyle());
+  verifyFormat("@property BOOL editable;", getMozillaStyle());
+  verifyFormat("@property (assign, getter=isEditable) BOOL editable;",
+               getWebKitStyle());
+  verifyFormat("@property BOOL editable;", getWebKitStyle());
+
+  verifyFormat("@import foo.bar;\n"
+               "@import baz;");
+}
+
+TEST_F(FormatTest, ObjCForIn) {
+  verifyFormat("- (void)test {\n"
+               "  for (NSString *n in arrayOfStrings) {\n"
+               "    foo(n);\n"
+               "  }\n"
+               "}");
+  verifyFormat("- (void)test {\n"
+               "  for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n"
+               "    foo(n);\n"
+               "  }\n"
+               "}");
+}
+
+TEST_F(FormatTest, ObjCLiterals) {
+  verifyFormat("@\"String\"");
+  verifyFormat("@1");
+  verifyFormat("@+4.8");
+  verifyFormat("@-4");
+  verifyFormat("@1LL");
+  verifyFormat("@.5");
+  verifyFormat("@'c'");
+  verifyFormat("@true");
+
+  verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);");
+  verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);");
+  verifyFormat("NSNumber *favoriteColor = @(Green);");
+  verifyFormat("NSString *path = @(getenv(\"PATH\"));");
+
+  verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];");
+}
+
+TEST_F(FormatTest, ObjCDictLiterals) {
+  verifyFormat("@{");
+  verifyFormat("@{}");
+  verifyFormat("@{@\"one\" : @1}");
+  verifyFormat("return @{@\"one\" : @1;");
+  verifyFormat("@{@\"one\" : @1}");
+
+  verifyFormat("@{@\"one\" : @{@2 : @1}}");
+  verifyFormat("@{\n"
+               "  @\"one\" : @{@2 : @1},\n"
+               "}");
+
+  verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
+  verifyIncompleteFormat("[self setDict:@{}");
+  verifyIncompleteFormat("[self setDict:@{@1 : @2}");
+  verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
+  verifyFormat(
+      "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
+  verifyFormat(
+      "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");
+
+  verifyFormat("NSDictionary *d = @{\n"
+               "  @\"nam\" : NSUserNam(),\n"
+               "  @\"dte\" : [NSDate date],\n"
+               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
+               "};");
+  verifyFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
+      "regularFont,\n"
+      "};");
+  verifyGoogleFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
+      "regularFont,\n"
+      "};");
+  verifyFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"
+      "      reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"
+      "};");
+
+  // We should try to be robust in case someone forgets the "@".
+  verifyFormat("NSDictionary *d = {\n"
+               "  @\"nam\" : NSUserNam(),\n"
+               "  @\"dte\" : [NSDate date],\n"
+               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
+               "};");
+  verifyFormat("NSMutableDictionary *dictionary =\n"
+               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
+               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
+               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
+               "      cccccccccccccccc : ccccccccccccccc\n"
+               "    }];");
+
+  // Ensure that casts before the key are kept on the same line as the key.
+  verifyFormat(
+      "NSDictionary *d = @{\n"
+      "  (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "  (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"
+      "};");
+}
+
+TEST_F(FormatTest, ObjCArrayLiterals) {
+  verifyIncompleteFormat("@[");
+  verifyFormat("@[]");
+  verifyFormat(
+      "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
+  verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");
+  verifyFormat("NSArray *array = @[ [foo description] ];");
+
+  verifyFormat(
+      "NSArray *some_variable = @[\n"
+      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "];");
+  verifyFormat(
+      "NSArray *some_variable = @[\n"
+      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n"
+      "];");
+  verifyFormat("NSArray *some_variable = @[\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "];");
+  verifyFormat("NSArray *array = @[\n"
+               "  @\"a\",\n"
+               "  @\"a\",\n" // Trailing comma -> one per line.
+               "];");
+
+  // We should try to be robust in case someone forgets the "@".
+  verifyFormat("NSArray *some_variable = [\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "];");
+  verifyFormat(
+      "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n"
+      "                                             index:(NSUInteger)index\n"
+      "                                nonDigitAttributes:\n"
+      "                                    (NSDictionary *)noDigitAttributes;");
+  verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
+               "  NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
+               "]];");
+}
 
 TEST_F(FormatTest, BreaksStringLiterals) {
   EXPECT_EQ("\"some text \"\n"
@@ -10960,13 +11694,13 @@
                  llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
   ASSERT_TRUE(
       FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS);
+  auto Style1 = getStyle("file", "/a/.clang-format", "Google", &FS);
   ASSERT_EQ(Style1, getLLVMStyle());
 
   // Test 2: fallback to default.
   ASSERT_TRUE(
       FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS);
+  auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", &FS);
   ASSERT_EQ(Style2, getMozillaStyle());
 
   // Test 3: format file in parent directory.
@@ -10975,7 +11709,7 @@
                  llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
   ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0,
                          llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", &FS);
   ASSERT_EQ(Style3, getGoogleStyle());
 }
 
diff --git a/unittests/Format/FormatTestObjC.cpp b/unittests/Format/FormatTestObjC.cpp
deleted file mode 100644
index 6a530f9..0000000
--- a/unittests/Format/FormatTestObjC.cpp
+++ /dev/null
@@ -1,822 +0,0 @@
-//===- unittest/Format/FormatTestObjC.cpp - Formatting unit tests----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Format/Format.h"
-
-#include "../Tooling/ReplacementTest.h"
-#include "FormatTestUtils.h"
-
-#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "gtest/gtest.h"
-
-#define DEBUG_TYPE "format-test"
-
-using clang::tooling::ReplacementTest;
-using clang::tooling::toReplacements;
-
-namespace clang {
-namespace format {
-namespace {
-
-class FormatTestObjC : public ::testing::Test {
-protected:
-  FormatTestObjC() {
-    Style = getLLVMStyle();
-    Style.Language = FormatStyle::LK_ObjC;
-  }
-
-  enum IncompleteCheck {
-    IC_ExpectComplete,
-    IC_ExpectIncomplete,
-    IC_DoNotCheck
-  };
-
-  std::string format(llvm::StringRef Code,
-                     IncompleteCheck CheckIncomplete = IC_ExpectComplete) {
-    DEBUG(llvm::errs() << "---\n");
-    DEBUG(llvm::errs() << Code << "\n\n");
-    std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
-    bool IncompleteFormat = false;
-    tooling::Replacements Replaces =
-        reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
-    if (CheckIncomplete != IC_DoNotCheck) {
-      bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete;
-      EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";
-    }
-    auto Result = applyAllReplacements(Code, Replaces);
-    EXPECT_TRUE(static_cast<bool>(Result));
-    DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
-    return *Result;
-  }
-
-  void verifyFormat(StringRef Code) {
-    EXPECT_EQ(Code.str(), format(test::messUp(Code)));
-  }
-
-  void verifyIncompleteFormat(StringRef Code) {
-    EXPECT_EQ(Code.str(), format(test::messUp(Code), IC_ExpectIncomplete));
-  }
-
-  FormatStyle Style;
-};
-
-TEST_F(FormatTestObjC, DetectsObjCInHeaders) {
-  Style = getStyle("LLVM", "a.h", "none", "@interface\n"
-                                          "- (id)init;");
-  EXPECT_EQ(FormatStyle::LK_ObjC, Style.Language);
-  Style = getStyle("LLVM", "a.h", "none", "@interface\n"
-                                          "+ (id)init;");
-  EXPECT_EQ(FormatStyle::LK_ObjC, Style.Language);
-
-  // No recognizable ObjC.
-  Style = getStyle("LLVM", "a.h", "none", "void f() {}");
-  EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
-}
-
-TEST_F(FormatTestObjC, FormatObjCTryCatch) {
-  verifyFormat("@try {\n"
-               "  f();\n"
-               "} @catch (NSException e) {\n"
-               "  @throw;\n"
-               "} @finally {\n"
-               "  exit(42);\n"
-               "}");
-  verifyFormat("DEBUG({\n"
-               "  @try {\n"
-               "  } @finally {\n"
-               "  }\n"
-               "});\n");
-}
-
-TEST_F(FormatTestObjC, FormatObjCAutoreleasepool) {
-  verifyFormat("@autoreleasepool {\n"
-               "  f();\n"
-               "}\n"
-               "@autoreleasepool {\n"
-               "  f();\n"
-               "}\n");
-  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
-  verifyFormat("@autoreleasepool\n"
-               "{\n"
-               "  f();\n"
-               "}\n"
-               "@autoreleasepool\n"
-               "{\n"
-               "  f();\n"
-               "}\n");
-}
-
-TEST_F(FormatTestObjC, FormatObjCInterface) {
-  verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
-               "@public\n"
-               "  int field1;\n"
-               "@protected\n"
-               "  int field2;\n"
-               "@private\n"
-               "  int field3;\n"
-               "@package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface /* wait for it */ Foo\n"
-               "+ (id)init;\n"
-               "// Look, a comment!\n"
-               "- (int)answerWith:(int)i;\n"
-               "@end");
-
-  verifyFormat("@interface Foo\n"
-               "@end\n"
-               "@interface Bar\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : /**/ Bar /**/ <Baz, /**/ Quux>\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff)\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo ()\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar <Baz, Quux> {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo () {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
-               " @public\n"
-               "  int field1;\n"
-               " @protected\n"
-               "  int field2;\n"
-               " @private\n"
-               "  int field3;\n"
-               " @package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-  verifyFormat("@interface Foo : Bar<Baz, Quux>\n"
-               "+ (id)init;\n"
-               "@end");
-  verifyFormat("@interface Foo (HackStuff)<MyProtocol>\n"
-               "+ (id)init;\n"
-               "@end");
-  Style.BinPackParameters = false;
-  Style.ColumnLimit = 80;
-  verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
-               "}");
-}
-
-TEST_F(FormatTestObjC, FormatObjCImplementation) {
-  verifyFormat("@implementation Foo : NSObject {\n"
-               "@public\n"
-               "  int field1;\n"
-               "@protected\n"
-               "  int field2;\n"
-               "@private\n"
-               "  int field3;\n"
-               "@package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo\n"
-               "+ (id)init {\n"
-               "  if (true)\n"
-               "    return nil;\n"
-               "}\n"
-               "// Look, a comment!\n"
-               "- (int)answerWith:(int)i {\n"
-               "  return i;\n"
-               "}\n"
-               "+ (int)answerWith:(int)i {\n"
-               "  return i;\n"
-               "}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo\n"
-               "@end\n"
-               "@implementation Bar\n"
-               "@end");
-
-  EXPECT_EQ("@implementation Foo : Bar\n"
-            "+ (id)init {\n}\n"
-            "- (void)foo {\n}\n"
-            "@end",
-            format("@implementation Foo : Bar\n"
-                   "+(id)init{}\n"
-                   "-(void)foo{}\n"
-                   "@end"));
-
-  verifyFormat("@implementation Foo {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo : Bar {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo (HackStuff)\n"
-               "+ (id)init {\n}\n"
-               "@end");
-  verifyFormat("@implementation ObjcClass\n"
-               "- (void)method;\n"
-               "{}\n"
-               "@end");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat("@implementation Foo : NSObject {\n"
-               " @public\n"
-               "  int field1;\n"
-               " @protected\n"
-               "  int field2;\n"
-               " @private\n"
-               "  int field3;\n"
-               " @package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-}
-
-TEST_F(FormatTestObjC, FormatObjCProtocol) {
-  verifyFormat("@protocol Foo\n"
-               "@property(weak) id delegate;\n"
-               "- (NSUInteger)numberOfThings;\n"
-               "@end");
-
-  verifyFormat("@protocol MyProtocol <NSObject>\n"
-               "- (NSUInteger)numberOfThings;\n"
-               "@end");
-
-  verifyFormat("@protocol Foo;\n"
-               "@protocol Bar;\n");
-
-  verifyFormat("@protocol Foo\n"
-               "@end\n"
-               "@protocol Bar\n"
-               "@end");
-
-  verifyFormat("@protocol myProtocol\n"
-               "- (void)mandatoryWithInt:(int)i;\n"
-               "@optional\n"
-               "- (void)optional;\n"
-               "@required\n"
-               "- (void)required;\n"
-               "@optional\n"
-               "@property(assign) int madProp;\n"
-               "@end\n");
-
-  verifyFormat("@property(nonatomic, assign, readonly)\n"
-               "    int *looooooooooooooooooooooooooooongNumber;\n"
-               "@property(nonatomic, assign, readonly)\n"
-               "    NSString *looooooooooooooooooooooooooooongName;");
-
-  verifyFormat("@implementation PR18406\n"
-               "}\n"
-               "@end");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat("@protocol MyProtocol<NSObject>\n"
-               "- (NSUInteger)numberOfThings;\n"
-               "@end");
-}
-
-TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) {
-  verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n"
-               "                   rect:(NSRect)theRect\n"
-               "               interval:(float)theInterval {\n"
-               "}");
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "      longKeyword:(NSRect)theRect\n"
-               "    longerKeyword:(float)theInterval\n"
-               "            error:(NSError **)theError {\n"
-               "}");
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "          longKeyword:(NSRect)theRect\n"
-               "    evenLongerKeyword:(float)theInterval\n"
-               "                error:(NSError **)theError {\n"
-               "}");
-  Style.ColumnLimit = 60;
-  verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"
-               "                         y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"
-               "    NS_DESIGNATED_INITIALIZER;");
-  verifyFormat("- (void)drawRectOn:(id)surface\n"
-               "            ofSize:(size_t)height\n"
-               "                  :(size_t)width;");
-
-  // Continuation indent width should win over aligning colons if the function
-  // name is long.
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  Style.ColumnLimit = 40;
-  Style.IndentWrappedFunctionNames = true;
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "    dontAlignNamef:(NSRect)theRect {\n"
-               "}");
-
-  // Make sure we don't break aligning for short parameter names.
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "       aShortf:(NSRect)theRect {\n"
-               "}");
-
-  // Format pairs correctly.
-  Style.ColumnLimit = 80;
-  verifyFormat("- (void)drawRectOn:(id)surface\n"
-               "            ofSize:(aaaaaaaa)height\n"
-               "                  :(size_t)width\n"
-               "          atOrigin:(size_t)x\n"
-               "                  :(size_t)y\n"
-               "             aaaaa:(a)yyy\n"
-               "               bbb:(d)cccc;");
-  verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;");
-}
-
-TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
-  verifyFormat("[foo bar:baz];");
-  verifyFormat("return [foo bar:baz];");
-  verifyFormat("return (a)[foo bar:baz];");
-  verifyFormat("f([foo bar:baz]);");
-  verifyFormat("f(2, [foo bar:baz]);");
-  verifyFormat("f(2, a ? b : c);");
-  verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");
-
-  // Unary operators.
-  verifyFormat("int a = +[foo bar:baz];");
-  verifyFormat("int a = -[foo bar:baz];");
-  verifyFormat("int a = ![foo bar:baz];");
-  verifyFormat("int a = ~[foo bar:baz];");
-  verifyFormat("int a = ++[foo bar:baz];");
-  verifyFormat("int a = --[foo bar:baz];");
-  verifyFormat("int a = sizeof [foo bar:baz];");
-  verifyFormat("int a = alignof [foo bar:baz];");
-  verifyFormat("int a = &[foo bar:baz];");
-  verifyFormat("int a = *[foo bar:baz];");
-  // FIXME: Make casts work, without breaking f()[4].
-  // verifyFormat("int a = (int)[foo bar:baz];");
-  // verifyFormat("return (int)[foo bar:baz];");
-  // verifyFormat("(void)[foo bar:baz];");
-  verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];");
-
-  // Binary operators.
-  verifyFormat("[foo bar:baz], [foo bar:baz];");
-  verifyFormat("[foo bar:baz] = [foo bar:baz];");
-  verifyFormat("[foo bar:baz] *= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] /= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] %= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] += [foo bar:baz];");
-  verifyFormat("[foo bar:baz] -= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] <<= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >>= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] &= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ^= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] |= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");
-  verifyFormat("[foo bar:baz] || [foo bar:baz];");
-  verifyFormat("[foo bar:baz] && [foo bar:baz];");
-  verifyFormat("[foo bar:baz] | [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ^ [foo bar:baz];");
-  verifyFormat("[foo bar:baz] & [foo bar:baz];");
-  verifyFormat("[foo bar:baz] == [foo bar:baz];");
-  verifyFormat("[foo bar:baz] != [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] <= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] > [foo bar:baz];");
-  verifyFormat("[foo bar:baz] < [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >> [foo bar:baz];");
-  verifyFormat("[foo bar:baz] << [foo bar:baz];");
-  verifyFormat("[foo bar:baz] - [foo bar:baz];");
-  verifyFormat("[foo bar:baz] + [foo bar:baz];");
-  verifyFormat("[foo bar:baz] * [foo bar:baz];");
-  verifyFormat("[foo bar:baz] / [foo bar:baz];");
-  verifyFormat("[foo bar:baz] % [foo bar:baz];");
-  // Whew!
-
-  verifyFormat("return in[42];");
-  verifyFormat("for (auto v : in[1]) {\n}");
-  verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}");
-  verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}");
-  verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}");
-  verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}");
-  verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}");
-  verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
-               "}");
-  verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");
-  verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");
-  verifyFormat("[self aaaaa:(Type)a bbbbb:3];");
-
-  verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
-  verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
-  verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");
-  verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");
-  verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");
-  verifyFormat("[button setAction:@selector(zoomOut:)];");
-  verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];");
-
-  verifyFormat("arr[[self indexForFoo:a]];");
-  verifyFormat("throw [self errorFor:a];");
-  verifyFormat("@throw [self errorFor:a];");
-
-  verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];");
-  verifyFormat("[(id)foo bar:(id) ? baz : quux];");
-  verifyFormat("4 > 4 ? (id)a : (id)baz;");
-
-  // This tests that the formatter doesn't break after "backing" but before ":",
-  // which would be at 80 columns.
-  verifyFormat(
-      "void f() {\n"
-      "  if ((self = [super initWithContentRect:contentRect\n"
-      "                               styleMask:styleMask ?: otherMask\n"
-      "                                 backing:NSBackingStoreBuffered\n"
-      "                                   defer:YES]))");
-
-  verifyFormat(
-      "[foo checkThatBreakingAfterColonWorksOk:\n"
-      "         [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];");
-
-  verifyFormat("[myObj short:arg1 // Force line break\n"
-               "          longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n"
-               "    evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n"
-               "                error:arg4];");
-  verifyFormat(
-      "void f() {\n"
-      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
-      "                                     pos.width(), pos.height())\n"
-      "                styleMask:NSBorderlessWindowMask\n"
-      "                  backing:NSBackingStoreBuffered\n"
-      "                    defer:NO]);\n"
-      "}");
-  verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n"
-               "                             with:contentsNativeView];");
-
-  verifyFormat(
-      "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n"
-      "           owner:nillllll];");
-
-  verifyFormat(
-      "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n"
-      "        forType:kBookmarkButtonDragType];");
-
-  verifyFormat("[defaultCenter addObserver:self\n"
-               "                  selector:@selector(willEnterFullscreen)\n"
-               "                      name:kWillEnterFullscreenNotification\n"
-               "                    object:nil];");
-  verifyFormat("[image_rep drawInRect:drawRect\n"
-               "             fromRect:NSZeroRect\n"
-               "            operation:NSCompositeCopy\n"
-               "             fraction:1.0\n"
-               "       respectFlipped:NO\n"
-               "                hints:nil];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n"
-               "    aaaaaaaaaaaaaaaaaaaaaa];");
-
-  verifyFormat(
-      "scoped_nsobject<NSTextField> message(\n"
-      "    // The frame will be fixed up when |-setMessageText:| is called.\n"
-      "    [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);");
-  verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n"
-               "    aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n"
-               "         aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n"
-               "          aaaa:bbb];");
-  verifyFormat("[self param:function( //\n"
-               "                parameter)]");
-  verifyFormat(
-      "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
-      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
-      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];");
-
-  // Variadic parameters.
-  verifyFormat(
-      "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];");
-  verifyFormat(
-      "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
-      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
-      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");
-  verifyFormat("[self // break\n"
-               "      a:a\n"
-               "    aaa:aaa];");
-  verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
-               "          [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
-
-  // Formats pair-parameters.
-  verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
-  verifyFormat("[I drawRectOn:surface //\n"
-               "        ofSize:aa:bbb\n"
-               "      atOrigin:cc:dd];");
-
-  Style.ColumnLimit = 70;
-  verifyFormat(
-      "void f() {\n"
-      "  popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n"
-      "                                 pos.width(), pos.height())\n"
-      "                syeMask:NSBorderlessWindowMask\n"
-      "                  bking:NSBackingStoreBuffered\n"
-      "                    der:NO]);\n"
-      "}");
-
-  Style.ColumnLimit = 60;
-  verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n"
-               "        .aaaaaaaa];"); // FIXME: Indentation seems off.
-  // FIXME: This violates the column limit.
-  verifyFormat(
-      "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    aaaaaaaaaaaaaaaaa:aaaaaaaa\n"
-      "                  aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
-
-  Style = getChromiumStyle(FormatStyle::LK_ObjC);
-  Style.ColumnLimit = 80;
-  verifyFormat(
-      "void f() {\n"
-      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
-      "                                     pos.width(), pos.height())\n"
-      "                styleMask:NSBorderlessWindowMask\n"
-      "                  backing:NSBackingStoreBuffered\n"
-      "                    defer:NO]);\n"
-      "}");
-}
-
-TEST_F(FormatTestObjC, ObjCAt) {
-  verifyFormat("@autoreleasepool");
-  verifyFormat("@catch");
-  verifyFormat("@class");
-  verifyFormat("@compatibility_alias");
-  verifyFormat("@defs");
-  verifyFormat("@dynamic");
-  verifyFormat("@encode");
-  verifyFormat("@end");
-  verifyFormat("@finally");
-  verifyFormat("@implementation");
-  verifyFormat("@import");
-  verifyFormat("@interface");
-  verifyFormat("@optional");
-  verifyFormat("@package");
-  verifyFormat("@private");
-  verifyFormat("@property");
-  verifyFormat("@protected");
-  verifyFormat("@protocol");
-  verifyFormat("@public");
-  verifyFormat("@required");
-  verifyFormat("@selector");
-  verifyFormat("@synchronized");
-  verifyFormat("@synthesize");
-  verifyFormat("@throw");
-  verifyFormat("@try");
-
-  EXPECT_EQ("@interface", format("@ interface"));
-
-  // The precise formatting of this doesn't matter, nobody writes code like
-  // this.
-  verifyFormat("@ /*foo*/ interface");
-}
-
-TEST_F(FormatTestObjC, ObjCSnippets) {
-  verifyFormat("@autoreleasepool {\n"
-               "  foo();\n"
-               "}");
-  verifyFormat("@class Foo, Bar;");
-  verifyFormat("@compatibility_alias AliasName ExistingClass;");
-  verifyFormat("@dynamic textColor;");
-  verifyFormat("char *buf1 = @encode(int *);");
-  verifyFormat("char *buf1 = @encode(typeof(4 * 5));");
-  verifyFormat("char *buf1 = @encode(int **);");
-  verifyFormat("Protocol *proto = @protocol(p1);");
-  verifyFormat("SEL s = @selector(foo:);");
-  verifyFormat("@synchronized(self) {\n"
-               "  f();\n"
-               "}");
-
-  verifyFormat("@import foo.bar;\n"
-               "@import baz;");
-
-  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
-
-  verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
-  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
-
-  Style = getMozillaStyle();
-  verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
-  verifyFormat("@property BOOL editable;");
-
-  Style = getWebKitStyle();
-  verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
-  verifyFormat("@property BOOL editable;");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
-  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
-}
-
-TEST_F(FormatTestObjC, ObjCForIn) {
-  verifyFormat("- (void)test {\n"
-               "  for (NSString *n in arrayOfStrings) {\n"
-               "    foo(n);\n"
-               "  }\n"
-               "}");
-  verifyFormat("- (void)test {\n"
-               "  for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n"
-               "    foo(n);\n"
-               "  }\n"
-               "}");
-}
-
-TEST_F(FormatTestObjC, ObjCLiterals) {
-  verifyFormat("@\"String\"");
-  verifyFormat("@1");
-  verifyFormat("@+4.8");
-  verifyFormat("@-4");
-  verifyFormat("@1LL");
-  verifyFormat("@.5");
-  verifyFormat("@'c'");
-  verifyFormat("@true");
-
-  verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);");
-  verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);");
-  verifyFormat("NSNumber *favoriteColor = @(Green);");
-  verifyFormat("NSString *path = @(getenv(\"PATH\"));");
-
-  verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];");
-}
-
-TEST_F(FormatTestObjC, ObjCDictLiterals) {
-  verifyFormat("@{");
-  verifyFormat("@{}");
-  verifyFormat("@{@\"one\" : @1}");
-  verifyFormat("return @{@\"one\" : @1;");
-  verifyFormat("@{@\"one\" : @1}");
-
-  verifyFormat("@{@\"one\" : @{@2 : @1}}");
-  verifyFormat("@{\n"
-               "  @\"one\" : @{@2 : @1},\n"
-               "}");
-
-  verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
-  verifyIncompleteFormat("[self setDict:@{}");
-  verifyIncompleteFormat("[self setDict:@{@1 : @2}");
-  verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
-  verifyFormat(
-      "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
-  verifyFormat(
-      "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");
-
-  verifyFormat("NSDictionary *d = @{\n"
-               "  @\"nam\" : NSUserNam(),\n"
-               "  @\"dte\" : [NSDate date],\n"
-               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
-               "};");
-  verifyFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
-      "regularFont,\n"
-      "};");
-  verifyFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"
-      "      reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"
-      "};");
-
-  // We should try to be robust in case someone forgets the "@".
-  verifyFormat("NSDictionary *d = {\n"
-               "  @\"nam\" : NSUserNam(),\n"
-               "  @\"dte\" : [NSDate date],\n"
-               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
-               "};");
-  verifyFormat("NSMutableDictionary *dictionary =\n"
-               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
-               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
-               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
-               "      cccccccccccccccc : ccccccccccccccc\n"
-               "    }];");
-
-  // Ensure that casts before the key are kept on the same line as the key.
-  verifyFormat(
-      "NSDictionary *d = @{\n"
-      "  (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"
-      "  (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"
-      "};");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
-      "regularFont,\n"
-      "};");
-}
-
-TEST_F(FormatTestObjC, ObjCArrayLiterals) {
-  verifyIncompleteFormat("@[");
-  verifyFormat("@[]");
-  verifyFormat(
-      "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
-  verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");
-  verifyFormat("NSArray *array = @[ [foo description] ];");
-
-  verifyFormat(
-      "NSArray *some_variable = @[\n"
-      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "];");
-  verifyFormat(
-      "NSArray *some_variable = @[\n"
-      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n"
-      "];");
-  verifyFormat("NSArray *some_variable = @[\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "];");
-  verifyFormat("NSArray *array = @[\n"
-               "  @\"a\",\n"
-               "  @\"a\",\n" // Trailing comma -> one per line.
-               "];");
-
-  // We should try to be robust in case someone forgets the "@".
-  verifyFormat("NSArray *some_variable = [\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "];");
-  verifyFormat(
-      "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n"
-      "                                             index:(NSUInteger)index\n"
-      "                                nonDigitAttributes:\n"
-      "                                    (NSDictionary *)noDigitAttributes;");
-  verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
-               "  NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
-               "]];");
-}
-} // end namespace
-} // end namespace format
-} // end namespace clang
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/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index 918167b..b5a6fd9 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -12,6 +12,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
@@ -64,10 +65,12 @@
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
     VoidModuleLoader ModLoader;
+    MemoryBufferCache PCMCache;
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, LangOpts, Target.get());
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                    SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr,
+                    SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                    /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
     PP.EnterMainSourceFile();
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index 064abaf..0841791 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -14,6 +14,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
@@ -161,13 +162,14 @@
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
     VoidModuleLoader ModLoader;
+    MemoryBufferCache PCMCache;
 
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, LangOpts, Target.get());
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
 
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                    SourceMgr, HeaderInfo, ModLoader,
+                    SourceMgr, PCMCache, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
@@ -198,11 +200,12 @@
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
 
     VoidModuleLoader ModLoader;
+    MemoryBufferCache PCMCache;
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, OpenCLLangOpts, Target.get());
 
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags,
-                    OpenCLLangOpts, SourceMgr, HeaderInfo, ModLoader,
+                    OpenCLLangOpts, SourceMgr, PCMCache, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
diff --git a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index dccfffd..b635604 100644
--- a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -12,6 +12,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
@@ -93,10 +94,11 @@
   SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
   VoidModuleLoader ModLoader;
+  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, Target.get());
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, HeaderInfo, ModLoader,
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
diff --git a/unittests/Tooling/ReplacementTest.h b/unittests/Tooling/ReplacementTest.h
index b6fe5c7..91530f0 100644
--- a/unittests/Tooling/ReplacementTest.h
+++ b/unittests/Tooling/ReplacementTest.h
@@ -24,7 +24,7 @@
 /// \brief Converts a set of replacements to Replacements class.
 /// \return A Replacements class containing \p Replaces on success; otherwise,
 /// an empty Replacements is returned.
-inline tooling::Replacements
+static tooling::Replacements
 toReplacements(const std::set<tooling::Replacement> &Replaces) {
   tooling::Replacements Result;
   for (const auto &R : Replaces) {
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