Merge pull request #14920 from davidungar/PR-18-9-batch-fix

[Batch mode]: Use first primary name for batch input file name.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 59149f7..55317a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,7 +6,7 @@
 
 | Contents               |
 | :--------------------- |
-| [Swift 5.0](#swift-50) |
+| [Swift 4.2](#swift-42) |
 | [Swift 4.1](#swift-41) |
 | [Swift 4.0](#swift-40) |
 | [Swift 3.1](#swift-31) |
@@ -20,7 +20,7 @@
 
 </details>
 
-Swift 5.0
+Swift 4.2
 ---------
 
 * Public classes may now have internal `required` initializers. The rule for
@@ -47,6 +47,25 @@
 Swift 4.1
 ---------
 
+* [SE-0075][]
+
+  Compile-time testing for the existence and importability of modules is now
+  implemented as a build configuration test.  The `canImport` test allows
+  the development of features that require a possibly-failing import 
+  declaration across multiple platforms.  
+
+  ```swift
+  #if canImport(UIKit)
+    import UIKit
+    class MyView : UIView {}
+  #elseif canImport(AppKit)
+    import AppKit
+    class MyView : NSView {}
+  #else
+    class MyView : CustomView {}
+  #endif
+  ```
+
 * [SE-0189][]
 
   If an initializer is declared in a different module from a struct, it must
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e9281bf..0050546 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -128,7 +128,7 @@
 # SWIFT_VERSION is deliberately /not/ cached so that an existing build directory
 # can be reused when a new version of Swift comes out (assuming the user hasn't
 # manually set it as part of their own CMake configuration).
-set(SWIFT_VERSION "4.1")
+set(SWIFT_VERSION "4.2")
 
 set(SWIFT_VENDOR "" CACHE STRING
     "The vendor name of the Swift compiler")
diff --git a/benchmark/utils/DriverUtils.swift b/benchmark/utils/DriverUtils.swift
index f5b5398..74f59d6 100644
--- a/benchmark/utils/DriverUtils.swift
+++ b/benchmark/utils/DriverUtils.swift
@@ -208,14 +208,10 @@
     }
 
     if let x = benchArgs.optionalArgsMap["--sleep"] {
-      if x.isEmpty {
+      guard let v = Int(x) else {
         return .fail("--sleep requires a non-empty integer value")
       }
-      let v: Int? = Int(x)
-      if v == nil {
-        return .fail("--sleep requires a non-empty integer value")
-      }
-      afterRunSleep = v!
+      afterRunSleep = v
     }
 
     if let _ = benchArgs.optionalArgsMap["--list"] {
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index f489be3..e837cf6 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -183,12 +183,16 @@
   if(optimized OR CFLAGS_FORCE_BUILD_OPTIMIZED)
     list(APPEND result "-O2")
 
-    # Omit leaf frame pointers on x86.
-    if("${CFLAGS_ARCH}" STREQUAL "i386" OR "${CFLAGS_ARCH}" STREQUAL "i686")
-      if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
-        list(APPEND result "-momit-leaf-frame-pointer")
-      else()
-        list(APPEND result "/Oy")
+    # Omit leaf frame pointers on x86 production builds (optimized, no debug
+    # info, and no asserts).
+    is_build_type_with_debuginfo("${CFLAGS_BUILD_TYPE}" debug)
+    if(NOT debug AND NOT CFLAGS_ENABLE_ASSERTIONS)
+      if("${CFLAGS_ARCH}" STREQUAL "i386" OR "${CFLAGS_ARCH}" STREQUAL "i686")
+        if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
+          list(APPEND result "-momit-leaf-frame-pointer")
+        else()
+          list(APPEND result "/Oy")
+        endif()
       endif()
     endif()
   else()
@@ -248,6 +252,13 @@
     list(APPEND result "-D_DLL")
     # NOTE: We assume that we are using VS 2015 U2+
     list(APPEND result "-D_ENABLE_ATOMIC_ALIGNMENT_FIX")
+
+    # msvcprt's std::function requires RTTI, but we do not want RTTI data.
+    # Emulate /GR-
+    if(NOT SWIFT_COMPILER_IS_MSVC_LIKE)
+      list(APPEND result -frtti)
+      list(APPEND result -Xclang;-fno-rtti-data)
+    endif()
   endif()
 
   if(CFLAGS_ENABLE_ASSERTIONS)
diff --git a/cmake/modules/SwiftHandleGybSources.cmake b/cmake/modules/SwiftHandleGybSources.cmake
index c01269b..45245b9 100644
--- a/cmake/modules/SwiftHandleGybSources.cmake
+++ b/cmake/modules/SwiftHandleGybSources.cmake
@@ -37,10 +37,6 @@
       GYB_SINGLE # prefix
       "${options}" "${single_value_args}" "${multi_value_args}" ${ARGN})
 
-  set(gyb_flags
-      ${SWIFT_GYB_FLAGS}
-      ${GYB_SINGLE_FLAGS})
-
   set(gyb_tool "${SWIFT_SOURCE_DIR}/utils/gyb")
   set(gyb_tool_source "${gyb_tool}" "${gyb_tool}.py")
 
@@ -62,11 +58,9 @@
       COMMAND
           "${CMAKE_COMMAND}" -E make_directory "${dir}"
       COMMAND
-          "${PYTHON_EXECUTABLE}" "${gyb_tool}" "${gyb_flags}"
-          -o "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_SOURCE}"
+          "${PYTHON_EXECUTABLE}" "${gyb_tool}" ${SWIFT_GYB_FLAGS} ${GYB_SINGLE_FLAGS} -o "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_SOURCE}"
       COMMAND
-          "${CMAKE_COMMAND}" -E copy_if_different
-          "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_OUTPUT}"
+          "${CMAKE_COMMAND}" -E copy_if_different "${GYB_SINGLE_OUTPUT}.tmp" "${GYB_SINGLE_OUTPUT}"
       COMMAND
           "${CMAKE_COMMAND}" -E remove "${GYB_SINGLE_OUTPUT}.tmp"
       OUTPUT "${GYB_SINGLE_OUTPUT}"
diff --git a/docs/ABIStabilityManifesto.md b/docs/ABIStabilityManifesto.md
index 243ccea..19d52a6 100644
--- a/docs/ABIStabilityManifesto.md
+++ b/docs/ABIStabilityManifesto.md
@@ -116,7 +116,7 @@
 
 Resilient types are required to have opaque layout when exposed outside their resilience domain. Inside a resilience domain, this requirement is lifted and their layout may be statically known or opaque as determined by their type (see [previous section](#opaque-layout)).
 
-Annotations may be applied to a library's types in future versions of that library, in which case the annotations are versioned, yet the library remains binary compatible. How how this will impact the ABI is still under investigation [[SR-3911](https://bugs.swift.org/browse/SR-3911)].
+Annotations may be applied to a library's types in future versions of that library, in which case the annotations are versioned, yet the library remains binary compatible. How this will impact the ABI is still under investigation [[SR-3911](https://bugs.swift.org/browse/SR-3911)].
 
 
 #### <a name="abstraction-levels"></a>Abstraction Levels
diff --git a/docs/Serialization.rst b/docs/Serialization.rst
index 9655ecf..57f55ab 100644
--- a/docs/Serialization.rst
+++ b/docs/Serialization.rst
@@ -135,7 +135,7 @@
   of ``@_transparent``. The SIL block precedes the AST block because it affects
   which AST nodes get serialized.
 
-- The **SIL index black** contains tables for accessing various SIL entities by
+- The **SIL index block** contains tables for accessing various SIL entities by
   their names, along with a mapping of unique IDs for these to the appropriate
   bit offsets into the SIL block.
 
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index aed6000..8c4f7d6 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -1021,6 +1021,10 @@
     /// Only meaningful for class descriptors.
     Class_SuperclassReferenceKind = 12,
     Class_SuperclassReferenceKind_width = 2,
+
+    /// Whether the immediate class members in this metadata are allocated
+    /// at negative offsets.  For now, we don't use this.
+    Class_AreImmediateMembersNegative = 11,
   };
 
 public:
@@ -1037,6 +1041,9 @@
   FLAGSET_DEFINE_FLAG_ACCESSORS(Class_HasResilientSuperclass,
                                 class_hasResilientSuperclass,
                                 class_setHasResilientSuperclass)
+  FLAGSET_DEFINE_FLAG_ACCESSORS(Class_AreImmediateMembersNegative,
+                                class_areImmediateMembersNegative,
+                                class_setAreImmediateMembersNegative)
 
   FLAGSET_DEFINE_FIELD_ACCESSORS(Class_SuperclassReferenceKind,
                                  Class_SuperclassReferenceKind_width,
diff --git a/include/swift/AST/Attr.def b/include/swift/AST/Attr.def
index 2bcaf62..9569816 100644
--- a/include/swift/AST/Attr.def
+++ b/include/swift/AST/Attr.def
@@ -214,9 +214,9 @@
           NotSerialized | RejectByParser, /* Not serialized */48)
 
 // Also handles unowned and unowned(weak).
-DECL_ATTR(weak, Ownership, OnVar | OnParam | DeclModifier | NotSerialized,
+DECL_ATTR(weak, ReferenceOwnership, OnVar | OnParam | DeclModifier | NotSerialized,
           /* Not serialized */49)
-DECL_ATTR_ALIAS(unowned, Ownership)
+DECL_ATTR_ALIAS(unowned, ReferenceOwnership)
 
 DECL_ATTR(effects, Effects, OnFunc | OnConstructor | OnDestructor |
           UserInaccessible, 50)
diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h
index a31a22f..78f21c4 100644
--- a/include/swift/AST/Attr.h
+++ b/include/swift/AST/Attr.h
@@ -105,13 +105,18 @@
   
   bool hasConvention() const { return convention.hasValue(); }
   StringRef getConvention() const { return *convention; }
-  
-  bool hasOwnership() const { return getOwnership() != Ownership::Strong; }
-  Ownership getOwnership() const {
-    if (has(TAK_sil_weak)) return Ownership::Weak;
-    if (has(TAK_sil_unowned)) return Ownership::Unowned;
-    if (has(TAK_sil_unmanaged)) return Ownership::Unmanaged;
-    return Ownership::Strong;
+
+  bool hasOwnership() const {
+    return getOwnership() != ReferenceOwnership::Strong;
+  }
+  ReferenceOwnership getOwnership() const {
+    if (has(TAK_sil_weak))
+      return ReferenceOwnership::Weak;
+    if (has(TAK_sil_unowned))
+      return ReferenceOwnership::Unowned;
+    if (has(TAK_sil_unmanaged))
+      return ReferenceOwnership::Unmanaged;
+    return ReferenceOwnership::Strong;
   }
   
   void clearOwnership() {
@@ -965,24 +970,27 @@
 
 
 /// Represents weak/unowned/unowned(unsafe) decl modifiers.
-class OwnershipAttr : public DeclAttribute {
-  const Ownership ownership;
+class ReferenceOwnershipAttr : public DeclAttribute {
+  const ReferenceOwnership ownership;
+
 public:
-  OwnershipAttr(SourceRange range, Ownership kind)
-    : DeclAttribute(DAK_Ownership, range.Start, range, /*Implicit=*/false),
-      ownership(kind) {}
+  ReferenceOwnershipAttr(SourceRange range, ReferenceOwnership kind)
+      : DeclAttribute(DAK_ReferenceOwnership, range.Start, range,
+                      /*Implicit=*/false),
+        ownership(kind) {}
 
-  OwnershipAttr(Ownership kind) : OwnershipAttr(SourceRange(), kind) {}
+  ReferenceOwnershipAttr(ReferenceOwnership kind)
+      : ReferenceOwnershipAttr(SourceRange(), kind) {}
 
-  Ownership get() const { return ownership; }
+  ReferenceOwnership get() const { return ownership; }
 
   /// Returns a copy of this attribute without any source information.
-  OwnershipAttr *clone(ASTContext &context) const {
-    return new (context) OwnershipAttr(get());
+  ReferenceOwnershipAttr *clone(ASTContext &context) const {
+    return new (context) ReferenceOwnershipAttr(get());
   }
 
   static bool classof(const DeclAttribute *DA) {
-    return DA->getKind() == DAK_Ownership;
+    return DA->getKind() == DAK_ReferenceOwnership;
   }
 };
 
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 2d43a1f..c974d92 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -4606,7 +4606,20 @@
   bool isLet() const { return getSpecifier() == Specifier::Let; }
   /// Is this an immutable 'shared' property?
   bool isShared() const { return getSpecifier() == Specifier::Shared; }
-  
+
+  ValueOwnership getValueOwnership() const {
+    switch (getSpecifier()) {
+    case Specifier::Let:
+      return ValueOwnership::Default;
+    case Specifier::Var:
+      return ValueOwnership::Default;
+    case Specifier::InOut:
+      return ValueOwnership::InOut;
+    case Specifier::Shared:
+      return ValueOwnership::Shared;
+    }
+  }
+
   /// Is this an element in a capture list?
   bool isCaptureList() const { return Bits.VarDecl.IsCaptureList; }
 
diff --git a/include/swift/AST/DiagnosticConsumer.h b/include/swift/AST/DiagnosticConsumer.h
index 9f1edf3..578e432 100644
--- a/include/swift/AST/DiagnosticConsumer.h
+++ b/include/swift/AST/DiagnosticConsumer.h
@@ -19,6 +19,7 @@
 #ifndef SWIFT_BASIC_DIAGNOSTICCONSUMER_H
 #define SWIFT_BASIC_DIAGNOSTICCONSUMER_H
 
+#include "swift/Basic/LLVM.h"
 #include "swift/Basic/SourceLoc.h"
 #include "llvm/Support/SourceMgr.h"
 
@@ -111,6 +112,75 @@
                         ArrayRef<DiagnosticArgument> FormatArgs,
                         const DiagnosticInfo &Info) override;
 };
+
+/// \brief DiagnosticConsumer that funnels diagnostics in certain files to
+/// particular sub-consumers.
+///
+/// The intended use case for such a consumer is "batch mode" compilations,
+/// where we want to record diagnostics for each file as if they were compiled
+/// separately. This is important for incremental builds, so that if a file has
+/// warnings but doesn't get recompiled in the next build, the warnings persist.
+///
+/// Diagnostics that are not in one of the special files are emitted into every
+/// sub-consumer. This is necessary to deal with, for example, diagnostics in a
+/// bridging header imported from Objective-C, which isn't really about the
+/// current file.
+class FileSpecificDiagnosticConsumer : public DiagnosticConsumer {
+public:
+  /// A diagnostic consumer, along with the name of the buffer that it should
+  /// be associated with. An empty string means that a consumer is not
+  /// associated with any particular buffer, and should only receive diagnostics
+  /// that are not in any of the other consumers' files.
+  using ConsumerPair =
+      std::pair<std::string, std::unique_ptr<DiagnosticConsumer>>;
+
+private:
+  /// All consumers owned by this FileSpecificDiagnosticConsumer.
+  const SmallVector<ConsumerPair, 4> SubConsumers;
+
+  using ConsumersOrderedByRangeEntry =
+    std::pair<CharSourceRange, DiagnosticConsumer *>;
+
+  /// The consumers owned by this FileSpecificDiagnosticConsumer, sorted by
+  /// the end locations of each file so that a lookup by position can be done
+  /// using binary search.
+  ///
+  /// Generated and cached when the first diagnostic with a location is emitted.
+  /// This allows diagnostics to be emitted before files are actually opened,
+  /// as long as they don't have source locations.
+  ///
+  /// \see #consumerForLocation
+  SmallVector<ConsumersOrderedByRangeEntry, 4> ConsumersOrderedByRange;
+
+  /// Indicates which consumer to send Note diagnostics too.
+  ///
+  /// Notes are always considered attached to the error, warning, or remark
+  /// that was most recently emitted.
+  ///
+  /// If null, Note diagnostics are sent to every consumer.
+  DiagnosticConsumer *ConsumerForSubsequentNotes = nullptr;
+
+public:
+  /// Takes ownership of the DiagnosticConsumers specified in \p consumers.
+  ///
+  /// There must not be two consumers for the same file (i.e., having the same
+  /// buffer name).
+  explicit FileSpecificDiagnosticConsumer(
+      SmallVectorImpl<ConsumerPair> &consumers);
+
+  void handleDiagnostic(SourceManager &SM, SourceLoc Loc,
+                        DiagnosticKind Kind,
+                        StringRef FormatString,
+                        ArrayRef<DiagnosticArgument> FormatArgs,
+                        const DiagnosticInfo &Info) override;
+
+   bool finishProcessing() override;
+
+private:
+  void computeConsumersOrderedByRange(SourceManager &SM);
+  DiagnosticConsumer *consumerForLocation(SourceManager &SM,
+                                          SourceLoc loc) const;
+};
   
 } // end namespace swift
 
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 70531ab..b2b5d35 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1915,7 +1915,7 @@
 ERROR(override_ownership_mismatch,none,
       "cannot override %select{strong|weak|unowned|unowned(unsafe)}0 property "
       "with %select{strong|weak|unowned|unowned(unsafe)}1 property",
-      (/*Ownership*/unsigned, /*Ownership*/unsigned))
+      (/*ReferenceOwnership*/unsigned, /*ReferenceOwnership*/unsigned))
 ERROR(override_dynamic_self_mismatch,none,
       "cannot override a Self return type with a non-Self return type",
       ())
@@ -3152,22 +3152,22 @@
 ERROR(invalid_ownership_type,none,
       "'%select{strong|weak|unowned|unowned}0' may only be applied to "
       "class and class-bound protocol types, not %1",
-      (/*Ownership*/unsigned, Type))
+      (/*ReferenceOwnership*/unsigned, Type))
 ERROR(invalid_ownership_protocol_type,none,
       "'%select{strong|weak|unowned|unowned}0' must not be applied to "
       "non-class-bound %1; consider adding a protocol conformance that has a class bound",
-      (/*Ownership*/unsigned, Type))
+      (/*ReferenceOwnership*/unsigned, Type))
 ERROR(invalid_weak_ownership_not_optional,none,
       "'weak' variable should have optional type %0", (Type))
 ERROR(invalid_weak_let,none,
       "'weak' must be a mutable variable, because it may change at runtime", ())
 ERROR(ownership_invalid_in_protocols,none,
       "'%select{strong|weak|unowned|unowned}0' cannot be applied to a property declaration in a protocol",
-      (/*Ownership*/unsigned))
+      (/*ReferenceOwnership*/unsigned))
 WARNING(ownership_invalid_in_protocols_compat_warning,none,
       "'%select{strong|weak|unowned|unowned}0' should not be applied to a property declaration "
       "in a protocol and will be disallowed in future versions",
-      (/*Ownership*/unsigned))
+      (/*ReferenceOwnership*/unsigned))
 
 // required
 ERROR(required_initializer_nonclass,none,
diff --git a/include/swift/AST/Ownership.h b/include/swift/AST/Ownership.h
index c7f1464..2d8f3de 100644
--- a/include/swift/AST/Ownership.h
+++ b/include/swift/AST/Ownership.h
@@ -1,4 +1,4 @@
-//===--- Ownership.h - Swift ASTs for Reference Ownership -------*- C++ -*-===//
+//===--- Ownership.h - Swift ASTs for Ownership ---------------*- C++ -*-===//
 //
 // This source file is part of the Swift.org open source project
 //
@@ -10,9 +10,9 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file defines common structures for working with the different
-// kinds of reference ownership supported by Swift, such as 'weak' and
-// 'unowned'.
+// This file defines common structures for working with the different kinds of
+// reference ownership supported by Swift, such as 'weak' and 'unowned', as well
+// as the different kinds of value ownership, such as 'inout' and '__shared'.
 //
 //===----------------------------------------------------------------------===//
 
@@ -26,7 +26,7 @@
 /// Different kinds of reference ownership supported by Swift.
 // This enum is used in diagnostics. If you add a case here, the diagnostics
 // must be updated as well.
-enum class Ownership : uint8_t {
+enum class ReferenceOwnership : uint8_t {
   /// \brief a strong reference (the default semantics)
   Strong,
 
@@ -39,7 +39,17 @@
   /// \brief an 'unowned(unsafe)' reference
   Unmanaged,
 };
-  
+
+/// Different kinds of value ownership supported by Swift.
+enum class ValueOwnership : uint8_t {
+  /// \brief the default ownership (owned)
+  Default,
+  /// \brief an 'inout' mutating pointer-like value
+  InOut,
+  /// \brief a '__shared' non-mutating pointer-like value
+  Shared
+};
+
 } // end namespace swift
 
 #endif
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index b613ae7..4b5324b 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -1594,17 +1594,16 @@
     return ParameterTypeFlags(OptionSet<ParameterFlags>(raw));
   }
 
-  ParameterTypeFlags(bool variadic, bool autoclosure, bool escaping, bool inOut, bool shared)
-      : value((variadic ? Variadic : 0) |
-              (autoclosure ? AutoClosure : 0) |
+  ParameterTypeFlags(bool variadic, bool autoclosure, bool escaping,
+                     ValueOwnership ownership)
+      : value((variadic ? Variadic : 0) | (autoclosure ? AutoClosure : 0) |
               (escaping ? Escaping : 0) |
-              (inOut ? InOut : 0) |
-              (shared ? Shared : 0)) {}
+              (ownership == ValueOwnership::InOut ? InOut : 0) |
+              (ownership == ValueOwnership::Shared ? Shared : 0)) {}
 
   /// Create one from what's present in the parameter type
-  inline static ParameterTypeFlags fromParameterType(Type paramTy,
-                                                     bool isVariadic,
-                                                     bool isShared);
+  inline static ParameterTypeFlags
+  fromParameterType(Type paramTy, bool isVariadic, ValueOwnership ownership);
 
   bool isNone() const { return !value; }
   bool isVariadic() const { return value.contains(Variadic); }
@@ -1613,6 +1612,15 @@
   bool isInOut() const { return value.contains(InOut); }
   bool isShared() const { return value.contains(Shared); }
 
+  ValueOwnership getValueOwnership() const {
+    if (isInOut())
+      return ValueOwnership::InOut;
+    else if (isShared())
+      return ValueOwnership::Shared;
+
+    return ValueOwnership::Default;
+  }
+
   ParameterTypeFlags withVariadic(bool variadic) const {
     return ParameterTypeFlags(variadic ? value | ParameterTypeFlags::Variadic
                                        : value - ParameterTypeFlags::Variadic);
@@ -4752,15 +4760,18 @@
 private:
   Type Referent;
 public:
-  static ReferenceStorageType *get(Type referent, Ownership ownership,
+  static ReferenceStorageType *get(Type referent, ReferenceOwnership ownership,
                                    const ASTContext &C);
 
   Type getReferentType() const { return Referent; }
-  Ownership getOwnership() const {
+  ReferenceOwnership getOwnership() const {
     switch (getKind()) {
-    case TypeKind::WeakStorage: return Ownership::Weak;
-    case TypeKind::UnownedStorage: return Ownership::Unowned;
-    case TypeKind::UnmanagedStorage: return Ownership::Unmanaged;
+    case TypeKind::WeakStorage:
+      return ReferenceOwnership::Weak;
+    case TypeKind::UnownedStorage:
+      return ReferenceOwnership::Unowned;
+    case TypeKind::UnmanagedStorage:
+      return ReferenceOwnership::Unmanaged;
     default: llvm_unreachable("Unhandled reference storage type");
     }
   }
@@ -4772,10 +4783,10 @@
   }
 };
 BEGIN_CAN_TYPE_WRAPPER(ReferenceStorageType, Type)
-  static CanReferenceStorageType get(CanType referent, Ownership ownership) {
-    return CanReferenceStorageType(ReferenceStorageType::get(referent,
-                                                   ownership,
-                                                   referent->getASTContext()));
+static CanReferenceStorageType get(CanType referent,
+                                   ReferenceOwnership ownership) {
+  return CanReferenceStorageType(ReferenceStorageType::get(
+      referent, ownership, referent->getASTContext()));
   }
   PROXY_CAN_TYPE_SIMPLE_GETTER(getReferentType)
 END_CAN_TYPE_WRAPPER(ReferenceStorageType, Type)
@@ -4789,8 +4800,8 @@
 
 public:
   static UnownedStorageType *get(Type referent, const ASTContext &C) {
-    return static_cast<UnownedStorageType*>(
-                 ReferenceStorageType::get(referent, Ownership::Unowned, C));
+    return static_cast<UnownedStorageType *>(
+        ReferenceStorageType::get(referent, ReferenceOwnership::Unowned, C));
   }
 
   /// Is this unowned storage type known to be loadable within the given
@@ -4820,8 +4831,8 @@
 
 public:
   static UnmanagedStorageType *get(Type referent, const ASTContext &C) {
-    return static_cast<UnmanagedStorageType*>(
-                 ReferenceStorageType::get(referent, Ownership::Unmanaged, C));
+    return static_cast<UnmanagedStorageType *>(
+        ReferenceStorageType::get(referent, ReferenceOwnership::Unmanaged, C));
   }
 
   // Implement isa/cast/dyncast/etc.
@@ -4845,8 +4856,8 @@
 
 public:
   static WeakStorageType *get(Type referent, const ASTContext &C) {
-    return static_cast<WeakStorageType*>(
-                    ReferenceStorageType::get(referent, Ownership::Weak, C));
+    return static_cast<WeakStorageType *>(
+        ReferenceStorageType::get(referent, ReferenceOwnership::Weak, C));
   }
 
   // Implement isa/cast/dyncast/etc.
@@ -5165,7 +5176,8 @@
 
 /// Create one from what's present in the parameter decl and type
 inline ParameterTypeFlags
-ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic, bool isShared) {
+ParameterTypeFlags::fromParameterType(Type paramTy, bool isVariadic,
+                                      ValueOwnership ownership) {
   bool autoclosure = paramTy->is<AnyFunctionType>() &&
                      paramTy->castTo<AnyFunctionType>()->isAutoClosure();
   bool escaping = paramTy->is<AnyFunctionType>() &&
@@ -5174,8 +5186,12 @@
   // decomposition.  Start by enabling the assertion there and fixing up those
   // callers, then remove this, then remove
   // ParameterTypeFlags::fromParameterType entirely.
-  bool inOut = paramTy->is<InOutType>();
-  return {isVariadic, autoclosure, escaping, inOut, isShared};
+  if (paramTy->is<InOutType>()) {
+    assert(ownership == ValueOwnership::Default ||
+           ownership == ValueOwnership::InOut);
+    ownership = ValueOwnership::InOut;
+  }
+  return {isVariadic, autoclosure, escaping, ownership};
 }
 
 inline const Type *BoundGenericType::getTrailingObjectsPointer() const {
diff --git a/include/swift/Basic/FlagSet.h b/include/swift/Basic/FlagSet.h
index e58bf08..8567163 100644
--- a/include/swift/Basic/FlagSet.h
+++ b/include/swift/Basic/FlagSet.h
@@ -60,7 +60,7 @@
     if (value) {
       Bits |= maskFor<Bit>();
     } else {
-      Bits |= ~maskFor<Bit>();
+      Bits &= ~maskFor<Bit>();
     }
   }
 
diff --git a/include/swift/Driver/ToolChain.h b/include/swift/Driver/ToolChain.h
index 7ec9333..c7b62c7 100644
--- a/include/swift/Driver/ToolChain.h
+++ b/include/swift/Driver/ToolChain.h
@@ -199,8 +199,10 @@
   ///
   /// \param args Invocation arguments.
   /// \param sanitizer Sanitizer name.
+  /// \param shared Whether the library is shared
   virtual bool sanitizerRuntimeLibExists(const llvm::opt::ArgList &args,
-                                         StringRef sanitizer) const;
+                                         StringRef sanitizer,
+                                         bool shared=true) const;
 
 };
 } // end namespace driver
diff --git a/include/swift/Frontend/InputFile.h b/include/swift/Frontend/InputFile.h
index 484a08c..caed06f 100644
--- a/include/swift/Frontend/InputFile.h
+++ b/include/swift/Frontend/InputFile.h
@@ -91,6 +91,10 @@
   std::string loadedModuleTracePath() const {
     return getPrimarySpecificPaths().SupplementaryOutputs.LoadedModuleTracePath;
   }
+  std::string serializedDiagnosticsPath() const {
+    return getPrimarySpecificPaths().SupplementaryOutputs
+        .SerializedDiagnosticsPath;
+  }
 };
 } // namespace swift
 
diff --git a/include/swift/Frontend/SerializedDiagnosticConsumer.h b/include/swift/Frontend/SerializedDiagnosticConsumer.h
index 55115b9..ac55515 100644
--- a/include/swift/Frontend/SerializedDiagnosticConsumer.h
+++ b/include/swift/Frontend/SerializedDiagnosticConsumer.h
@@ -29,13 +29,14 @@
   class DiagnosticConsumer;
 
   namespace serialized_diagnostics {
-    /// \brief Create a DiagnosticConsumer that serializes diagnostics to a
-    ///        file.
+    /// Create a DiagnosticConsumer that serializes diagnostics to a file, using
+    /// Clang's serialized diagnostics format.
     ///
-    /// \param serializedDiagnosticsPath the file path to write the diagnostics.
+    /// \param outputPath the file path to write the diagnostics to.
     ///
     /// \returns A new diagnostic consumer that serializes diagnostics.
-    DiagnosticConsumer *createConsumer(llvm::StringRef serializedDiagnosticsPath);
+    std::unique_ptr<DiagnosticConsumer>
+    createConsumer(llvm::StringRef outputPath);
   }
 }
 
diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def
index 682bf2b..e295f3b 100644
--- a/include/swift/IDE/DigesterEnums.def
+++ b/include/swift/IDE/DigesterEnums.def
@@ -91,6 +91,8 @@
 KEY(superclassUsr)
 KEY(parentExtensionReqs)
 KEY(hasDefaultArg)
+KEY(conformingProtocols)
+KEY(enumRawTypeName)
 
 KNOWN_TYPE(Optional)
 KNOWN_TYPE(ImplicitlyUnwrappedOptional)
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index 995581d..858b331 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -756,9 +756,6 @@
   bool isForeignTypeMetadataCandidate() const {
     return getKind() == Kind::ForeignTypeMetadataCandidate;
   }
-  bool isObjCClassRef() const {
-    return getKind() == Kind::ObjCClassRef;
-  }
 
   /// Determine whether this entity will be weak-imported.
   bool isWeakImported(ModuleDecl *module) const {
diff --git a/include/swift/Option/SanitizerOptions.h b/include/swift/Option/SanitizerOptions.h
index aef2f02..8454584 100644
--- a/include/swift/Option/SanitizerOptions.h
+++ b/include/swift/Option/SanitizerOptions.h
@@ -32,11 +32,9 @@
 //         sanitizer dylib with a given name.
 /// \return Returns a SanitizerKind.
 OptionSet<SanitizerKind> parseSanitizerArgValues(
-        const llvm::opt::ArgList &Args,
-        const llvm::opt::Arg *A,
-        const llvm::Triple &Triple,
-        DiagnosticEngine &Diag,
-        llvm::function_ref<bool(llvm::StringRef)> sanitizerRuntimeLibExists);
+    const llvm::opt::ArgList &Args, const llvm::opt::Arg *A,
+    const llvm::Triple &Triple, DiagnosticEngine &Diag,
+    llvm::function_ref<bool(llvm::StringRef, bool)> sanitizerRuntimeLibExists);
 
 /// \brief Parses a -sanitize-coverage= argument's value.
 llvm::SanitizerCoverageOptions parseSanitizerCoverageArgValue(
diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h
index 1cfbe09..71a45e7 100644
--- a/include/swift/Parse/Lexer.h
+++ b/include/swift/Parse/Lexer.h
@@ -461,6 +461,16 @@
   };
 
 private:
+  /// Nul character meaning kind.
+  enum class NulCharacterKind {
+    /// String buffer terminator.
+    BufferEnd,
+    /// Embedded nul character.
+    Embedded,
+    /// Code completion marker.
+    CodeCompletion
+  };
+
   /// For a source location in the current buffer, returns the corresponding
   /// pointer.
   const char *getBufferPtrForSourceLoc(SourceLoc Loc) const {
@@ -520,6 +530,8 @@
   /// Try to lex conflict markers by checking for the presence of the start and
   /// end of the marker in diff3 or Perforce style respectively.
   bool tryLexConflictMarker(bool EatNewline);
+
+  NulCharacterKind getNulCharacterKind(const char *Ptr) const;
 };
   
 /// Given an ordered token \param Array , get the iterator pointing to the first
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index 6e67e55..599aec4 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -1444,7 +1444,8 @@
                    const SourceManager &SM,
                    unsigned BufferID,
                    unsigned Offset = 0,
-                   unsigned EndOffset = 0);
+                   unsigned EndOffset = 0,
+                   DiagnosticEngine *Diags = nullptr);
 } // end namespace swift
 
 #endif
diff --git a/include/swift/Remote/MetadataReader.h b/include/swift/Remote/MetadataReader.h
index 9e365cf..a331b43 100644
--- a/include/swift/Remote/MetadataReader.h
+++ b/include/swift/Remote/MetadataReader.h
@@ -233,7 +233,7 @@
       return StoredPointer();
 
     auto classMeta = cast<TargetClassMetadata<Runtime>>(meta);
-    return classMeta->SuperClass;
+    return classMeta->Superclass;
   }
 
   /// Given a remote pointer to class metadata, attempt to discover its class
@@ -537,32 +537,24 @@
   ///
   /// The offset is in units of words, from the start of the class's
   /// metadata.
-  llvm::Optional<uint32_t>
+  llvm::Optional<int32_t>
   readGenericArgsOffset(MetadataRef metadata,
                         ContextDescriptorRef descriptor) {
     switch (descriptor->getKind()) {
     case ContextDescriptorKind::Class: {
       auto type = cast<TargetClassDescriptor<Runtime>>(descriptor);
 
-      auto *classMetadata = dyn_cast<TargetClassMetadata<Runtime>>(metadata);
-      if (!classMetadata)
+      if (!type->hasResilientSuperclass())
+        return type->getNonResilientGenericArgumentOffset();
+
+      auto bounds = readMetadataBoundsOfSuperclass(descriptor);
+      if (!bounds)
         return llvm::None;
 
-      if (!classMetadata->SuperClass)
-        return type->getGenericArgumentOffset(nullptr, nullptr);
+      bounds->adjustForSubclass(type->areImmediateMembersNegative(),
+                                type->NumImmediateMembers);
 
-      auto superMetadata = readMetadata(classMetadata->SuperClass);
-      if (!superMetadata)
-        return llvm::None;
-
-      auto superClassMetadata =
-        dyn_cast<TargetClassMetadata<Runtime>>(superMetadata);
-      if (!superClassMetadata)
-        return llvm::None;
-
-      auto result =
-        type->getGenericArgumentOffset(classMetadata, superClassMetadata);
-      return result;
+      return bounds->ImmediateMembersOffset / sizeof(StoredPointer);
     }
 
     case ContextDescriptorKind::Enum: {
@@ -580,6 +572,76 @@
     }
   }
 
+  using ClassMetadataBounds = TargetClassMetadataBounds<Runtime>;
+
+  // This follows computeMetadataBoundsForSuperclass.
+  llvm::Optional<ClassMetadataBounds>
+  readMetadataBoundsOfSuperclass(ContextDescriptorRef subclassRef) {
+    auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
+
+    auto rawSuperclass =
+      resolveNullableRelativeField(subclassRef, subclass->Superclass);
+    if (!rawSuperclass) {
+      return ClassMetadataBounds::forSwiftRootClass();
+    }
+
+    return forTypeReference<ClassMetadataBounds>(
+      subclass->getSuperclassReferenceKind(), *rawSuperclass,
+      [&](ContextDescriptorRef superclass)
+            -> llvm::Optional<ClassMetadataBounds> {
+        if (!isa<TargetClassDescriptor<Runtime>>(superclass))
+          return llvm::None;
+        return readMetadataBoundsOfSuperclass(superclass);
+      },
+      [&](MetadataRef metadata) -> llvm::Optional<ClassMetadataBounds> {
+        auto cls = dyn_cast<TargetClassMetadata<Runtime>>(metadata);
+        if (!cls)
+          return llvm::None;
+
+        return cls->getClassBoundsAsSwiftSuperclass();
+      });
+  }
+
+  template <class Result, class DescriptorFn, class MetadataFn>
+  llvm::Optional<Result>
+  forTypeReference(TypeMetadataRecordKind refKind, StoredPointer ref,
+                   const DescriptorFn &descriptorFn,
+                   const MetadataFn &metadataFn) {
+    switch (refKind) {
+    case TypeMetadataRecordKind::IndirectNominalTypeDescriptor: {
+      StoredPointer descriptorAddress = 0;
+      if (!Reader->readInteger(RemoteAddress(ref), &descriptorAddress))
+        return llvm::None;
+
+      ref = descriptorAddress;
+      LLVM_FALLTHROUGH;
+    }
+
+    case TypeMetadataRecordKind::DirectNominalTypeDescriptor: {
+      auto descriptor = readContextDescriptor(ref);
+      if (!descriptor)
+        return llvm::None;
+
+      return descriptorFn(descriptor);
+    }
+
+    case TypeMetadataRecordKind::IndirectObjCClass: {
+      StoredPointer classRef = 0;
+      if (!Reader->readInteger(RemoteAddress(ref), &classRef))
+        return llvm::None;
+
+      auto metadata = readMetadata(classRef);
+      if (!metadata)
+        return llvm::None;
+
+      return metadataFn(metadata);
+    }
+
+    default:
+      return llvm::None;
+    }
+  }
+
   /// Read a single generic type argument from a bound generic type
   /// metadata.
   llvm::Optional<StoredPointer>
@@ -921,7 +983,7 @@
         if (descriptorAddress || !skipArtificialSubclasses)
           return static_cast<StoredPointer>(descriptorAddress);
 
-        auto superclassMetadataAddress = classMeta->SuperClass;
+        auto superclassMetadataAddress = classMeta->Superclass;
         if (!superclassMetadataAddress)
           return 0;
 
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index cb5b1eb..df39028 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -86,6 +86,7 @@
 struct RuntimeTarget<4> {
   using StoredPointer = uint32_t;
   using StoredSize = uint32_t;
+  using StoredPointerDifference = int32_t;
   static constexpr size_t PointerSize = 4;
 };
 
@@ -93,6 +94,7 @@
 struct RuntimeTarget<8> {
   using StoredPointer = uint64_t;
   using StoredSize = uint64_t;
+  using StoredPointerDifference = int64_t;
   static constexpr size_t PointerSize = 8;
 };
 
@@ -104,6 +106,10 @@
   static constexpr size_t PointerSize = sizeof(uintptr_t);
   using StoredPointer = uintptr_t;
   using StoredSize = size_t;
+  using StoredPointerDifference = ptrdiff_t;
+
+  static_assert(sizeof(StoredSize) == sizeof(StoredPointerDifference),
+                "target uses differently-sized size_t and ptrdiff_t");
   
   template <typename T>
   using Pointer = T*;
@@ -134,6 +140,7 @@
 struct External {
   using StoredPointer = typename Runtime::StoredPointer;
   using StoredSize = typename Runtime::StoredSize;
+  using StoredPointerDifference = typename Runtime::StoredPointerDifference;
   static constexpr size_t PointerSize = Runtime::PointerSize;
   const StoredPointer PointerValue;
   
@@ -740,6 +747,7 @@
 }
 
 template <typename Runtime> struct TargetGenericMetadataInstantiationCache;
+template <typename Runtime> struct TargetAnyClassMetadata;
 template <typename Runtime> struct TargetClassMetadata;
 template <typename Runtime> struct TargetStructMetadata;
 template <typename Runtime> struct TargetOpaqueMetadata;
@@ -755,18 +763,50 @@
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Winvalid-offsetof"
 
+/// Bounds for metadata objects.
+template <typename Runtime>
+struct TargetMetadataBounds {
+  using StoredSize = typename Runtime::StoredSize;
+
+  /// The negative extent of the metadata, in words.
+  uint32_t NegativeSizeInWords;
+
+  /// The positive extent of the metadata, in words.
+  uint32_t PositiveSizeInWords;
+
+  /// Return the total size of the metadata in bytes, including both
+  /// negatively- and positively-offset members.
+  StoredSize getTotalSizeInBytes() const {
+    return (StoredSize(NegativeSizeInWords) + StoredSize(PositiveSizeInWords))
+              * sizeof(void*);
+  }
+
+  /// Return the offset of the address point of the metadata from its
+  /// start, in bytes.
+  StoredSize getAddressPointInBytes() const {
+    return StoredSize(NegativeSizeInWords) * sizeof(void*);
+  }
+};
+using MetadataBounds = TargetMetadataBounds<InProcess>;
+
 /// The common structure of all type metadata.
 template <typename Runtime>
 struct TargetMetadata {
   using StoredPointer = typename Runtime::StoredPointer;
 
+  /// The basic header type.
+  typedef TargetTypeMetadataHeader<Runtime> HeaderType;
+
   constexpr TargetMetadata()
     : Kind(static_cast<StoredPointer>(MetadataKind::Class)) {}
   constexpr TargetMetadata(MetadataKind Kind)
     : Kind(static_cast<StoredPointer>(Kind)) {}
-  
-  /// The basic header type.
-  typedef TargetTypeMetadataHeader<Runtime> HeaderType;
+
+#if SWIFT_OBJC_INTEROP
+protected:
+  constexpr TargetMetadata(TargetAnyClassMetadata<Runtime> *isa)
+    : Kind(reinterpret_cast<StoredPointer>(isa)) {}
+#endif
 
 private:
   /// The kind. Only valid for non-class metadata; getKind() must be used to get
@@ -783,6 +823,17 @@
     Kind = static_cast<StoredPointer>(kind);
   }
 
+#if SWIFT_OBJC_INTEROP
+protected:
+  const TargetAnyClassMetadata<Runtime> *getClassISA() const {
+    return reinterpret_cast<const TargetAnyClassMetadata<Runtime> *>(Kind);
+  }
+  void setClassISA(const TargetAnyClassMetadata<Runtime> *isa) {
+    Kind = reinterpret_cast<StoredPointer>(isa);
+  }
+#endif
+
+public:
   /// Is this a class object--the metadata record for a Swift class (which also
   /// serves as the class object), or the class object for an ObjC class (which
   /// is not metadata)?
@@ -956,7 +1007,7 @@
 
     auto asWords = reinterpret_cast<
       ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> const *>(this);
-    return asWords + description->getGenericArgumentOffset(this);
+    return asWords + description->getGenericArgumentOffset();
   }
 
   bool satisfiesClassConstraint() const;
@@ -1008,19 +1059,32 @@
     const FullOpaqueMetadata METADATA_SYM(Symbol);
 #include "swift/Runtime/BuiltinTypes.def"
 
+using HeapObjectDestroyer =
+  SWIFT_CC(swift) void(SWIFT_CONTEXT HeapObject *);
+
 /// The prefix on a heap metadata.
-struct HeapMetadataHeaderPrefix {
+template <typename Runtime>
+struct TargetHeapMetadataHeaderPrefix {
   /// Destroy the object, returning the allocated size of the object
   /// or 0 if the object shouldn't be deallocated.
-  SWIFT_CC(swift) void (*destroy)(SWIFT_CONTEXT HeapObject *);
+  TargetPointer<Runtime, HeapObjectDestroyer> destroy;
 };
+using HeapMetadataHeaderPrefix =
+  TargetHeapMetadataHeaderPrefix<InProcess>;
 
 /// The header present on all heap metadata.
-struct HeapMetadataHeader : HeapMetadataHeaderPrefix, TypeMetadataHeader {
-  constexpr HeapMetadataHeader(const HeapMetadataHeaderPrefix &heapPrefix,
-                               const TypeMetadataHeader &typePrefix)
-    : HeapMetadataHeaderPrefix(heapPrefix), TypeMetadataHeader(typePrefix) {}
+template <typename Runtime>
+struct TargetHeapMetadataHeader
+    : TargetHeapMetadataHeaderPrefix<Runtime>,
+      TargetTypeMetadataHeader<Runtime> {
+  constexpr TargetHeapMetadataHeader(
+      const TargetHeapMetadataHeaderPrefix<Runtime> &heapPrefix,
+      const TargetTypeMetadataHeader<Runtime> &typePrefix)
+    : TargetHeapMetadataHeaderPrefix<Runtime>(heapPrefix),
+      TargetTypeMetadataHeader<Runtime>(typePrefix) {}
 };
+using HeapMetadataHeader =
+  TargetHeapMetadataHeader<InProcess>;
 
 /// The common structure of all metadata for heap-allocated types.  A
 /// pointer to one of these can be retrieved by loading the 'isa'
@@ -1030,11 +1094,15 @@
 /// not be the Swift type metadata for the object's dynamic type.
 template <typename Runtime>
 struct TargetHeapMetadata : TargetMetadata<Runtime> {
-  typedef HeapMetadataHeader HeaderType;
+  using HeaderType = TargetHeapMetadataHeader<Runtime>;
 
   TargetHeapMetadata() = default;
-  constexpr TargetHeapMetadata(const TargetMetadata<Runtime> &base)
-    : TargetMetadata<Runtime>(base) {}
+  constexpr TargetHeapMetadata(MetadataKind kind)
+    : TargetMetadata<Runtime>(kind) {}
+#if SWIFT_OBJC_INTEROP
+  constexpr TargetHeapMetadata(TargetAnyClassMetadata<Runtime> *isa)
+    : TargetMetadata<Runtime>(isa) {}
+#endif
 };
 using HeapMetadata = TargetHeapMetadata<InProcess>;
 
@@ -1075,12 +1143,141 @@
   uint32_t getVTableOffset(const TargetClassMetadata<Runtime> *metadata) const {
     const auto *description = metadata->getDescription();
     if (description->hasResilientSuperclass())
-      return metadata->SuperClass->getSizeInWords() + VTableOffset;
+      return metadata->Superclass->getSizeInWords() + VTableOffset;
     return VTableOffset;
   }
 };
 
-typedef SWIFT_CC(swift) void (*ClassIVarDestroyer)(SWIFT_CONTEXT HeapObject *);
+/// The bounds of a class metadata object.
+///
+/// This type is a currency type and is not part of the ABI.
+/// See TargetStoredClassMetadataBounds for the type of the class
+/// metadata bounds variable.
+template <typename Runtime>
+struct TargetClassMetadataBounds : TargetMetadataBounds<Runtime> {
+  using StoredPointer = typename Runtime::StoredPointer;
+  using StoredSize = typename Runtime::StoredSize;
+  using StoredPointerDifference = typename Runtime::StoredPointerDifference;
+
+  using TargetMetadataBounds<Runtime>::NegativeSizeInWords;
+  using TargetMetadataBounds<Runtime>::PositiveSizeInWords;
+
+  /// The offset from the address point of the metadata to the immediate
+  /// members.
+  StoredPointerDifference ImmediateMembersOffset;
+
+  constexpr TargetClassMetadataBounds() = default;
+  constexpr TargetClassMetadataBounds(
+              StoredPointerDifference immediateMembersOffset,
+              uint32_t negativeSizeInWords, uint32_t positiveSizeInWords)
+    : TargetMetadataBounds<Runtime>{negativeSizeInWords, positiveSizeInWords},
+      ImmediateMembersOffset(immediateMembersOffset) {}
+
+  /// Return the basic bounds of all Swift class metadata.
+  /// The immediate members offset will not be meaningful.
+  static constexpr TargetClassMetadataBounds<Runtime> forSwiftRootClass() {
+    using Metadata = FullMetadata<TargetClassMetadata<Runtime>>;
+    return forAddressPointAndSize(sizeof(typename Metadata::HeaderType),
+                                  sizeof(Metadata));
+  }
+
+  /// Return the bounds of a Swift class metadata with the given address
+  /// point and size (both in bytes).
+  /// The immediate members offset will not be meaningful.
+  static constexpr TargetClassMetadataBounds<Runtime>
+  forAddressPointAndSize(StoredSize addressPoint, StoredSize totalSize) {
+    return {
+      // Immediate offset in bytes.
+      StoredPointerDifference(totalSize - addressPoint),
+      // Negative size in words.
+      uint32_t(addressPoint / sizeof(StoredPointer)),
+      // Positive size in words.
+      uint32_t((totalSize - addressPoint) / sizeof(StoredPointer))
+    };
+  }
+
+  /// Adjust these bounds for a subclass with the given immediate-members
+  /// section.
+  void adjustForSubclass(bool areImmediateMembersNegative,
+                         uint32_t numImmediateMembers) {
+    if (areImmediateMembersNegative) {
+      NegativeSizeInWords += numImmediateMembers;
+      ImmediateMembersOffset =
+        -StoredPointerDifference(NegativeSizeInWords) * sizeof(StoredPointer);
+    } else {
+      ImmediateMembersOffset = PositiveSizeInWords * sizeof(StoredPointer);
+      PositiveSizeInWords += numImmediateMembers;
+    }
+  }
+};
+using ClassMetadataBounds =
+  TargetClassMetadataBounds<InProcess>;
+
+/// The portion of a class metadata object that is compatible with
+/// all classes, even non-Swift ones.
+template <typename Runtime>
+struct TargetAnyClassMetadata : public TargetHeapMetadata<Runtime> {
+  using StoredPointer = typename Runtime::StoredPointer;
+  using StoredSize = typename Runtime::StoredSize;
+
+#if SWIFT_OBJC_INTEROP
+  constexpr TargetAnyClassMetadata(TargetAnyClassMetadata<Runtime> *isa,
+                                   TargetClassMetadata<Runtime> *superclass)
+    : TargetHeapMetadata<Runtime>(isa),
+      Superclass(superclass),
+      CacheData{nullptr, nullptr},
+      Data(SWIFT_CLASS_IS_SWIFT_MASK) {}
+#endif
+
+  constexpr TargetAnyClassMetadata(TargetClassMetadata<Runtime> *superclass)
+    : TargetHeapMetadata<Runtime>(MetadataKind::Class),
+      Superclass(superclass),
+      CacheData{nullptr, nullptr},
+      Data(SWIFT_CLASS_IS_SWIFT_MASK) {}
+
+#if SWIFT_OBJC_INTEROP
+  // Allow setting the metadata kind to a class ISA on class metadata.
+  using TargetMetadata<Runtime>::getClassISA;
+  using TargetMetadata<Runtime>::setClassISA;
+#endif
+
+  // Note that ObjC classes does not have a metadata header.
+
+  /// The metadata for the superclass.  This is null for the root class.
+  ConstTargetMetadataPointer<Runtime, swift::TargetClassMetadata> Superclass;
+
+  // TODO: remove the CacheData and Data fields in non-ObjC-interop builds.
+
+  /// The cache data is used for certain dynamic lookups; it is owned
+  /// by the runtime and generally needs to interoperate with
+  /// Objective-C's use.
+  TargetPointer<Runtime, void> CacheData[2];
+
+  /// The data pointer is used for out-of-line metadata and is
+  /// generally opaque, except that the compiler sets the low bit in
+  /// order to indicate that this is a Swift metatype and therefore
+  /// that the type metadata header is present.
+  StoredSize Data;
+  
+  static constexpr StoredPointer offsetToData() {
+    return offsetof(TargetAnyClassMetadata, Data);
+  }
+
+  /// Is this object a valid swift type metadata?  That is, can it be
+  /// safely downcast to ClassMetadata?
+  bool isTypeMetadata() const {
+    return (Data & SWIFT_CLASS_IS_SWIFT_MASK);
+  }
+  /// A different perspective on the same bit
+  bool isPureObjC() const {
+    return !isTypeMetadata();
+  }
+};
+using AnyClassMetadata =
+  TargetAnyClassMetadata<InProcess>;
+
+using ClassIVarDestroyer =
+  SWIFT_CC(swift) void(SWIFT_CONTEXT HeapObject *);
 
 /// The structure of all class metadata.  This structure is embedded
 /// directly within the class's heap metadata structure and therefore
@@ -1089,69 +1286,28 @@
 /// Note that the layout of this type is compatible with the layout of
 /// an Objective-C class.
 template <typename Runtime>
-struct TargetClassMetadata : public TargetHeapMetadata<Runtime> {
+struct TargetClassMetadata : public TargetAnyClassMetadata<Runtime> {
   using StoredPointer = typename Runtime::StoredPointer;
   using StoredSize = typename Runtime::StoredSize;
+
   friend class ReflectionContext;
+
   TargetClassMetadata() = default;
-  constexpr TargetClassMetadata(const TargetHeapMetadata<Runtime> &base,
-             ConstTargetMetadataPointer<Runtime, swift::TargetClassMetadata> superClass,
-             StoredPointer data,
+  constexpr TargetClassMetadata(const TargetAnyClassMetadata<Runtime> &base,
              ClassFlags flags,
-             StoredPointer ivarDestroyer,
+             ClassIVarDestroyer *ivarDestroyer,
              StoredPointer size, StoredPointer addressPoint,
              StoredPointer alignMask,
              StoredPointer classSize, StoredPointer classAddressPoint)
-    : TargetHeapMetadata<Runtime>(base), SuperClass(superClass),
-      CacheData {0, 0}, Data(data),
+    : TargetAnyClassMetadata<Runtime>(base),
       Flags(flags), InstanceAddressPoint(addressPoint),
       InstanceSize(size), InstanceAlignMask(alignMask),
       Reserved(0), ClassSize(classSize), ClassAddressPoint(classAddressPoint),
       Description(nullptr), IVarDestroyer(ivarDestroyer) {}
 
-  // Description's copy ctor is deleted so we have to do this the hard way.
-  TargetClassMetadata(const TargetClassMetadata &other)
-      : TargetHeapMetadata<Runtime>(other),
-        SuperClass(other.SuperClass),
-        CacheData{other.CacheData[0], other.CacheData[1]},
-        Data(other.Data), Flags(other.Flags),
-        InstanceAddressPoint(other.InstanceAddressPoint),
-        InstanceSize(other.InstanceSize),
-        InstanceAlignMask(other.InstanceAlignMask), Reserved(other.Reserved),
-        ClassSize(other.ClassSize), ClassAddressPoint(other.ClassAddressPoint),
-        Description(other.Description), IVarDestroyer(other.IVarDestroyer) {}
-
-  /// The metadata for the superclass.  This is null for the root class.
-  ConstTargetMetadataPointer<Runtime, swift::TargetClassMetadata> SuperClass;
-
-  /// The cache data is used for certain dynamic lookups; it is owned
-  /// by the runtime and generally needs to interoperate with
-  /// Objective-C's use.
-  StoredPointer CacheData[2];
-
-  /// The data pointer is used for out-of-line metadata and is
-  /// generally opaque, except that the compiler sets the low bit in
-  /// order to indicate that this is a Swift metatype and therefore
-  /// that the type metadata header is present.
-  StoredPointer Data;
-  
-  static constexpr StoredPointer offsetToData() {
-    return offsetof(TargetClassMetadata, Data);
-  }
-
-  /// Is this object a valid swift type metadata?
-  bool isTypeMetadata() const {
-    return (Data & SWIFT_CLASS_IS_SWIFT_MASK);
-  }
-  /// A different perspective on the same bit
-  bool isPureObjC() const {
-    return !isTypeMetadata();
-  }
-
-private:
   // The remaining fields are valid only when isTypeMetadata().
   // The Objective-C runtime knows the offsets to some of these fields.
-  // Be careful when changing them.
+  // Be careful when accessing them.
 
   /// Swift-specific class flags.
   ClassFlags Flags;
@@ -1177,15 +1333,19 @@
   /// The offset of the address point within the class object.
   uint32_t ClassAddressPoint;
 
+  // Description is by far the most likely field for a client to try
+  // to access directly, so we force access to go through accessors.
+private:
   /// An out-of-line Swift-specific description of the type, or null
   /// if this is an artificial subclass.  We currently provide no
   /// supported mechanism for making a non-artificial subclass
   /// dynamically.
   ConstTargetMetadataPointer<Runtime, TargetClassDescriptor> Description;
 
+public:
   /// A function for destroying instance variables, used to clean up
   /// after an early return from a constructor.
-  StoredPointer IVarDestroyer;
+  TargetPointer<Runtime, ClassIVarDestroyer> IVarDestroyer;
 
   // After this come the class members, laid out as follows:
   //   - class members for the superclass (recursively)
@@ -1194,7 +1354,8 @@
   //   - class variables (if we choose to support these)
   //   - "tabulated" virtual methods
 
-public:
+  using TargetAnyClassMetadata<Runtime>::isTypeMetadata;
+
   ConstTargetMetadataPointer<Runtime, TargetClassDescriptor>
   getDescription() const {
     assert(isTypeMetadata());
@@ -1205,12 +1366,6 @@
     Description = description;
   }
 
-  /// Only valid if the target is in-process.
-  ClassIVarDestroyer getIVarDestroyer() const {
-    assert(isTypeMetadata());
-    return reinterpret_cast<ClassIVarDestroyer>(IVarDestroyer);
-  }
-
   /// Is this class an artificial subclass, such as one dynamically
   /// created for various dynamic purposes like KVO?
   bool isArtificialSubclass() const {
@@ -1302,6 +1457,33 @@
     return size / sizeof(StoredPointer);
   }
 
+  /// Given that this class is serving as the superclass of a Swift class,
+  /// return its bounds as metadata.
+  ///
+  /// Note that the ImmediateMembersOffset member will not be meaningful.
+  TargetClassMetadataBounds<Runtime>
+  getClassBoundsAsSwiftSuperclass() const {
+    using Bounds = TargetClassMetadataBounds<Runtime>;
+
+    auto rootBounds = Bounds::forSwiftRootClass();
+
+    // If the class is not type metadata, just use the root-class bounds.
+    if (!isTypeMetadata())
+      return rootBounds;
+
+    // Otherwise, pull out the bounds from the metadata.
+    auto bounds = Bounds::forAddressPointAndSize(getClassAddressPoint(),
+                                                 getClassSize());
+
+    // Round the bounds up to the required dimensions.
+    if (bounds.NegativeSizeInWords < rootBounds.NegativeSizeInWords)
+      bounds.NegativeSizeInWords = rootBounds.NegativeSizeInWords;
+    if (bounds.PositiveSizeInWords < rootBounds.PositiveSizeInWords)
+      bounds.PositiveSizeInWords = rootBounds.PositiveSizeInWords;
+
+    return bounds;
+  }
+
   static bool classof(const TargetMetadata<Runtime> *metadata) {
     return metadata->getKind() == MetadataKind::Class;
   }
@@ -1437,7 +1619,7 @@
     mutable std::atomic<CacheValue> Cache;
   };
 
-  struct HeaderType : HeaderPrefix, TypeMetadataHeader {};
+  struct HeaderType : HeaderPrefix, TargetTypeMetadataHeader<Runtime> {};
 
   TargetPointer<Runtime, const char> getName() const {
     return reinterpret_cast<TargetPointer<Runtime, const char>>(
@@ -1514,7 +1696,7 @@
 
   /// The superclass of the foreign class, if any.
   ConstTargetMetadataPointer<Runtime, swift::TargetForeignClassMetadata>
-    SuperClass;
+    Superclass;
 
   /// Reserved space.  For now, these should be zero-initialized.
   StoredPointer Reserved[3];
@@ -1555,11 +1737,14 @@
 struct TargetStructMetadata : public TargetValueMetadata<Runtime> {
   using StoredPointer = typename Runtime::StoredPointer;
   using TargetValueMetadata<Runtime>::TargetValueMetadata;
-  
+
   const TargetStructDescriptor<Runtime> *getDescription() const {
     return llvm::cast<TargetStructDescriptor<Runtime>>(this->Description);
   }
 
+  // The first trailing field of struct metadata is always the generic
+  // argument array.
+
   /// Get a pointer to the field offset vector, if present, or null.
   const StoredPointer *getFieldOffsets() const {
     auto offset = getDescription()->FieldOffsetVectorOffset;
@@ -1569,6 +1754,10 @@
     return reinterpret_cast<const StoredPointer *>(asWords + offset);
   }
 
+  static constexpr int32_t getGenericArgumentOffset() {
+    return sizeof(TargetStructMetadata<Runtime>) / sizeof(void*);
+  }
+
   static bool classof(const TargetMetadata<Runtime> *metadata) {
     return metadata->getKind() == MetadataKind::Struct;
   }
@@ -1586,6 +1775,9 @@
     return llvm::cast<TargetEnumDescriptor<Runtime>>(this->Description);
   }
 
+  // The first trailing field of enum metadata is always the generic
+  // argument array.
+
   /// True if the metadata records the size of the payload area.
   bool hasPayloadSize() const {
     return getDescription()->hasPayloadSizeOffset();
@@ -1610,6 +1802,10 @@
     return *asWords;
   }
 
+  static constexpr int32_t getGenericArgumentOffset() {
+    return sizeof(TargetEnumMetadata<Runtime>) / sizeof(void*);
+  }
+
   static bool classof(const TargetMetadata<Runtime> *metadata) {
     return metadata->getKind() == MetadataKind::Enum
       || metadata->getKind() == MetadataKind::Optional;
@@ -2056,6 +2252,62 @@
 using GenericMetadataInstantiationCache =
   TargetGenericMetadataInstantiationCache<InProcess>;
 
+/// The pattern for class metadata.
+template <typename Runtime>
+struct TargetGenericClassMetadataPattern {
+  using StoredPointer = typename Runtime::StoredPointer;
+
+  /// The heap-destructor function.
+  TargetPointer<Runtime, HeapObjectDestroyer> Destroy;
+
+  /// The ivar-destructor function.
+  TargetPointer<Runtime, ClassIVarDestroyer> IVarDestroyer;
+
+  /// The class flags.
+  ClassFlags Flags;
+
+  /// The size of the immedate-members pattern, in words.
+  ///
+  /// This pattern will be copied into the immediate-members section of
+  /// the allocated class metadata.  The pattern data is at the start of
+  /// the pattern buffer.
+  ///
+  /// The rest of the immediate-members section will be zeroed.
+  uint16_t ImmediateMembersPattern_Size;
+
+  /// The offset into the immediate-members section of the metadata, in
+  /// words, into which to copy the immediate-members pattern.
+  uint16_t ImmediateMembersPattern_TargetOffset;
+
+  /// The total amount of extra space to allocate in the metadata, in words.
+  /// This space will always be allocated after the metadata.
+  uint16_t NumExtraDataWords;
+
+  // TODO: only in ObjC interop
+
+  /// The offset of the class RO-data within the extra data pattern,
+  /// in words.
+  uint16_t ClassRODataOffset;
+
+  /// The offset of the metaclass object within the extra data pattern,
+  /// in words.
+  uint16_t MetaclassObjectOffset;
+
+  /// The offset of the metaclass RO-data within the extra data pattern,
+  /// in words.
+  uint16_t MetaclassRODataOffset;
+
+  const StoredPointer *getImmediateMembersPattern() const {
+    return reinterpret_cast<const StoredPointer *>(this + 1);
+  }
+
+  const StoredPointer *getExtraDataPattern() const {
+    return getImmediateMembersPattern() + ImmediateMembersPattern_Size;
+  }
+};
+using GenericClassMetadataPattern =
+  TargetGenericClassMetadataPattern<InProcess>;
+
 /// Heap metadata for a box, which may have been generated statically by the
 /// compiler or by the runtime.
 template <typename Runtime>
@@ -2468,17 +2720,20 @@
 
 using ModuleContextDescriptor = TargetModuleContextDescriptor<InProcess>;
 
-struct GenericContextDescriptorHeader {
-  unsigned NumParams, NumRequirements, NumKeyArguments, NumExtraArguments;
+template<typename Runtime>
+struct TargetGenericContextDescriptorHeader {
+  uint32_t NumParams, NumRequirements, NumKeyArguments, NumExtraArguments;
   
-  unsigned getNumArguments() const {
+  uint32_t getNumArguments() const {
     return NumKeyArguments + NumExtraArguments;
   }
-  
+
   bool hasArguments() const {
     return getNumArguments() > 0;
   }
 };
+using GenericContextDescriptorHeader =
+  TargetGenericContextDescriptorHeader<InProcess>;
 
 /// A reference to a generic parameter that is the subject of a requirement.
 /// This can refer either directly to a generic parameter or to a path to an
@@ -2699,32 +2954,36 @@
 
 /// CRTP class for a context descriptor that includes trailing generic
 /// context description.
-template<typename Self,
-         typename HeaderType = GenericContextDescriptorHeader,
-         typename...FollowingTrailingObjects>
+template<class Self,
+         template <typename> class TargetGenericContextHeaderType =
+           TargetGenericContextDescriptorHeader,
+         typename... FollowingTrailingObjects>
 class TrailingGenericContextObjects;
 
-template<template<typename> class TargetSelf,
-         typename Runtime,
-         typename HeaderType,
-         typename...FollowingTrailingObjects>
-class TrailingGenericContextObjects<
-  TargetSelf<Runtime>,
-  HeaderType,
-  FollowingTrailingObjects...
-> : protected swift::ABI::TrailingObjects<TargetSelf<Runtime>,
-      HeaderType,
+// This oddity with partial specialization is necessary to get
+// reasonable-looking code while also working around various kinds of
+// compiler bad behavior with injected class names.
+template<class Runtime,
+         template <typename> class TargetSelf,
+         template <typename> class TargetGenericContextHeaderType,
+         typename... FollowingTrailingObjects>
+class TrailingGenericContextObjects<TargetSelf<Runtime>,
+                                    TargetGenericContextHeaderType,
+                                    FollowingTrailingObjects...> :
+  protected swift::ABI::TrailingObjects<TargetSelf<Runtime>,
+      TargetGenericContextHeaderType<Runtime>,
       GenericParamDescriptor,
       TargetGenericRequirementDescriptor<Runtime>,
       FollowingTrailingObjects...>
 {
 protected:
   using Self = TargetSelf<Runtime>;
+  using GenericContextHeaderType = TargetGenericContextHeaderType<Runtime>;
   using GenericRequirementDescriptor =
     TargetGenericRequirementDescriptor<Runtime>;
 
   using TrailingObjects = swift::ABI::TrailingObjects<Self,
-    HeaderType,
+    GenericContextHeaderType,
     GenericParamDescriptor,
     GenericRequirementDescriptor,
     FollowingTrailingObjects...>;
@@ -2737,12 +2996,16 @@
     return static_cast<const Self *>(this);
   }
 public:
-  const HeaderType &getFullGenericContextHeader() const {
+  using StoredSize = typename Runtime::StoredSize;
+  using StoredPointer = typename Runtime::StoredPointer;
+
+  const GenericContextHeaderType &getFullGenericContextHeader() const {
     assert(asSelf()->isGeneric());
-    return *this->template getTrailingObjects<HeaderType>();
+    return *this->template getTrailingObjects<GenericContextHeaderType>();
   }
 
-  const GenericContextDescriptorHeader &getGenericContextHeader() const {
+  const TargetGenericContextDescriptorHeader<Runtime> &
+  getGenericContextHeader() const {
     /// HeaderType ought to be convertible to GenericContextDescriptorHeader.
     return getFullGenericContextHeader();
   }
@@ -2772,8 +3035,15 @@
             getGenericContextHeader().NumRequirements};
   }
 
+  /// Return the amount of space that the generic arguments take up in
+  /// metadata of this type.
+  StoredSize getGenericArgumentsStorageSize() const {
+    return StoredSize(getGenericContextHeader().getNumArguments())
+             * sizeof(StoredPointer);
+  }
+
 protected:
-  size_t numTrailingObjects(OverloadToken<HeaderType>) const {
+  size_t numTrailingObjects(OverloadToken<GenericContextHeaderType>) const {
     return asSelf()->isGeneric() ? 1 : 0;
   }
   
@@ -2789,7 +3059,8 @@
 /// Reference to a generic context.
 template<typename Runtime>
 struct TargetGenericContext final
-  : TrailingGenericContextObjects<TargetGenericContext<Runtime>>
+  : TrailingGenericContextObjects<TargetGenericContext<Runtime>,
+                                  TargetGenericContextDescriptorHeader>
 {
   // This struct is supposed to be empty, but TrailingObjects respects the
   // unique-address-per-object C++ rule, so even if this type is empty, the
@@ -2808,7 +3079,7 @@
 {
 private:
   using TrailingGenericContextObjects
-    = TrailingGenericContextObjects<TargetExtensionContextDescriptor>;
+    = TrailingGenericContextObjects<TargetExtensionContextDescriptor<Runtime>>;
 
   /// A mangling of the `Self` type context that the extension extends.
   /// The mangled name represents the type in the generic context encoded by
@@ -2853,13 +3124,6 @@
 
 template <typename Runtime>
 struct TargetTypeGenericContextDescriptorHeader {
-  /// Indicates the offset of the instantiation arguments for a type's generic
-  /// contexts in instances of its type metadata. For a value type or class
-  /// without resilient superclasses, this the the offset from the address
-  /// point of the metadata. For a class with a resilient superclass, this
-  /// offset is relative to the end of the superclass metadata.
-  uint32_t ArgumentOffset;
-
   using InstantiationFunction_t =
     TargetMetadata<Runtime> *(const TargetTypeContextDescriptor<Runtime> *type,
                               const void *arguments);
@@ -2878,9 +3142,9 @@
   }
 
   /// The base header.  Must always be the final member.
-  GenericContextDescriptorHeader Base;
+  TargetGenericContextDescriptorHeader<Runtime> Base;
   
-  operator const GenericContextDescriptorHeader &() const {
+  operator const TargetGenericContextDescriptorHeader<Runtime> &() const {
     return Base;
   }
 };
@@ -3011,20 +3275,20 @@
   const TargetTypeGenericContextDescriptorHeader<Runtime> &
     getFullGenericContextHeader() const;
 
-  const GenericContextDescriptorHeader &getGenericContextHeader() const {
+  const TargetGenericContextDescriptorHeader<Runtime> &
+  getGenericContextHeader() const {
     return getFullGenericContextHeader();
   }
 
   /// Return the offset of the start of generic arguments in the nominal
   /// type's metadata. The returned value is measured in sizeof(void*).
-  uint32_t getGenericArgumentOffset(
-                               const TargetMetadata<Runtime> *metadata) const;
+  int32_t getGenericArgumentOffset() const;
 
   /// Return the start of the generic arguments array in the nominal
   /// type's metadata. The returned value is measured in sizeof(void*).
   const TargetMetadata<Runtime> * const *getGenericArguments(
                                const TargetMetadata<Runtime> *metadata) const {
-    auto offset = getGenericArgumentOffset(metadata);
+    auto offset = getGenericArgumentOffset();
     auto words =
       reinterpret_cast<const TargetMetadata<Runtime> * const *>(metadata);
     return words + offset;
@@ -3038,18 +3302,103 @@
 
 using TypeContextDescriptor = TargetTypeContextDescriptor<InProcess>;
 
+/// Storage for class metadata bounds.  This is the variable returned
+/// by getAddrOfClassMetadataBounds in the compiler.
+///
+/// This storage is initialized before the allocation of any metadata
+/// for the class to which it belongs.  In classes without resilient
+/// superclasses, it is initialized statically with values derived
+/// during compilation.  In classes with resilient superclasses, it
+/// is initialized dynamically, generally during the allocation of
+/// the first metadata of this class's type.  If metadata for this
+/// class is available to you to use, you must have somehow synchronized
+/// with the thread which allocated the metadata, and therefore the
+/// complete initialization of this variable is also ordered before
+/// your access.  That is why you can safely access this variable,
+/// and moreover access it without further atomic accesses.  However,
+/// since this variable may be accessed in a way that is not dependency-
+/// ordered on the metadata pointer, it is important that you do a full
+/// synchronization and not just a dependency-ordered (consume)
+/// synchronization when sharing class metadata pointers between
+/// threads.  (There are other reasons why this is true; for example,
+/// field offset variables are also accessed without dependency-ordering.)
+///
+/// If you are accessing this storage without such a guarantee, you
+/// should be aware that it may be lazily initialized, and moreover
+/// it may be getting lazily initialized from another thread.  To ensure
+/// correctness, the fields must be read in the correct order: the
+/// immediate-members offset is initialized last with a store-release,
+/// so it must be read first with a load-acquire, and if the result
+/// is non-zero then the rest of the variable is known to be valid.
+/// (No locking is required because racing initializations should always
+/// assign the same values to the storage.)
+template <typename Runtime>
+struct TargetStoredClassMetadataBounds {
+  using StoredPointerDifference =
+    typename Runtime::StoredPointerDifference;
+
+  /// The offset to the immediate members.  This value is in bytes so that
+  /// clients don't have to sign-extend it.
+
+
+  /// It is not necessary to use atomic-ordered loads when accessing this
+  /// variable just to read the immediate-members offset when drilling to
+  /// the immediate members of an already-allocated metadata object.
+  /// The proper initialization of this variable is always ordered before
+  /// any allocation of metadata for this class.
+  std::atomic<StoredPointerDifference> ImmediateMembersOffset;
+
+  /// The positive and negative bounds of the class metadata.
+  TargetMetadataBounds<Runtime> Bounds;
+
+  /// Attempt to read the cached immediate-members offset.
+  ///
+  /// \return true if the read was successful, or false if the cache hasn't
+  ///   been filled yet
+  bool tryGetImmediateMembersOffset(StoredPointerDifference &output) {
+    output = ImmediateMembersOffset.load(std::memory_order_relaxed);
+    return output != 0;
+  }
+
+  /// Attempt to read the full cached bounds.
+  ///
+  /// \return true if the read was successful, or false if the cache hasn't
+  ///   been filled yet
+  bool tryGet(TargetClassMetadataBounds<Runtime> &output) {
+    auto offset = ImmediateMembersOffset.load(std::memory_order_acquire);
+    if (offset == 0) return false;
+
+    output.ImmediateMembersOffset = offset;
+    output.NegativeSizeInWords = Bounds.NegativeSizeInWords;
+    output.PositiveSizeInWords = Bounds.PositiveSizeInWords;
+    return true;
+  }
+
+  void initialize(TargetClassMetadataBounds<Runtime> value) {
+    assert(value.ImmediateMembersOffset != 0 &&
+           "attempting to initialize metadata bounds cache to a zero state!");
+
+    Bounds.NegativeSizeInWords = value.NegativeSizeInWords;
+    Bounds.PositiveSizeInWords = value.PositiveSizeInWords;
+    ImmediateMembersOffset.store(value.ImmediateMembersOffset,
+                                 std::memory_order_release);
+  }
+};
+using StoredClassMetadataBounds =
+  TargetStoredClassMetadataBounds<InProcess>;
+
 template <typename Runtime>
 class TargetClassDescriptor final
     : public TargetTypeContextDescriptor<Runtime>,
       public TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
-                              TargetTypeGenericContextDescriptorHeader<Runtime>,
+                              TargetTypeGenericContextDescriptorHeader,
                               /*additional trailing objects:*/
                               TargetVTableDescriptorHeader<Runtime>,
                               TargetMethodDescriptor<Runtime>> {
 private:
   using TrailingGenericContextObjects =
     TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
-                            TargetTypeGenericContextDescriptorHeader<Runtime>,
+                                  TargetTypeGenericContextDescriptorHeader,
                                   TargetVTableDescriptorHeader<Runtime>,
                                   TargetMethodDescriptor<Runtime>>;
 
@@ -3061,9 +3410,14 @@
   using MethodDescriptor = TargetMethodDescriptor<Runtime>;
   using VTableDescriptorHeader = TargetVTableDescriptorHeader<Runtime>;
 
+  using StoredPointer = typename Runtime::StoredPointer;
+  using StoredPointerDifference = typename Runtime::StoredPointerDifference;
+  using StoredSize = typename Runtime::StoredSize;
+
   using TrailingGenericContextObjects::getGenericContext;
   using TrailingGenericContextObjects::getGenericContextHeader;
   using TrailingGenericContextObjects::getFullGenericContextHeader;
+  using TargetTypeContextDescriptor<Runtime>::getTypeContextDescriptorFlags;
 
   /// The superclass of this class.  This pointer can be interpreted
   /// using the superclass reference kind stored in the type context
@@ -3071,7 +3425,55 @@
   ///
   /// Note that SwiftObject, the implicit superclass of all Swift root
   /// classes when building with ObjC compatibility, does not appear here.
-  TargetRelativeDirectPointer<Runtime, const void, /*nullable*/true> SuperClass;
+  TargetRelativeDirectPointer<Runtime, const void, /*nullable*/true> Superclass;
+
+  /// Does this class have a formal superclass?
+  bool hasSuperclass() const {
+    return !Superclass.isNull();
+  }
+
+  TypeMetadataRecordKind getSuperclassReferenceKind() const {
+    return getTypeContextDescriptorFlags().class_getSuperclassReferenceKind();
+  }
+
+  union {
+    /// If this descriptor does not have a resilient superclass, this is the
+    /// negative size of metadata objects of this class (in words).
+    uint32_t MetadataNegativeSizeInWords;
+
+    /// If this descriptor has a resilient superclass, this is a reference
+    /// to a cache holding the metadata's extents.
+    TargetRelativeDirectPointer<Runtime,
+                                TargetStoredClassMetadataBounds<Runtime>>
+      ResilientMetadataBounds;
+  };
+
+  union {
+    /// If this descriptor does not have a resilient superclass, this is the
+    /// positive size of metadata objects of this class (in words).
+    uint32_t MetadataPositiveSizeInWords;
+
+    // Maybe add something here that's useful only for resilient types?
+  };
+
+  /// The number of additional members added by this class to the class
+  /// metadata.  This data is opaque by default to the runtime, other than
+  /// as exposed in other members; it's really just
+  /// NumImmediateMembers * sizeof(void*) bytes of data.
+  ///
+  /// Whether those bytes are added before or after the address point
+  /// depends on areImmediateMembersNegative().
+  uint32_t NumImmediateMembers; // ABI: could be uint16_t?
+
+  StoredSize getImmediateMembersSize() const {
+    return StoredSize(NumImmediateMembers) * sizeof(StoredPointer);
+  }
+
+  /// Are the immediate members of the class metadata allocated at negative
+  /// offsets instead of positive?
+  bool areImmediateMembersNegative() const {
+    return getTypeContextDescriptorFlags().class_areImmediateMembersNegative();
+  }
 
   /// The number of stored properties in the class, not including its
   /// superclasses. If there is a field offset vector, this is its length.
@@ -3113,7 +3515,7 @@
     const auto *description = metadata->getDescription();
 
     if (description->hasResilientSuperclass())
-      return metadata->SuperClass->getSizeInWords() + FieldOffsetVectorOffset;
+      return metadata->Superclass->getSizeInWords() + FieldOffsetVectorOffset;
 
     return FieldOffsetVectorOffset;
   }
@@ -3139,29 +3541,49 @@
             numTrailingObjects(OverloadToken<MethodDescriptor>{})};
   }
 
-  /// This is factored in a silly way because remote mirrors cannot directly
-  /// dereference the SuperClass field of class metadata.
-  uint32_t getGenericArgumentOffset(
-                      const TargetClassMetadata<Runtime> *classMetadata,
-                      const TargetClassMetadata<Runtime> *superMetadata) const {
-    auto Offset = getFullGenericContextHeader().ArgumentOffset;
-    if (hasResilientSuperclass())
-      return superMetadata->getSizeInWords() + Offset;
+  /// Return the bounds of this class's metadata.
+  TargetClassMetadataBounds<Runtime> getMetadataBounds() const {
+    if (!hasResilientSuperclass())
+      return getNonResilientMetadataBounds();
 
-    return Offset;
+    // This lookup works by ADL and will intentionally fail for
+    // non-InProcess instantiations.
+    return getResilientMetadataBounds(this);
+  }
+
+  /// Given that this class is known to not have a resilient superclass
+  /// return its metadata bounds.
+  TargetClassMetadataBounds<Runtime> getNonResilientMetadataBounds() const {
+    return { getNonResilientImmediateMembersOffset()
+               * StoredPointerDifference(sizeof(void*)),
+             MetadataNegativeSizeInWords,
+             MetadataPositiveSizeInWords };
   }
 
   /// Return the offset of the start of generic arguments in the nominal
-  /// type's metadata. The returned value is measured in sizeof(void*).
-  uint32_t
-  getGenericArgumentOffset(const TargetMetadata<Runtime> *metadata) const {
-    if (hasResilientSuperclass()) {
-      auto *classMetadata = llvm::cast<ClassMetadata>(metadata);
-      auto *superMetadata = llvm::cast<ClassMetadata>(classMetadata->SuperClass);
-      return getGenericArgumentOffset(classMetadata, superMetadata);
-    }
+  /// type's metadata. The returned value is measured in words.
+  int32_t getGenericArgumentOffset() const {
+    if (!hasResilientSuperclass())
+      return getNonResilientGenericArgumentOffset();
 
-    return getFullGenericContextHeader().ArgumentOffset;
+    // This lookup works by ADL and will intentionally fail for
+    // non-InProcess instantiations.
+    return getResilientImmediateMembersOffset(this);
+  }
+
+  /// Given that this class is known to not have a resilient superclass,
+  /// return the offset of its generic arguments in words.
+  int32_t getNonResilientGenericArgumentOffset() const {
+    return getNonResilientImmediateMembersOffset();
+  }
+
+  /// Given that this class is known to not have a resilient superclass,
+  /// return the offset of its immediate members in words.
+  int32_t getNonResilientImmediateMembersOffset() const {
+    assert(!hasResilientSuperclass());
+    return areImmediateMembersNegative()
+             ? -int32_t(MetadataNegativeSizeInWords)
+             : int32_t(MetadataPositiveSizeInWords - NumImmediateMembers);
   }
 
   void *getMethod(unsigned i) const {
@@ -3177,6 +3599,11 @@
 
 using ClassDescriptor = TargetClassDescriptor<InProcess>;
 
+/// Compute the bounds of class metadata with a resilient superclass.
+ClassMetadataBounds getResilientMetadataBounds(
+                                           const ClassDescriptor *descriptor);
+int32_t getResilientImmediateMembersOffset(const ClassDescriptor *descriptor);
+
 template <typename Runtime>
 class TargetValueTypeDescriptor
     : public TargetTypeContextDescriptor<Runtime> {
@@ -3192,11 +3619,11 @@
 class TargetStructDescriptor final
     : public TargetValueTypeDescriptor<Runtime>,
       public TrailingGenericContextObjects<TargetStructDescriptor<Runtime>,
-                            TargetTypeGenericContextDescriptorHeader<Runtime>> {
+                            TargetTypeGenericContextDescriptorHeader> {
 private:
   using TrailingGenericContextObjects =
     TrailingGenericContextObjects<TargetStructDescriptor<Runtime>,
-                             TargetTypeGenericContextDescriptorHeader<Runtime>>;
+                                  TargetTypeGenericContextDescriptorHeader>;
 
   using TrailingObjects =
     typename TrailingGenericContextObjects::TrailingObjects;
@@ -3219,8 +3646,8 @@
   /// its stored properties.
   bool hasFieldOffsetVector() const { return FieldOffsetVectorOffset != 0; }
 
-  uint32_t getGenericArgumentOffset() const {
-    return getFullGenericContextHeader().ArgumentOffset;
+  static constexpr int32_t getGenericArgumentOffset() {
+    return TargetStructMetadata<Runtime>::getGenericArgumentOffset();
   }
 
   static bool classof(const TargetContextDescriptor<Runtime> *cd) {
@@ -3234,11 +3661,11 @@
 class TargetEnumDescriptor final
     : public TargetValueTypeDescriptor<Runtime>,
       public TrailingGenericContextObjects<TargetEnumDescriptor<Runtime>,
-                            TargetTypeGenericContextDescriptorHeader<Runtime>> {
+                                     TargetTypeGenericContextDescriptorHeader> {
 private:
   using TrailingGenericContextObjects =
     TrailingGenericContextObjects<TargetEnumDescriptor<Runtime>,
-                             TargetTypeGenericContextDescriptorHeader<Runtime>>;
+                                  TargetTypeGenericContextDescriptorHeader>;
 
   using TrailingObjects =
     typename TrailingGenericContextObjects::TrailingObjects;
@@ -3275,8 +3702,8 @@
     return getPayloadSizeOffset() != 0;
   }
 
-  uint32_t getGenericArgumentOffset() const {
-    return getFullGenericContextHeader().ArgumentOffset;
+  static constexpr int32_t getGenericArgumentOffset() {
+    return TargetEnumMetadata<Runtime>::getGenericArgumentOffset();
   }
 
   static bool classof(const TargetContextDescriptor<Runtime> *cd) {
@@ -3318,12 +3745,11 @@
 }
 
 template <typename Runtime>
-uint32_t TargetTypeContextDescriptor<Runtime>::getGenericArgumentOffset(
-                                const TargetMetadata<Runtime> *metadata) const {
+int32_t TargetTypeContextDescriptor<Runtime>::getGenericArgumentOffset() const {
   switch (this->getKind()) {
   case ContextDescriptorKind::Class:
     return llvm::cast<TargetClassDescriptor<Runtime>>(this)
-        ->getGenericArgumentOffset(metadata);
+        ->getGenericArgumentOffset();
   case ContextDescriptorKind::Enum:
     return llvm::cast<TargetEnumDescriptor<Runtime>>(this)
         ->getGenericArgumentOffset();
@@ -3376,16 +3802,32 @@
 swift_getGenericMetadata(const TypeContextDescriptor *description,
                          const void *arguments);
 
-// Callback to allocate a generic class metadata object.
+/// Allocate a generic class metadata object.  This is intended to be
+/// called by the metadata instantiation function of a generic class.
+///
+/// This function:
+///   - computes the required size of the metadata object based on the
+///     class hierarchy;
+///   - allocates memory for the metadata object based on the computed
+///     size and the additional requirements imposed by the pattern;
+///   - copies information from the pattern into the allocated metadata; and
+///   - fully initializes the ClassMetadata header, except that the
+///     superclass pointer will be null (or SwiftObject under ObjC interop
+///     if there is no formal superclass).
+///
+/// The instantiation function is responsible for completing the
+/// initialization, including:
+///   - setting the superclass pointer;
+///   - copying class data from the superclass;
+///   - installing the generic arguments;
+///   - installing new v-table entries and overrides; and
+///   - registering the class with the runtime under ObjC interop.
+/// Most of this work can be achieved by calling swift_initClassMetadata.
 SWIFT_RUNTIME_EXPORT
 ClassMetadata *
 swift_allocateGenericClassMetadata(const ClassDescriptor *description,
-                                   const void *metadataTemplate,
-                                   size_t metadataTemplateSize,
-                                   size_t metadataTemplateAddressPoint,
                                    const void *arguments,
-                                   ClassMetadata *superclass,
-                                   size_t numImmediateMembers);
+                                   const GenericClassMetadataPattern *pattern);
 
 // Callback to allocate a generic struct/enum metadata object.
 SWIFT_RUNTIME_EXPORT
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index b4f8b509..ad3b74f 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -799,16 +799,11 @@
          ATTRS(NoUnwind, ReadOnly))
 
 // Metadata *swift_allocateGenericClassMetadata(ClassDescriptor *type,
-//                                              const void *template,
-//                                              size_t templateSize,
-//                                              size_t templateAddressPoint,
 //                                              const void * const *arguments,
-//                                              objc_class *superclass,
-//                                              size_t numImmediateMembers);
+//                                              const void *template);
 FUNCTION(AllocateGenericClassMetadata, swift_allocateGenericClassMetadata,
          C_CC, RETURNS(TypeMetadataPtrTy),
-         ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, SizeTy, SizeTy,
-              Int8PtrPtrTy, ObjCClassPtrTy, SizeTy),
+         ARGS(TypeContextDescriptorPtrTy, Int8PtrPtrTy, Int8PtrPtrTy),
          ATTRS(NoUnwind))
 
 // Metadata *swift_allocateGenericValueMetadata(ValueTypeDescriptor *type,
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index f4a8021..63c1b41 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -55,7 +55,7 @@
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
 /// Don't worry about adhering to the 80-column limit for this line.
-const uint16_t VERSION_MINOR = 400; // Last change: sil_property
+const uint16_t VERSION_MINOR = 401; // Last change: ValueOwnership
 
 using DeclIDField = BCFixed<31>;
 
@@ -311,13 +311,22 @@
 
 // These IDs must \em not be renumbered or reordered without incrementing
 // VERSION_MAJOR.
-enum Ownership : uint8_t {
+enum ReferenceOwnership : uint8_t {
   Strong = 0,
   Weak,
   Unowned,
   Unmanaged,
 };
-using OwnershipField = BCFixed<2>;
+using ReferenceOwnershipField = BCFixed<2>;
+
+// These IDs must \em not be renumbered or reordered without incrementing
+// VERSION_MAJOR.
+enum ValueOwnership : uint8_t {
+  Default = 0,
+  InOut,
+  Shared,
+};
+using ValueOwnershipField = BCFixed<2>;
 
 // These IDs must \em not be renumbered or reordered without incrementing
 // VERSION_MAJOR.
@@ -656,8 +665,7 @@
     BCFixed<1>,         // vararg?
     BCFixed<1>,         // autoclosure?
     BCFixed<1>,         // escaping?
-    BCFixed<1>,         // inout?
-    BCFixed<1>          // shared?
+    ValueOwnershipField // inout, shared or owned?
   >;
 
   using TupleTypeLayout = BCRecordLayout<
@@ -671,8 +679,7 @@
     BCFixed<1>,         // vararg?
     BCFixed<1>,         // autoclosure?
     BCFixed<1>,         // escaping?
-    BCFixed<1>,         // inout?
-    BCFixed<1>          // shared?
+    ValueOwnershipField // inout, shared or owned?
   >;
 
   using FunctionTypeLayout = BCRecordLayout<
@@ -800,8 +807,8 @@
 
   using ReferenceStorageTypeLayout = BCRecordLayout<
     REFERENCE_STORAGE_TYPE,
-    OwnershipField,  // ownership
-    TypeIDField      // implementation type
+    ReferenceOwnershipField, // ownership
+    TypeIDField              // implementation type
   >;
 
   using UnboundGenericTypeLayout = BCRecordLayout<
@@ -1410,7 +1417,8 @@
   >;
 
   // Stub layouts, unused.
-  using OwnershipDeclAttrLayout = BCRecordLayout<Ownership_DECL_ATTR>;
+  using ReferenceOwnershipDeclAttrLayout
+    = BCRecordLayout<ReferenceOwnership_DECL_ATTR>;
   using RawDocCommentDeclAttrLayout = BCRecordLayout<RawDocComment_DECL_ATTR>;
   using AccessControlDeclAttrLayout = BCRecordLayout<AccessControl_DECL_ATTR>;
   using SetterAccessDeclAttrLayout = BCRecordLayout<SetterAccess_DECL_ATTR>;
diff --git a/include/swift/Subsystems.h b/include/swift/Subsystems.h
index 36ade9a..caf4ca8 100644
--- a/include/swift/Subsystems.h
+++ b/include/swift/Subsystems.h
@@ -128,6 +128,7 @@
   std::vector<Token> tokenize(const LangOptions &LangOpts,
                               const SourceManager &SM, unsigned BufferID,
                               unsigned Offset = 0, unsigned EndOffset = 0,
+                              DiagnosticEngine *Diags = nullptr,
                               bool KeepComments = true,
                               bool TokenizeInterpolatedString = true,
                               ArrayRef<Token> SplitTokens = ArrayRef<Token>());
diff --git a/include/swift/SwiftDemangle/Platform.h b/include/swift/SwiftDemangle/Platform.h
index 286018a..c44121d 100644
--- a/include/swift/SwiftDemangle/Platform.h
+++ b/include/swift/SwiftDemangle/Platform.h
@@ -17,7 +17,7 @@
 extern "C" {
 #endif
 
-#if defined(SwiftDemangle_EXPORTS)
+#if defined(swiftDemangle_EXPORTS)
 # if defined(__ELF__)
 #   define SWIFT_DEMANGLE_LINKAGE __attribute__((__visibility__("protected")))
 # elif defined(__MACH__)
diff --git a/include/swift/SwiftRemoteMirror/CMakeLists.txt b/include/swift/SwiftRemoteMirror/CMakeLists.txt
index bbaba07..69d8450 100644
--- a/include/swift/SwiftRemoteMirror/CMakeLists.txt
+++ b/include/swift/SwiftRemoteMirror/CMakeLists.txt
@@ -1,9 +1,12 @@
 set(swift_remote_mirror_headers)
 list(APPEND swift_remote_mirror_headers
-  "MemoryReaderInterface.h"
-  "SwiftRemoteMirror.h"
-  "SwiftRemoteMirrorTypes.h")
+       MemoryReaderInterface.h
+       Platform.h
+       SwiftRemoteMirror.h
+       SwiftRemoteMirrorTypes.h)
 swift_install_in_component("swift-remote-mirror-headers"
-  FILES ${swift_remote_mirror_headers}
-  DESTINATION "include/swift/SwiftRemoteMirror")
+                           FILES
+                             ${swift_remote_mirror_headers}
+                           DESTINATION
+                             "include/swift/SwiftRemoteMirror")
 
diff --git a/include/swift/SwiftRemoteMirror/Platform.h b/include/swift/SwiftRemoteMirror/Platform.h
new file mode 100644
index 0000000..5353344
--- /dev/null
+++ b/include/swift/SwiftRemoteMirror/Platform.h
@@ -0,0 +1,45 @@
+//===-- SwiftRemoteMirror/Platform.h - Remote Mirror Platform --*-- C++ -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_REMOTE_MIRROR_PLATFORM_H
+#define SWIFT_REMOTE_MIRROR_PLATFORM_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(swiftRemoteMirror_EXPORTS)
+# if defined(__ELF__)
+#   define SWIFT_REMOTE_MIRROR_LINKAGE __attribute__((__visibility__("protected")))
+# elif defined(__MACH__)
+#   define SWIFT_REMOTE_MIRROR_LINKAGE __attribute__((__visibility__("default")))
+# else
+#   define SWIFT_REMOTE_MIRROR_LINKAGE __declspec(dllexport)
+# endif
+#else
+# if defined(__ELF__)
+#   define SWIFT_REMOTE_MIRROR_LINKAGE __attribute__((__visibility__("default")))
+# elif defined(__MACH__)
+#   define SWIFT_REMOTE_MIRROR_LINKAGE __attribute__((__visibility__("default")))
+# else
+#   define SWIFT_REMOTE_MIRROR_LINKAGE __declspec(dllimport)
+# endif
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
+
+
diff --git a/include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h b/include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h
index 81e0a13..1909b94 100644
--- a/include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h
+++ b/include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h
@@ -20,6 +20,7 @@
 #ifndef SWIFT_REFLECTION_SWIFT_REFLECTION_H
 #define SWIFT_REFLECTION_SWIFT_REFLECTION_H
 
+#include "Platform.h"
 #include "MemoryReaderInterface.h"
 #include "SwiftRemoteMirrorTypes.h"
 
@@ -37,34 +38,34 @@
 #endif
 
 /// Get the metadata version supported by the Remote Mirror library.
-uint16_t
-swift_reflection_getSupportedMetadataVersion();
+SWIFT_REMOTE_MIRROR_LINKAGE
+uint16_t swift_reflection_getSupportedMetadataVersion();
 
 /// \returns An opaque reflection context.
+SWIFT_REMOTE_MIRROR_LINKAGE
 SwiftReflectionContextRef
-swift_reflection_createReflectionContext(
-    void *ReaderContext,
-    PointerSizeFunction getPointerSize,
-    SizeSizeFunction getSizeSize,
-    ReadBytesFunction readBytes,
-    GetStringLengthFunction getStringLength,
-    GetSymbolAddressFunction getSymbolAddress);
+swift_reflection_createReflectionContext(void *ReaderContext,
+                                         PointerSizeFunction getPointerSize,
+                                         SizeSizeFunction getSizeSize,
+                                         ReadBytesFunction readBytes,
+                                         GetStringLengthFunction getStringLength,
+                                         GetSymbolAddressFunction getSymbolAddress);
 
 /// Destroys an opaque reflection context.
+SWIFT_REMOTE_MIRROR_LINKAGE
 void
 swift_reflection_destroyReflectionContext(SwiftReflectionContextRef Context);
 
 /// Add reflection sections for a loaded Swift image.
-void
-swift_reflection_addReflectionInfo(SwiftReflectionContextRef ContextRef,
-                                   swift_reflection_info_t Info);
-
+SWIFT_REMOTE_MIRROR_LINKAGE
+void swift_reflection_addReflectionInfo(SwiftReflectionContextRef ContextRef,
+                                        swift_reflection_info_t Info);
 
 /// Returns a boolean indicating if the isa mask was successfully
 /// read, in which case it is stored in the isaMask out parameter.
-int
-swift_reflection_readIsaMask(SwiftReflectionContextRef ContextRef,
-                             uintptr_t *outIsaMask);
+SWIFT_REMOTE_MIRROR_LINKAGE
+int swift_reflection_readIsaMask(SwiftReflectionContextRef ContextRef,
+                                 uintptr_t *outIsaMask);
 
 /// Returns an opaque type reference for a metadata pointer, or
 /// NULL if one can't be constructed.
@@ -72,6 +73,7 @@
 /// This function loses information; in particular, passing the
 /// result to swift_reflection_infoForTypeRef() will not give
 /// the same result as calling swift_reflection_infoForMetadata().
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_typeref_t
 swift_reflection_typeRefForMetadata(SwiftReflectionContextRef ContextRef,
                                     uintptr_t Metadata);
@@ -82,11 +84,13 @@
 /// This function loses information; in particular, passing the
 /// result to swift_reflection_infoForTypeRef() will not give
 /// the same result as calling swift_reflection_infoForInstance().
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_typeref_t
 swift_reflection_typeRefForInstance(SwiftReflectionContextRef ContextRef,
                                     uintptr_t Object);
 
 /// Returns a typeref from a mangled type name string.
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_typeref_t
 swift_reflection_typeRefForMangledTypeName(SwiftReflectionContextRef ContextRef,
                                            const char *MangledName,
@@ -94,47 +98,52 @@
 
 /// Returns a structure describing the layout of a value of a typeref.
 /// For classes, this returns the reference value itself.
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_typeinfo_t
 swift_reflection_infoForTypeRef(SwiftReflectionContextRef ContextRef,
                                 swift_typeref_t OpaqueTypeRef);
 
 /// Returns the information about a child field of a value by index.
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_childinfo_t
 swift_reflection_childOfTypeRef(SwiftReflectionContextRef ContextRef,
-                                swift_typeref_t OpaqueTypeRef,
-                                unsigned Index);
+                                swift_typeref_t OpaqueTypeRef, unsigned Index);
 
 /// Returns a structure describing the layout of a class instance
 /// from the isa pointer of a class.
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_typeinfo_t
 swift_reflection_infoForMetadata(SwiftReflectionContextRef ContextRef,
                                  uintptr_t Metadata);
 
 /// Returns the information about a child field of a class instance
 /// by index.
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_childinfo_t
 swift_reflection_childOfMetadata(SwiftReflectionContextRef ContextRef,
-                                 uintptr_t Metadata,
-                                 unsigned Index);
+                                 uintptr_t Metadata, unsigned Index);
 
 /// Returns a structure describing the layout of a class or closure
 /// context instance, from a pointer to the object itself.
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_typeinfo_t
 swift_reflection_infoForInstance(SwiftReflectionContextRef ContextRef,
                                  uintptr_t Object);
 
 /// Returns the information about a child field of a class or closure
 /// context instance.
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_childinfo_t
 swift_reflection_childOfInstance(SwiftReflectionContextRef ContextRef,
-                                 uintptr_t Object,
-                                 unsigned Index);
+                                 uintptr_t Object, unsigned Index);
 
 /// Returns the number of generic arguments of a typeref.
+SWIFT_REMOTE_MIRROR_LINKAGE
 unsigned
 swift_reflection_genericArgumentCountOfTypeRef(swift_typeref_t OpaqueTypeRef);
 
 /// Returns a fully instantiated typeref for a generic argument by index.
+SWIFT_REMOTE_MIRROR_LINKAGE
 swift_typeref_t
 swift_reflection_genericArgumentOfTypeRef(swift_typeref_t OpaqueTypeRef,
                                           unsigned Index);
@@ -158,6 +167,7 @@
 ///
 /// Returns true if InstanceTypeRef and StartOfInstanceData contain valid
 /// valid values.
+SWIFT_REMOTE_MIRROR_LINKAGE
 int swift_reflection_projectExistential(SwiftReflectionContextRef ContextRef,
                                         swift_addr_t ExistentialAddress,
                                         swift_typeref_t ExistentialTypeRef,
@@ -165,17 +175,21 @@
                                         swift_addr_t *OutStartOfInstanceData);
 
 /// Dump a brief description of the typeref as a tree to stderr.
+SWIFT_REMOTE_MIRROR_LINKAGE
 void swift_reflection_dumpTypeRef(swift_typeref_t OpaqueTypeRef);
 
 /// Dump information about the layout for a typeref.
+SWIFT_REMOTE_MIRROR_LINKAGE
 void swift_reflection_dumpInfoForTypeRef(SwiftReflectionContextRef ContextRef,
                                          swift_typeref_t OpaqueTypeRef);
 
 /// Dump information about the layout of a class instance from its isa pointer.
+SWIFT_REMOTE_MIRROR_LINKAGE
 void swift_reflection_dumpInfoForMetadata(SwiftReflectionContextRef ContextRef,
                                           uintptr_t Metadata);
 
 /// Dump information about the layout of a class or closure context instance.
+SWIFT_REMOTE_MIRROR_LINKAGE
 void swift_reflection_dumpInfoForInstance(SwiftReflectionContextRef ContextRef,
                                           uintptr_t Object);
 
@@ -186,10 +200,9 @@
 ///
 /// Returns the length of the demangled string this function tried to copy
 /// into `OutDemangledName`.
-size_t swift_reflection_demangle(const char *MangledName,
-                                 size_t Length,
-                                 char *OutDemangledName,
-                                 size_t MaxLength);
+SWIFT_REMOTE_MIRROR_LINKAGE
+size_t swift_reflection_demangle(const char *MangledName, size_t Length,
+                                 char *OutDemangledName, size_t MaxLength);
 
 #ifdef __cplusplus
 } // extern "C"
diff --git a/include/swift/Syntax/CMakeLists.txt b/include/swift/Syntax/CMakeLists.txt
index e22a57a..3917a36 100644
--- a/include/swift/Syntax/CMakeLists.txt
+++ b/include/swift/Syntax/CMakeLists.txt
@@ -1,6 +1,8 @@
-set(line_directive "#line" "%(line)d" "\"%(file)s\"")
-set(SWIFT_GYB_FLAGS
-  --line-directive "'${line_directive}'")
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
+  set(SWIFT_GYB_FLAGS --line-directive "^\"#line %(line)d \\\"%(file)s\\\"^\"")
+else()
+  set(SWIFT_GYB_FLAGS --line-directive "\'#line" "%(line)d" "\"%(file)s\"\'")
+endif()
 
 set(generated_include_sources
     SyntaxKind.h.gyb
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 659a6ec..6336d03 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -3376,9 +3376,10 @@
   return compTy;
 }
 
-ReferenceStorageType *ReferenceStorageType::get(Type T, Ownership ownership,
+ReferenceStorageType *ReferenceStorageType::get(Type T,
+                                                ReferenceOwnership ownership,
                                                 const ASTContext &C) {
-  assert(ownership != Ownership::Strong &&
+  assert(ownership != ReferenceOwnership::Strong &&
          "ReferenceStorageType is unnecessary for strong ownership");
   assert(!T->hasTypeVariable()); // not meaningful in type-checker
   auto properties = T->getRecursiveProperties();
@@ -3390,16 +3391,17 @@
 
 
   switch (ownership) {
-  case Ownership::Strong: llvm_unreachable("not possible");
-  case Ownership::Unowned:
+  case ReferenceOwnership::Strong:
+    llvm_unreachable("not possible");
+  case ReferenceOwnership::Unowned:
     return entry = new (C, arena) UnownedStorageType(
                T, T->isCanonical() ? &C : nullptr, properties);
-  case Ownership::Weak:
+  case ReferenceOwnership::Weak:
     assert(T->getOptionalObjectType() &&
            "object of weak storage type is not optional");
     return entry = new (C, arena)
                WeakStorageType(T, T->isCanonical() ? &C : nullptr, properties);
-  case Ownership::Unmanaged:
+  case ReferenceOwnership::Unmanaged:
     return entry = new (C, arena) UnmanagedStorageType(
                T, T->isCanonical() ? &C : nullptr, properties);
   }
@@ -3564,9 +3566,10 @@
       
   default:
 //    assert(type->is<InOutType>() && "Found naked inout type");
-    result.push_back(AnyFunctionType::Param(type->getInOutObjectType(),
-                                            Identifier(),
-                                            ParameterTypeFlags::fromParameterType(type, false, false)));
+    result.push_back(
+        AnyFunctionType::Param(type->getInOutObjectType(), Identifier(),
+                               ParameterTypeFlags::fromParameterType(
+                                   type, false, ValueOwnership::Default)));
     return;
   }
 }
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index 374689c..cd0c9a1 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -2249,9 +2249,9 @@
 
       // The fact that this is *directly* be a reference storage type
       // cuts the code down quite a bit in getTypeOfReference.
-      if (var->getAttrs().hasAttribute<OwnershipAttr>() !=
+      if (var->getAttrs().hasAttribute<ReferenceOwnershipAttr>() !=
           isa<ReferenceStorageType>(var->getInterfaceType().getPointer())) {
-        if (var->getAttrs().hasAttribute<OwnershipAttr>()) {
+        if (var->getAttrs().hasAttribute<ReferenceOwnershipAttr>()) {
           Out << "VarDecl has an ownership attribute, but its type"
                  " is not a ReferenceStorageType: ";
         } else {
diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp
index 366ea07..42d480b 100644
--- a/lib/AST/Attr.cpp
+++ b/lib/AST/Attr.cpp
@@ -338,7 +338,7 @@
 #include "swift/AST/Attr.def"
   case DAK_Inline:
   case DAK_AccessControl:
-  case DAK_Ownership:
+  case DAK_ReferenceOwnership:
   case DAK_Effects:
   case DAK_Optimize:
     if (DeclAttribute::isDeclModifier(getKind())) {
@@ -622,12 +622,16 @@
     }
     llvm_unreachable("bad access level");
 
-  case DAK_Ownership:
-    switch (cast<OwnershipAttr>(this)->get()) {
-    case Ownership::Strong: llvm_unreachable("Never present in the attribute");
-    case Ownership::Weak:      return "weak";
-    case Ownership::Unowned:   return "unowned";
-    case Ownership::Unmanaged: return "unowned(unsafe)";
+  case DAK_ReferenceOwnership:
+    switch (cast<ReferenceOwnershipAttr>(this)->get()) {
+    case ReferenceOwnership::Strong:
+      llvm_unreachable("Never present in the attribute");
+    case ReferenceOwnership::Weak:
+      return "weak";
+    case ReferenceOwnership::Unowned:
+      return "unowned";
+    case ReferenceOwnership::Unmanaged:
+      return "unowned(unsafe)";
     }
     llvm_unreachable("bad ownership kind");
   case DAK_RawDocComment:
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 44c79c1..d8b0f72 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1177,7 +1177,7 @@
   // Look through most attributes.
   if (const auto attributed = dyn_cast<AttributedTypeRepr>(typeRepr)) {
     // Weak ownership implies optionality.
-    if (attributed->getAttrs().getOwnership() == Ownership::Weak)
+    if (attributed->getAttrs().getOwnership() == ReferenceOwnership::Weak)
       return true;
 
     return isDefaultInitializable(attributed->getTypeRepr());
@@ -4416,8 +4416,8 @@
 }
 
 ParameterTypeFlags ParamDecl::getParameterFlags() const {
-  return ParameterTypeFlags::fromParameterType(getType(), isVariadic(), isShared())
-            .withInOut(isInOut());
+  return ParameterTypeFlags::fromParameterType(getType(), isVariadic(),
+                                               getValueOwnership());
 }
 
 /// Return the full source range of this parameter.
diff --git a/lib/AST/DiagnosticConsumer.cpp b/lib/AST/DiagnosticConsumer.cpp
index 0681432..230dc55 100644
--- a/lib/AST/DiagnosticConsumer.cpp
+++ b/lib/AST/DiagnosticConsumer.cpp
@@ -14,15 +14,172 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "swift-basic"
+#define DEBUG_TYPE "swift-ast"
 #include "swift/AST/DiagnosticConsumer.h"
 #include "swift/AST/DiagnosticEngine.h"
+#include "swift/Basic/Defer.h"
+#include "swift/Basic/SourceManager.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace swift;
 
-DiagnosticConsumer::~DiagnosticConsumer() { }
+DiagnosticConsumer::~DiagnosticConsumer() = default;
+
+llvm::SMLoc DiagnosticConsumer::getRawLoc(SourceLoc loc) {
+  return loc.Value;
+}
+
+LLVM_ATTRIBUTE_UNUSED
+static bool hasDuplicateFileNames(
+    ArrayRef<FileSpecificDiagnosticConsumer::ConsumerPair> consumers) {
+  llvm::StringSet<> seenFiles;
+  for (const auto &consumerPair : consumers) {
+    if (consumerPair.first.empty()) {
+      // We can handle multiple consumers that aren't associated with any file,
+      // because they only collect diagnostics that aren't in any of the special
+      // files. This isn't an important use case to support, but also SmallSet
+      // doesn't handle empty strings anyway!
+      continue;
+    }
+
+    bool isUnique = seenFiles.insert(consumerPair.first).second;
+    if (!isUnique)
+      return true;
+  }
+  return false;
+}
+
+FileSpecificDiagnosticConsumer::FileSpecificDiagnosticConsumer(
+    SmallVectorImpl<ConsumerPair> &consumers)
+  : SubConsumers(std::move(consumers)) {
+  assert(!SubConsumers.empty() &&
+         "don't waste time handling diagnostics that will never get emitted");
+  assert(!hasDuplicateFileNames(SubConsumers) &&
+         "having multiple consumers for the same file is not implemented");
+}
+
+void FileSpecificDiagnosticConsumer::computeConsumersOrderedByRange(
+    SourceManager &SM) {
+  // Look up each file's source range and add it to the "map" (to be sorted).
+  for (const ConsumerPair &pair : SubConsumers) {
+    if (pair.first.empty())
+      continue;
+
+    Optional<unsigned> bufferID = SM.getIDForBufferIdentifier(pair.first);
+    assert(bufferID.hasValue() && "consumer registered for unknown file");
+    CharSourceRange range = SM.getRangeForBuffer(bufferID.getValue());
+    ConsumersOrderedByRange.emplace_back(range, pair.second.get());
+  }
+
+  // Sort the "map" by buffer /end/ location, for use with std::lower_bound
+  // later. (Sorting by start location would produce the same sort, since the
+  // ranges must not be overlapping, but since we need to check end locations
+  // later it's consistent to sort by that here.)
+  std::sort(ConsumersOrderedByRange.begin(), ConsumersOrderedByRange.end(),
+            [](const ConsumersOrderedByRangeEntry &left,
+               const ConsumersOrderedByRangeEntry &right) -> bool {
+    auto compare = std::less<const char *>();
+    return compare(getRawLoc(left.first.getEnd()).getPointer(),
+                   getRawLoc(right.first.getEnd()).getPointer());
+  });
+
+  // Check that the ranges are non-overlapping. If the files really are all
+  // distinct, this should be trivially true, but if it's ever not we might end
+  // up mis-filing diagnostics.
+  assert(ConsumersOrderedByRange.end() ==
+           std::adjacent_find(ConsumersOrderedByRange.begin(),
+                              ConsumersOrderedByRange.end(),
+                              [](const ConsumersOrderedByRangeEntry &left,
+                                 const ConsumersOrderedByRangeEntry &right) {
+                                return left.first.overlaps(right.first);
+                              }) &&
+         "overlapping ranges despite having distinct files");
+}
+
+DiagnosticConsumer *
+FileSpecificDiagnosticConsumer::consumerForLocation(SourceManager &SM,
+                                                    SourceLoc loc) const {
+  // If there's only one consumer, we'll use it no matter what, because...
+  // - ...all diagnostics within the file will go to that consumer.
+  // - ...all diagnostics not within the file will not be claimed by any
+  //   consumer, and so will go to all (one) consumers.
+  if (SubConsumers.size() == 1)
+    return SubConsumers.front().second.get();
+
+  // Diagnostics with invalid locations always go to every consumer.
+  if (loc.isInvalid())
+    return nullptr;
+
+  // This map is generated on first use and cached, to allow the
+  // FileSpecificDiagnosticConsumer to be set up before the source files are
+  // actually loaded.
+  if (ConsumersOrderedByRange.empty()) {
+    auto *mutableThis = const_cast<FileSpecificDiagnosticConsumer*>(this);
+    mutableThis->computeConsumersOrderedByRange(SM);
+  }
+
+  // This std::lower_bound call is doing a binary search for the first range
+  // that /might/ contain 'loc'. Specifically, since the ranges are sorted
+  // by end location, it's looking for the first range where the end location
+  // is greater than or equal to 'loc'.
+  auto possiblyContainingRangeIter =
+      std::lower_bound(ConsumersOrderedByRange.begin(),
+                       ConsumersOrderedByRange.end(),
+                       loc,
+                       [](const ConsumersOrderedByRangeEntry &entry,
+                          SourceLoc loc) -> bool {
+    auto compare = std::less<const char *>();
+    return compare(getRawLoc(entry.first.getEnd()).getPointer(),
+                   getRawLoc(loc).getPointer());
+  });
+
+  if (possiblyContainingRangeIter != ConsumersOrderedByRange.end() &&
+      possiblyContainingRangeIter->first.contains(loc)) {
+    return possiblyContainingRangeIter->second;
+  }
+
+  return nullptr;
+}
+
+void FileSpecificDiagnosticConsumer::handleDiagnostic(
+    SourceManager &SM, SourceLoc Loc, DiagnosticKind Kind,
+    StringRef FormatString, ArrayRef<DiagnosticArgument> FormatArgs,
+    const DiagnosticInfo &Info) {
+
+  DiagnosticConsumer *specificConsumer;
+  switch (Kind) {
+  case DiagnosticKind::Error:
+  case DiagnosticKind::Warning:
+  case DiagnosticKind::Remark:
+    specificConsumer = consumerForLocation(SM, Loc);
+    ConsumerForSubsequentNotes = specificConsumer;
+    break;
+  case DiagnosticKind::Note:
+    specificConsumer = ConsumerForSubsequentNotes;
+    break;
+  }
+
+  if (specificConsumer) {
+    specificConsumer->handleDiagnostic(SM, Loc, Kind, FormatString, FormatArgs,
+                                       Info);
+  } else {
+    for (auto &subConsumer : SubConsumers) {
+      subConsumer.second->handleDiagnostic(SM, Loc, Kind, FormatString,
+                                           FormatArgs, Info);
+    }
+  }
+}
+
+bool FileSpecificDiagnosticConsumer::finishProcessing() {
+  // Deliberately don't use std::any_of here because we don't want early-exit
+  // behavior.
+  bool hadError = false;
+  for (auto &subConsumer : SubConsumers)
+    hadError |= subConsumer.second->finishProcessing();
+  return hadError;
+}
 
 void NullDiagnosticConsumer::handleDiagnostic(
     SourceManager &SM, SourceLoc Loc, DiagnosticKind Kind,
diff --git a/lib/AST/Parameter.cpp b/lib/AST/Parameter.cpp
index 98c56de..2adab4f 100644
--- a/lib/AST/Parameter.cpp
+++ b/lib/AST/Parameter.cpp
@@ -127,10 +127,10 @@
 
   for (auto P : *this) {
     auto type = getType(P);
-    argumentInfo.emplace_back(type->getInOutObjectType(), P->getArgumentName(),
-                              ParameterTypeFlags::fromParameterType(
-                                  type, P->isVariadic(), P->isShared())
-                                  .withInOut(P->isInOut()));
+    argumentInfo.emplace_back(
+        type->getInOutObjectType(), P->getArgumentName(),
+        ParameterTypeFlags::fromParameterType(type, P->isVariadic(),
+                                              P->getValueOwnership()));
   }
 
   return TupleType::get(argumentInfo, C);
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
index e363a30..7efc861 100644
--- a/lib/Basic/Version.cpp
+++ b/lib/Basic/Version.cpp
@@ -319,9 +319,9 @@
   switch (Components[0]) {
   case 3:
 #ifdef SWIFT_VERSION_PATCHLEVEL
-    return Version{3, 3, SWIFT_VERSION_PATCHLEVEL};
+    return Version{3, 4, SWIFT_VERSION_PATCHLEVEL};
 #else
-    return Version{3, 3};
+    return Version{3, 4};
 #endif
   case 4:
     static_assert(SWIFT_VERSION_MAJOR == 4,
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 3089929..1cbda0c 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -2054,7 +2054,8 @@
     return;
   }
   if (attrs & clang::ObjCPropertyDecl::OBJC_PR_weak) {
-    prop->getAttrs().add(new (ctx) OwnershipAttr(Ownership::Weak));
+    prop->getAttrs().add(new (ctx)
+                             ReferenceOwnershipAttr(ReferenceOwnership::Weak));
     prop->setType(WeakStorageType::get(prop->getType(), ctx));
     prop->setInterfaceType(WeakStorageType::get(
         prop->getInterfaceType(), ctx));
@@ -2062,7 +2063,8 @@
   }
   if ((attrs & clang::ObjCPropertyDecl::OBJC_PR_assign) ||
       (attrs & clang::ObjCPropertyDecl::OBJC_PR_unsafe_unretained)) {
-    prop->getAttrs().add(new (ctx) OwnershipAttr(Ownership::Unmanaged));
+    prop->getAttrs().add(
+        new (ctx) ReferenceOwnershipAttr(ReferenceOwnership::Unmanaged));
     prop->setType(UnmanagedStorageType::get(prop->getType(), ctx));
     prop->setInterfaceType(UnmanagedStorageType::get(
         prop->getInterfaceType(), ctx));
@@ -4735,7 +4737,7 @@
           !isa<clang::ObjCProtocolDecl>(redecl->getDeclContext()))
         original->setImplicit(false);
 
-      if (!original->getAttrs().hasAttribute<OwnershipAttr>() &&
+      if (!original->getAttrs().hasAttribute<ReferenceOwnershipAttr>() &&
           !original->getAttrs().hasAttribute<NSCopyingAttr>()) {
         applyPropertyOwnership(original,
                                redecl->getPropertyAttributesAsWritten());
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index f43a17a..1b9e677 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -419,7 +419,7 @@
     /// TaskFinishedResponse::ContinueExecution from any of the constituent
     /// calls.
     TaskFinishedResponse
-    unpackAndFinishBatch(ProcessId Pid, int ReturnCode, StringRef Output,
+    unpackAndFinishBatch(int ReturnCode, StringRef Output,
                          StringRef Errors, const BatchJob *B) {
       if (Comp.ShowJobLifecycle)
         llvm::outs() << "Batch job finished: " << LogJob(B) << "\n";
@@ -428,7 +428,8 @@
         if (Comp.ShowJobLifecycle)
           llvm::outs() << "  ==> Unpacked batch constituent finished: "
                        << LogJob(J) << "\n";
-        auto r = taskFinished(Pid, ReturnCode, Output, Errors, (void *)J);
+        auto r = taskFinished(llvm::sys::ProcessInfo::InvalidPid, ReturnCode, Output,
+                              Errors, (void *)J);
         if (r != TaskFinishedResponse::ContinueExecution)
           res = r;
       }
@@ -443,26 +444,29 @@
                  StringRef Errors, void *Context) {
       const Job *FinishedCmd = (const Job *)Context;
 
-      if (Comp.ShowDriverTimeCompilation) {
-        DriverTimers[FinishedCmd]->stopTimer();
+      if (Pid != llvm::sys::ProcessInfo::InvalidPid) {
+
+        if (Comp.ShowDriverTimeCompilation) {
+          DriverTimers[FinishedCmd]->stopTimer();
+        }
+
+        if (Comp.Level == OutputLevel::Parseable) {
+          // Parseable output was requested.
+          parseable_output::emitFinishedMessage(llvm::errs(), *FinishedCmd, Pid,
+                                                ReturnCode, Output);
+        } else {
+          // Otherwise, send the buffered output to stderr, though only if we
+          // support getting buffered output.
+          if (TaskQueue::supportsBufferingOutput())
+            llvm::errs() << Output;
+        }
       }
 
       if (BatchJobs.count(FinishedCmd) != 0) {
-        return unpackAndFinishBatch(Pid, ReturnCode, Output, Errors,
+        return unpackAndFinishBatch(ReturnCode, Output, Errors,
                                     static_cast<const BatchJob *>(FinishedCmd));
       }
 
-      if (Comp.Level == OutputLevel::Parseable) {
-        // Parseable output was requested.
-        parseable_output::emitFinishedMessage(llvm::errs(), *FinishedCmd, Pid,
-                                              ReturnCode, Output);
-      } else {
-        // Otherwise, send the buffered output to stderr, though only if we
-        // support getting buffered output.
-        if (TaskQueue::supportsBufferingOutput())
-          llvm::errs() << Output;
-      }
-
       // In order to handle both old dependencies that have disappeared and new
       // dependencies that have arisen, we need to reload the dependency file.
       // Do this whether or not the build succeeded.
@@ -505,30 +509,6 @@
       return TaskFinishedResponse::ContinueExecution;
     }
 
-    /// Unpack a \c BatchJob that has finished into its constituent \c Job
-    /// members, and call \c taskSignalled on each, propagating any \c
-    /// TaskFinishedResponse other than \c
-    /// TaskFinishedResponse::ContinueExecution from any of the constituent
-    /// calls.
-    TaskFinishedResponse
-    unpackAndSignalBatch(ProcessId Pid, StringRef ErrorMsg, StringRef Output,
-                         StringRef Errors, const BatchJob *B,
-                         Optional<int> Signal) {
-      if (Comp.ShowJobLifecycle)
-        llvm::outs() << "Batch job signalled: " << LogJob(B) << "\n";
-      auto res = TaskFinishedResponse::ContinueExecution;
-      for (const Job *J : B->getCombinedJobs()) {
-        if (Comp.ShowJobLifecycle)
-          llvm::outs() << "  ==> Unpacked batch constituent signalled: "
-                       << LogJob(J) << "\n";
-        auto r = taskSignalled(Pid, ErrorMsg, Output, Errors,
-                               (void *)J, Signal);
-        if (r != TaskFinishedResponse::ContinueExecution)
-          res = r;
-      }
-      return res;
-    }
-
     TaskFinishedResponse
     taskSignalled(ProcessId Pid, StringRef ErrorMsg, StringRef Output,
                   StringRef Errors, void *Context, Optional<int> Signal) {
@@ -538,12 +518,6 @@
         DriverTimers[SignalledCmd]->stopTimer();
       }
 
-      if (BatchJobs.count(SignalledCmd) != 0) {
-        return unpackAndSignalBatch(Pid, ErrorMsg, Output, Errors,
-                                    static_cast<const BatchJob *>(SignalledCmd),
-                                    Signal);
-      }
-
       if (Comp.Level == OutputLevel::Parseable) {
         // Parseable output was requested.
         parseable_output::emitSignalledMessage(llvm::errs(), *SignalledCmd,
@@ -554,7 +528,6 @@
         if (TaskQueue::supportsBufferingOutput())
           llvm::errs() << Output;
       }
-
       if (!ErrorMsg.empty())
         Comp.Diags.diagnose(SourceLoc(), diag::error_unable_to_execute_command,
                             ErrorMsg);
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 9abdd59..c4186b8 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -1356,8 +1356,8 @@
   if (const Arg *A = Args.getLastArg(options::OPT_sanitize_EQ))
     OI.SelectedSanitizers = parseSanitizerArgValues(
         Args, A, TC.getTriple(), Diags,
-        [&](StringRef sanitizerName) {
-          return TC.sanitizerRuntimeLibExists(Args, sanitizerName);
+        [&](StringRef sanitizerName, bool shared) {
+          return TC.sanitizerRuntimeLibExists(Args, sanitizerName, shared);
         });
 
   if (const Arg *A = Args.getLastArg(options::OPT_sanitize_coverage_EQ)) {
diff --git a/lib/Driver/ParseableOutput.cpp b/lib/Driver/ParseableOutput.cpp
index 73e59cd..5fed352 100644
--- a/lib/Driver/ParseableOutput.cpp
+++ b/lib/Driver/ParseableOutput.cpp
@@ -133,9 +133,9 @@
       }
     }
     types::forAllTypes([&](types::ID Ty) {
-      auto Output = Cmd.getOutput().getAdditionalOutputForType(Ty);
-      if (!Output.empty())
-        Outputs.push_back(OutputPair(Ty, Output));
+        for (auto Output : Cmd.getOutput().getAdditionalOutputsForType(Ty)) {
+          Outputs.push_back(OutputPair(Ty, Output));
+        }
     });
   }
 
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index e5c3532..59be9d8 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -317,7 +317,8 @@
 
 bool
 ToolChain::sanitizerRuntimeLibExists(const ArgList &args,
-                                     StringRef sanitizerName) const {
+                                     StringRef sanitizerName,
+                                     bool shared) const {
   // Assume no sanitizers are supported by default.
   // This method should be overriden by a platform-specific subclass.
   return false;
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 37d50c7..d8e7610 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1132,18 +1132,21 @@
 }
 
 bool toolchains::Darwin::sanitizerRuntimeLibExists(
-    const ArgList &args, StringRef sanitizer) const {
+    const ArgList &args, StringRef sanitizer, bool shared) const {
   SmallString<128> sanitizerLibPath;
   getClangLibraryPath(*this, args, sanitizerLibPath);
   llvm::sys::path::append(sanitizerLibPath,
-      getSanitizerRuntimeLibNameForDarwin(sanitizer, this->getTriple()));
+                          getSanitizerRuntimeLibNameForDarwin(
+                              sanitizer, this->getTriple(), shared));
   return llvm::sys::fs::exists(sanitizerLibPath.str());
 }
 
 bool toolchains::GenericUnix::sanitizerRuntimeLibExists(
-    const ArgList &args, StringRef sanitizer) const {
+    const ArgList &args, StringRef sanitizer, bool shared) const {
   SmallString<128> sanitizerLibPath;
   getClangLibraryPath(*this, args, sanitizerLibPath);
+
+  // All libraries are static for linux.
   llvm::sys::path::append(sanitizerLibPath,
       getSanitizerRuntimeLibNameForLinux(sanitizer, this->getTriple()));
   return llvm::sys::fs::exists(sanitizerLibPath.str());
@@ -1784,4 +1787,3 @@
 std::string toolchains::Cygwin::getTargetForLinker() const {
   return "";
 }
-
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 6a30cb7..64f7038 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -34,7 +34,8 @@
   Darwin(const Driver &D, const llvm::Triple &Triple) : ToolChain(D, Triple) {}
   ~Darwin() = default;
   bool sanitizerRuntimeLibExists(const llvm::opt::ArgList &args,
-                                 StringRef sanitizerLibName)
+                                 StringRef sanitizerLibName,
+                                 bool shared)
       const override;
 };
 
@@ -73,7 +74,8 @@
   GenericUnix(const Driver &D, const llvm::Triple &Triple) : ToolChain(D, Triple) {}
   ~GenericUnix() = default;
   bool sanitizerRuntimeLibExists(const llvm::opt::ArgList &args,
-                                 StringRef sanitizerLibName)
+                                 StringRef sanitizerLibName,
+                                 bool shared)
       const override;
 };
 
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index f00ba48..6eb05c3 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -686,7 +686,7 @@
   if (const Arg *A = Args.getLastArg(options::OPT_sanitize_EQ)) {
     Opts.Sanitizers = parseSanitizerArgValues(
         Args, A, Triple, Diags,
-        /* sanitizerRuntimeLibExists= */[](StringRef libName) {
+        /* sanitizerRuntimeLibExists= */[](StringRef libName, bool shared) {
 
           // The driver has checked the existence of the library
           // already.
diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp
index e801410..f3634f3 100644
--- a/lib/Frontend/FrontendOptions.cpp
+++ b/lib/Frontend/FrontendOptions.cpp
@@ -116,19 +116,15 @@
     else
       fn(input.outputFilename());
   }
-  (void)InputsAndOutputs.forEachInputProducingSupplementaryOutput(
-      [&](const InputFile &inp) -> bool {
-        const SupplementaryOutputPaths &outs =
-            inp.getPrimarySpecificPaths().SupplementaryOutputs;
-        const std::string *outputs[] = {&outs.ModuleOutputPath,
-                                        &outs.ModuleDocOutputPath,
-                                        &outs.ObjCHeaderOutputPath};
-        for (const std::string *next : outputs) {
-          if (!next->empty())
-            fn(*next);
-        }
-        return false;
-      });
+  const SupplementaryOutputPaths &outs =
+      input.getPrimarySpecificPaths().SupplementaryOutputs;
+  const std::string *outputs[] = {&outs.ModuleOutputPath,
+                                  &outs.ModuleDocOutputPath,
+                                  &outs.ObjCHeaderOutputPath};
+  for (const std::string *next : outputs) {
+    if (!next->empty())
+      fn(*next);
+  }
 }
 
 const char *
diff --git a/lib/Frontend/PrintingDiagnosticConsumer.cpp b/lib/Frontend/PrintingDiagnosticConsumer.cpp
index 11c1eab..69a8933 100644
--- a/lib/Frontend/PrintingDiagnosticConsumer.cpp
+++ b/lib/Frontend/PrintingDiagnosticConsumer.cpp
@@ -63,10 +63,6 @@
   };
 } // end anonymous namespace
 
-llvm::SMLoc DiagnosticConsumer::getRawLoc(SourceLoc loc) {
-  return loc.Value;
-}
-
 void PrintingDiagnosticConsumer::handleDiagnostic(
     SourceManager &SM, SourceLoc Loc, DiagnosticKind Kind,
     StringRef FormatString, ArrayRef<DiagnosticArgument> FormatArgs,
diff --git a/lib/Frontend/SerializedDiagnosticConsumer.cpp b/lib/Frontend/SerializedDiagnosticConsumer.cpp
index bf61701..bd4dec1 100644
--- a/lib/Frontend/SerializedDiagnosticConsumer.cpp
+++ b/lib/Frontend/SerializedDiagnosticConsumer.cpp
@@ -222,9 +222,10 @@
 };
 } // end anonymous namespace
 
-namespace swift { namespace serialized_diagnostics {
-  DiagnosticConsumer *createConsumer(StringRef serializedDiagnosticsPath) {
-    return new SerializedDiagnosticConsumer(serializedDiagnosticsPath);
+namespace swift {
+namespace serialized_diagnostics {
+  std::unique_ptr<DiagnosticConsumer> createConsumer(StringRef outputPath) {
+    return llvm::make_unique<SerializedDiagnosticConsumer>(outputPath);
   }
 } // namespace serialized_diagnostics
 } // namespace swift
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index 3bce5e8..b83b771 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -1335,7 +1335,7 @@
 
   // Just because we had an AST error it doesn't mean we can't performLLVM.
   bool HadError = Instance.getASTContext().hadError();
-  
+
   // If the AST Context has no errors but no IRModule is available,
   // parallelIRGen happened correctly, since parallel IRGen produces multiple
   // modules.
@@ -1509,6 +1509,50 @@
       ProfileEvents, ProfileEntities);
 }
 
+/// Creates a diagnostic consumer that handles serializing diagnostics, based on
+/// the supplementary output paths specified by \p inputsAndOutputs.
+///
+/// The returned consumer will handle producing multiple serialized diagnostics
+/// files if necessary, by using sub-consumers for each file and dispatching to
+/// the right one.
+///
+/// If no serialized diagnostics are being produced, returns null.
+static std::unique_ptr<DiagnosticConsumer>
+createSerializedDiagnosticConsumerIfNeeded(
+    const FrontendInputsAndOutputs &inputsAndOutputs) {
+
+  // The "4" here is somewhat arbitrary. In practice we're going to have one
+  // sub-consumer for each .dia file we're trying to output, which (again in
+  // practice) is going to be 1 in WMO mode and equal to the number of primary
+  // inputs in batch mode. That in turn is going to be "the number of files we
+  // need to recompile in this build, divided by the number of jobs". So a
+  // value of "4" here means that there would be no heap allocation on a clean
+  // build of a module with up to 32 files on an 8-core machine, if the user
+  // doesn't customize anything.
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 4>
+      serializedConsumers;
+
+  inputsAndOutputs.forEachInputProducingSupplementaryOutput(
+      [&](const InputFile &Input) -> bool {
+    std::string serializedDiagnosticsPath = Input.serializedDiagnosticsPath();
+    if (serializedDiagnosticsPath.empty())
+      return false;
+
+    serializedConsumers.emplace_back(
+        Input.file(),
+        serialized_diagnostics::createConsumer(serializedDiagnosticsPath));
+
+    // Continue for other inputs.
+    return false;
+  });
+
+  if (serializedConsumers.empty())
+    return nullptr;
+  if (serializedConsumers.size() == 1)
+    return std::move(serializedConsumers.front()).second;
+  return llvm::make_unique<FileSpecificDiagnosticConsumer>(serializedConsumers);
+}
+
 int swift::performFrontend(ArrayRef<const char *> Args,
                            const char *Argv0, void *MainAddr,
                            FrontendObserver *observer) {
@@ -1621,20 +1665,13 @@
   // arguments are generated by the driver, not directly by a user. The driver
   // is responsible for emitting diagnostics for its own errors. See SR-2683
   // for details.
-  //
-  // FIXME: Do we need one SerializedConsumer per primary? Owned by the
-  // SourceFile?
-  std::unique_ptr<DiagnosticConsumer> SerializedConsumer;
-  {
-    const std::string &SerializedDiagnosticsPath =
-        Invocation.getSerializedDiagnosticsPathForAtMostOnePrimary();
-    if (!SerializedDiagnosticsPath.empty()) {
-      SerializedConsumer.reset(
-          serialized_diagnostics::createConsumer(SerializedDiagnosticsPath));
-      Instance->addDiagnosticConsumer(SerializedConsumer.get());
-    }
-  }
+  std::unique_ptr<DiagnosticConsumer> SerializedConsumerDispatcher =
+      createSerializedDiagnosticConsumerIfNeeded(
+        Invocation.getFrontendOptions().InputsAndOutputs);
+  if (SerializedConsumerDispatcher)
+    Instance->addDiagnosticConsumer(SerializedConsumerDispatcher.get());
 
+  // FIXME: The fix-its need to be multiplexed like the serialized diagnostics.
   std::unique_ptr<DiagnosticConsumer> FixitsConsumer;
   {
     const std::string &FixitsOutputPath =
diff --git a/lib/IRGen/ClassMetadataVisitor.h b/lib/IRGen/ClassMetadataVisitor.h
index 1dbfd60..566e4ac 100644
--- a/lib/IRGen/ClassMetadataVisitor.h
+++ b/lib/IRGen/ClassMetadataVisitor.h
@@ -113,8 +113,7 @@
     asImpl().noteStartOfImmediateMembers(theClass);
 
     // Add space for the generic parameters, if applicable.
-    // Note that we only add references for the immediate parameters;
-    // parameters for the parent context are handled by the parent.
+    // This must always be the first item in the immediate members.
     asImpl().addGenericFields(theClass, type, theClass);
 
     // Add vtable entries.
diff --git a/lib/IRGen/EnumMetadataVisitor.h b/lib/IRGen/EnumMetadataVisitor.h
index bc8334a..402bf06 100644
--- a/lib/IRGen/EnumMetadataVisitor.h
+++ b/lib/IRGen/EnumMetadataVisitor.h
@@ -50,12 +50,10 @@
     // EnumMetadata header.
     asImpl().addNominalTypeDescriptor();
 
-    // If changing this layout, you must update the magic number in
-    // emitParentMetadataRef.
-
     // Instantiation-specific.
 
-    // Add fields for generic cases.
+    // Generic arguments.
+    // This must always be the first piece of trailing data.
     asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
 
     // Reserve a word to cache the payload size if the type has dynamic layout.
diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp
index d48f8d5..baeee73 100644
--- a/lib/IRGen/GenClass.cpp
+++ b/lib/IRGen/GenClass.cpp
@@ -1947,7 +1947,7 @@
       if (!prop->isSettable(prop->getDeclContext()))
         outs << ",R";
       // Weak and Unowned properties are (weak).
-      else if (prop->getAttrs().hasAttribute<OwnershipAttr>())
+      else if (prop->getAttrs().hasAttribute<ReferenceOwnershipAttr>())
         outs << ",W";
       // If the property is @NSCopying, or is bridged to a value class, the
       // property is (copy).
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index d635dfb..ec0f4c2 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2442,15 +2442,6 @@
                               Alignment alignment,
                               llvm::Type *defaultType,
                               ConstantReference::Directness forceIndirectness) {
-  // ObjC class references can always be directly referenced, even in
-  // the weird cases where we don't see a definition.
-  if (entity.isObjCClassRef()) {
-    auto value = getAddrOfObjCClassRef(
-      const_cast<ClassDecl *>(cast<ClassDecl>(entity.getDecl())));
-    return { cast<llvm::Constant>(value.getAddress()),
-             ConstantReference::Direct };
-  }
-
   // Ensure the variable is at least forward-declared.
   if (entity.isForeignTypeMetadataCandidate()) {
     auto foreignCandidate
@@ -2528,7 +2519,7 @@
 
     kind = TypeMetadataRecordKind::IndirectObjCClass;
     defaultTy = TypeMetadataPtrTy;
-    entity = LinkEntity::forObjCClassRef(clas);
+    entity = LinkEntity::forObjCClass(clas);
   } else {
     // A reference to a concrete type.
     // TODO: consider using a symbolic reference (i.e. a symbol string
@@ -2543,8 +2534,8 @@
 
   // Adjust the flags now that we know whether the reference to this
   // entity will be indirect.
-  if (ref.isIndirect()) {
-    assert(kind == TypeMetadataRecordKind::DirectNominalTypeDescriptor);
+  if (ref.isIndirect() &&
+      kind == TypeMetadataRecordKind::DirectNominalTypeDescriptor) {
     kind = TypeMetadataRecordKind::IndirectNominalTypeDescriptor;
   }
 
@@ -3351,11 +3342,18 @@
 
 /// Returns the address of a class metadata base offset.
 llvm::Constant *
-IRGenModule::getAddrOfClassMetadataBaseOffset(ClassDecl *D,
-                                              ForDefinition_t forDefinition) {
+IRGenModule::getAddrOfClassMetadataBounds(ClassDecl *D,
+                                          ForDefinition_t forDefinition) {
+  // StoredClassMetadataBounds
+  auto layoutTy = llvm::StructType::get(getLLVMContext(), {
+    SizeTy,  // Immediate members offset
+    Int32Ty, // Negative size in words
+    Int32Ty  // Positive size in words
+  });
+
   LinkEntity entity = LinkEntity::forClassMetadataBaseOffset(D);
   return getAddrOfLLVMVariable(entity, getPointerAlignment(), forDefinition,
-                               SizeTy, DebugTypeInfo());
+                               layoutTy, DebugTypeInfo());
 }
 
 /// Return the address of a generic type's metadata instantiation cache.
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 92a6b49..7f81ae9 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -1113,8 +1113,7 @@
   unsigned index = 1;
 
   Address addr(metadata, IGF.IGM.getPointerAlignment());
-  addr = IGF.Builder.CreateBitCast(addr,
-                                   IGF.IGM.TypeMetadataPtrTy->getPointerTo());
+  addr = IGF.Builder.CreateElementBitCast(addr, IGF.IGM.TypeMetadataPtrTy);
   return IGF.Builder.CreateConstArrayGEP(addr, index, IGF.IGM.getPointerSize());
 }
 
@@ -2107,13 +2106,13 @@
       auto &C = IGF.IGM.Context;
       CanType referent;
       switch (type->getOwnership()) {
-      case Ownership::Strong:
+      case ReferenceOwnership::Strong:
         llvm_unreachable("shouldn't be a ReferenceStorageType");
-      case Ownership::Weak:
+      case ReferenceOwnership::Weak:
         referent = type.getReferentType().getOptionalObjectType();
         break;
-      case Ownership::Unmanaged:
-      case Ownership::Unowned:
+      case ReferenceOwnership::Unmanaged:
+      case ReferenceOwnership::Unowned:
         referent = type.getReferentType();
         break;
       }
@@ -2134,7 +2133,7 @@
       //
       // FIXME: This sounds wrong, an Objective-C tagged pointer could be
       // stored in an unmanaged reference for instance.
-      if (type->getOwnership() == Ownership::Unmanaged) {
+      if (type->getOwnership() == ReferenceOwnership::Unmanaged) {
         auto metatype = CanMetatypeType::get(C.TheNativeObjectType);
         return emitFromValueWitnessTable(metatype);
       }
@@ -2161,7 +2160,7 @@
 
       // Get the reference storage type of the builtin object whose value
       // witness we can borrow.
-      if (type->getOwnership() == Ownership::Weak)
+      if (type->getOwnership() == ReferenceOwnership::Weak)
         valueWitnessReferent = OptionalType::get(valueWitnessReferent)
           ->getCanonicalType();
 
@@ -2644,19 +2643,12 @@
     
     /// Fill in the fields of a TypeGenericContextDescriptorHeader.
     void addGenericParametersHeader() {
-      asImpl().addGenericParamsOffset();
       asImpl().addMetadataInstantiationFunction();
       asImpl().addMetadataInstantiationCache();
 
       super::addGenericParametersHeader();
     }
 
-    void addGenericParamsOffset() {
-      // Include the offset to the generic argument vector inside a metadata
-      // record for this type.
-      B.addInt32(asImpl().getGenericParamsOffset() / IGM.getPointerSize());
-    }
-
     void addMetadataInstantiationFunction() {
       if (!HasMetadata) {
         B.addInt32(0);
@@ -2716,7 +2708,6 @@
     }
 
     // Subclasses should provide:
-    // Size getGenericParamsOffset();
     // ContextDescriptorKind getContextKind();
     // void addLayoutInfo(); // ABI TODO: should be superseded
   };
@@ -2797,7 +2788,7 @@
       return cast<StructDecl>(Type);
     }
 
-    Size FieldVectorOffset, GenericParamsOffset;
+    Size FieldVectorOffset;
 
   public:
     StructContextDescriptorBuilder(IRGenModule &IGM, StructDecl *Type,
@@ -2805,14 +2796,9 @@
       : super(IGM, Type, requireMetadata)
     {
       auto &layout = IGM.getMetadataLayout(getType());
-      GenericParamsOffset = layout.getStaticGenericRequirementsOffset();
       FieldVectorOffset = layout.getFieldOffsetVectorOffset().getStatic();
     }
 
-    Size getGenericParamsOffset() {
-      return GenericParamsOffset;
-    }
-
     ContextDescriptorKind getContextKind() {
       return ContextDescriptorKind::Struct;
     }
@@ -2848,7 +2834,6 @@
       return cast<EnumDecl>(Type);
     }
     
-    Size GenericParamsOffset;
     Size PayloadSizeOffset;
     const EnumImplStrategy &Strategy;
     
@@ -2860,15 +2845,10 @@
                      getType()->getDeclaredTypeInContext()->getCanonicalType()))
     {
       auto &layout = IGM.getMetadataLayout(getType());
-      GenericParamsOffset = layout.getStaticGenericRequirementsOffset();
       if (layout.hasPayloadSizeOffset())
         PayloadSizeOffset = layout.getPayloadSizeOffset().getStatic();
     }
     
-    Size getGenericParamsOffset() {
-      return GenericParamsOffset;
-    }
-
     ContextDescriptorKind getContextKind() {
       return ContextDescriptorKind::Enum;
     }
@@ -2913,44 +2893,30 @@
       return cast<ClassDecl>(Type);
     }
 
+    // Non-null unless the type is foreign.
+    ClassMetadataLayout *MetadataLayout = nullptr;
+
     Optional<TypeEntityReference> SuperClassRef;
 
-    // Offsets of key fields in the metadata records.
-    Size FieldVectorOffset, GenericParamsOffset;
-
-    SILVTable *VTable;
-
-    Size VTableOffset;
-    unsigned VTableSize;
+    SILVTable *VTable = nullptr;
+    unsigned VTableSize = 0;
 
   public:
     ClassContextDescriptorBuilder(IRGenModule &IGM, ClassDecl *Type,
                                   RequireMetadata_t requireMetadata)
       : super(IGM, Type, requireMetadata)
     {
-      if (getType()->isForeign()) {
-        VTable = nullptr;
-        VTableSize = 0;
-        return;
-      }
+      if (getType()->isForeign()) return;
+
+      MetadataLayout = &IGM.getClassMetadataLayout(Type);
 
       if (auto superclassDecl = getType()->getSuperclassDecl()) {
         SuperClassRef = IGM.getTypeEntityReference(superclassDecl);
       }
 
-      auto &layout = IGM.getClassMetadataLayout(getType());
-
-      VTable = IGM.getSILModule().lookUpVTable(getType());
-      VTableSize = layout.getVTableSize();
-
-      if (layout.hasResilientSuperclass()) {
-        FieldVectorOffset = layout.getRelativeFieldOffsetVectorOffset();
-        GenericParamsOffset = layout.getRelativeGenericRequirementsOffset();
-        VTableOffset = layout.getRelativeVTableOffset();
-      } else {
-        FieldVectorOffset = layout.getStaticFieldOffsetVectorOffset();
-        GenericParamsOffset = layout.getStaticGenericRequirementsOffset();
-        VTableOffset = layout.getStaticVTableOffset();
+      VTableSize = MetadataLayout->getVTableSize();
+      if (VTableSize) {
+        VTable = IGM.getSILModule().lookUpVTable(getType());
       }
     }
     
@@ -2966,14 +2932,17 @@
     uint16_t getKindSpecificFlags() {
       TypeContextDescriptorFlags flags;
 
-      flags.setIsReflectable(true); // class is always reflectable
+      // Classes are always reflectable.
+      flags.setIsReflectable(true);
 
       if (!getType()->isForeign()) {
+        if (MetadataLayout->areImmediateMembersNegative())
+          flags.class_setAreImmediateMembersNegative(true);
+
         if (VTableSize != 0)
           flags.class_setHasVTable(true);
 
-        auto &layout = IGM.getClassMetadataLayout(getType());
-        if (layout.hasResilientSuperclass())
+        if (MetadataLayout->hasResilientSuperclass())
           flags.class_setHasResilientSuperclass(true);
       }
 
@@ -2986,15 +2955,21 @@
       return flags.getOpaqueValue();
     }
     
-    Size getGenericParamsOffset() {
-      return GenericParamsOffset;
+    Size getFieldVectorOffset() {
+      if (!MetadataLayout) return Size(0);
+      return (MetadataLayout->hasResilientSuperclass()
+                ? MetadataLayout->getRelativeFieldOffsetVectorOffset()
+                : MetadataLayout->getStaticFieldOffsetVectorOffset());
     }
     
     void addVTable() {
       if (VTableSize == 0)
         return;
-      
-      B.addInt32(VTableOffset / IGM.getPointerSize());
+
+      auto offset = MetadataLayout->hasResilientSuperclass()
+                      ? MetadataLayout->getRelativeVTableOffset()
+                      : MetadataLayout->getStaticVTableOffset();
+      B.addInt32(offset / IGM.getPointerSize());
       B.addInt32(VTableSize);
       
       addVTableEntries(getType());
@@ -3052,11 +3027,45 @@
         B.addInt32(0);
       }
 
+      // union {
+      //   uint32_t MetadataNegativeSizeInWords;
+      //   RelativeDirectPointer<StoredClassMetadataBounds>
+      //     ResilientMetadataBounds;
+      // };
+      if (!MetadataLayout) {
+        // FIXME: do something meaningful for foreign classes?
+        B.addInt32(0);
+      } else if (!MetadataLayout->hasResilientSuperclass()) {
+        B.addInt32(MetadataLayout->getSize().AddressPoint
+                     / IGM.getPointerSize());
+      } else {
+        B.addRelativeAddress(
+          IGM.getAddrOfClassMetadataBounds(getType(), NotForDefinition));
+      }
+
+      // union {
+      //   uint32_t MetadataPositiveSizeInWords;
+      // };
+      if (!MetadataLayout) {
+        // FIXME: do something meaningful for foreign classes?
+        B.addInt32(0);
+      } else if (!MetadataLayout->hasResilientSuperclass()) {
+        B.addInt32(MetadataLayout->getSize().getOffsetToEnd()
+                     / IGM.getPointerSize());
+      } else {
+        B.addInt32(0); // currently unused
+      }
+
+      // uint32_t NumImmediateMembers;
+      auto numImmediateMembers =
+        (MetadataLayout ? MetadataLayout->getNumImmediateMembers() : 0);
+      B.addInt32(numImmediateMembers);
+
       // uint32_t NumFields;
       B.addInt32(std::distance(properties.begin(), properties.end()));
 
       // uint32_t FieldOffsetVectorOffset;
-      B.addInt32(FieldVectorOffset / IGM.getPointerSize());
+      B.addInt32(getFieldVectorOffset() / IGM.getPointerSize());
 
       addFieldTypes(IGM, getType(), properties);
     }
@@ -3193,7 +3202,11 @@
 namespace {
   /// An adapter class which turns a metadata layout class into a
   /// generic metadata layout class.
-  template <class Impl, class Base>
+  ///
+  /// If AddGenericArguments is false, fill ops will be added for the
+  /// arguments, but space for them won't actually be built into the
+  /// pattern.
+  template <class Impl, class Base, bool AddGenericArguments = true>
   class GenericMetadataBuilderBase : public Base {
     typedef Base super;
 
@@ -3210,7 +3223,7 @@
 
     /// The total size of the template (following any header).
     Size TemplateSize = Size::invalid();
-    
+
     IRGenModule &IGM = super::IGM;
     using super::asImpl;
     using super::Target;
@@ -3319,6 +3332,10 @@
 
       TemplateSize = getNextOffsetFromTemplateHeader();
 
+      asImpl().emitInstantiationDefinitions();
+    }
+
+    void emitInstantiationDefinitions() {
       asImpl().emitCreateFunction();
       asImpl().emitInstantiationCache();
     }
@@ -3337,14 +3354,16 @@
     template <class... T>
     void addGenericArgument(CanType type, T &&...args) {
       FillOps.push_back({type, None});
-      super::addGenericArgument(type, std::forward<T>(args)...);
+      if (AddGenericArguments)
+        super::addGenericArgument(type, std::forward<T>(args)...);
     }
 
     template <class... T>
     void addGenericWitnessTable(CanType type, ProtocolConformanceRef conf,
                                 T &&...args) {
       FillOps.push_back({type, conf});
-      super::addGenericWitnessTable(type, conf, std::forward<T>(args)...);
+      if (AddGenericArguments)
+        super::addGenericWitnessTable(type, conf, std::forward<T>(args)...);
     }
     
     // Can be overridden by subclassers to emit other dependent metadata.
@@ -3544,11 +3563,10 @@
     using super::Target;
     using super::asImpl;
 
-    bool HasResilientSuperclass = false;
-
     ConstantStructBuilder &B;
     const StructLayout &Layout;
     const ClassLayout &FieldLayout;
+    ClassMetadataLayout &MetadataLayout;
 
     MemberBuilder Members;
 
@@ -3558,47 +3576,59 @@
                              const ClassLayout &fieldLayout)
       : super(IGM, theClass), B(builder),
         Layout(layout), FieldLayout(fieldLayout),
+        MetadataLayout(IGM.getClassMetadataLayout(theClass)),
         Members(IGM, theClass, builder, layout, fieldLayout) {}
 
   public:
-    void noteResilientSuperclass() {
-      HasResilientSuperclass = true;
-    }
+    void noteResilientSuperclass() {}
 
     void noteStartOfImmediateMembers(ClassDecl *theClass) {
+      if (theClass == Target) {
+        emitClassMetadataBaseOffset();
+      }
+    }
+
+    /// Emit the base-offset variable for the class.
+    void emitClassMetadataBaseOffset() {
       // Only classes defined in resilient modules, or those that have
       // a resilient superclass need this.
-      if (!HasResilientSuperclass &&
-          !IGM.isResilient(theClass, ResilienceExpansion::Minimal)) {
+      if (!MetadataLayout.hasResilientSuperclass() &&
+          !IGM.isResilient(Target, ResilienceExpansion::Minimal)) {
         return;
       }
 
-      if (theClass == Target) {
-        auto *offsetAddr =
-          IGM.getAddrOfClassMetadataBaseOffset(theClass,
-                                               ForDefinition);
-        auto *offsetVar = cast<llvm::GlobalVariable>(offsetAddr);
+      auto *offsetAddr =
+        IGM.getAddrOfClassMetadataBounds(Target, ForDefinition);
+      auto *offsetVar = cast<llvm::GlobalVariable>(offsetAddr);
 
-        if (HasResilientSuperclass) {
-          // If the superclass is resilient to us, we have to compute and
-          // initialize the global when we initialize the metadata.
-          auto *init = llvm::ConstantInt::get(IGM.SizeTy, 0);
-
-          offsetVar->setInitializer(init);
-          offsetVar->setConstant(false);
-          return;
-        }
-
-        // Otherwise, we know the offset at compile time, even if our
-        // clients do not, so just emit a constant.
-        auto &layout = IGM.getClassMetadataLayout(theClass);
-
-        auto value = layout.getStartOfImmediateMembers();
-        auto *init = llvm::ConstantInt::get(IGM.SizeTy, value.getValue());
+      if (MetadataLayout.hasResilientSuperclass()) {
+        // If the superclass is resilient to us, we have to compute and
+        // initialize the global when we initialize the metadata.
+        auto init = llvm::ConstantAggregateZero::get(offsetVar->getValueType());
 
         offsetVar->setInitializer(init);
-        offsetVar->setConstant(true);
+        offsetVar->setConstant(false);
+        return;
       }
+
+      // Otherwise, we know the offset at compile time, even if our
+      // clients do not, so just emit a constant.
+      auto &layout = IGM.getClassMetadataLayout(Target);
+
+      auto immediateMembersOffset = layout.getStartOfImmediateMembers();
+      auto size = layout.getSize();
+      auto negativeSizeInWords = size.AddressPoint / IGM.getPointerSize();
+      auto positiveSizeInWords = size.getOffsetToEnd() / IGM.getPointerSize();
+
+      auto initTy = cast<llvm::StructType>(offsetVar->getValueType());
+      auto *init = llvm::ConstantStruct::get(initTy, {
+        llvm::ConstantInt::get(IGM.SizeTy, immediateMembersOffset.getValue()),
+        llvm::ConstantInt::get(IGM.Int32Ty, negativeSizeInWords),
+        llvm::ConstantInt::get(IGM.Int32Ty, positiveSizeInWords)
+      });
+
+      offsetVar->setInitializer(init);
+      offsetVar->setConstant(true);
     }
 
     /// The 'metadata flags' field in a class is actually a pointer to
@@ -3744,16 +3774,16 @@
     }
 
     void addClassSize() {
-      auto size = IGM.getMetadataLayout(Target).getSize();
+      auto size = MetadataLayout.getSize();
       B.addInt32(size.FullSize.getValue());
     }
 
     void addClassAddressPoint() {
       // FIXME: Wrong
-      auto size = IGM.getMetadataLayout(Target).getSize();
+      auto size = MetadataLayout.getSize();
       B.addInt32(size.AddressPoint.getValue());
     }
-    
+
     void addClassCacheData() {
       // We initially fill in these fields with addresses taken from
       // the ObjC runtime.
@@ -3857,52 +3887,20 @@
       return metadata;
     }
 
-    // Store the runtime-computed metadata size of our superclass into the
-    // target class's metadata base offset global variable.
-    //
-    // Note that this code will run for each generic instantiation of the
-    // class, if the class is generic. This should be OK because the
-    // metadata size does not change between generic instantiations, so
-    // all stores after the first should be idempotent.
-    void emitInitializeClassMetadataBaseOffset(IRGenFunction &IGF,
-                                               llvm::Value *superMetadata) {
-      if (!HasResilientSuperclass)
-        return;
+    /// Materialize type metadata for the given type and store it into the
+    /// superclass field of the given metadata.
+    void emitStoreOfSuperclass(IRGenFunction &IGF, CanType superclassType,
+                               llvm::Value *metadata) {
+      llvm::Value *superMetadata =
+        emitClassHeapMetadataRef(IGF, superclassType,
+                                 MetadataValueType::TypeMetadata,
+                                 /*allowUninit*/ false);
 
-      auto &layout = IGM.getClassMetadataLayout(Target);
-
-      // Load the size of the superclass metadata.
-      Address metadataAsBytes(
-          IGF.Builder.CreateBitCast(superMetadata, IGF.IGM.Int8PtrTy),
-          IGM.getPointerAlignment());
-
-      Address sizeSlot = IGF.Builder.CreateConstByteArrayGEP(
-          metadataAsBytes,
-          layout.getMetadataSizeOffset());
-      sizeSlot = IGF.Builder.CreateBitCast(sizeSlot,
-                                           IGM.Int32Ty->getPointerTo());
-      llvm::Value *size = IGF.Builder.CreateLoad(sizeSlot);
-
-      Address addressPointSlot = IGF.Builder.CreateConstByteArrayGEP(
-          metadataAsBytes,
-          layout.getMetadataAddressPointOffset());
-      addressPointSlot = IGF.Builder.CreateBitCast(addressPointSlot,
-                                                   IGM.Int32Ty->getPointerTo());
-      llvm::Value *addressPoint = IGF.Builder.CreateLoad(addressPointSlot);
-
-      size = IGF.Builder.CreateSub(size, addressPoint);
-
-      if (IGM.SizeTy != IGM.Int32Ty)
-        size = IGF.Builder.CreateZExt(size, IGM.SizeTy);
-
-      Address offsetAddr(
-          IGM.getAddrOfClassMetadataBaseOffset(Target,
-                                               NotForDefinition),
-          IGM.getPointerAlignment());
-
-      // FIXME: Do we need to worry about memory barriers here, and when we
-      // load from the global?
-      IGF.Builder.CreateStore(size, offsetAddr);
+      Address superField =
+        emitAddressOfSuperclassRefInClassMetadata(IGF, metadata);
+      superField = IGF.Builder.CreateElementBitCast(superField,
+                                                    IGM.TypeMetadataPtrTy);
+      IGF.Builder.CreateStore(superMetadata, superField);
     }
 
     // Update vtable entries for method overrides. The runtime copies in
@@ -3989,7 +3987,6 @@
     using super::Target;
     using super::B;
     using super::addReferenceToHeapMetadata;
-    using super::emitInitializeClassMetadataBaseOffset;
     using super::emitFinishInitializationOfClassMetadata;
     using super::emitFinishIdempotentInitialization;
     using super::emitFieldOffsetGlobals;
@@ -4080,18 +4077,7 @@
       // Initialize the superclass if we didn't do so as a constant.
       if (HasUnfilledSuperclass) {
         auto superclass = type->getSuperclass()->getCanonicalType();
-        llvm::Value *superMetadata =
-          emitClassHeapMetadataRef(IGF, superclass,
-                                   MetadataValueType::TypeMetadata,
-                                   /*allowUninit*/ false);
-
-        emitInitializeClassMetadataBaseOffset(IGF, superMetadata);
-
-        Address superField =
-          emitAddressOfSuperclassRefInClassMetadata(IGF, metadata);
-        superField = IGF.Builder.CreateElementBitCast(superField,
-                                                     IGM.TypeMetadataPtrTy);
-        IGF.Builder.CreateStore(superMetadata, superField);
+        this->emitStoreOfSuperclass(IGF, superclass, metadata);
       }
 
       // Relocate the metadata if it has a superclass that is resilient
@@ -4139,20 +4125,18 @@
       : super(IGM, theClass, builder, layout, fieldLayout) {}
   };
 
-  /// A builder for generic class metadata.
+  /// A builder for GenericClassMetadataPattern objects.
   class GenericClassMetadataBuilder :
     public GenericMetadataBuilderBase<GenericClassMetadataBuilder,
                       ClassMetadataBuilderBase<GenericClassMetadataBuilder,
-                                               ResilientClassMemberBuilder>>
+                                               ResilientClassMemberBuilder>,
+                                      /*add generic arguments*/ false>
   {
     typedef GenericMetadataBuilderBase super;
 
-    Size MetaclassPtrOffset = Size::invalid();
-    Size ClassRODataPtrOffset = Size::invalid();
-    Size MetaclassRODataPtrOffset = Size::invalid();
-    Size DependentMetaclassPoint = Size::invalid();
-    Size DependentClassRODataPoint = Size::invalid();
-    Size DependentMetaclassRODataPoint = Size::invalid();
+    Optional<ConstantAggregateBuilderBase::PlaceholderPosition>
+      NumExtraDataWords, ClassRODataOffset, MetaclassObjectOffset,
+      MetaclassRODataOffset;
   public:
     GenericClassMetadataBuilder(IRGenModule &IGM, ClassDecl *theClass,
                                 ConstantStructBuilder &B,
@@ -4165,70 +4149,107 @@
       HasDependentMetadata = true;
     }
 
-    void addSuperClass() {
-      // Filled in by the runtime.
-      B.addNullPointer(IGM.TypeMetadataPtrTy);
+    void layout() {
+      // HeapObjectDestroyer *Destroy;
+      addDestructorFunction();
+
+      // ClassIVarDestroyer *IVarDestroyer;
+      addIVarDestroyer();
+
+      // ClassFlags Flags;
+      addClassFlags();
+
+      // TODO: consider using this to initialize the field offsets (and then
+      // suppress dynamic layout for them).
+      // uint16_t ImmediateMembersPattern_Size;
+      // uint16_t ImmediateMembersPattern_TargetOffset;
+      B.addInt16(0);
+      B.addInt16(0);
+
+      // uint16_t NumExtraDataWords;
+      NumExtraDataWords = B.addPlaceholderWithSize(IGM.Int16Ty);
+
+      // uint16_t ClassRODataOffset;
+      ClassRODataOffset = B.addPlaceholderWithSize(IGM.Int16Ty);
+
+      // uint16_t MetaclassObjectOffset;
+      MetaclassObjectOffset = B.addPlaceholderWithSize(IGM.Int16Ty);
+
+      // uint16_t MetadataRODataOffset;
+      MetaclassRODataOffset = B.addPlaceholderWithSize(IGM.Int16Ty);
+
+      // Immediate members pattern:
+      //   (currently we don't take advantage of this)
+
+      // Extra data pattern:
+      addExtraDataPattern();
+
+      // We're done with the pattern now.
+#ifndef NDEBUG
+      auto finalOffset = getNextOffsetFromTemplateHeader();
+#endif
+
+      // Emit the base-offset variable.
+      emitClassMetadataBaseOffset();
+
+      // Emit the nominal type descriptor.
+      (void) ClassContextDescriptorBuilder(IGM, Target, RequireMetadata).emit();
+
+      // Register fill ops for all the immediate type arguments.
+      addGenericFields(Target, Target->getDeclaredTypeInContext(), Target);
+
+      // Emit instantiation information.
+      emitInstantiationDefinitions();
+
+      assert(finalOffset == getNextOffsetFromTemplateHeader() &&
+             "shouldn't have added anything to the pattern");
     }
 
-    llvm::Value *emitAllocateMetadata(IRGenFunction &IGF,
-                                      llvm::Value *descriptor,
-                                      llvm::Value *arguments) {
-      llvm::Value *superMetadata;
-      if (Target->hasSuperclass()) {
-        Type superclass = Target->getSuperclass();
-        superclass = Target->mapTypeIntoContext(superclass);
-        superMetadata =
-          emitClassHeapMetadataRef(IGF, superclass->getCanonicalType(),
-                                   MetadataValueType::ObjCClass);
+    uint16_t getOffsetInWords(Size begin, Size offset) {
+      // Subtract the offset from the initial offset and divide by the
+      // pointer size, rounding up.
+      auto result =
+        (offset - begin + IGM.getPointerSize() - Size(1))
+          / IGM.getPointerSize();
+      assert(result < (1 << 16));
+      return uint16_t(result);
+    };
 
-        emitInitializeClassMetadataBaseOffset(IGF, superMetadata);
-      } else if (IGM.ObjCInterop) {
-        superMetadata = emitObjCHeapMetadataRef(IGF,
-                               IGM.getObjCRuntimeBaseForSwiftRootClass(Target));
-      } else {
-        superMetadata = llvm::ConstantPointerNull::get(IGM.ObjCClassPtrTy);
+    void addExtraDataPattern() {
+      Size extraDataBegin = getNextOffsetFromTemplateHeader();
+
+      uint16_t classRODataOffsetWords = 0;
+      uint16_t metaclassObjectOffsetWords = 0;
+      uint16_t metaclassRODataOffsetWords = 0;
+      if (IGM.ObjCInterop) {
+        // Add the metaclass object.
+        metaclassObjectOffsetWords =
+          getOffsetInWords(extraDataBegin, getNextOffsetFromTemplateHeader());
+        addMetaclassObject();
+
+        // Add the RO-data objects.
+        auto roDataPoints =
+          emitClassPrivateDataFields(IGM, B, Target);
+        classRODataOffsetWords =
+          getOffsetInWords(extraDataBegin, roDataPoints.first);
+        metaclassRODataOffsetWords =
+          getOffsetInWords(extraDataBegin, roDataPoints.second);
       }
 
-      auto templatePointer = IGM.getAddrOfTypeMetadataPattern(Target);
-      auto templateSize = IGM.getSize(TemplateSize);
-      auto templateAddressPoint = IGM.getSize(AddressPoint);
+      auto extraDataEnd = getNextOffsetFromTemplateHeader();
+      auto numExtraDataWords = getOffsetInWords(extraDataBegin, extraDataEnd);
 
-      auto numImmediateMembers =
-        IGM.getSize(Size(IGM.getClassMetadataLayout(Target).getNumImmediateMembers()));
+      B.fillPlaceholderWithInt(*NumExtraDataWords, IGM.Int16Ty,
+                               numExtraDataWords);
+      B.fillPlaceholderWithInt(*ClassRODataOffset, IGM.Int16Ty,
+                               classRODataOffsetWords);
+      B.fillPlaceholderWithInt(*MetaclassObjectOffset, IGM.Int16Ty,
+                               metaclassObjectOffsetWords);
+      B.fillPlaceholderWithInt(*MetaclassRODataOffset, IGM.Int16Ty,
+                               metaclassRODataOffsetWords);
+    }
 
-      return IGF.Builder.CreateCall(IGM.getAllocateGenericClassMetadataFn(),
-                                    {descriptor, templatePointer, templateSize,
-                                     templateAddressPoint, arguments,
-                                     superMetadata, numImmediateMembers});
-    }
-    
-    void addMetadataFlags() {
-      // The metaclass pointer will be instantiated here.
-      MetaclassPtrOffset = getNextOffsetFromTemplateHeader();
-      B.addInt(IGM.MetadataKindTy, 0);
-    }
-    
-    void addClassDataPointer() {
-      // The rodata pointer will be instantiated here.
-      // Make sure we at least set the 'is Swift class' bit, though.
-      ClassRODataPtrOffset = getNextOffsetFromTemplateHeader();
-      if (!IGM.ObjCInterop) {
-        // FIXME: Remove null data altogether rdar://problem/18801263
-        B.addInt(IGM.MetadataKindTy, 1);
-      } else {
-        B.addInt(IGM.MetadataKindTy, IGM.UseDarwinPreStableABIBit ? 1 : 2);
-      }
-    }
-    
-    void addDependentData() {
-      if (!IGM.ObjCInterop) {
-        // Every piece of data in the dependent data appears to be related to
-        // Objective-C information. If we're not doing Objective-C interop, we
-        // can just skip adding it to the class.
-        return;
-      }
-      // Emit space for the dependent metaclass.
-      DependentMetaclassPoint = getNextOffsetFromTemplateHeader();
+    void addMetaclassObject() {
       // isa
       ClassDecl *rootClass = getRootClassForMetaclass(IGM, Target);
       auto isa = IGM.getAddrOfMetaclassObject(rootClass, NotForDefinition);
@@ -4240,17 +4261,9 @@
       // vtable
       B.add(IGM.getObjCEmptyVTablePtr());
       // rodata, which is always dependent
-      MetaclassRODataPtrOffset = getNextOffsetFromTemplateHeader();
       B.addInt(IGM.IntPtrTy, 0);
-
-      std::tie(DependentClassRODataPoint, DependentMetaclassRODataPoint)
-        = emitClassPrivateDataFields(IGM, B, Target);
     }
                             
-    void noteStartOfFieldOffsets(ClassDecl *whichClass) {}
-    
-    void noteEndOfFieldOffsets(ClassDecl *whichClass) {}
-    
     // Suppress GenericMetadataBuilderBase's default behavior of introducing
     // fill ops for generic arguments unless they belong directly to the target
     // class and not its ancestors.
@@ -4278,91 +4291,29 @@
       }
     }
 
+    llvm::Value *emitAllocateMetadata(IRGenFunction &IGF,
+                                      llvm::Value *descriptor,
+                                      llvm::Value *arguments) {
+      auto templatePointer = IGM.getAddrOfTypeMetadataPattern(Target);
+      auto metadata =
+        IGF.Builder.CreateCall(IGM.getAllocateGenericClassMetadataFn(),
+                               {descriptor, arguments, templatePointer});
+
+      return metadata;
+    }
+
     void emitInitializeMetadata(IRGenFunction &IGF,
                                 llvm::Value *metadata,
                                 bool isVWTMutable) {
       assert(!HasDependentVWT && "class should never have dependent VWT");
 
-      // Fill in the metaclass pointer.
-      Address metadataPtr(IGF.Builder.CreateBitCast(metadata, IGF.IGM.Int8PtrPtrTy),
-                          IGF.IGM.getPointerAlignment());
-      
-      llvm::Value *metaclass;
-      if (IGF.IGM.ObjCInterop) {
-        assert(!DependentMetaclassPoint.isInvalid());
-        assert(!MetaclassPtrOffset.isInvalid());
-
-        Address metaclassPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
-                                            MetaclassPtrOffset - AddressPoint);
-        metaclassPtrSlot = IGF.Builder.CreateBitCast(metaclassPtrSlot,
-                                        IGF.IGM.ObjCClassPtrTy->getPointerTo());
-        Address metaclassRawPtr = createPointerSizedGEP(IGF, metadataPtr,
-                                        DependentMetaclassPoint - AddressPoint);
-        metaclass = IGF.Builder.CreateBitCast(metaclassRawPtr,
-                                              IGF.IGM.ObjCClassPtrTy)
-          .getAddress();
-        IGF.Builder.CreateStore(metaclass, metaclassPtrSlot);
-      } else {
-        // FIXME: Remove altogether rather than injecting a NULL value.
-        // rdar://problem/18801263
-        assert(!MetaclassPtrOffset.isInvalid());
-        Address metaclassPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
-                                            MetaclassPtrOffset - AddressPoint);
-        metaclassPtrSlot = IGF.Builder.CreateBitCast(metaclassPtrSlot,
-                                        IGF.IGM.ObjCClassPtrTy->getPointerTo());
-        IGF.Builder.CreateStore(
-          llvm::ConstantPointerNull::get(IGF.IGM.ObjCClassPtrTy), 
-          metaclassPtrSlot);
-      }
-      
-      // Fill in the rodata reference in the class.
-      Address classRODataPtr;
-      if (IGF.IGM.ObjCInterop) {
-        assert(!DependentClassRODataPoint.isInvalid());
-        assert(!ClassRODataPtrOffset.isInvalid());
-        Address rodataPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
-                                           ClassRODataPtrOffset - AddressPoint);
-        rodataPtrSlot = IGF.Builder.CreateBitCast(rodataPtrSlot,
-                                              IGF.IGM.IntPtrTy->getPointerTo());
-        
-        classRODataPtr = createPointerSizedGEP(IGF, metadataPtr,
-                                      DependentClassRODataPoint - AddressPoint);
-        // Set the low bit of the value to indicate "compiled by Swift".
-        llvm::Value *rodata = IGF.Builder.CreatePtrToInt(
-                                classRODataPtr.getAddress(), IGF.IGM.IntPtrTy);
-        rodata = IGF.Builder.CreateOr(rodata, 1);
-        IGF.Builder.CreateStore(rodata, rodataPtrSlot);
-      } else {
-        // NOTE: Unlike other bits of the metadata that should later be removed,
-        // this one is important because things check this value's flags to
-        // determine what kind of object it is. That said, if those checks
-        // are determined to be removable, we can remove this as well per
-        // rdar://problem/18801263
-        assert(!ClassRODataPtrOffset.isInvalid());
-        Address rodataPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
-                                           ClassRODataPtrOffset - AddressPoint);
-        rodataPtrSlot = IGF.Builder.CreateBitCast(rodataPtrSlot,
-                                              IGF.IGM.IntPtrTy->getPointerTo());
-        
-        IGF.Builder.CreateStore(llvm::ConstantInt::get(IGF.IGM.IntPtrTy, 1), 
-                                                                rodataPtrSlot);
-      }
-
-      // Fill in the rodata reference in the metaclass.
-      Address metaclassRODataPtr;
-      if (IGF.IGM.ObjCInterop) {
-        assert(!DependentMetaclassRODataPoint.isInvalid());
-        assert(!MetaclassRODataPtrOffset.isInvalid());
-        Address rodataPtrSlot = createPointerSizedGEP(IGF, metadataPtr,
-                                      MetaclassRODataPtrOffset - AddressPoint);
-        rodataPtrSlot = IGF.Builder.CreateBitCast(rodataPtrSlot,
-                                              IGF.IGM.IntPtrTy->getPointerTo());
-        
-        metaclassRODataPtr = createPointerSizedGEP(IGF, metadataPtr,
-                                 DependentMetaclassRODataPoint - AddressPoint);
-        llvm::Value *rodata = IGF.Builder.CreatePtrToInt(
-                            metaclassRODataPtr.getAddress(), IGF.IGM.IntPtrTy);
-        IGF.Builder.CreateStore(rodata, rodataPtrSlot);
+      // Install the superclass.  The runtime takes care of installing
+      // SwiftObject if we're building with ObjC interop and don't have
+      // a formal superclass.
+      if (Target->hasSuperclass()) {
+        CanType superclass = Target->mapTypeIntoContext(Target->getSuperclass())
+                                   ->getCanonicalType();
+        emitStoreOfSuperclass(IGF, superclass, metadata);
       }
 
       // We can assume that this never relocates the metadata because
diff --git a/lib/IRGen/GenMeta.h b/lib/IRGen/GenMeta.h
index ee85978..3f398c8 100644
--- a/lib/IRGen/GenMeta.h
+++ b/lib/IRGen/GenMeta.h
@@ -151,13 +151,6 @@
                                     ArchetypeType *archetype);
 
   /// Given a reference to nominal type metadata of the given type,
-  /// derive a reference to the parent type metadata.  There must be a
-  /// parent type.
-  llvm::Value *emitParentMetadataRef(IRGenFunction &IGF,
-                                     NominalTypeDecl *theDecl,
-                                     llvm::Value *metadata);
-
-  /// Given a reference to nominal type metadata of the given type,
   /// derive a reference to the type metadata stored in the nth
   /// requirement slot.  The type must have generic arguments.
   llvm::Value *emitArgumentMetadataRef(IRGenFunction &IGF,
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 5377b02..2fdf1c4 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -1210,7 +1210,8 @@
           ConcreteType(SILWT->getConformance()->getDeclContext()
                          ->mapTypeIntoContext(
                            SILWT->getConformance()->getType()
-                             ->getCanonicalType())),
+                             ->getCanonicalType())
+                         ->getCanonicalType()),
           Conformance(*SILWT->getConformance()),
           SILEntries(SILWT->getEntries()),
           SILConditionalConformances(SILWT->getConditionalConformances()),
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 5b93a9a..6fb2258 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -1150,8 +1150,8 @@
   /// Determine whether the given type requires foreign type metadata.
   bool requiresForeignTypeMetadata(CanType type);
 
-  llvm::Constant *getAddrOfClassMetadataBaseOffset(ClassDecl *D,
-                                                 ForDefinition_t forDefinition);
+  llvm::Constant *getAddrOfClassMetadataBounds(ClassDecl *D,
+                                               ForDefinition_t forDefinition);
   llvm::Constant *getAddrOfTypeContextDescriptor(NominalTypeDecl *D,
                                       RequireMetadata_t requireMetadata,
                                       ConstantInit definition = ConstantInit());
diff --git a/lib/IRGen/MetadataLayout.cpp b/lib/IRGen/MetadataLayout.cpp
index 491539f..852cf2a 100644
--- a/lib/IRGen/MetadataLayout.cpp
+++ b/lib/IRGen/MetadataLayout.cpp
@@ -162,11 +162,13 @@
   if (offset.isStatic())
     return Offset(offset.getStaticOffset());
 
-  Address offsetBaseAddr(
-    IGF.IGM.getAddrOfClassMetadataBaseOffset(cast<ClassDecl>(getDecl()),
-                                             NotForDefinition),
+  Address layoutAddr(
+    IGF.IGM.getAddrOfClassMetadataBounds(cast<ClassDecl>(getDecl()),
+                                         NotForDefinition),
     IGF.IGM.getPointerAlignment());
 
+  auto offsetBaseAddr = IGF.Builder.CreateStructGEP(layoutAddr, 0, Size(0));
+
   // FIXME: Should this be an invariant load?
   llvm::Value *offsetVal = IGF.Builder.CreateLoad(offsetBaseAddr, "base");
 
diff --git a/lib/IRGen/MetadataLayout.h b/lib/IRGen/MetadataLayout.h
index cc0851d..9410c56 100644
--- a/lib/IRGen/MetadataLayout.h
+++ b/lib/IRGen/MetadataLayout.h
@@ -227,6 +227,10 @@
     return HasResilientSuperclass;
   }
 
+  constexpr static bool areImmediateMembersNegative() {
+    return false;
+  }
+
   Size getMetadataSizeOffset() const;
 
   Size getMetadataAddressPointOffset() const;
diff --git a/lib/IRGen/StructMetadataVisitor.h b/lib/IRGen/StructMetadataVisitor.h
index 15e29fc..ce870fe 100644
--- a/lib/IRGen/StructMetadataVisitor.h
+++ b/lib/IRGen/StructMetadataVisitor.h
@@ -48,10 +48,10 @@
     // StructMetadata header.
     asImpl().addNominalTypeDescriptor();
 
-    // If changing this layout, you must update the magic number in
-    // emitParentMetadataRef.
-
     // Instantiation-specific.
+
+    // Generic arguments.
+    // This must always be the first piece of trailing data.
     asImpl().addGenericFields(Target, Target->getDeclaredTypeInContext());
 
     // Struct field offsets.
diff --git a/lib/Option/SanitizerOptions.cpp b/lib/Option/SanitizerOptions.cpp
index d168b29..62016b3 100644
--- a/lib/Option/SanitizerOptions.cpp
+++ b/lib/Option/SanitizerOptions.cpp
@@ -41,6 +41,18 @@
   llvm_unreachable("Unsupported sanitizer");
 }
 
+static const char* toFileName(const SanitizerKind kind) {
+  switch (kind) {
+  case SanitizerKind::Address:
+    return "asan";
+  case SanitizerKind::Thread:
+    return "tsan";
+  case SanitizerKind::Fuzzer:
+    return "fuzzer";
+  }
+  llvm_unreachable("Unsupported sanitizer");
+}
+
 llvm::SanitizerCoverageOptions swift::parseSanitizerCoverageArgValue(
     const llvm::opt::Arg *A, const llvm::Triple &Triple,
     DiagnosticEngine &Diags, OptionSet<SanitizerKind> sanitizers) {
@@ -108,33 +120,43 @@
   return opts;
 }
 
-static bool isTSanSupported(
-    const llvm::Triple &Triple,
-    llvm::function_ref<bool(llvm::StringRef)> sanitizerRuntimeLibExists) {
-
-  return Triple.isArch64Bit() && sanitizerRuntimeLibExists("tsan");
-}
-
 OptionSet<SanitizerKind> swift::parseSanitizerArgValues(
     const llvm::opt::ArgList &Args,
     const llvm::opt::Arg *A,
     const llvm::Triple &Triple,
     DiagnosticEngine &Diags,
-    llvm::function_ref<bool(llvm::StringRef)> sanitizerRuntimeLibExists) {
+    llvm::function_ref<bool(llvm::StringRef, bool)> sanitizerRuntimeLibExists) {
   OptionSet<SanitizerKind> sanitizerSet;
 
   // Find the sanitizer kind.
   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
-    StringRef opt = A->getValue(i);
-    if (opt == "address") {
-      sanitizerSet |= SanitizerKind::Address;
-    } else if (opt == "thread") {
-      sanitizerSet |= SanitizerKind::Thread;
-    } else if (opt == "fuzzer") {
-      sanitizerSet |= SanitizerKind::Fuzzer;
-    } else {
+    auto kind = llvm::StringSwitch<Optional<SanitizerKind>>(A->getValue(i))
+        .Case("address", SanitizerKind::Address)
+        .Case("thread", SanitizerKind::Thread)
+        .Case("fuzzer", SanitizerKind::Fuzzer)
+        .Default(None);
+    bool isShared = kind && *kind != SanitizerKind::Fuzzer;
+    if (!kind) {
       Diags.diagnose(SourceLoc(), diag::error_unsupported_option_argument,
           A->getOption().getPrefixedName(), A->getValue(i));
+    } else {
+      // Support is determined by existance of the sanitizer library.
+      bool sanitizerSupported =
+          sanitizerRuntimeLibExists(toFileName(*kind), isShared);
+
+      // TSan is explicitly not supported for 32 bits.
+      if (*kind == SanitizerKind::Thread && !Triple.isArch64Bit())
+        sanitizerSupported = false;
+
+      if (!sanitizerSupported) {
+        SmallString<128> b;
+        Diags.diagnose(SourceLoc(), diag::error_unsupported_opt_for_target,
+                       (A->getOption().getPrefixedName() + toStringRef(*kind))
+                           .toStringRef(b),
+                       Triple.getTriple());
+      } else {
+        sanitizerSet |= *kind;
+      }
     }
   }
 
@@ -159,16 +181,5 @@
             + toStringRef(SanitizerKind::Thread)).toStringRef(b2));
   }
 
-  // Thread Sanitizer only works on OS X and the simulators. It's only supported
-  // on 64 bit architectures.
-  if ((sanitizerSet & SanitizerKind::Thread) &&
-      !isTSanSupported(Triple, sanitizerRuntimeLibExists)) {
-    SmallString<128> b;
-    Diags.diagnose(SourceLoc(), diag::error_unsupported_opt_for_target,
-      (A->getOption().getPrefixedName()
-          + toStringRef(SanitizerKind::Thread)).toStringRef(b),
-      Triple.getTriple());
-  }
-
   return sanitizerSet;
 }
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 79ba4a2..312666e 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -351,16 +351,19 @@
       }
       break;   // Otherwise, eat other characters.
     case 0:
-      // If this is a random nul character in the middle of a buffer, skip it as
-      // whitespace.
-      if (CurPtr-1 != BufferEnd) {
+      switch (getNulCharacterKind(CurPtr - 1)) {
+      case NulCharacterKind::Embedded:
+        // If this is a random nul character in the middle of a buffer, skip it
+        // as whitespace.
         diagnoseEmbeddedNul(Diags, CurPtr-1);
-        break;
+        LLVM_FALLTHROUGH;
+      case NulCharacterKind::CodeCompletion:
+        continue;
+      case NulCharacterKind::BufferEnd:
+        // Otherwise, the last line of the file does not have a newline.
+        --CurPtr;
+        return;
       }
-
-      // Otherwise, the last line of the file does not have a newline.
-      --CurPtr;
-      return;
     }
   }
 }
@@ -422,26 +425,30 @@
 
       break;   // Otherwise, eat other characters.
     case 0:
-      // If this is a random nul character in the middle of a buffer, skip it as
-      // whitespace.
-      if (CurPtr-1 != BufferEnd) {
-        diagnoseEmbeddedNul(Diags, CurPtr-1);
-        break;
+      switch (getNulCharacterKind(CurPtr - 1)) {
+      case NulCharacterKind::Embedded:
+        // If this is a random nul character in the middle of a buffer, skip it
+        // as whitespace.
+        diagnoseEmbeddedNul(Diags, CurPtr - 1);
+        LLVM_FALLTHROUGH;
+      case NulCharacterKind::CodeCompletion:
+        continue;
+      case NulCharacterKind::BufferEnd: {
+        // Otherwise, we have an unterminated /* comment.
+        --CurPtr;
+
+        // Count how many levels deep we are.
+        llvm::SmallString<8> Terminator("*/");
+        while (--Depth != 0)
+          Terminator += "*/";
+
+        const char *EOL = (CurPtr[-1] == '\n') ? (CurPtr - 1) : CurPtr;
+        diagnose(EOL, diag::lex_unterminated_block_comment)
+            .fixItInsert(getSourceLoc(EOL), Terminator);
+        diagnose(StartPtr, diag::lex_comment_start);
+        return;
       }
-      
-      // Otherwise, we have an unterminated /* comment.
-      --CurPtr;
-
-      // Count how many levels deep we are.
-      llvm::SmallString<8> Terminator("*/");
-      while (--Depth != 0)
-        Terminator += "*/";
-
-      const char *EOL = (CurPtr[-1] == '\n') ? (CurPtr - 1) : CurPtr;
-      diagnose(EOL, diag::lex_unterminated_block_comment)
-        .fixItInsert(getSourceLoc(EOL), Terminator);
-      diagnose(StartPtr, diag::lex_comment_start);
-      return;
+      }
     }
   }
 }
@@ -1857,6 +1864,16 @@
   return false;
 }
 
+Lexer::NulCharacterKind Lexer::getNulCharacterKind(const char *Ptr) const {
+  assert(Ptr != nullptr && *Ptr == 0);
+  if (Ptr == CodeCompletionPtr) {
+    return NulCharacterKind::CodeCompletion;
+  }
+  if (Ptr == BufferEnd) {
+    return NulCharacterKind::BufferEnd;
+  }
+  return NulCharacterKind::Embedded;
+}
 
 void Lexer::tryLexEditorPlaceholder() {
   assert(CurPtr[-1] == '<' && CurPtr[0] == '#');
@@ -2164,22 +2181,23 @@
     return formToken(tok::unknown, TokStart);
 
   case 0:
-    if (CurPtr-1 == CodeCompletionPtr)
+    switch (getNulCharacterKind(CurPtr - 1)) {
+    case NulCharacterKind::CodeCompletion:
       return formToken(tok::code_complete, TokStart);
 
-    // If this is a random nul character in the middle of a buffer, skip it as
-    // whitespace.
-    if (CurPtr-1 != BufferEnd) {
+    case NulCharacterKind::Embedded:
+      // If this is a random nul character in the middle of a buffer, skip it as
+      // whitespace.
       diagnoseEmbeddedNul(Diags, CurPtr-1);
       goto Restart;
+    case NulCharacterKind::BufferEnd:
+      // Otherwise, this is the real end of the buffer.  Put CurPtr back into
+      // buffer bounds.
+      --CurPtr;
+      // Return EOF.
+      return formToken(tok::eof, TokStart);
     }
 
-    // Otherwise, this is the real end of the buffer.  Put CurPtr back into
-    // buffer bounds.
-    --CurPtr;
-    // Return EOF.
-    return formToken(tok::eof, TokStart);
-
   case '@': return formToken(tok::at_sign, TokStart);
   case '{': return formToken(tok::l_brace, TokStart);
   case '[': {
@@ -2323,7 +2341,6 @@
 Restart:
   const char *TriviaStart = CurPtr;
 
-  // TODO: Handle random nul('\0') character in the middle of a buffer.
   // TODO: Handle invalid UTF8 sequence which is skipped in lexImpl().
   switch (*CurPtr++) {
   case '\n':
@@ -2403,6 +2420,19 @@
       goto Restart;
     }
     break;
+  case 0:
+    switch (getNulCharacterKind(CurPtr - 1)) {
+    case NulCharacterKind::Embedded: {
+      diagnoseEmbeddedNul(Diags, CurPtr - 1);
+      size_t Length = CurPtr - TriviaStart;
+      Pieces.push_back(TriviaPiece::garbageText({TriviaStart, Length}));
+      goto Restart;
+    }
+    case NulCharacterKind::CodeCompletion:
+    case NulCharacterKind::BufferEnd:
+      break;
+    }
+    break;
   default:
     break;
   }
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 2e8e92b..b2dcd16 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -680,19 +680,20 @@
     break;
   }
 
-  case DAK_Ownership: {
+  case DAK_ReferenceOwnership: {
     // Handle weak/unowned/unowned(unsafe).
-    Ownership Kind = AttrName == "weak" ? Ownership::Weak : Ownership::Unowned;
+    auto Kind = AttrName == "weak" ? ReferenceOwnership::Weak
+                                   : ReferenceOwnership::Unowned;
     SourceLoc EndLoc = Loc;
 
-    if (Kind == Ownership::Unowned && Tok.is(tok::l_paren)) {
+    if (Kind == ReferenceOwnership::Unowned && Tok.is(tok::l_paren)) {
       // Parse an optional specifier after unowned.
       SourceLoc lp = consumeToken(tok::l_paren);
       if (Tok.is(tok::identifier) && Tok.getText() == "safe") {
         consumeToken();
       } else if (Tok.is(tok::identifier) && Tok.getText() == "unsafe") {
         consumeToken();
-        Kind = Ownership::Unmanaged;
+        Kind = ReferenceOwnership::Unmanaged;
       } else {
         diagnose(Tok, diag::attr_unowned_invalid_specifier);
         consumeIf(tok::identifier);
@@ -705,8 +706,8 @@
     }
 
     if (!DiscardAttribute)
-      Attributes.add(new (Context) OwnershipAttr(SourceRange(Loc, EndLoc),
-                                                 Kind));
+      Attributes.add(
+          new (Context) ReferenceOwnershipAttr(SourceRange(Loc, EndLoc), Kind));
     break;
   }
 
@@ -2350,7 +2351,7 @@
         Kind = DAK_AccessControl;
       } else if (Tok.isContextualKeyword("weak") ||
                  Tok.isContextualKeyword("unowned")) {
-        Kind = DAK_Ownership;
+        Kind = DAK_ReferenceOwnership;
       } else if (Tok.isContextualKeyword("optional")) {
         Kind = DAK_Optional;
       } else if (Tok.isContextualKeyword("required")) {
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index c7ae952..65dd272 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2498,20 +2498,21 @@
       // Check for the strength specifier: "weak", "unowned", or
       // "unowned(safe/unsafe)".
       SourceLoc loc;
-      Ownership ownershipKind = Ownership::Strong;
+      auto ownershipKind = ReferenceOwnership::Strong;
       if (Tok.isContextualKeyword("weak")){
         loc = consumeToken(tok::identifier);
-        ownershipKind = Ownership::Weak;
+        ownershipKind = ReferenceOwnership::Weak;
       } else if (Tok.isContextualKeyword("unowned")) {
         loc = consumeToken(tok::identifier);
-        ownershipKind = Ownership::Unowned;
+        ownershipKind = ReferenceOwnership::Unowned;
 
         // Skip over "safe" and "unsafe" if present.
         if (consumeIf(tok::l_paren)) {
           if (Tok.getText() == "safe")
-            ownershipKind = Ownership::Unowned; // FIXME: No "safe" variant.
+            ownershipKind =
+                ReferenceOwnership::Unowned; // FIXME: No "safe" variant.
           else if (Tok.getText() == "unsafe")
-            ownershipKind = Ownership::Unmanaged;
+            ownershipKind = ReferenceOwnership::Unmanaged;
           else
             diagnose(Tok, diag::attr_unowned_invalid_specifier);
           consumeIf(tok::identifier);
@@ -2570,17 +2571,17 @@
       // Create the VarDecl and the PatternBindingDecl for the captured
       // expression.  This uses the parent declcontext (not the closure) since
       // the initializer expression is evaluated before the closure is formed.
-      auto specifierKind = (ownershipKind != Ownership::Weak)
-                         ? VarDecl::Specifier::Let
-                         : VarDecl::Specifier::Var;
+      auto specifierKind = (ownershipKind != ReferenceOwnership::Weak)
+                               ? VarDecl::Specifier::Let
+                               : VarDecl::Specifier::Var;
       auto *VD = new (Context) VarDecl(/*isStatic*/false,
                                        specifierKind,
                                        /*isCaptureList*/true,
                                        nameLoc, name, Type(), CurDeclContext);
 
       // Attributes.
-      if (ownershipKind != Ownership::Strong)
-        VD->getAttrs().add(new (Context) OwnershipAttr(ownershipKind));
+      if (ownershipKind != ReferenceOwnership::Strong)
+        VD->getAttrs().add(new (Context) ReferenceOwnershipAttr(ownershipKind));
 
       auto pattern = new (Context) NamedPattern(VD, /*implicit*/true);
 
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 5044e91..f3c7858 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -45,6 +45,7 @@
 template <typename DF>
 void tokenize(const LangOptions &LangOpts, const SourceManager &SM,
               unsigned BufferID, unsigned Offset, unsigned EndOffset,
+              DiagnosticEngine * Diags,
               CommentRetentionMode RetainComments,
               TriviaRetentionMode TriviaRetention,
               bool TokenizeInterpolatedString, ArrayRef<Token> SplitTokens,
@@ -56,7 +57,7 @@
   if (Offset == 0 && EndOffset == 0)
     EndOffset = SM.getRangeForBuffer(BufferID).getByteLength();
 
-  Lexer L(LangOpts, SM, BufferID, /*Diags=*/nullptr, /*InSILMode=*/false,
+  Lexer L(LangOpts, SM, BufferID, Diags, /*InSILMode=*/false,
           RetainComments, TriviaRetention, Offset, EndOffset);
 
   auto TokComp = [&](const Token &A, const Token &B) {
@@ -260,6 +261,7 @@
 
       std::vector<Token> NewTokens = swift::tokenize(LangOpts, SM, BufID,
                                                      Offset, EndOffset,
+                                                     /*Diags=*/nullptr,
                                                      /*KeepComments=*/true);
       Toks.insert(Toks.end(), NewTokens.begin(), NewTokens.end());
 
@@ -278,12 +280,14 @@
 std::vector<Token> swift::tokenize(const LangOptions &LangOpts,
                                    const SourceManager &SM, unsigned BufferID,
                                    unsigned Offset, unsigned EndOffset,
+                                   DiagnosticEngine *Diags,
                                    bool KeepComments,
                                    bool TokenizeInterpolatedString,
                                    ArrayRef<Token> SplitTokens) {
   std::vector<Token> Tokens;
 
   tokenize(LangOpts, SM, BufferID, Offset, EndOffset,
+           Diags,
            KeepComments ? CommentRetentionMode::ReturnAsTokens
                         : CommentRetentionMode::AttachToNextToken,
            TriviaRetentionMode::WithoutTrivia, TokenizeInterpolatedString,
@@ -299,13 +303,15 @@
 std::vector<std::pair<RC<syntax::RawSyntax>, syntax::AbsolutePosition>>
 swift::tokenizeWithTrivia(const LangOptions &LangOpts, const SourceManager &SM,
                           unsigned BufferID, unsigned Offset,
-                          unsigned EndOffset) {
+                          unsigned EndOffset,
+                          DiagnosticEngine *Diags) {
   std::vector<std::pair<RC<syntax::RawSyntax>, syntax::AbsolutePosition>>
       Tokens;
   syntax::AbsolutePosition RunningPos;
 
   tokenize(
       LangOpts, SM, BufferID, Offset, EndOffset,
+      Diags,
       CommentRetentionMode::AttachToNextToken, TriviaRetentionMode::WithTrivia,
       /*TokenizeInterpolatedString=*/false,
       /*SplitTokens=*/ArrayRef<Token>(),
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index c6cc8c2..da75cf4 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -593,36 +593,43 @@
 
     assert(numEltTypes > 0);
 
-    // If we don't have 'self', we don't need to do anything special.
-    if (!extInfo.hasSelfParam() && !Foreign.Self.isImportAsMember()) {
-      CanType ty = AnyFunctionType::composeInput(M.getASTContext(), params,
-                                                 /*canonicalVararg*/true)
-                      ->getCanonicalType();
+    auto handleParameter = [&](AbstractionPattern pattern,
+                               ParameterTypeFlags paramFlags, CanType ty) {
       CanTupleType tty = dyn_cast<TupleType>(ty);
       // If the abstraction pattern is opaque, and the tuple type is
       // materializable -- if it doesn't contain an l-value type -- then it's
       // a valid target for substitution and we should not expand it.
-      if (!tty || (origType.isTypeParameter() && !tty->hasInOutElement())) {
-        auto flags = (params.size() == 1)
-                   ? params.front().getParameterFlags()
-                   : ParameterTypeFlags();
-        if (flags.isShared()) {
-          visitSharedType(origType, ty, extInfo.getSILRepresentation());
+      auto silExtInfo = extInfo.getSILRepresentation();
+      if (!tty || (pattern.isTypeParameter() && !tty->hasInOutElement())) {
+        if (paramFlags.isShared()) {
+          visitSharedType(pattern, ty, silExtInfo);
         } else {
-          visit(origType, ty);
+          visit(pattern, ty);
         }
         return;
       }
 
       for (auto i : indices(tty.getElementTypes())) {
-        if (tty->getElement(i).getParameterFlags().isShared()) {
-          visitSharedType(origType.getTupleElementType(i),
-                          tty.getElementType(i),
-                          extInfo.getSILRepresentation());
+        auto patternEltTy = pattern.getTupleElementType(i);
+        auto trueEltTy = tty.getElementType(i);
+        auto flags = tty->getElement(i).getParameterFlags();
+        if (flags.isShared()) {
+          visitSharedType(patternEltTy, trueEltTy, silExtInfo);
         } else {
-          visit(origType.getTupleElementType(i), tty.getElementType(i));
+          visit(patternEltTy, trueEltTy);
         }
       }
+    };
+
+    // If we don't have 'self', we don't need to do anything special.
+    if (!extInfo.hasSelfParam() && !Foreign.Self.isImportAsMember()) {
+      CanType ty = AnyFunctionType::composeInput(M.getASTContext(), params,
+                                                 /*canonicalVararg*/true)
+                      ->getCanonicalType();
+      auto flags = (params.size() == 1) ? params.front().getParameterFlags()
+                                        : ParameterTypeFlags();
+
+      handleParameter(origType, flags, ty);
       return;
     }
 
@@ -630,25 +637,11 @@
 
     // Process all the non-self parameters.
     for (unsigned i = 0; i != numNonSelfParams; ++i) {
-      CanType ty =  params[i].getType();
-      CanTupleType tty = dyn_cast<TupleType>(ty);
+      CanType ty = params[i].getType();
       AbstractionPattern eltPattern = origType.getTupleElementType(i);
-      // If the abstraction pattern is opaque, and the tuple type is
-      // materializable -- if it doesn't contain an l-value type -- then it's
-      // a valid target for substitution and we should not expand it.
-      if (!tty || (eltPattern.isTypeParameter() && !tty->hasInOutElement())) {
-        if (params[i].isShared()) {
-          visitSharedType(eltPattern, ty, extInfo.getSILRepresentation());
-        } else {
-          visit(eltPattern, ty);
-        }
-        continue;
-      }
+      auto flags = params[i].getParameterFlags();
 
-      assert(eltPattern.isTuple());
-      for (unsigned j = 0; j < eltPattern.getNumTupleElements(); ++j) {
-        visit(eltPattern.getTupleElementType(j), tty.getElementType(j));
-      }
+      handleParameter(eltPattern, flags, ty);
     }
 
     // Process the self parameter.  Note that we implicitly drop self
diff --git a/lib/SIL/SILPrinter.cpp b/lib/SIL/SILPrinter.cpp
index ab86919..357f728 100644
--- a/lib/SIL/SILPrinter.cpp
+++ b/lib/SIL/SILPrinter.cpp
@@ -2634,7 +2634,7 @@
   }
   
   OS << "\n\nimport Builtin\nimport " << STDLIB_NAME
-     << "\nimport SwiftShims" << "\n\n";
+     << "\nimport " << SWIFT_SHIMS_NAME << "\n\n";
 
   // Print the declarations and types from the associated context (origin module or
   // current file).
diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp
index 74ac49b..e1aa7e4 100644
--- a/lib/SILGen/SILGenLValue.cpp
+++ b/lib/SILGen/SILGenLValue.cpp
@@ -2926,12 +2926,12 @@
   auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
 
   switch (swiftStorageType->getOwnership()) {
-  case Ownership::Weak:
+  case ReferenceOwnership::Weak:
     // Weak storage types are handled with their underlying type.
     llvm_unreachable("weak pointers are always the right optional types");
-  case Ownership::Strong:
+  case ReferenceOwnership::Strong:
     llvm_unreachable("strong reference storage type should be impossible");
-  case Ownership::Unowned: {
+  case ReferenceOwnership::Unowned: {
     // For @unowned(safe) types, we need to generate a strong retain and
     // strip the unowned box.
     auto unownedType = storageType.castTo<UnownedStorageType>();
@@ -2940,7 +2940,7 @@
 
     return B.createCopyUnownedValue(loc, src);
   }
-  case Ownership::Unmanaged: {
+  case ReferenceOwnership::Unmanaged: {
     // For @unowned(unsafe) types, we need to strip the unmanaged box
     // and then do an (unsafe) retain.
     auto unmanagedType = storageType.castTo<UnmanagedStorageType>();
@@ -2957,16 +2957,16 @@
   auto swiftStorageType = src.getType().castTo<ReferenceStorageType>();
 
   switch (swiftStorageType->getOwnership()) {
-  case Ownership::Weak:
+  case ReferenceOwnership::Weak:
     // Weak storage types are handled with their underlying type.
     llvm_unreachable("weak pointers are always the right optional types");
-  case Ownership::Strong:
+  case ReferenceOwnership::Strong:
     llvm_unreachable("strong reference storage type should be impossible");
-  case Ownership::Unowned:
+  case ReferenceOwnership::Unowned:
     // For @unowned(safe) types, we need to generate a strong retain and
     // strip the unowned box.
     return B.createCopyUnownedValue(loc, src);
-  case Ownership::Unmanaged:
+  case ReferenceOwnership::Unmanaged:
     // For @unowned(unsafe) types, we need to strip the unmanaged box
     // and then do an (unsafe) retain.
     return B.createUnsafeCopyUnownedValue(loc, src);
@@ -2985,12 +2985,12 @@
   auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
 
   switch (swiftStorageType->getOwnership()) {
-  case Ownership::Weak: {
+  case ReferenceOwnership::Weak: {
     // For @weak types, we need to create an Optional<T>.
     // Optional<T> is currently loadable, but it probably won't be forever.
     return SGF.B.createLoadWeak(loc, src, isTake);
   }
-  case Ownership::Unowned: {
+  case ReferenceOwnership::Unowned: {
     // For @unowned(safe) types, we need to strip the unowned box.
     auto unownedType = storageType.castTo<UnownedStorageType>();
     if (!unownedType->isLoadable(ResilienceExpansion::Maximal)) {
@@ -3012,7 +3012,7 @@
     SGF.B.createDestroyValue(loc, unownedValue);
     return strongValue;
   }
-  case Ownership::Unmanaged: {
+  case ReferenceOwnership::Unmanaged: {
     // For @unowned(unsafe) types, we need to strip the unmanaged box.
     auto unmanagedType = storageType.castTo<UnmanagedStorageType>();
     auto value = SGF.B.createLoad(loc, src, LoadOwnershipQualifier::Trivial);
@@ -3021,7 +3021,7 @@
     // SEMANTIC ARC TODO: Does this need a cleanup?
     return SGF.B.createCopyValue(loc, result);
   }
-  case Ownership::Strong:
+  case ReferenceOwnership::Strong:
     llvm_unreachable("strong reference storage type should be impossible");
   }
 }
@@ -3039,7 +3039,7 @@
   auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
 
   switch (swiftStorageType->getOwnership()) {
-  case Ownership::Weak: {
+  case ReferenceOwnership::Weak: {
     // For @weak types, we need to break down an Optional<T> and then
     // emit the storeWeak ourselves.
     SGF.B.createStoreWeak(loc, value, dest, isInit);
@@ -3048,7 +3048,7 @@
     SGF.B.emitDestroyValueOperation(loc, value);
     return;
   }
-  case Ownership::Unowned: {
+  case ReferenceOwnership::Unowned: {
     // For @unowned(safe) types, we need to enter the unowned box by
     // turning the strong retain into an unowned retain.
     auto unownedType = storageType.castTo<UnownedStorageType>();
@@ -3068,7 +3068,7 @@
     SGF.B.emitDestroyValueOperation(loc, value);
     return;
   }
-  case Ownership::Unmanaged: {
+  case ReferenceOwnership::Unmanaged: {
     // For @unowned(unsafe) types, we need to enter the unmanaged box and
     // release the strong retain.
     auto unmanagedValue =
@@ -3077,7 +3077,7 @@
     SGF.B.emitDestroyValueOperation(loc, value);
     return;
   }
-  case Ownership::Strong:
+  case ReferenceOwnership::Strong:
     llvm_unreachable("strong reference storage type should be impossible");
   }
 }
@@ -3159,11 +3159,11 @@
 
   auto swiftStorageType = storageType.castTo<ReferenceStorageType>();
   switch (swiftStorageType->getOwnership()) {
-  case Ownership::Weak:
+  case ReferenceOwnership::Weak:
     llvm_unreachable("weak types are never loadable");
-  case Ownership::Strong:
+  case ReferenceOwnership::Strong:
     llvm_unreachable("strong reference storage type should be impossible");
-  case Ownership::Unowned: {
+  case ReferenceOwnership::Unowned: {
     // For @unowned types, place into an unowned box.
     auto unownedType = storageType.castTo<UnownedStorageType>();
     assert(unownedType->isLoadable(ResilienceExpansion::Maximal));
@@ -3174,7 +3174,7 @@
     B.emitDestroyValueOperation(loc, semanticValue);
     return unowned;
   }
-  case Ownership::Unmanaged: {
+  case ReferenceOwnership::Unmanaged: {
     // For @unmanaged types, place into an unmanaged box.
     SILValue unmanaged =
       B.createRefToUnmanaged(loc, semanticValue, storageType);
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index 7ffecf9..2314db6 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -1573,6 +1573,9 @@
       ///
       /// Valid: reabstraction info, InnerResult, OuterResult.
       ReabstractDirectToDirect,
+
+      /// Ignore the next direct inner result, since the outer is 'Void'.
+      IgnoreDirectResult,
     };
 
     Operation(Kind kind) : TheKind(kind) {}
@@ -1717,6 +1720,24 @@
                                     SILResultInfo outerResult,
                                     SILValue optOuterResultAddr);
 
+  void planIgnoredResult(AbstractionPattern innerOrigType,
+                         CanType innerSubstType, PlanData &planData) {
+    if (innerOrigType.isTuple()) {
+      auto innerSubstTuple = cast<TupleType>(innerSubstType);
+      for (unsigned i = 0, n = innerSubstTuple->getNumElements(); i != n; ++i)
+        planIgnoredResult(innerOrigType.getTupleElementType(i),
+                          innerSubstTuple.getElementType(i), planData);
+      return;
+    }
+
+    auto innerResult = claimNextInnerResult(planData);
+    if (innerResult.isFormalIndirect() &&
+        SGF.silConv.isSILIndirect(innerResult))
+      (void)addInnerIndirectResultTemporary(planData, innerResult);
+    else
+      addIgnoreDirectResult();
+  }
+
   /// Claim the next inner result from the plan data.
   SILResultInfo claimNextInnerResult(PlanData &data) {
     return claimNext(data.InnerResults);
@@ -1866,6 +1887,10 @@
     op.OuterOrigType = outerOrigType;
     op.OuterSubstType = outerSubstType;
   }
+
+  void addIgnoreDirectResult() {
+    (void)addOperation(Operation::IgnoreDirectResult);
+  }
 };
 
 } // end anonymous namespace
@@ -1876,6 +1901,13 @@
                          AbstractionPattern outerOrigType,
                          CanType outerSubstType,
                          PlanData &planData) {
+  // Conversion from `() -> T` to `() -> Void` is allowed when
+  // the argument is a closure.
+  if (!innerSubstType->isVoid() && outerSubstType->isVoid()) {
+    planIgnoredResult(innerOrigType, innerSubstType, planData);
+    return;
+  }
+
   // The substituted types must match up in tuple-ness and arity.
   assert(
       isa<TupleType>(innerSubstType) == isa<TupleType>(outerSubstType) ||
@@ -2584,6 +2616,10 @@
     case Operation::InjectOptionalIndirect:
       SGF.B.createInjectEnumAddr(Loc, op.OuterResultAddr, op.SomeDecl);
       continue;
+
+    case Operation::IgnoreDirectResult:
+      (void)claimNext(innerDirectResults);
+      continue;
     }
     llvm_unreachable("bad operation kind");
   }
diff --git a/lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp b/lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp
index 37570d6..6e5c567 100644
--- a/lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp
+++ b/lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp
@@ -2367,9 +2367,7 @@
                             DT, nullptr);
 
       DEBUG(getFunction()->viewCFG());
-    }
 
-    if (HasChanged) {
       // We preserve the dominator tree. Let's invalidate everything
       // else.
       DA->lockInvalidation();
diff --git a/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp b/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
index b36d7a9..7264c14 100644
--- a/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
+++ b/lib/SILOptimizer/Mandatory/AccessEnforcementSelection.cpp
@@ -244,6 +244,20 @@
   // capture and, for some reason, the closure is dead.
 }
 
+// Verify that accesses are not nested before mandatory inlining.
+// Closure captures should also not be nested within an access.
+static void checkUsesOfAccess(BeginAccessInst *access) {
+#ifndef NDEBUG
+  // These conditions are only true prior to mandatory inlining.
+  assert(!access->getFunction()->wasDeserializedCanonical());
+  for (auto *use : access->getUses()) {
+    auto user = use->getUser();
+    assert(!isa<BeginAccessInst>(user));
+    assert(!isa<PartialApplyInst>(user));
+  }
+#endif
+}
+
 void SelectEnforcement::analyzeProjection(ProjectBoxInst *projection) {
   for (auto *use : projection->getUses()) {
     auto user = use->getUser();
@@ -253,6 +267,8 @@
       if (access->getEnforcement() == SILAccessEnforcement::Unknown)
         Accesses.push_back(access);
 
+      checkUsesOfAccess(access);
+
       continue;
     }
     if (isa<PartialApplyInst>(user))
@@ -564,16 +580,26 @@
 void AccessEnforcementSelection::processFunction(SILFunction *F) {
   DEBUG(llvm::dbgs() << "Access Enforcement Selection in " << F->getName()
                      << "\n");
+
+  // This ModuleTransform needs to analyze closures and their parent scopes in
+  // the same pass, and the parent needs to be analyzed before the closure.
 #ifndef NDEBUG
   auto *CSA = getAnalysis<ClosureScopeAnalysis>();
   if (isNonEscapingClosure(F->getLoweredFunctionType())) {
     for (auto *scopeF : CSA->getClosureScopes(F)) {
       DEBUG(llvm::dbgs() << "  Parent scope: " << scopeF->getName() << "\n");
       assert(visited.count(scopeF));
+      // Closures must be defined in the same module as their parent scope.
+      assert(scopeF->wasDeserializedCanonical()
+             == F->wasDeserializedCanonical());
     }
   }
   visited.insert(F);
 #endif
+  // Deserialized functions, which have been mandatory inlined, no longer meet
+  // the structural requirements on access markers required by this pass.
+  if (F->wasDeserializedCanonical())
+    return;
 
   for (auto &bb : *F) {
     for (auto ii = bb.begin(), ie = bb.end(); ii != ie;) {
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 4ed18d5..a66963f 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -2014,8 +2014,8 @@
                                           TVO_CanBindToInOut);
 
         // For weak variables, use Optional<T>.
-        if (auto *OA = var->getAttrs().getAttribute<OwnershipAttr>())
-          if (OA->get() == Ownership::Weak) {
+        if (auto *OA = var->getAttrs().getAttribute<ReferenceOwnershipAttr>())
+          if (OA->get() == ReferenceOwnership::Weak) {
             ty = CS.getTypeChecker().getOptionalType(var->getLoc(), ty);
             if (!ty) return Type();
           }
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index 451f047..f506284 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -1007,14 +1007,32 @@
   // Compare the type variable bindings.
   auto &tc = cs.getTypeChecker();
   for (auto &binding : diff.typeBindings) {
-    // If the type variable isn't one for which we should be looking at the
-    // bindings, don't.
-    if (!binding.typeVar->getImpl().prefersSubtypeBinding())
-      continue;
-
     auto type1 = binding.bindings[idx1];
     auto type2 = binding.bindings[idx2];
 
+    auto &impl = binding.typeVar->getImpl();
+
+    if (auto *locator = impl.getLocator()) {
+      auto path = locator->getPath();
+      if (!path.empty() &&
+          path.back().getKind() == ConstraintLocator::ClosureResult) {
+        // Since we support `() -> T` to `() -> Void` and
+        // `() -> Never` to `() -> T` conversions, it's always
+        // preferable to pick `T` rather than `Never` with
+        // all else being equal.
+        if (type2->isUninhabited())
+          ++score1;
+
+        if (type1->isUninhabited())
+          ++score2;
+      }
+    }
+
+    // If the type variable isn't one for which we should be looking at the
+    // bindings, don't.
+    if (!impl.prefersSubtypeBinding())
+      continue;
+
     // If the types are equivalent, there's nothing more to do.
     if (type1->isEqual(type2))
       continue;
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index a2b3578..e3eddf2 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1212,10 +1212,8 @@
     return result;
 
   // Result type can be covariant (or equal).
-  return matchTypes(func1->getResult(), func2->getResult(), subKind,
-                     subflags,
-                     locator.withPathElement(
-                       ConstraintLocator::FunctionResult));
+  return matchTypes(func1->getResult(), func2->getResult(), subKind, subflags,
+                    locator.withPathElement(ConstraintLocator::FunctionResult));
 }
 
 ConstraintSystem::TypeMatchResult
@@ -1501,6 +1499,8 @@
 ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
                              TypeMatchOptions flags,
                              ConstraintLocatorBuilder locator) {
+  auto origType1 = type1;
+
   bool isArgumentTupleConversion
           = kind == ConstraintKind::ArgumentTupleConversion ||
             kind == ConstraintKind::OperatorArgumentTupleConversion;
@@ -2243,7 +2243,32 @@
   // Allow '() -> T' to '() -> ()' and '() -> Never' to '() -> T' for closure
   // literals.
   if (auto elt = locator.last()) {
-    if (elt->getKind() == ConstraintLocator::ClosureResult) {
+    auto isClosureResult = [&]() {
+      if (elt->getKind() == ConstraintLocator::ClosureResult)
+        return true;
+
+      // If constraint is matching function results where
+      // left-hand side is a 'closure result' we need to allow
+      // certain implicit conversions.
+      if (elt->getKind() != ConstraintLocator::FunctionResult)
+        return false;
+
+      if (auto *typeVar = origType1->getAs<TypeVariableType>()) {
+        auto *locator = typeVar->getImpl().getLocator();
+        if (!locator)
+          return false;
+
+        auto path = locator->getPath();
+        if (path.empty())
+          return false;
+
+        return path.back().getKind() == ConstraintLocator::ClosureResult;
+      }
+
+      return false;
+    };
+
+    if (isClosureResult()) {
       if (concrete && kind >= ConstraintKind::Subtype &&
           (type1->isUninhabited() || type2->isVoid())) {
         increaseScore(SK_FunctionConversion);
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index c2e6c92..0410e3e 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -189,8 +189,8 @@
   void visitConsumingAttr(ConsumingAttr *attr) { visitMutationAttr(attr); }
   void visitDynamicAttr(DynamicAttr *attr);
 
-  void visitOwnershipAttr(OwnershipAttr *attr) {
-    TC.checkOwnershipAttr(cast<VarDecl>(D), attr);
+  void visitReferenceOwnershipAttr(ReferenceOwnershipAttr *attr) {
+    TC.checkReferenceOwnershipAttr(cast<VarDecl>(D), attr);
   }
 
   void visitFinalAttr(FinalAttr *attr) {
@@ -821,8 +821,8 @@
     IGNORED_ATTR(ObjCRuntimeName)
     IGNORED_ATTR(Optional)
     IGNORED_ATTR(Override)
-    IGNORED_ATTR(Ownership)
     IGNORED_ATTR(RawDocComment)
+    IGNORED_ATTR(ReferenceOwnership)
     IGNORED_ATTR(RequiresStoredPropertyInits)
     IGNORED_ATTR(RestatedObjCConformance)
     IGNORED_ATTR(Semantics)
@@ -2106,11 +2106,12 @@
   if (!var->hasType())
     return;
 
-  if (auto *attr = var->getAttrs().getAttribute<OwnershipAttr>())
-    checkOwnershipAttr(var, attr);
+  if (auto *attr = var->getAttrs().getAttribute<ReferenceOwnershipAttr>())
+    checkReferenceOwnershipAttr(var, attr);
 }
 
-void TypeChecker::checkOwnershipAttr(VarDecl *var, OwnershipAttr *attr) {
+void TypeChecker::checkReferenceOwnershipAttr(VarDecl *var,
+                                              ReferenceOwnershipAttr *attr) {
   // Don't check ownership attribute if the declaration is already marked invalid.
   if (var->isInvalid())
     return;
@@ -2127,12 +2128,12 @@
   // A weak variable must have type R? or R! for some ownership-capable type R.
   Type underlyingType = type;
   switch (ownershipKind) {
-  case Ownership::Strong:
+  case ReferenceOwnership::Strong:
     llvm_unreachable("Cannot specify 'strong' in an ownership attribute");
-  case Ownership::Unowned:
-  case Ownership::Unmanaged:
+  case ReferenceOwnership::Unowned:
+  case ReferenceOwnership::Unmanaged:
     break;
-  case Ownership::Weak:
+  case ReferenceOwnership::Weak:
     if (var->isLet()) {
       diagnose(var->getStartLoc(), diag::invalid_weak_let);
       attr->setInvalid();
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 77b6384..d64e9a1 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -6225,13 +6225,15 @@
 
     // If we have an explicit ownership modifier and our parent doesn't,
     // complain.
-    auto parentAttr = matchDecl->getAttrs().getAttribute<OwnershipAttr>();
-    if (auto ownershipAttr = decl->getAttrs().getAttribute<OwnershipAttr>()) {
-      Ownership parentOwnership;
+    auto parentAttr =
+        matchDecl->getAttrs().getAttribute<ReferenceOwnershipAttr>();
+    if (auto ownershipAttr =
+            decl->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
+      ReferenceOwnership parentOwnership;
       if (parentAttr)
         parentOwnership = parentAttr->get();
       else
-        parentOwnership = Ownership::Strong;
+        parentOwnership = ReferenceOwnership::Strong;
       if (parentOwnership != ownershipAttr->get()) {
         TC.diagnose(decl, diag::override_ownership_mismatch,
                     (unsigned)parentOwnership,
@@ -6505,7 +6507,7 @@
     UNINTERESTING_ATTR(Prefix)
     UNINTERESTING_ATTR(Postfix)
     UNINTERESTING_ATTR(Infix)
-    UNINTERESTING_ATTR(Ownership)
+    UNINTERESTING_ATTR(ReferenceOwnership)
 
     UNINTERESTING_ATTR(SynthesizedProtocol)
     UNINTERESTING_ATTR(RequiresStoredPropertyInits)
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 6c69d01..4bfcae2 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -1099,7 +1099,7 @@
       var->setInterfaceType(type->mapTypeOutOfContext());
 
     checkTypeModifyingDeclAttributes(var);
-    if (var->getAttrs().hasAttribute<OwnershipAttr>())
+    if (var->getAttrs().hasAttribute<ReferenceOwnershipAttr>())
       type = var->getType()->getReferenceStorageReferent();
     else if (!var->isInvalid())
       type = var->getType();
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index 879d0e0..1eb9085 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -2854,10 +2854,20 @@
 
     ParameterTypeFlags paramFlags;
     if (isImmediateFunctionInput) {
-      bool isShared = (tyR->getKind() == TypeReprKind::Shared);
-      bool isInOut = (tyR->getKind() == TypeReprKind::InOut);
-      paramFlags = ParameterTypeFlags::fromParameterType(ty, variadic, isShared)
-                     .withInOut(isInOut);
+      ValueOwnership ownership;
+      switch (tyR->getKind()) {
+      case TypeReprKind::Shared:
+        ownership = ValueOwnership::Shared;
+        break;
+      case TypeReprKind::InOut:
+        ownership = ValueOwnership::InOut;
+        break;
+      default:
+        ownership = ValueOwnership::Default;
+        break;
+      }
+      paramFlags =
+          ParameterTypeFlags::fromParameterType(ty, variadic, ownership);
     }
     elements.emplace_back(ty->getInOutObjectType(), name, paramFlags);
   }
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index dd6fddf..61bd01b 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -1318,7 +1318,7 @@
   void checkDeclAttributes(Decl *D);
   void checkTypeModifyingDeclAttributes(VarDecl *var);
 
-  void checkOwnershipAttr(VarDecl *D, OwnershipAttr *attr);
+  void checkReferenceOwnershipAttr(VarDecl *D, ReferenceOwnershipAttr *attr);
 
   void computeAccessLevel(ValueDecl *D);
   void computeDefaultAccessLevel(ExtensionDecl *D);
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index ba1d6ba..8d0c1db 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -2078,6 +2078,24 @@
   return None;
 }
 
+/// Translate from the serialization VarDeclSpecifier enumerators, which are
+/// guaranteed to be stable, to the AST ones.
+static Optional<swift::VarDecl::Specifier>
+getActualVarDeclSpecifier(serialization::VarDeclSpecifier raw) {
+  switch (raw) {
+#define CASE(ID) \
+  case serialization::VarDeclSpecifier::ID: \
+    return swift::VarDecl::Specifier::ID;
+  CASE(Let)
+  CASE(Var)
+  CASE(InOut)
+  CASE(Shared)
+  }
+#undef CASE
+  return None;
+}
+
+
 void ModuleFile::configureStorage(AbstractStorageDecl *decl,
                                   unsigned rawStorageKind,
                                   serialization::DeclID getter,
@@ -2894,7 +2912,7 @@
     DeclContextID contextID;
     bool isImplicit, isObjC, isStatic, hasNonPatternBindingInit;
     bool isGetterMutating, isSetterMutating;
-    unsigned specifier;
+    unsigned rawSpecifier;
     uint8_t storageKind, rawAccessLevel, rawSetterAccessLevel;
     TypeID interfaceTypeID;
     DeclID getterID, setterID, materializeForSetID, willSetID, didSetID;
@@ -2902,7 +2920,7 @@
     ArrayRef<uint64_t> dependencyIDs;
 
     decls_block::VarLayout::readRecord(scratch, nameID, contextID,
-                                       isImplicit, isObjC, isStatic, specifier,
+                                       isImplicit, isObjC, isStatic, rawSpecifier,
                                        hasNonPatternBindingInit,
                                        isGetterMutating, isSetterMutating,
                                        storageKind, interfaceTypeID,
@@ -2954,9 +2972,15 @@
     if (declOrOffset.isComplete())
       return declOrOffset;
 
-    auto var = createDecl<VarDecl>(/*IsStatic*/isStatic,
-                                   (VarDecl::Specifier)specifier,
-                                   /*IsCaptureList*/false, SourceLoc(), name,
+    auto specifier = getActualVarDeclSpecifier(
+        (serialization::VarDeclSpecifier)rawSpecifier);
+    if (!specifier) {
+      error();
+      return nullptr;
+    }
+
+    auto var = createDecl<VarDecl>(/*IsStatic*/ isStatic, *specifier,
+                                   /*IsCaptureList*/ false, SourceLoc(), name,
                                    Type(), DC);
     var->setHasNonPatternBindingInit(hasNonPatternBindingInit);
     var->setIsGetterMutating(isGetterMutating);
@@ -2967,7 +2991,8 @@
     var->setInterfaceType(interfaceType);
 
     if (auto referenceStorage = interfaceType->getAs<ReferenceStorageType>())
-      AddAttribute(new (ctx) OwnershipAttr(referenceStorage->getOwnership()));
+      AddAttribute(
+          new (ctx) ReferenceOwnershipAttr(referenceStorage->getOwnership()));
 
     configureStorage(var, storageKind, getterID, setterID, materializeForSetID,
                      addressorID, mutableAddressorID, willSetID, didSetID);
@@ -3002,18 +3027,25 @@
   case decls_block::PARAM_DECL: {
     IdentifierID argNameID, paramNameID;
     DeclContextID contextID;
-    unsigned specifier;
+    unsigned rawSpecifier;
     TypeID interfaceTypeID;
 
     decls_block::ParamLayout::readRecord(scratch, argNameID, paramNameID,
-                                         contextID, specifier, interfaceTypeID);
+                                         contextID, rawSpecifier,
+                                         interfaceTypeID);
 
     auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
     if (declOrOffset.isComplete())
       return declOrOffset;
 
-    auto param = createDecl<ParamDecl>((VarDecl::Specifier)specifier,
-                                       SourceLoc(), SourceLoc(),
+    auto specifier = getActualVarDeclSpecifier(
+        (serialization::VarDeclSpecifier)rawSpecifier);
+    if (!specifier) {
+      error();
+      return nullptr;
+    }
+
+    auto param = createDecl<ParamDecl>(*specifier, SourceLoc(), SourceLoc(),
                                        getIdentifier(argNameID), SourceLoc(),
                                        getIdentifier(paramNameID), Type(), DC);
 
@@ -3995,15 +4027,35 @@
   }
 }
 
-/// Translate from the serialization Ownership enumerators, which are
+/// Translate from the serialization ReferenceOwnership enumerators, which are
 /// guaranteed to be stable, to the AST ones.
-static
-Optional<swift::Ownership> getActualOwnership(serialization::Ownership raw) {
+static Optional<swift::ReferenceOwnership>
+getActualReferenceOwnership(serialization::ReferenceOwnership raw) {
   switch (raw) {
-  case serialization::Ownership::Strong:   return swift::Ownership::Strong;
-  case serialization::Ownership::Unmanaged:return swift::Ownership::Unmanaged;
-  case serialization::Ownership::Unowned:  return swift::Ownership::Unowned;
-  case serialization::Ownership::Weak:     return swift::Ownership::Weak;
+  case serialization::ReferenceOwnership::Strong:
+    return swift::ReferenceOwnership::Strong;
+  case serialization::ReferenceOwnership::Unmanaged:
+    return swift::ReferenceOwnership::Unmanaged;
+  case serialization::ReferenceOwnership::Unowned:
+    return swift::ReferenceOwnership::Unowned;
+  case serialization::ReferenceOwnership::Weak:
+    return swift::ReferenceOwnership::Weak;
+  }
+  return None;
+}
+
+/// Translate from the serialization ValueOwnership enumerators, which are
+/// guaranteed to be stable, to the AST ones.
+static Optional<swift::ValueOwnership>
+getActualValueOwnership(serialization::ValueOwnership raw) {
+  switch (raw) {
+#define CASE(ID) \
+  case serialization::ValueOwnership::ID: \
+    return swift::ValueOwnership::ID;
+  CASE(Default)
+  CASE(InOut)
+  CASE(Shared)
+#undef CASE
   }
   return None;
 }
@@ -4148,19 +4200,25 @@
 
   case decls_block::PAREN_TYPE: {
     TypeID underlyingID;
-    bool isVariadic, isAutoClosure, isEscaping, isInOut, isShared;
+    bool isVariadic, isAutoClosure, isEscaping;
+    unsigned rawOwnership;
     decls_block::ParenTypeLayout::readRecord(scratch, underlyingID, isVariadic,
                                              isAutoClosure, isEscaping,
-                                             isInOut, isShared);
+                                             rawOwnership);
+    auto ownership =
+        getActualValueOwnership((serialization::ValueOwnership)rawOwnership);
+    if (!ownership) {
+      error();
+      return nullptr;
+    }
 
     auto underlyingTy = getTypeChecked(underlyingID);
     if (!underlyingTy)
       return underlyingTy.takeError();
-    
+
     typeOrOffset = ParenType::get(
         ctx, underlyingTy.get()->getInOutObjectType(),
-        ParameterTypeFlags(isVariadic, isAutoClosure, isEscaping,
-                           isInOut, isShared));
+        ParameterTypeFlags(isVariadic, isAutoClosure, isEscaping, *ownership));
     break;
   }
 
@@ -4180,19 +4238,27 @@
 
       IdentifierID nameID;
       TypeID typeID;
-      bool isVariadic, isAutoClosure, isEscaping, isInOut, isShared;
-      decls_block::TupleTypeEltLayout::readRecord(
-          scratch, nameID, typeID, isVariadic, isAutoClosure, isEscaping,
-          isInOut, isShared);
+      bool isVariadic, isAutoClosure, isEscaping;
+      unsigned rawOwnership;
+      decls_block::TupleTypeEltLayout::readRecord(scratch, nameID, typeID,
+                                                  isVariadic, isAutoClosure,
+                                                  isEscaping, rawOwnership);
+
+      auto ownership =
+          getActualValueOwnership((serialization::ValueOwnership)rawOwnership);
+      if (!ownership) {
+        error();
+        return nullptr;
+      }
 
       auto elementTy = getTypeChecked(typeID);
       if (!elementTy)
         return elementTy.takeError();
-      
-      elements.emplace_back(
-          elementTy.get()->getInOutObjectType(), getIdentifier(nameID),
-          ParameterTypeFlags(isVariadic, isAutoClosure, isEscaping,
-                             isInOut, isShared));
+
+      elements.emplace_back(elementTy.get()->getInOutObjectType(),
+                            getIdentifier(nameID),
+                            ParameterTypeFlags(isVariadic, isAutoClosure,
+                                               isEscaping, *ownership));
     }
 
     typeOrOffset = TupleType::get(elements, ctx);
@@ -4326,8 +4392,8 @@
     decls_block::ReferenceStorageTypeLayout::readRecord(scratch, rawOwnership,
                                                         objectTypeID);
 
-    auto ownership =
-      getActualOwnership((serialization::Ownership) rawOwnership);
+    auto ownership = getActualReferenceOwnership(
+        (serialization::ReferenceOwnership)rawOwnership);
     if (!ownership.hasValue()) {
       error();
       break;
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index e805030..dfeb917 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -2169,7 +2169,7 @@
 
   switch (DA->getKind()) {
   case DAK_RawDocComment:
-  case DAK_Ownership: // Serialized as part of the type.
+  case DAK_ReferenceOwnership: // Serialized as part of the type.
   case DAK_AccessControl:
   case DAK_SetterAccess:
   case DAK_ObjCBridged:
@@ -3478,12 +3478,23 @@
 
 /// Translate from the AST ownership enum to the Serialization enum
 /// values, which are guaranteed to be stable.
-static uint8_t getRawStableOwnership(swift::Ownership ownership) {
+static uint8_t
+getRawStableReferenceOwnership(swift::ReferenceOwnership ownership) {
   switch (ownership) {
-  SIMPLE_CASE(Ownership, Strong)
-  SIMPLE_CASE(Ownership, Weak)
-  SIMPLE_CASE(Ownership, Unowned)
-  SIMPLE_CASE(Ownership, Unmanaged)
+  SIMPLE_CASE(ReferenceOwnership, Strong)
+  SIMPLE_CASE(ReferenceOwnership, Weak)
+  SIMPLE_CASE(ReferenceOwnership, Unowned)
+  SIMPLE_CASE(ReferenceOwnership, Unmanaged)
+  }
+  llvm_unreachable("bad ownership kind");
+}
+/// Translate from the AST ownership enum to the Serialization enum
+/// values, which are guaranteed to be stable.
+static uint8_t getRawStableValueOwnership(swift::ValueOwnership ownership) {
+  switch (ownership) {
+  SIMPLE_CASE(ValueOwnership, Default)
+  SIMPLE_CASE(ValueOwnership, InOut)
+  SIMPLE_CASE(ValueOwnership, Shared)
   }
   llvm_unreachable("bad ownership kind");
 }
@@ -3589,12 +3600,14 @@
   case TypeKind::Paren: {
     auto parenTy = cast<ParenType>(ty.getPointer());
     auto paramFlags = parenTy->getParameterFlags();
+    auto rawOwnership =
+        getRawStableValueOwnership(paramFlags.getValueOwnership());
 
     unsigned abbrCode = DeclTypeAbbrCodes[ParenTypeLayout::Code];
     ParenTypeLayout::emitRecord(
         Out, ScratchRecord, abbrCode, addTypeRef(parenTy->getUnderlyingType()),
         paramFlags.isVariadic(), paramFlags.isAutoClosure(),
-        paramFlags.isEscaping(), paramFlags.isInOut(), paramFlags.isShared());
+        paramFlags.isEscaping(), rawOwnership);
     break;
   }
 
@@ -3607,11 +3620,12 @@
     abbrCode = DeclTypeAbbrCodes[TupleTypeEltLayout::Code];
     for (auto &elt : tupleTy->getElements()) {
       auto paramFlags = elt.getParameterFlags();
+      auto rawOwnership =
+          getRawStableValueOwnership(paramFlags.getValueOwnership());
       TupleTypeEltLayout::emitRecord(
           Out, ScratchRecord, abbrCode, addDeclBaseNameRef(elt.getName()),
           addTypeRef(elt.getType()), paramFlags.isVariadic(),
-          paramFlags.isAutoClosure(), paramFlags.isEscaping(),
-          paramFlags.isInOut(), paramFlags.isShared());
+          paramFlags.isAutoClosure(), paramFlags.isEscaping(), rawOwnership);
     }
 
     break;
@@ -3890,7 +3904,8 @@
     auto refTy = cast<ReferenceStorageType>(ty.getPointer());
 
     unsigned abbrCode = DeclTypeAbbrCodes[ReferenceStorageTypeLayout::Code];
-    auto stableOwnership = getRawStableOwnership(refTy->getOwnership());
+    auto stableOwnership =
+        getRawStableReferenceOwnership(refTy->getOwnership());
     ReferenceStorageTypeLayout::emitRecord(Out, ScratchRecord, abbrCode,
                                            stableOwnership,
                                   addTypeRef(refTy->getReferentType()));
diff --git a/lib/Syntax/CMakeLists.txt b/lib/Syntax/CMakeLists.txt
index d9364f4..2656c05 100644
--- a/lib/Syntax/CMakeLists.txt
+++ b/lib/Syntax/CMakeLists.txt
@@ -1,6 +1,8 @@
-set(line_directive "#line" "%(line)d" "\"%(file)s\"")
-set(SWIFT_GYB_FLAGS
-  --line-directive "'${line_directive}'")
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
+  set(SWIFT_GYB_FLAGS --line-directive "^\"#line %(line)d \\\"%(file)s\\\"^\"")
+else()
+  set(SWIFT_GYB_FLAGS --line-directive "\'#line" "%(line)d" "\"%(file)s\"\'")
+endif()
 
 add_swift_library(swiftSyntax STATIC
   SyntaxNodes.cpp.gyb
diff --git a/stdlib/public/SwiftRemoteMirror/CMakeLists.txt b/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
index bacdf0d..93255e9 100644
--- a/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
+++ b/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
@@ -4,10 +4,15 @@
 # libswiftRemoteMirror.dylib should not have runtime dependencies; it's
 # always built as a shared library.
 if(SWIFT_BUILD_DYNAMIC_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR)
-  add_swift_library(swiftRemoteMirror SHARED TARGET_LIBRARY DONT_EMBED_BITCODE NOSWIFTRT
-      SwiftRemoteMirror.cpp
-      LINK_LIBRARIES swiftReflection
-      C_COMPILE_FLAGS ${SWIFT_RUNTIME_CXX_FLAGS}
-      LINK_FLAGS ${SWIFT_RUNTIME_LINK_FLAGS}
-      INSTALL_IN_COMPONENT swift-remote-mirror)
+  add_swift_library(swiftRemoteMirror
+                    SHARED TARGET_LIBRARY DONT_EMBED_BITCODE NOSWIFTRT
+                    SwiftRemoteMirror.cpp
+                    LINK_LIBRARIES
+                      swiftReflection
+                    C_COMPILE_FLAGS
+                      ${SWIFT_RUNTIME_CXX_FLAGS} -DswiftRemoteMirror_EXPORTS
+                    LINK_FLAGS
+                      ${SWIFT_RUNTIME_LINK_FLAGS}
+                    INSTALL_IN_COMPONENT
+                      swift-remote-mirror)
 endif()
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 6381f3f..ad513ee 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -48,7 +48,7 @@
   CTypes.swift
   DebuggerSupport.swift
   DoubleWidth.swift.gyb
-  DropWhile.swift.gyb
+  DropWhile.swift
   Dump.swift
   EmptyCollection.swift
   Equatable.swift
diff --git a/stdlib/public/core/DropWhile.swift b/stdlib/public/core/DropWhile.swift
new file mode 100644
index 0000000..741808d
--- /dev/null
+++ b/stdlib/public/core/DropWhile.swift
@@ -0,0 +1,257 @@
+//===--- DropWhile.swift - Lazy views for drop(while:) --------*- swift -*-===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+/// A sequence whose elements consist of the elements that follow the initial
+/// consecutive elements of some base sequence that satisfy a given predicate.
+@_fixed_layout // FIXME(sil-serialize-all)
+public struct LazyDropWhileSequence<Base: Sequence> {
+  public typealias Element = Base.Element
+  
+  /// Create an instance with elements `transform(x)` for each element
+  /// `x` of base.
+  @_inlineable // FIXME(sil-serialize-all)
+  @_versioned // FIXME(sil-serialize-all)
+  internal init(_base: Base, predicate: @escaping (Element) -> Bool) {
+    self._base = _base
+    self._predicate = predicate
+  }
+
+  @_versioned // FIXME(sil-serialize-all)
+  internal var _base: Base
+  @_versioned // FIXME(sil-serialize-all)
+  internal let _predicate: (Element) -> Bool
+}
+
+extension LazyDropWhileSequence {
+  /// An iterator over the elements traversed by a base iterator that follow the
+  /// initial consecutive elements that satisfy a given predicate.
+  ///
+  /// This is the associated iterator for the `LazyDropWhileSequence`,
+  /// `LazyDropWhileCollection`, and `LazyDropWhileBidirectionalCollection`
+  /// types.
+  @_fixed_layout // FIXME(sil-serialize-all)
+  public struct Iterator {
+    public typealias Element = Base.Element
+    
+    @_inlineable // FIXME(sil-serialize-all)
+    @_versioned // FIXME(sil-serialize-all)
+    internal init(_base: Base.Iterator, predicate: @escaping (Element) -> Bool) {
+      self._base = _base
+      self._predicate = predicate
+    }
+
+    @_versioned // FIXME(sil-serialize-all)
+    internal var _predicateHasFailed = false
+    @_versioned // FIXME(sil-serialize-all)
+    internal var _base: Base.Iterator
+    @_versioned // FIXME(sil-serialize-all)
+    internal let _predicate: (Element) -> Bool
+  }
+}
+
+extension LazyDropWhileSequence.Iterator: IteratorProtocol {
+  @_inlineable // FIXME(sil-serialize-all)
+  public mutating func next() -> Element? {
+    // Once the predicate has failed for the first time, the base iterator
+    // can be used for the rest of the elements.
+    if _predicateHasFailed {
+      return _base.next()
+    }
+
+    // Retrieve and discard elements from the base iterator until one fails
+    // the predicate.
+    while let nextElement = _base.next() {
+      if !_predicate(nextElement) {
+        _predicateHasFailed = true
+        return nextElement
+      }
+    }
+    return nil
+  }  
+}
+
+extension LazyDropWhileSequence: Sequence {
+  public typealias SubSequence = AnySequence<Element> // >:(
+
+  /// Returns an iterator over the elements of this sequence.
+  ///
+  /// - Complexity: O(1).
+  @_inlineable // FIXME(sil-serialize-all)
+  public func makeIterator() -> Iterator {
+    return Iterator(_base: _base.makeIterator(), predicate: _predicate)
+  }
+}
+
+extension LazyDropWhileSequence: LazySequenceProtocol {
+  public typealias Elements = LazyDropWhileSequence
+}
+
+extension LazySequenceProtocol {
+  /// Returns a lazy sequence that skips any initial elements that satisfy
+  /// `predicate`.
+  ///
+  /// - Parameter predicate: A closure that takes an element of the sequence as
+  ///   its argument and returns `true` if the element should be skipped or
+  ///   `false` otherwise. Once `predicate` returns `false` it will not be
+  ///   called again.
+  @_inlineable // FIXME(sil-serialize-all)
+  public func drop(
+    while predicate: @escaping (Elements.Element) -> Bool
+  ) -> LazyDropWhileSequence<Self.Elements> {
+    return LazyDropWhileSequence(_base: self.elements, predicate: predicate)
+  }
+}
+
+/// A lazy wrapper that includes the elements of an underlying
+/// collection after any initial consecutive elements that satisfy a
+/// predicate.
+///
+/// - Note: The performance of accessing `startIndex`, `first`, or any methods
+///   that depend on `startIndex` depends on how many elements satisfy the
+///   predicate at the start of the collection, and may not offer the usual
+///   performance given by the `Collection` protocol. Be aware, therefore,
+///   that general operations on lazy collections may not have the
+///   documented complexity.
+@_fixed_layout // FIXME(sil-serialize-all)
+public struct LazyDropWhileCollection<Base: Collection> {
+  public typealias Element = Base.Element
+  
+  @_inlineable // FIXME(sil-serialize-all)
+  @_versioned // FIXME(sil-serialize-all)
+  internal init(_base: Base, predicate: @escaping (Element) -> Bool) {
+    self._base = _base
+    self._predicate = predicate
+  }
+
+  @_versioned // FIXME(sil-serialize-all)
+  internal var _base: Base
+  @_versioned // FIXME(sil-serialize-all)
+  internal let _predicate: (Element) -> Bool
+}
+
+extension LazyDropWhileCollection: Sequence {
+  public typealias Iterator = LazyDropWhileSequence<Base>.Iterator
+  
+  /// Returns an iterator over the elements of this sequence.
+  ///
+  /// - Complexity: O(1).
+  @_inlineable // FIXME(sil-serialize-all)
+  public func makeIterator() -> Iterator {
+    return Iterator(_base: _base.makeIterator(), predicate: _predicate)
+  }
+}
+
+extension LazyDropWhileCollection {
+  public typealias SubSequence = Slice<LazyDropWhileCollection<Base>>
+
+  /// A position in a `LazyDropWhileCollection` or
+  /// `LazyDropWhileBidirectionalCollection` instance.
+  @_fixed_layout // FIXME(sil-serialize-all)
+  public struct Index {
+    /// The position corresponding to `self` in the underlying collection.
+    public let base: Base.Index
+
+    @_inlineable // FIXME(sil-serialize-all)
+    @_versioned // FIXME(sil-serialize-all)
+    internal init(_base: Base.Index) {
+      self.base = _base
+    }
+  }
+}
+
+extension LazyDropWhileCollection.Index: Equatable, Comparable {
+  @_inlineable // FIXME(sil-serialize-all)
+  public static func == (
+    lhs: LazyDropWhileCollection<Base>.Index,
+    rhs: LazyDropWhileCollection<Base>.Index
+  ) -> Bool {
+    return lhs.base == rhs.base
+  }
+
+  @_inlineable // FIXME(sil-serialize-all)
+  public static func < (
+    lhs: LazyDropWhileCollection<Base>.Index,
+    rhs: LazyDropWhileCollection<Base>.Index
+  ) -> Bool {
+    return lhs.base < rhs.base
+  }
+}
+
+extension LazyDropWhileCollection.Index: Hashable where Base.Index: Hashable {
+  public var hashValue: Int {
+    return base.hashValue
+  }
+}
+
+extension LazyDropWhileCollection: Collection {
+  @_inlineable // FIXME(sil-serialize-all)
+  public var startIndex: Index {
+    var index = _base.startIndex
+    while index != _base.endIndex && _predicate(_base[index]) {
+      _base.formIndex(after: &index)
+    }
+    return Index(_base: index)
+  }
+
+  @_inlineable // FIXME(sil-serialize-all)
+  public var endIndex: Index {
+    return Index(_base: _base.endIndex)
+  }
+
+  @_inlineable // FIXME(sil-serialize-all)
+  public func index(after i: Index) -> Index {
+    _precondition(i.base < _base.endIndex, "Can't advance past endIndex")
+    return Index(_base: _base.index(after: i.base))
+  }
+
+
+  @_inlineable // FIXME(sil-serialize-all)
+  public subscript(position: Index) -> Element {
+    return _base[position.base]
+  }
+}
+
+extension LazyDropWhileCollection: LazyCollectionProtocol { }
+
+extension LazyDropWhileCollection: BidirectionalCollection 
+where Base: BidirectionalCollection {
+  @_inlineable // FIXME(sil-serialize-all)
+  public func index(before i: Index) -> Index {
+    _precondition(i > startIndex, "Can't move before startIndex")
+    return Index(_base: _base.index(before: i.base))
+  }
+}
+
+extension LazyCollectionProtocol {
+  /// Returns a lazy collection that skips any initial elements that satisfy
+  /// `predicate`.
+  ///
+  /// - Parameter predicate: A closure that takes an element of the collection
+  ///   as its argument and returns `true` if the element should be skipped or
+  ///   `false` otherwise. Once `predicate` returns `false` it will not be
+  ///   called again.
+  @_inlineable // FIXME(sil-serialize-all)
+  public func drop(
+    while predicate: @escaping (Elements.Element) -> Bool
+  ) -> LazyDropWhileCollection<Self.Elements> {
+    return LazyDropWhileCollection(
+      _base: self.elements, predicate: predicate)
+  }
+}
+
+@available(*, deprecated, renamed: "LazyDropWhileSequence.Iterator")
+public typealias LazyDropWhileIterator<T> = LazyDropWhileSequence<T>.Iterator where T: Sequence
+@available(*, deprecated, renamed: "LazyDropWhileCollection.Index")
+public typealias LazyDropWhileIndex<T> = LazyDropWhileCollection<T>.Index where T: Collection
+@available(*, deprecated, renamed: "LazyDropWhileCollection")
+public typealias LazyDropWhileBidirectionalCollection<T> = LazyDropWhileCollection<T> where T: BidirectionalCollection
+
diff --git a/stdlib/public/core/DropWhile.swift.gyb b/stdlib/public/core/DropWhile.swift.gyb
deleted file mode 100644
index c15e285..0000000
--- a/stdlib/public/core/DropWhile.swift.gyb
+++ /dev/null
@@ -1,252 +0,0 @@
-//===--- DropWhile.swift.gyb - Lazy views for drop(while:) ----*- swift -*-===//
-//
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See https://swift.org/LICENSE.txt for license information
-// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-//===----------------------------------------------------------------------===//
-
-%{
-from gyb_stdlib_support import (
-    TRAVERSALS,
-    collectionForTraversal
-)
-}%
-
-//===--- Iterator & Sequence ----------------------------------------------===//
-
-/// An iterator over the elements traversed by a base iterator that follow the
-/// initial consecutive elements that satisfy a given predicate.
-///
-/// This is the associated iterator for the `LazyDropWhileSequence`,
-/// `LazyDropWhileCollection`, and `LazyDropWhileBidirectionalCollection`
-/// types.
-@_fixed_layout // FIXME(sil-serialize-all)
-public struct LazyDropWhileIterator<Base : IteratorProtocol> :
-  IteratorProtocol, Sequence {
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public mutating func next() -> Base.Element? {
-    // Once the predicate has failed for the first time, the base iterator
-    // can be used for the rest of the elements.
-    if _predicateHasFailed {
-      return _base.next()
-    }
-
-    // Retrieve and discard elements from the base iterator until one fails
-    // the predicate.
-    while let nextElement = _base.next() {
-      if !_predicate(nextElement) {
-        _predicateHasFailed = true
-        return nextElement
-      }
-    }
-    return nil
-  }
-
-  @_inlineable // FIXME(sil-serialize-all)
-  @_versioned // FIXME(sil-serialize-all)
-  internal init(_base: Base, predicate: @escaping (Base.Element) -> Bool) {
-    self._base = _base
-    self._predicate = predicate
-  }
-
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _predicateHasFailed = false
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _base: Base
-  @_versioned // FIXME(sil-serialize-all)
-  internal let _predicate: (Base.Element) -> Bool
-}
-
-/// A sequence whose elements consist of the elements that follow the initial
-/// consecutive elements of some base sequence that satisfy a given predicate.
-@_fixed_layout // FIXME(sil-serialize-all)
-public struct LazyDropWhileSequence<Base : Sequence> : LazySequenceProtocol {
-
-  public typealias Elements = LazyDropWhileSequence
-
-  /// Returns an iterator over the elements of this sequence.
-  ///
-  /// - Complexity: O(1).
-  @_inlineable // FIXME(sil-serialize-all)
-  public func makeIterator() -> LazyDropWhileIterator<Base.Iterator> {
-    return LazyDropWhileIterator(
-      _base: _base.makeIterator(), predicate: _predicate)
-  }
-
-  /// Create an instance with elements `transform(x)` for each element
-  /// `x` of base.
-  @_inlineable // FIXME(sil-serialize-all)
-  @_versioned // FIXME(sil-serialize-all)
-  internal init(_base: Base, predicate: @escaping (Base.Element) -> Bool) {
-    self._base = _base
-    self._predicate = predicate
-  }
-
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _base: Base
-  @_versioned // FIXME(sil-serialize-all)
-  internal let _predicate: (Base.Element) -> Bool
-}
-
-extension LazySequenceProtocol {
-  /// Returns a lazy sequence that skips any initial elements that satisfy
-  /// `predicate`.
-  ///
-  /// - Parameter predicate: A closure that takes an element of the sequence as
-  ///   its argument and returns `true` if the element should be skipped or
-  ///   `false` otherwise. Once `predicate` returns `false` it will not be
-  ///   called again.
-  @_inlineable // FIXME(sil-serialize-all)
-  public func drop(
-    while predicate: @escaping (Elements.Element) -> Bool
-  ) -> LazyDropWhileSequence<Self.Elements> {
-    return LazyDropWhileSequence(_base: self.elements, predicate: predicate)
-  }
-}
-
-//===--- Collections ------------------------------------------------------===//
-
-/// A position in a `LazyDropWhileCollection` or
-/// `LazyDropWhileBidirectionalCollection` instance.
-@_fixed_layout // FIXME(sil-serialize-all)
-public struct LazyDropWhileIndex<Base : Collection> : Comparable {
-  /// The position corresponding to `self` in the underlying collection.
-  public let base: Base.Index
-
-  @_inlineable // FIXME(sil-serialize-all)
-  @_versioned // FIXME(sil-serialize-all)
-  internal init(base: Base.Index) {
-    self.base = base
-  }
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public static func == (
-    lhs: LazyDropWhileIndex, rhs: LazyDropWhileIndex
-  ) -> Bool {
-    return lhs.base == rhs.base
-  }
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public static func < (
-    lhs: LazyDropWhileIndex, rhs: LazyDropWhileIndex
-  ) -> Bool {
-    return lhs.base < rhs.base
-  }
-}
-
-extension LazyDropWhileIndex : Hashable where Base.Index : Hashable {
-  public var hashValue: Int {
-    return base.hashValue
-  }
-}
-
-% for Traversal in ['Forward', 'Bidirectional']:
-%   Collection = collectionForTraversal(Traversal)
-%   Self = "LazyDropWhile" + Collection
-
-/// A lazy `${Collection}` wrapper that includes the elements of an underlying
-/// collection after any initial consecutive elements that satisfy a
-/// predicate.
-///
-/// - Note: The performance of accessing `startIndex`, `first`, or any methods
-///   that depend on `startIndex` depends on how many elements satisfy the
-///   predicate at the start of the collection, and may not offer the usual
-///   performance given by the `Collection` protocol. Be aware, therefore,
-///   that general operations on `${Self}` instances may not have the
-///   documented complexity.
-@_fixed_layout // FIXME(sil-serialize-all)
-public struct ${Self}<
-  Base : ${Collection}
-> : LazyCollectionProtocol, ${Collection} {
-
-  // FIXME(compiler limitation): should be inferable.
-  public typealias Index = LazyDropWhileIndex<Base>
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public var startIndex: Index {
-    var index = _base.startIndex
-    while index != _base.endIndex && _predicate(_base[index]) {
-      _base.formIndex(after: &index)
-    }
-    return LazyDropWhileIndex(base: index)
-  }
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public var endIndex: Index {
-    return LazyDropWhileIndex(base: _base.endIndex)
-  }
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public func index(after i: Index) -> Index {
-    _precondition(i.base < _base.endIndex, "Can't advance past endIndex")
-    return LazyDropWhileIndex(base: _base.index(after: i.base))
-  }
-
-%   if Traversal == 'Bidirectional':
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public func index(before i: Index) -> Index {
-    _precondition(i > startIndex, "Can't move before startIndex")
-    return LazyDropWhileIndex(base: _base.index(before: i.base))
-  }
-
-%   end
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public subscript(position: Index) -> Base.Element {
-    return _base[position.base]
-  }
-
-  @_inlineable // FIXME(sil-serialize-all)
-  public func makeIterator() -> LazyDropWhileIterator<Base.Iterator> {
-    return LazyDropWhileIterator(
-      _base: _base.makeIterator(), predicate: _predicate)
-  }
-
-  @_inlineable // FIXME(sil-serialize-all)
-  @_versioned // FIXME(sil-serialize-all)
-  internal init(_base: Base, predicate: @escaping (Base.Element) -> Bool) {
-    self._base = _base
-    self._predicate = predicate
-  }
-
-  @_versioned // FIXME(sil-serialize-all)
-  internal var _base: Base
-  @_versioned // FIXME(sil-serialize-all)
-  internal let _predicate: (Base.Element) -> Bool
-}
-
-extension LazyCollectionProtocol
-%   if Collection != 'Collection':
-  where
-  Self : ${Collection},
-Elements : ${Collection}
-%   end
-{
-  /// Returns a lazy collection that skips any initial elements that satisfy
-  /// `predicate`.
-  ///
-  /// - Parameter predicate: A closure that takes an element of the collection
-  ///   as its argument and returns `true` if the element should be skipped or
-  ///   `false` otherwise. Once `predicate` returns `false` it will not be
-  ///   called again.
-  @_inlineable // FIXME(sil-serialize-all)
-  public func drop(
-    while predicate: @escaping (Elements.Element) -> Bool
-  ) -> LazyDropWhile${Collection}<Self.Elements> {
-    return LazyDropWhile${Collection}(
-      _base: self.elements, predicate: predicate)
-  }
-}
-
-% end
-
-// ${'Local Variables'}:
-// eval: (read-only-mode 1)
-// End:
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index 4f69a62..76bc9ca 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -884,8 +884,8 @@
 # operator:
 #     +   unsafeAdding(_:)
 #     -   unsafeSubtracting(_:)
-#     *   unsafeMultiplying(_:)
-#     /   unsafeDividing(by:)
+#     *   unsafeMultiplied(by:)
+#     /   unsafeDivided(by:)
 def unsafeOperationComment(operator):
     comments = {
         '+': """\
diff --git a/stdlib/public/core/PrefixWhile.swift b/stdlib/public/core/PrefixWhile.swift
index 9b5ca63..92a627d 100644
--- a/stdlib/public/core/PrefixWhile.swift
+++ b/stdlib/public/core/PrefixWhile.swift
@@ -74,6 +74,8 @@
 }
 
 extension LazyPrefixWhileSequence: Sequence {
+  public typealias SubSequence = AnySequence<Element> // >:(
+  
   @_inlineable // FIXME(sil-serialize-all)
   public func makeIterator() -> Iterator {
     return Iterator(_base: _base.makeIterator(), predicate: _predicate)
@@ -112,6 +114,7 @@
 @_fixed_layout // FIXME(sil-serialize-all)
 public struct LazyPrefixWhileCollection<Base: Collection> {
   public typealias Element = Base.Element
+  public typealias SubSequence = Slice<LazyPrefixWhileCollection<Base>>
   
   @_inlineable // FIXME(sil-serialize-all)
   @_versioned // FIXME(sil-serialize-all)
diff --git a/stdlib/public/core/RangeReplaceableCollection.swift b/stdlib/public/core/RangeReplaceableCollection.swift
index 8e35596..5b42713 100644
--- a/stdlib/public/core/RangeReplaceableCollection.swift
+++ b/stdlib/public/core/RangeReplaceableCollection.swift
@@ -832,6 +832,7 @@
   public mutating func removeLast() -> Element {
     _precondition(!isEmpty, "Can't remove last element from an empty collection")
     // NOTE if you change this implementation, change popLast above as well
+    // AND change the tie-breaker implementations in the next extension
     if let result = _customRemoveLast() { return result }
     return remove(at: index(before: endIndex))
   }
@@ -865,10 +866,27 @@
   }
 }
 
-// FIXME: swift-3-indexing-model: file a bug for the compiler?
 /// Ambiguity breakers.
 extension RangeReplaceableCollection
-  where Self : BidirectionalCollection, SubSequence == Self {
+where Self : BidirectionalCollection, SubSequence == Self {
+  /// Removes and returns the last element of the collection.
+  ///
+  /// Calling this method may invalidate all saved indices of this
+  /// collection. Do not rely on a previously stored index value after
+  /// altering a collection with any operation that can change its length.
+  ///
+  /// - Returns: The last element of the collection if the collection is not
+  /// empty; otherwise, `nil`.
+  ///
+  /// - Complexity: O(1)
+  @_inlineable
+  public mutating func popLast() -> Element? {
+    if isEmpty { return nil }
+    // duplicate of removeLast logic below, to avoid redundant precondition
+    if let result = _customRemoveLast() { return result }
+    return remove(at: index(before: endIndex))
+  }
+
   /// Removes and returns the last element of the collection.
   ///
   /// The collection must not be empty.
@@ -884,9 +902,8 @@
   @discardableResult
   public mutating func removeLast() -> Element {
     _precondition(!isEmpty, "Can't remove last element from an empty collection")
-    if let result = _customRemoveLast() {
-      return result
-    }
+    // NOTE if you change this implementation, change popLast above as well
+    if let result = _customRemoveLast() { return result }
     return remove(at: index(before: endIndex))
   }
 
diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp
index c551c89..a023d4a 100644
--- a/stdlib/public/runtime/Casting.cpp
+++ b/stdlib/public/runtime/Casting.cpp
@@ -75,7 +75,7 @@
     auto classType = static_cast<const ClassMetadata *>(type);
     // Look through artificial subclasses.
     while (classType->isTypeMetadata() && classType->isArtificialSubclass())
-      classType = classType->SuperClass;
+      classType = classType->Superclass;
 
     // Ask the Objective-C runtime to name ObjC classes.
     if (!classType->isTypeMetadata()) {
@@ -262,7 +262,7 @@
     if (sourceType == targetType) {
       return sourceType;
     }
-    sourceType = sourceType->SuperClass;
+    sourceType = sourceType->Superclass;
   } while (sourceType);
   
   return nullptr;
@@ -3228,7 +3228,7 @@
 const Metadata *swift::_swift_class_getSuperclass(const Metadata *theClass) {
   if (const ClassMetadata *classType = theClass->getClassObject())
     if (classHasSuperclass(classType))
-      return getMetadataForClass(classType->SuperClass);
+      return getMetadataForClass(classType->Superclass);
   return nullptr;
 }
 
diff --git a/stdlib/public/runtime/Demangle.cpp b/stdlib/public/runtime/Demangle.cpp
index 0cf3b33..af0d7fe 100644
--- a/stdlib/public/runtime/Demangle.cpp
+++ b/stdlib/public/runtime/Demangle.cpp
@@ -263,7 +263,7 @@
 #if SWIFT_OBJC_INTEROP
     // Peek through artificial subclasses.
     while (classType->isTypeMetadata() && classType->isArtificialSubclass())
-      classType = classType->SuperClass;
+      classType = classType->Superclass;
 #endif
     description = classType->getDescription();
     break;
diff --git a/stdlib/public/runtime/ErrorObjectNative.cpp b/stdlib/public/runtime/ErrorObjectNative.cpp
index 7d8ef2d..1b1a8ae 100644
--- a/stdlib/public/runtime/ErrorObjectNative.cpp
+++ b/stdlib/public/runtime/ErrorObjectNative.cpp
@@ -61,7 +61,7 @@
 /// Heap metadata for Error boxes.
 static const FullMetadata<HeapMetadata> ErrorMetadata{
   HeapMetadataHeader{{_destroyErrorObject}, {&VALUE_WITNESS_SYM(Bo)}},
-  Metadata{MetadataKind::ErrorObject},
+  HeapMetadata(MetadataKind::ErrorObject),
 };
 
 BoxPair
diff --git a/stdlib/public/runtime/HeapObject.cpp b/stdlib/public/runtime/HeapObject.cpp
index 6fa1417..c4a78d2 100644
--- a/stdlib/public/runtime/HeapObject.cpp
+++ b/stdlib/public/runtime/HeapObject.cpp
@@ -658,10 +658,10 @@
     }
 #endif
 
-    if (auto fn = classMetadata->getIVarDestroyer())
-      fn(object);
+    if (classMetadata->IVarDestroyer)
+      classMetadata->IVarDestroyer(object);
 
-    classMetadata = classMetadata->SuperClass->getClassObject();
+    classMetadata = classMetadata->Superclass->getClassObject();
     assert(classMetadata && "Given metatype not a superclass of object type?");
   }
 
@@ -671,7 +671,7 @@
   if (!usesNativeSwiftReferenceCounting(classMetadata)) {
     // Find the pure Objective-C superclass.
     while (!classMetadata->isPureObjC())
-      classMetadata = classMetadata->SuperClass->getClassObject();
+      classMetadata = classMetadata->Superclass->getClassObject();
 
     // Set the class to the pure Objective-C superclass, so that when dealloc
     // runs, it starts at that superclass.
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index cb874d8..049e67f 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -74,6 +74,92 @@
 
 static const size_t ValueTypeMetadataAddressPoint = sizeof(TypeMetadataHeader);
 
+static ClassMetadataBounds
+computeMetadataBoundsForSuperclass(const void *ref,
+                                   TypeMetadataRecordKind refKind) {
+  switch (refKind) {
+  case TypeMetadataRecordKind::IndirectNominalTypeDescriptor: {
+    auto description = *reinterpret_cast<const ClassDescriptor * const *>(ref);
+    if (!description) {
+      swift::fatalError(0, "instantiating class metadata for class with "
+                           "missing weak-linked ancestor");
+    }
+    return description->getMetadataBounds();
+  }
+
+  case TypeMetadataRecordKind::DirectNominalTypeDescriptor: {
+    auto description = reinterpret_cast<const ClassDescriptor *>(ref);
+    return description->getMetadataBounds();
+  }
+
+  case TypeMetadataRecordKind::IndirectObjCClass:
+#if SWIFT_OBJC_INTEROP
+    {
+      auto cls = *reinterpret_cast<const Class *>(ref);
+      cls = swift_getInitializedObjCClass(cls);
+      auto metadata = reinterpret_cast<const ClassMetadata *>(cls);
+      return metadata->getClassBoundsAsSwiftSuperclass();
+    }
+#else
+    // fallthrough
+#endif
+
+  case TypeMetadataRecordKind::Reserved:
+    break;
+  }
+  swift_runtime_unreachable("unsupported superclass reference kind");
+}
+
+static ClassMetadataBounds computeMetadataBoundsFromSuperclass(
+                                      const ClassDescriptor *description,
+                                      StoredClassMetadataBounds &storedBounds) {
+  ClassMetadataBounds bounds;
+
+  // Compute the bounds for the superclass, extending it to the minimum
+  // bounds of a Swift class.
+  if (const void *superRef = description->Superclass.get()) {
+    bounds = computeMetadataBoundsForSuperclass(superRef,
+                                     description->getSuperclassReferenceKind());
+  } else {
+    bounds = ClassMetadataBounds::forSwiftRootClass();
+  }
+
+  // Add the subclass's immediate members.
+  bounds.adjustForSubclass(description->areImmediateMembersNegative(),
+                           description->NumImmediateMembers);
+
+  // Cache before returning.
+  storedBounds.initialize(bounds);
+  return bounds;
+}
+
+ClassMetadataBounds
+swift::getResilientMetadataBounds(const ClassDescriptor *description) {
+  assert(description->hasResilientSuperclass());
+  auto &storedBounds = *description->ResilientMetadataBounds.get();
+
+  ClassMetadataBounds bounds;
+  if (storedBounds.tryGet(bounds)) {
+    return bounds;
+  }
+
+  return computeMetadataBoundsFromSuperclass(description, storedBounds);
+}
+
+int32_t
+swift::getResilientImmediateMembersOffset(const ClassDescriptor *description) {
+  assert(description->hasResilientSuperclass());
+  auto &storedBounds = *description->ResilientMetadataBounds.get();
+
+  ptrdiff_t result;
+  if (storedBounds.tryGetImmediateMembersOffset(result)) {
+    return result / sizeof(void*);
+  }
+
+  auto bounds = computeMetadataBoundsFromSuperclass(description, storedBounds);
+  return bounds.ImmediateMembersOffset / sizeof(void*);
+}
+
 namespace {
   struct GenericCacheEntry;
 
@@ -94,9 +180,7 @@
 
     size_t getNumArguments() const { return NumArguments; }
 
-    static GenericCacheEntry *getFromMetadata(
-                            const TypeGenericContextDescriptorHeader &generics,
-                                              Metadata *metadata) {
+    static GenericCacheEntry *getFromMetadata(Metadata *metadata) {
       char *bytes = (char*) metadata;
       if (auto classType = dyn_cast<ClassMetadata>(metadata)) {
         assert(classType->isTypeMetadata());
@@ -142,65 +226,148 @@
   return lazyCache->unsafeGetAlreadyInitialized();
 }
 
+#if SWIFT_OBJC_INTEROP
+extern "C" void *_objc_empty_cache;
+#endif
+
+static void
+initializeClassMetadataFromPattern(ClassMetadata *metadata,
+                                   ClassMetadataBounds bounds,
+                                   const ClassDescriptor *description,
+                                   const GenericClassMetadataPattern *pattern) {
+  auto fullMetadata = asFullMetadata(metadata);
+  char *rawMetadata = reinterpret_cast<char*>(metadata);
+
+  // Install the extra-data pattern.
+  void **metadataExtraData =
+    reinterpret_cast<void**>(rawMetadata) + bounds.PositiveSizeInWords;
+  memcpy(metadataExtraData, pattern->getExtraDataPattern(),
+         size_t(pattern->NumExtraDataWords) * sizeof(void*));
+
+  // Install the immediate members pattern:
+  void **immediateMembers =
+    reinterpret_cast<void**>(rawMetadata + bounds.ImmediateMembersOffset);
+
+  // Zero out the entire immediate-members section.
+  // TODO: only memset the parts that aren't covered by the pattern.
+  memset(immediateMembers, 0, description->getImmediateMembersSize());
+
+  // Copy the immediate-members pattern.
+  if (auto immediateSize = pattern->ImmediateMembersPattern_Size) {
+    memcpy(immediateMembers + pattern->ImmediateMembersPattern_TargetOffset,
+           pattern->getImmediateMembersPattern(),
+           size_t(immediateSize) * sizeof(void*));
+  }
+
+  // Initialize the header:
+
+  // Heap destructor.
+  fullMetadata->destroy = pattern->Destroy;
+
+  // Value witness table.
+#if SWIFT_OBJC_INTEROP
+  fullMetadata->ValueWitnesses =
+    (pattern->Flags & ClassFlags::UsesSwiftRefcounting)
+       ? &VALUE_WITNESS_SYM(Bo)
+       : &VALUE_WITNESS_SYM(BO);
+#else
+  fullMetadata->ValueWitnesses = &VALUE_WITNESS_SYM(Bo);
+#endif
+
+#if SWIFT_OBJC_INTEROP
+  // Install the metaclass's RO-data pointer.
+  auto metaclass = reinterpret_cast<AnyClassMetadata *>(
+      metadataExtraData + pattern->MetaclassObjectOffset);
+  auto metaclassRO = metadataExtraData + pattern->MetaclassRODataOffset;
+  metaclass->Data = reinterpret_cast<uintptr_t>(metaclassRO);
+#endif
+
+  // MetadataKind / isa.
+#if SWIFT_OBJC_INTEROP
+  metadata->setClassISA(metaclass);
+#else
+  metadata->setKind(MetadataKind::Class);
+#endif
+
+  // Superclass.
+  metadata->Superclass = nullptr;
+#if SWIFT_OBJC_INTEROP
+  // If the class doesn't have a formal superclass, automatically set
+  // it to SwiftObject.
+  if (!description->hasSuperclass()) {
+    metadata->Superclass = getRootSuperclass();
+  }
+#endif
+
+#if SWIFT_OBJC_INTEROP
+  // Cache data.  Install the same initializer that the compiler is
+  // required to use.  We don't need to do this in non-ObjC-interop modes.
+  metadata->CacheData[0] = &_objc_empty_cache;
+  metadata->CacheData[1] = nullptr;
+#endif
+
+  // RO-data pointer.
+#if SWIFT_OBJC_INTEROP
+  auto classRO = metadataExtraData + pattern->ClassRODataOffset;
+  metadata->Data =
+    reinterpret_cast<uintptr_t>(classRO) | SWIFT_CLASS_IS_SWIFT_MASK;
+#else
+  metadata->Data = SWIFT_CLASS_IS_SWIFT_MASK;
+#endif
+
+  // Class flags.
+  metadata->Flags = pattern->Flags;
+
+  // Instance layout.
+  metadata->InstanceAddressPoint = 0;
+  metadata->InstanceSize = 0;
+  metadata->InstanceAlignMask = 0;
+
+  // Reserved.
+  metadata->Reserved = 0;
+
+  // Class metadata layout.
+  metadata->ClassSize = bounds.getTotalSizeInBytes();
+  metadata->ClassAddressPoint = bounds.getAddressPointInBytes();
+
+  // Class descriptor.
+  metadata->setDescription(description);
+
+  // I-var destroyer.
+  metadata->IVarDestroyer = pattern->IVarDestroyer;
+}
+
 ClassMetadata *
 swift::swift_allocateGenericClassMetadata(const ClassDescriptor *description,
-                                          const void *metadataTemplate,
-                                          size_t templateSize,
-                                          size_t templateAddressPoint,
                                           const void *arguments,
-                                          ClassMetadata *superclass,
-                                          size_t numImmediateMembers) {
+                                    const GenericClassMetadataPattern *pattern){
   void * const *argumentsAsArray = reinterpret_cast<void * const *>(arguments);
   auto &generics = description->getFullGenericContextHeader();
+  auto &cache = unsafeGetInitializedCache(generics);
+
   size_t numGenericArguments = generics.Base.NumKeyArguments;
 
-  size_t metadataSize;
-  if (superclass && superclass->isTypeMetadata()) {
-    assert(superclass->getClassAddressPoint() <= templateAddressPoint);
+  // Compute the formal bounds of the metadata.
+  auto bounds = description->getMetadataBounds();
 
-    metadataSize = (superclass->getClassSize() -
-                    superclass->getClassAddressPoint() +
-                    templateAddressPoint +
-                    numImmediateMembers * sizeof(void *));
-    assert(templateSize <= metadataSize);
-  } else {
-    metadataSize = (templateSize +
-                    numImmediateMembers * sizeof(void *));
-  }
+  // Augment that with any required extra data from the pattern.
+  auto allocationBounds = bounds;
+  allocationBounds.PositiveSizeInWords += pattern->NumExtraDataWords;
 
-  auto &cache = unsafeGetInitializedCache(generics);
-  char *bytes = GenericCacheEntry::allocate(cache.getAllocator(),
-                                            argumentsAsArray,
-                                            numGenericArguments,
-                                            metadataSize)->getData<char>();
+  auto entry = GenericCacheEntry::allocate(cache.getAllocator(),
+                                           argumentsAsArray,
+                                           numGenericArguments,
+                                        allocationBounds.getTotalSizeInBytes());
 
-  // Copy in the metadata template.
-  memcpy(bytes, metadataTemplate, templateSize);
+  auto bytes = entry->getData<char>();
+  auto addressPoint = bytes + allocationBounds.getAddressPointInBytes();
+  auto metadata = reinterpret_cast<ClassMetadata *>(addressPoint);
 
-  // Zero out the rest of the metadata.
-  memset(bytes + templateSize, 0, metadataSize - templateSize);
+  initializeClassMetadataFromPattern(metadata, bounds, description, pattern);
 
-  // Okay, move to the address point.
-  ClassMetadata *metadata =
-    reinterpret_cast<ClassMetadata *>(bytes + templateAddressPoint);
-  auto patternBytes =
-    reinterpret_cast<const char*>(metadataTemplate) +
-    templateAddressPoint;
-  auto patternMetadata = reinterpret_cast<const ClassMetadata*>(patternBytes);
+  assert(GenericCacheEntry::getFromMetadata(metadata) == entry);
   assert(metadata->isTypeMetadata());
 
-  // Overwrite the superclass field.
-  metadata->SuperClass = superclass;
-  // Adjust the relative reference to the nominal type descriptor.
-  if (!metadata->isArtificialSubclass()) {
-    metadata->setDescription(patternMetadata->getDescription());
-  }
-
-  // The pattern might have private prefix matter prior to the start
-  // of metadata.
-  assert(metadata->getClassAddressPoint() <= templateAddressPoint);
-  metadata->setClassSize(metadataSize);
-
   return metadata;
 }
 
@@ -241,7 +408,7 @@
     [&]() -> GenericCacheEntry* {
       // Create new metadata to cache.
       auto metadata = generics.InstantiationFunction(description, arguments);
-      auto entry = GenericCacheEntry::getFromMetadata(generics, metadata);
+      auto entry = GenericCacheEntry::getFromMetadata(metadata);
       entry->Value = metadata;
       return entry;
     });
@@ -1475,7 +1642,7 @@
     _swift_initGenericClassObjCName(theClass);
 #endif
 
-  const ClassMetadata *theSuperclass = theClass->SuperClass;
+  const ClassMetadata *theSuperclass = theClass->Superclass;
 
   // Copy the class's immediate methods from the nominal type descriptor
   // to the class metadata.
@@ -1509,8 +1676,8 @@
     // Copy the generic requirements.
     if (description->isGeneric()
         && description->getGenericContextHeader().hasArguments()) {
-      memcpy(classWords + description->getGenericArgumentOffset(ancestor),
-             superWords + description->getGenericArgumentOffset(ancestor),
+      memcpy(classWords + description->getGenericArgumentOffset(),
+             superWords + description->getGenericArgumentOffset(),
              description->getGenericContextHeader().getNumArguments() *
                sizeof(uintptr_t));
     }
@@ -1531,7 +1698,7 @@
              superWords + fieldOffsetVector,
              description->NumFields * sizeof(uintptr_t));
     }
-    ancestor = ancestor->SuperClass;
+    ancestor = ancestor->Superclass;
   }
 
 #if SWIFT_OBJC_INTEROP
@@ -1540,7 +1707,7 @@
   auto theMetaclass = (ClassMetadata *)object_getClass((id)theClass);
   auto theSuperMetaclass
     = (const ClassMetadata *)object_getClass(id_const_cast(theSuperclass));
-  theMetaclass->SuperClass = theSuperMetaclass;
+  theMetaclass->Superclass = theSuperMetaclass;
 #endif
 }
 
@@ -1556,7 +1723,10 @@
 swift::swift_relocateClassMetadata(ClassMetadata *self,
                                    size_t templateSize,
                                    size_t numImmediateMembers) {
-  const ClassMetadata *superclass = self->SuperClass;
+  // Force the initialization of the metadata layout.
+  (void) self->getDescription()->getMetadataBounds();
+
+  const ClassMetadata *superclass = self->Superclass;
 
   size_t metadataSize;
   if (superclass && superclass->isTypeMetadata()) {
@@ -1608,7 +1778,7 @@
 
   // If we have a superclass, start from its size and alignment instead.
   if (classHasSuperclass(self)) {
-    const ClassMetadata *super = self->SuperClass;
+    const ClassMetadata *super = self->Superclass;
 
     // This is straightforward if the superclass is Swift.
 #if SWIFT_OBJC_INTEROP
diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp
index 273877b..9233234 100644
--- a/stdlib/public/runtime/MetadataLookup.cpp
+++ b/stdlib/public/runtime/MetadataLookup.cpp
@@ -657,7 +657,7 @@
   LookupDependentMemberFn lookupDependentMember;
 
   /// Ownership information related to the metadata we are trying to lookup.
-  TypeOwnership Ownership;
+  TypeReferenceOwnership ReferenceOwnership;
 
 public:
   DecodedMetadataBuilder(Demangler &demangler,
@@ -940,17 +940,17 @@
   }
 
   BuiltType createUnownedStorageType(BuiltType base) {
-    Ownership.setUnowned();
+    ReferenceOwnership.setUnowned();
     return base;
   }
 
   BuiltType createUnmanagedStorageType(BuiltType base) {
-    Ownership.setUnmanaged();
+    ReferenceOwnership.setUnmanaged();
     return base;
   }
 
   BuiltType createWeakStorageType(BuiltType base) {
-    Ownership.setWeak();
+    ReferenceOwnership.setWeak();
     return base;
   }
 
@@ -959,7 +959,9 @@
     return BuiltType();
   }
 
-  TypeOwnership getOwnership() const { return Ownership; }
+  TypeReferenceOwnership getReferenceOwnership() const {
+    return ReferenceOwnership;
+  }
 };
 
 }
@@ -1020,7 +1022,7 @@
     });
 
   auto type = Demangle::decodeMangledType(builder, node);
-  return {type, builder.getOwnership()};
+  return {type, builder.getReferenceOwnership()};
 }
 
 SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
diff --git a/stdlib/public/runtime/Private.h b/stdlib/public/runtime/Private.h
index 6582683..a6b4995 100644
--- a/stdlib/public/runtime/Private.h
+++ b/stdlib/public/runtime/Private.h
@@ -29,7 +29,7 @@
 
 namespace swift {
 
-class TypeOwnership {
+class TypeReferenceOwnership {
   enum : uint8_t {
     Weak = 1 << 0,
     Unowned = 1 << 1,
@@ -38,10 +38,10 @@
 
   uint8_t Data;
 
-  constexpr TypeOwnership(uint8_t Data) : Data(Data) {}
+  constexpr TypeReferenceOwnership(uint8_t Data) : Data(Data) {}
 
 public:
-  constexpr TypeOwnership() : Data(0) {}
+  constexpr TypeReferenceOwnership() : Data(0) {}
 
   bool isWeak() const { return Data & Weak; }
   bool isUnowned() const { return Data & Unowned; }
@@ -60,19 +60,19 @@
 /// itself related info has to be bundled with it.
 class TypeInfo {
   const Metadata *Type;
-  const TypeOwnership Ownership;
+  const TypeReferenceOwnership ReferenceOwnership;
 
 public:
-  TypeInfo() : Type(nullptr), Ownership() {}
+  TypeInfo() : Type(nullptr), ReferenceOwnership() {}
 
-  TypeInfo(const Metadata *type, TypeOwnership ownership)
-      : Type(type), Ownership(ownership) {}
+  TypeInfo(const Metadata *type, TypeReferenceOwnership ownership)
+      : Type(type), ReferenceOwnership(ownership) {}
 
   operator const Metadata *() { return Type; }
 
-  bool isWeak() const { return Ownership.isWeak(); }
-  bool isUnowned() const { return Ownership.isUnowned(); }
-  bool isUnmanaged() const { return Ownership.isUnmanaged(); }
+  bool isWeak() const { return ReferenceOwnership.isWeak(); }
+  bool isUnowned() const { return ReferenceOwnership.isUnowned(); }
+  bool isUnmanaged() const { return ReferenceOwnership.isUnmanaged(); }
 };
 
 #if SWIFT_HAS_ISA_MASKING
@@ -190,7 +190,7 @@
   /// Check if a class has a formal superclass in the AST.
   static inline
   bool classHasSuperclass(const ClassMetadata *c) {
-    return (c->SuperClass && c->SuperClass != getRootSuperclass());
+    return  (c->Superclass && c->Superclass != getRootSuperclass());
   }
 
   /// Replace entries of a freshly-instantiated value witness table with more
diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp
index 80b1bd3..fcca5c5 100644
--- a/stdlib/public/runtime/ProtocolConformance.cpp
+++ b/stdlib/public/runtime/ProtocolConformance.cpp
@@ -470,7 +470,7 @@
   // If the type is a class, try its superclass.
   if (const ClassMetadata *classType = type->getClassObject()) {
     if (classHasSuperclass(classType)) {
-      type = getMetadataForClass(classType->SuperClass);
+      type = getMetadataForClass(classType->Superclass);
       goto recur;
     }
   }
@@ -513,7 +513,7 @@
     // If the type is a class, try its superclass.
     if (const ClassMetadata *classType = type->getClassObject()) {
       if (classHasSuperclass(classType)) {
-        type = getMetadataForClass(classType->SuperClass);
+        type = getMetadataForClass(classType->Superclass);
         continue;
       }
     }
diff --git a/stdlib/public/runtime/ReflectionMirror.mm b/stdlib/public/runtime/ReflectionMirror.mm
index 2781eb3..7280fdf 100644
--- a/stdlib/public/runtime/ReflectionMirror.mm
+++ b/stdlib/public/runtime/ReflectionMirror.mm
@@ -563,7 +563,7 @@
 
       // Look through artificial subclasses.
       while (isa->isTypeMetadata() && isa->isArtificialSubclass()) {
-        isa = isa->SuperClass;
+        isa = isa->Superclass;
       }
       passedType = isa;
     }
diff --git a/stdlib/public/runtime/SwiftObject.mm b/stdlib/public/runtime/SwiftObject.mm
index 6b1494d..a7d2f72 100644
--- a/stdlib/public/runtime/SwiftObject.mm
+++ b/stdlib/public/runtime/SwiftObject.mm
@@ -112,7 +112,7 @@
   while (classAsMetadata && classAsMetadata->isTypeMetadata()) {
     if (!classAsMetadata->isArtificialSubclass())
       return classAsMetadata;
-    classAsMetadata = classAsMetadata->SuperClass;
+    classAsMetadata = classAsMetadata->Superclass;
   }
 
   id objcObject = reinterpret_cast<id>(object);
@@ -195,10 +195,10 @@
   return _swift_getObjCClassOfAllocated(self);
 }
 + (Class)superclass {
-  return (Class)((const ClassMetadata*) self)->SuperClass;
+  return (Class)((const ClassMetadata*) self)->Superclass;
 }
 - (Class)superclass {
-  return (Class)_swift_getClassOfAllocated(self)->SuperClass;
+  return (Class)_swift_getClassOfAllocated(self)->Superclass;
 }
 
 + (BOOL)isMemberOfClass:(Class)cls {
@@ -289,7 +289,7 @@
 
 - (BOOL)isKindOfClass:(Class)someClass {
   for (auto cls = _swift_getClassOfAllocated(self); cls != nullptr;
-       cls = cls->SuperClass)
+       cls = cls->Superclass)
     if (cls == (const ClassMetadata*) someClass)
       return YES;
 
@@ -298,7 +298,7 @@
 
 + (BOOL)isSubclassOfClass:(Class)someClass {
   for (auto cls = (const ClassMetadata*) self; cls != nullptr;
-       cls = cls->SuperClass)
+       cls = cls->Superclass)
     if (cls == (const ClassMetadata*) someClass)
       return YES;
 
diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift
index 005ba6c..ed45e11 100644
--- a/test/Constraints/closures.swift
+++ b/test/Constraints/closures.swift
@@ -630,7 +630,6 @@
   let iter = I_33429010()
   var acc: Int = 0 // expected-warning {{}}
   let _: Int = AnySequence { iter }.rdar33429010(into: acc, { $0 + $1 })
-  // expected-warning@-1 {{result of operator '+' is unused}}
   let _: Int = AnySequence { iter }.rdar33429010(into: acc, { $0.rdar33429010_incr($1) })
 }
 
@@ -652,3 +651,38 @@
      str.replaceSubrange(range, with: str[range].reversed())
   }])
 }
+
+protocol P_37790062 {
+  associatedtype T
+  var elt: T { get }
+}
+
+func rdar37790062() {
+  struct S<T> {
+    init(_ a: () -> T, _ b: () -> T) {}
+  }
+
+  class C1 : P_37790062 {
+    typealias T = Int
+    var elt: T { return 42 }
+  }
+
+  class C2 : P_37790062 {
+    typealias T = (String, Int, Void)
+    var elt: T { return ("question", 42, ()) }
+  }
+
+  func foo() -> Int { return 42 }
+  func bar() -> Void {}
+  func baz() -> (String, Int) { return ("question", 42) }
+  func bzz<T>(_ a: T) -> T { return a }
+  func faz<T: P_37790062>(_ a: T) -> T.T { return a.elt }
+
+  _ = S({ foo() }, { bar() }) // Ok, should infer T to be 'Void'
+  _ = S({ baz() }, { bar() }) // Ok, should infer T to be 'Void'
+  _ = S({ bzz(("question", 42)) }, { bar() }) // Ok
+  _ = S({ bzz(String.self) }, { bar() }) // Ok
+  _ = S({ bzz(((), (()))) }, { bar() }) // Ok
+  _ = S({ bzz(C1()) }, { bar() }) // Ok
+  _ = S({ faz(C2()) }, { bar() }) // Ok
+}
diff --git a/test/Constraints/rdar37790062.swift b/test/Constraints/rdar37790062.swift
new file mode 100644
index 0000000..13d2f8c
--- /dev/null
+++ b/test/Constraints/rdar37790062.swift
@@ -0,0 +1,46 @@
+// RUN: %target-typecheck-verify-swift
+
+protocol A {
+  associatedtype V
+  associatedtype E: Error
+
+  init(value: V)
+  init(error: E)
+
+  func foo<U>(value: (V) -> U, error: (E) -> U) -> U
+}
+
+enum R<T, E: Error> : A {
+  case foo(T)
+  case bar(E)
+
+  init(value: T) { self = .foo(value) }
+  init(error: E) { self = .bar(error) }
+
+  func foo<R>(value: (T) -> R, error: (E) -> R) -> R {
+    fatalError()
+  }
+}
+
+protocol P {
+  associatedtype V
+
+  @discardableResult
+  func baz(callback: @escaping (V) -> Void) -> Self
+}
+
+class C<V> : P {
+  func baz(callback: @escaping (V) -> Void) -> Self { return self }
+}
+class D<T, E: Error> : C<R<T, E>> {
+  init(fn: (_ ret: @escaping (V) -> Void) -> Void) {}
+}
+
+extension A where V: P, V.V: A, E == V.V.E {
+  func bar() -> D<V.V.V, V.V.E> {
+    return D { complete in
+      foo(value: { promise in promise.baz { result in } },
+          error: { complete(R(error: $0)) })
+    }
+  }
+}
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_ios_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_ios_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_ios_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_iossim_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_iossim_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_iossim_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_tvos_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_tvos_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_tvos_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_tvossim_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_tvossim_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_tvossim_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_watchos_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_watchos_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_watchos_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_watchossim_dynamic.dylib b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_watchossim_dynamic.dylib
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.asan_watchossim_dynamic.dylib
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.fuzzer_osx.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.fuzzer_osx.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/darwin/libclang_rt.fuzzer_osx.a
diff --git a/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.fuzzer-x86_64.a b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.fuzzer-x86_64.a
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/fake-resource-dir/lib/swift/clang/lib/linux/libclang_rt.fuzzer-x86_64.a
diff --git a/test/Driver/batch_mode_parseable_output.swift b/test/Driver/batch_mode_parseable_output.swift
new file mode 100644
index 0000000..9930968
--- /dev/null
+++ b/test/Driver/batch_mode_parseable_output.swift
@@ -0,0 +1,125 @@
+// RUN: %empty-directory(%t)
+// RUN: touch %t/file-01.swift %t/file-02.swift %t/file-03.swift
+// RUN: echo 'public func main() {}' >%t/main.swift
+//
+// RUN: %swiftc_driver -enable-batch-mode -parseable-output -c -emit-module -module-name main -j 2 %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/main.swift 2>&1 | %FileCheck %s
+//
+//
+// CHECK: {{[1-9][0-9]*}}
+// CHECK-NEXT: {
+// CHECK-NEXT:   "kind": "began",
+// CHECK-NEXT:   "name": "compile",
+// CHECK-NEXT:   "command": "{{.*}}/swift{{c?}} -frontend -c -primary-file {{.*}}/file-01.swift -primary-file {{.*}}/file-02.swift {{.*}}/file-03.swift {{.*}}/main.swift {{.*}} -emit-module-doc-path {{.*}}/file-01-[[SWIFTDOC01:[a-z0-9]+]].swiftdoc -emit-module-doc-path {{.*}}/file-02-[[SWIFTDOC02:[a-z0-9]+]].swiftdoc -module-name main -emit-module-path {{.*}}/file-01-[[MODULE01:[a-z0-9]+]].swiftmodule -emit-module-path {{.*}}/file-02-[[MODULE02:[a-z0-9]+]].swiftmodule -o {{.*}}/file-01-[[OBJ01:[a-z0-9]+]].o -o {{.*}}/file-02-[[OBJ02:[a-z0-9]+]].o",
+// CHECK-NEXT:   "inputs": [
+// CHECK-NEXT:     "{{.*}}/file-01.swift",
+// CHECK-NEXT:     "{{.*}}/file-02.swift"
+// CHECK-NEXT:   ],
+// CHECK-NEXT:   "outputs": [
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "object",
+// CHECK-NEXT:       "path": "{{.*}}/file-01-[[OBJ01]].o"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "object",
+// CHECK-NEXT:       "path": "{{.*}}/file-02-[[OBJ02]].o"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftmodule",
+// CHECK-NEXT:       "path": "{{.*}}/file-01-[[MODULE01]].swiftmodule"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftmodule",
+// CHECK-NEXT:       "path": "{{.*}}/file-02-[[MODULE02]].swiftmodule"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftdoc",
+// CHECK-NEXT:       "path": "{{.*}}/file-01-[[SWIFTDOC01]].swiftdoc"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftdoc",
+// CHECK-NEXT:       "path": "{{.*}}/file-02-[[SWIFTDOC02]].swiftdoc"
+// CHECK-NEXT:     }
+// CHECK-NEXT:   ],
+// CHECK-NEXT:   "pid": {{[1-9][0-9]*}}
+// CHECK-NEXT: }
+// CHECK-NEXT: {{[1-9][0-9]*}}
+// CHECK-NEXT: {
+// CHECK-NEXT:   "kind": "began",
+// CHECK-NEXT:   "name": "compile",
+// CHECK-NEXT:   "command": "{{.*}}/swift{{c?}} -frontend -c {{.*}}/file-01.swift {{.*}}/file-02.swift -primary-file {{.*}}/file-03.swift -primary-file {{.*}}/main.swift {{.*}} -emit-module-doc-path {{.*}}/file-03-[[SWIFTDOC03:[a-z0-9]+]].swiftdoc -emit-module-doc-path {{.*}}/main-[[SWIFTDOCMAIN:[a-z0-9]+]].swiftdoc -module-name main -emit-module-path {{.*}}/file-03-[[MODULE03:[a-z0-9]+]].swiftmodule -emit-module-path {{.*}}/main-[[MODULEMAIN:[a-z0-9]+]].swiftmodule -o {{.*}}/file-03-[[OBJ03:[a-z0-9]+]].o -o {{.*}}/main-[[OBJMAIN:[a-z0-9]+]].o",
+// CHECK-NEXT:   "inputs": [
+// CHECK-NEXT:     "{{.*}}/file-03.swift",
+// CHECK-NEXT:     "{{.*}}/main.swift"
+// CHECK-NEXT:   ],
+// CHECK-NEXT:   "outputs": [
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "object",
+// CHECK-NEXT:       "path": "{{.*}}/file-03-[[OBJ03]].o"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "object",
+// CHECK-NEXT:       "path": "{{.*}}/main-[[OBJMAIN]].o"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftmodule",
+// CHECK-NEXT:       "path": "{{.*}}/file-03-[[MODULE03]].swiftmodule"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftmodule",
+// CHECK-NEXT:       "path": "{{.*}}/main-[[MODULEMAIN]].swiftmodule"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftdoc",
+// CHECK-NEXT:       "path": "{{.*}}/file-03-[[SWIFTDOC03]].swiftdoc"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftdoc",
+// CHECK-NEXT:       "path": "{{.*}}/main-[[SWIFTDOCMAIN]].swiftdoc"
+// CHECK-NEXT:     }
+// CHECK-NEXT:   ],
+// CHECK-NEXT:   "pid": {{[1-9][0-9]*}}
+// CHECK-NEXT: }
+// CHECK-NEXT: {{[1-9][0-9]*}}
+// CHECK-NEXT: {
+// CHECK-NEXT:   "kind": "finished",
+// CHECK-NEXT:   "name": "compile",
+// CHECK-NEXT:   "pid": {{[1-9][0-9]*}},
+// CHECK-NEXT:   "exit-status": 0
+// CHECK-NEXT: }
+// CHECK-NEXT: {{[1-9][0-9]*}}
+// CHECK-NEXT: {
+// CHECK-NEXT:   "kind": "finished",
+// CHECK-NEXT:   "name": "compile",
+// CHECK-NEXT:   "pid": {{[1-9][0-9]*}},
+// CHECK-NEXT:   "exit-status": 0
+// CHECK-NEXT: }
+// CHECK-NEXT: {{[1-9][0-9]*}}
+// CHECK-NEXT: {
+// CHECK-NEXT:   "kind": "began",
+// CHECK-NEXT:   "name": "merge-module",
+// CHECK-NEXT:   "command": "{{.*}}/swift{{c?}} -frontend -merge-modules -emit-module {{.*}}/file-01-[[MODULE01]].swiftmodule {{.*}}/file-02-[[MODULE02]].swiftmodule {{.*}}/file-03-[[MODULE03]].swiftmodule {{.*}}/main-[[MODULEMAIN]].swiftmodule {{.*}} -emit-module-doc-path main.swiftdoc -module-name main -o main.swiftmodule",
+// CHECK-NEXT:   "inputs": [
+// CHECK-NEXT:     "{{.*}}/file-01-[[OBJ01]].o",
+// CHECK-NEXT:     "{{.*}}/file-02-[[OBJ02]].o",
+// CHECK-NEXT:     "{{.*}}/file-03-[[OBJ03]].o",
+// CHECK-NEXT:     "{{.*}}/main-[[OBJMAIN]].o"
+// CHECK-NEXT:   ],
+// CHECK-NEXT:   "outputs": [
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftmodule",
+// CHECK-NEXT:       "path": "main.swiftmodule"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "type": "swiftdoc",
+// CHECK-NEXT:       "path": "main.swiftdoc"
+// CHECK-NEXT:     }
+// CHECK-NEXT:   ],
+// CHECK-NEXT:   "pid": {{[1-9][0-9]*}}
+// CHECK-NEXT: }
+// CHECK-NEXT: {{[1-9][0-9]*}}
+// CHECK-NEXT: {
+// CHECK-NEXT:   "kind": "finished",
+// CHECK-NEXT:   "name": "merge-module",
+// CHECK-NEXT:   "pid": {{[1-9][0-9]*}},
+// CHECK-NEXT:   "exit-status": 0
+// CHECK-NEXT: }
diff --git a/test/Driver/fuzzer.swift b/test/Driver/fuzzer.swift
index 4ab6c2a..937804d 100644
--- a/test/Driver/fuzzer.swift
+++ b/test/Driver/fuzzer.swift
@@ -1,4 +1,4 @@
-// RUN: %swiftc_driver -driver-print-jobs -sanitize=fuzzer,address %s | %FileCheck -check-prefix=LIBFUZZER %s
+// RUN: %swiftc_driver -driver-print-jobs -sanitize=fuzzer,address -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ %s | %FileCheck -check-prefix=LIBFUZZER %s
 
 // LIBFUZZER: libclang_rt.fuzzer
 @_cdecl("LLVMFuzzerTestOneInput") public func fuzzOneInput(Data: UnsafePointer<CChar>, Size: CLong) -> CInt {
diff --git a/test/Driver/sanitize_coverage.swift b/test/Driver/sanitize_coverage.swift
index 71f4a0b..d18574c 100644
--- a/test/Driver/sanitize_coverage.swift
+++ b/test/Driver/sanitize_coverage.swift
@@ -2,6 +2,7 @@
 // RUN: %swiftc_driver -driver-print-jobs -sanitize-coverage=func -sanitize=address %s | %FileCheck -check-prefix=SANCOV_FUNC %s
 // RUN: %swiftc_driver -driver-print-jobs -sanitize-coverage=bb -sanitize=address %s | %FileCheck -check-prefix=SANCOV_BB %s
 // RUN: %swiftc_driver -driver-print-jobs -sanitize-coverage=edge -sanitize=address %s | %FileCheck -check-prefix=SANCOV_EDGE %s
+// REQUIRES: asan_runtime
 
 // Try some options
 // RUN: %swiftc_driver -driver-print-jobs -sanitize-coverage=edge,indirect-calls,trace-bb,trace-cmp,8bit-counters  -sanitize=address %s | %FileCheck -check-prefix=SANCOV_EDGE_WITH_OPTIONS %s
diff --git a/test/Driver/sanitizers.swift b/test/Driver/sanitizers.swift
index 953bfed..d143c70 100644
--- a/test/Driver/sanitizers.swift
+++ b/test/Driver/sanitizers.swift
@@ -1,4 +1,5 @@
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-apple-macosx10.9 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_OSX %s
+// RUN: not %swiftc_driver -driver-print-jobs -sanitize=fuzzer -target x86_64-apple-macosx10.9 -resource-dir %S/Inputs/nonexistent-resource-dir %s 2>&1 | %FileCheck -check-prefix=FUZZER_NONEXISTENT %s
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-apple-ios7.1 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_IOSSIM %s
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target arm64-apple-ios7.1 %s  | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_IOS %s
 // RUN: %swiftc_driver -resource-dir %S/Inputs/fake-resource-dir/lib/swift/ -driver-print-jobs -sanitize=address -target x86_64-apple-tvos9.0 %s | %FileCheck -check-prefix=ASAN -check-prefix=ASAN_tvOS_SIM %s
@@ -54,6 +55,7 @@
 // TSAN_tvOS: unsupported option '-sanitize=thread' for target 'arm64-apple-tvos9.0'
 // TSAN_watchOS_SIM: unsupported option '-sanitize=thread' for target 'i386-apple-watchos2.0'
 // TSAN_watchOS: unsupported option '-sanitize=thread' for target 'armv7k-apple-watchos2.0'
+// FUZZER_NONEXISTENT: unsupported option '-sanitize=fuzzer' for target 'x86_64-apple-macosx10.9'
 // TSAN_LINUX: lib/swift/clang/lib/linux/libclang_rt.tsan-x86_64.a
 
 // TSAN: -rpath @executable_path
diff --git a/test/Frontend/batch-mode.swift b/test/Frontend/batch-mode.swift
index 8706761f..d407dad 100644
--- a/test/Frontend/batch-mode.swift
+++ b/test/Frontend/batch-mode.swift
@@ -3,7 +3,7 @@
 // RUN: echo 'public func b() { }' >%t/b.swift
 // RUN: echo 'public func c() { }' >%t/c.swift
 // RUN: echo 'public func main() {a(); b(); c()}' >%t/main.swift
-// RUN: %target-swift-frontend -c -enable-batch-mode -bypass-batch-mode-checks -module-name foo -primary-file %t/a.swift -primary-file %t/b.swift -primary-file %t/c.swift -primary-file %t/main.swift -o %t/a.o -o %t/b.o -o %t/c.o -o %t/main.o
+// RUN: %target-swift-frontend -c -enable-batch-mode -module-name foo -primary-file %t/a.swift -primary-file %t/b.swift -primary-file %t/c.swift -primary-file %t/main.swift -o %t/a.o -o %t/b.o -o %t/c.o -o %t/main.o
 //
 // RUN: llvm-objdump -t %t/a.o | swift-demangle | %FileCheck -check-prefix=CHECK-A %s
 // RUN: llvm-objdump -t %t/b.o | swift-demangle | %FileCheck -check-prefix=CHECK-B %s
diff --git a/test/Frontend/dependencies-selective-supplementaries.swift b/test/Frontend/dependencies-selective-supplementaries.swift
new file mode 100644
index 0000000..c1cd4bc
--- /dev/null
+++ b/test/Frontend/dependencies-selective-supplementaries.swift
@@ -0,0 +1,23 @@
+// This test verifies that, in batch-mode (i.e. >1 primary input),
+// we have fixed a bug that caused every primary input to be a dependent
+// of every ModuleOutputPath, etc.
+
+// RUN: %empty-directory(%t)
+// RUN: echo 'public func a() { }' >%t/a.swift
+// RUN: echo 'public func main() {a()}' >%t/main.swift
+// RUN: %target-swift-frontend -c -enable-batch-mode -module-name foo -primary-file %t/a.swift -primary-file %t/main.swift -emit-dependencies-path %t/a.d -emit-dependencies-path %t/main.d  -o %t/a.o -o %t/main.o -emit-module-path %t/a.swiftmodule -emit-module-path %t/main.swiftmodule
+// RUN: %FileCheck -check-prefix=CHECK-MAIN %s <%t/main.d
+// RUN: %FileCheck -check-prefix=NEGATIVE-MAIN %s <%t/main.d
+//
+// CHECK-MAIN-DAG: main.swiftmodule :
+// CHECK-MAIN-DAG: main.o :
+// NEGATIVE-MAIN-NOT: a.swiftmodule
+// NEGATIVE-MAIN-NOT: a.o
+//
+// RUN: %FileCheck -check-prefix=CHECK-A %s <%t/a.d
+// RUN: %FileCheck -check-prefix=NEGATIVE-A %s <%t/a.d
+//
+// CHECK-A-DAG: a.swiftmodule :
+// CHECK-A-DAG: a.o :
+// NEGATIVE-A-NOT: main.swiftmodule
+// NEGATIVE-A-NOT: main.o
diff --git a/test/IRGen/class_metadata.swift b/test/IRGen/class_metadata.swift
index 3f927a3..14ff7fb 100644
--- a/test/IRGen/class_metadata.swift
+++ b/test/IRGen/class_metadata.swift
@@ -63,14 +63,18 @@
 // CHECK-SAME: i32 {{.*}} @"$S14class_metadata1CCMa"
 //   Superclass.
 // CHECK-SAME: i32 {{.*}} @"$S14class_metadata1BCMn"
+//   Negative size in words.
+// CHECK-SAME: i32 2,
+//   Positive size in words.
+// CHECK-32-SAME: i32 15,
+// CHECK-64-SAME: i32 12,
+//   Num immediate members.
+// CHECK-32-SAME: i32 1,
 //   Field count.
 // CHECK-SAME: i32 0,
 //   Field offset vector offset.
 // CHECK-32-SAME: i32 15,
 // CHECK-64-SAME: i32 12,
-//   Argument offset.
-// CHECK-32-SAME: i32 14,
-// CHECK-64-SAME: i32 11,
 //   Instantiation function.
 // CHECK-SAME: i32 {{.*}} @"$S14class_metadata1CCMi"
 //   Instantiation cache.
diff --git a/test/IRGen/class_resilience.swift b/test/IRGen/class_resilience.swift
index da4709b..68e0063 100644
--- a/test/IRGen/class_resilience.swift
+++ b/test/IRGen/class_resilience.swift
@@ -16,9 +16,11 @@
 
 // CHECK: @"$S16class_resilience14ResilientChildC5fields5Int32VvpWvd" = hidden global [[INT]] {{8|16}}
 
-// CHECK: @"$S16class_resilience21ResilientGenericChildCMo" = {{(protected )?}}global [[INT]] 0
+// CHECK: @"$S16class_resilience21ResilientGenericChildCMo" = {{(protected )?}}global [[BOUNDS:{ (i32|i64), i32, i32 }]] zeroinitializer
 
-// CHECK: @"$S16class_resilience26ClassWithResilientPropertyCMo" = {{(protected )?}}constant [[INT]] {{52|80}}
+// CHECK: @"$S16class_resilience26ClassWithResilientPropertyCMo" = {{(protected )?}}constant [[BOUNDS]]
+// CHECK-SAME-32: { [[INT]] 52, i32 2, i32 13 }
+// CHECK-SAME-64: { [[INT]] 80, i32 2, i32 10 }
 
 // CHECK: @"$S16class_resilience28ClassWithMyResilientPropertyC1rAA0eF6StructVvpWvd" = hidden constant [[INT]] {{8|16}}
 // CHECK: @"$S16class_resilience28ClassWithMyResilientPropertyC5colors5Int32VvpWvd" = hidden constant [[INT]] {{12|20}}
@@ -28,6 +30,8 @@
 
 // CHECK: [[RESILIENTCHILD_NAME:@.*]] = private constant [15 x i8] c"ResilientChild\00"
 
+// CHECK: @"$S16class_resilience14ResilientChildCMo" = {{(protected )?}}global [[BOUNDS]] zeroinitializer
+
 // CHECK: @"$S16class_resilience14ResilientChildCMn" = {{(protected )?}}constant <{{.*}}> <{
 // --       flags: class, unique, reflectable, has vtable, has resilient superclass
 // CHECK-SAME:   <i32 0xD004_0050>
@@ -39,17 +43,23 @@
 // CHECK-SAME:   i32 3,
 // CHECK-SAME: }>
 
-// CHECK: @"$S16class_resilience14ResilientChildCMo" = {{(protected )?}}global [[INT]] 0
+// CHECK: @"$S16class_resilience16FixedLayoutChildCMo" = {{(protected )?}}global [[BOUNDS]] zeroinitializer
 
-// CHECK: @"$S16class_resilience16FixedLayoutChildCMo" = {{(protected )?}}global [[INT]] 0
+// CHECK: @"$S16class_resilience17MyResilientParentCMo" = {{(protected )?}}constant [[BOUNDS]]
+// CHECK-SAME-32: { [[INT]] 52, i32 2, i32 13 }
+// CHECK-SAME-64: { [[INT]] 80, i32 2, i32 10 }
 
-// CHECK: @"$S16class_resilience17MyResilientParentCMo" = {{(protected )?}}constant [[INT]] {{52|80}}
+// CHECK: @"$S16class_resilience16MyResilientChildCMo" = {{(protected )?}}constant [[BOUNDS]]
+// CHECK-SAME-32: { [[INT]] 60, i32 2, i32 15 }
+// CHECK-SAME-64: { [[INT]] 96, i32 2, i32 12 }
 
-// CHECK: @"$S16class_resilience16MyResilientChildCMo" = {{(protected )?}}constant [[INT]] {{60|96}}
+// CHECK: @"$S16class_resilience24MyResilientGenericParentCMo" = {{(protected )?}}constant [[BOUNDS]]
+// CHECK-SAME-32: { [[INT]] 52, i32 2, i32 13 }
+// CHECK-SAME-64: { [[INT]] 80, i32 2, i32 10 }
 
-// CHECK: @"$S16class_resilience24MyResilientGenericParentCMo" = {{(protected )?}}constant [[INT]] {{52|80}}
-
-// CHECK: @"$S16class_resilience24MyResilientConcreteChildCMo" = {{(protected )?}}constant [[INT]] {{64|104}}
+// CHECK: @"$S16class_resilience24MyResilientConcreteChildCMo" = {{(protected )?}}constant [[BOUNDS]]
+// CHECK-SAME-32: { [[INT]] 64, i32 2, i32 16 }
+// CHECK-SAME-64: { [[INT]] 104, i32 2, i32 13 }
 
 import resilient_class
 import resilient_struct
@@ -273,7 +283,7 @@
 
 // CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds %T16class_resilience21ResilientGenericChildC, %T16class_resilience21ResilientGenericChildC* %0, i32 0, i32 0, i32 0
 // CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ADDR]]
-// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S16class_resilience21ResilientGenericChildCMo"
+// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S16class_resilience21ResilientGenericChildCMo", i32 0, i32 0)
 // CHECK-NEXT: [[METADATA_OFFSET:%.*]] = add [[INT]] [[BASE]], {{16|32}}
 // CHECK-NEXT: [[ISA_ADDR:%.*]] = bitcast %swift.type* [[ISA]] to i8*
 // CHECK-NEXT: [[FIELD_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[ISA_ADDR]], [[INT]] [[METADATA_OFFSET]]
@@ -305,7 +315,7 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc %swift.type* @"$S15resilient_class29ResilientGenericOutsideParentC0B11_resilienceE22genericExtensionMethodxmyF"(%T15resilient_class29ResilientGenericOutsideParentC* swiftself) #0 {
 // CHECK:      [[ISA_ADDR:%.*]] = bitcast %T15resilient_class29ResilientGenericOutsideParentC* %0 to %swift.type**
 // CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
-// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class29ResilientGenericOutsideParentCMo"
+// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class29ResilientGenericOutsideParentCMo", i32 0, i32 0)
 // CHECK-NEXT: [[GENERIC_PARAM_OFFSET:%.*]] = add [[INT]] [[BASE]], 0
 // CHECK-NEXT: [[ISA_TMP:%.*]] = bitcast %swift.type* [[ISA]] to i8*
 // CHECK-NEXT: [[GENERIC_PARAM_TMP:%.*]] = getelementptr inbounds i8, i8* [[ISA_TMP]], [[INT]] [[GENERIC_PARAM_OFFSET]]
@@ -352,39 +362,21 @@
 
 // CHECK-LABEL: define private void @initialize_metadata_ResilientChild(i8*)
 
-// Get the superclass size and address point...
-
-// CHECK:              [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
-// CHECK:              [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER]] to i8*
-// CHECK:              [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
-// CHECK:              [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
-// CHECK:              [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
-// CHECK:              [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
-// CHECK:              [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
-// CHECK:              [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
-
-// CHECK:              [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]]
-
-// Initialize class metadata base offset...
-// CHECK-32:           store [[INT]] [[OFFSET]], [[INT]]* @"$S16class_resilience14ResilientChildCMo"
-
-// CHECK-64:           [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
-// CHECK-64:           store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @"$S16class_resilience14ResilientChildCMo"
-
 // Initialize the superclass field...
+// CHECK:              [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
 // CHECK:              store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}})
 
 // Relocate metadata if necessary...
 // CHECK:              [[METADATA:%.*]] = call %swift.type* @swift_relocateClassMetadata(%swift.type* {{.*}}, [[INT]] {{60|96}}, [[INT]] 4)
 
 // Initialize field offset vector...
-// CHECK:              [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S16class_resilience14ResilientChildCMo"
+// CHECK:              [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S16class_resilience14ResilientChildCMo", i32 0, i32 0)
 // CHECK:              [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{12|24}}
 
 // CHECK:              call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], [[INT]] 1, i8*** {{.*}}, [[INT]]* {{.*}})
 
 // Initialize constructor vtable override...
-// CHECK:              [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo"
+// CHECK:              [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
 // CHECK:              [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{16|32}}
 // CHECK:              [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
 // CHECK:              [[VTABLE_ENTRY_ADDR:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[OFFSET]]
@@ -392,7 +384,7 @@
 // CHECK:              store i8* bitcast (%T16class_resilience14ResilientChildC* (%T16class_resilience14ResilientChildC*)* @"$S16class_resilience14ResilientChildCACycfc" to i8*), i8** [[VTABLE_ENTRY_TMP]]
 
 // Initialize getValue() vtable override...
-// CHECK:              [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo"
+// CHECK:              [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
 // CHECK:              [[OFFSET:%.*]] = add [[INT]] [[BASE]], {{28|56}}
 // CHECK:              [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
 // CHECK:              [[VTABLE_ENTRY_ADDR:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[OFFSET]]
@@ -410,7 +402,7 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc i32 @"$S16class_resilience14ResilientChildC5fields5Int32VvgTj"(%T16class_resilience14ResilientChildC* swiftself)
 // CHECK:      [[ISA_ADDR:%.*]] = getelementptr inbounds %T16class_resilience14ResilientChildC, %T16class_resilience14ResilientChildC* %0, i32 0, i32 0, i32 0
 // CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
-// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S16class_resilience14ResilientChildCMo"
+// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S16class_resilience14ResilientChildCMo", i32 0, i32 0)
 // CHECK-NEXT: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[ISA]] to i8*
 // CHECK-NEXT: [[VTABLE_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[BASE]]
 // CHECK-NEXT: [[VTABLE_OFFSET_ADDR:%.*]] = bitcast i8* [[VTABLE_OFFSET_TMP]] to i32 (%T16class_resilience14ResilientChildC*)**
@@ -423,7 +415,7 @@
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S16class_resilience14ResilientChildC5fields5Int32VvsTj"(i32, %T16class_resilience14ResilientChildC* swiftself)
 // CHECK:      [[ISA_ADDR:%.*]] = getelementptr inbounds %T16class_resilience14ResilientChildC, %T16class_resilience14ResilientChildC* %1, i32 0, i32 0, i32 0
 // CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
-// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S16class_resilience14ResilientChildCMo"
+// CHECK-NEXT: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S16class_resilience14ResilientChildCMo", i32 0, i32 0)
 // CHECK-NEXT: [[METADATA_OFFSET:%.*]] = add [[INT]] [[BASE]], {{4|8}}
 // CHECK-NEXT: [[METADATA_BYTES:%.*]] = bitcast %swift.type* [[ISA]] to i8*
 // CHECK-NEXT: [[VTABLE_OFFSET_TMP:%.*]] = getelementptr inbounds i8, i8* [[METADATA_BYTES]], [[INT]] [[METADATA_OFFSET]]
@@ -437,26 +429,8 @@
 
 // CHECK-LABEL: define private void @initialize_metadata_FixedLayoutChild(i8*)
 
-// Get the superclass size and address point...
-
-// CHECK:              [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
-// CHECK:              [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER]] to i8*
-// CHECK:              [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
-// CHECK:              [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
-// CHECK:              [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
-// CHECK:              [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
-// CHECK:              [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
-// CHECK:              [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
-
-// CHECK:              [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]]
-
-// Initialize class metadata base offset...
-// CHECK-32:           store [[INT]] [[OFFSET]], [[INT]]* @"$S16class_resilience16FixedLayoutChildCMo"
-
-// CHECK-64:           [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
-// CHECK-64:           store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @"$S16class_resilience16FixedLayoutChildCMo"
-
 // Initialize the superclass field...
+// CHECK:              [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
 // CHECK:              store %swift.type* [[SUPER]], %swift.type** getelementptr inbounds ({{.*}})
 
 // Relocate metadata if necessary...
@@ -471,23 +445,14 @@
 
 // Get the superclass size and address point...
 
+// CHECK:              [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** bitcast ({{.*}} @"$S16class_resilience21ResilientGenericChildCMP" to i8**))
+
+// Initialize the superclass pointer...
 // CHECK:              [[SUPER:%.*]] = call %swift.type* @"$S15resilient_class29ResilientGenericOutsideParentCMa"(%swift.type* %T)
-// CHECK:              [[SUPER_TMP:%.*]] = bitcast %swift.type* [[SUPER]] to %objc_class*
-// CHECK:              [[SUPER_ADDR:%.*]] = bitcast %objc_class* [[SUPER_TMP]] to i8*
-// CHECK:              [[SIZE_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{36|56}}
-// CHECK:              [[SIZE_ADDR:%.*]] = bitcast i8* [[SIZE_TMP]] to i32*
-// CHECK:              [[SIZE:%.*]] = load i32, i32* [[SIZE_ADDR]]
-// CHECK:              [[ADDRESS_POINT_TMP:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], i32 {{40|60}}
-// CHECK:              [[ADDRESS_POINT_ADDR:%.*]] = bitcast i8* [[ADDRESS_POINT_TMP]] to i32*
-// CHECK:              [[ADDRESS_POINT:%.*]] = load i32, i32* [[ADDRESS_POINT_ADDR]]
+// CHECK:              [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type**
+// CHECK:              [[SUPER_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
+// CHECK:              store %swift.type* [[SUPER]], %swift.type** [[SUPER_ADDR]],
 
-// CHECK:              [[OFFSET:%.*]] = sub i32 [[SIZE]], [[ADDRESS_POINT]]
+// CHECK:              call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]],
 
-// Initialize class metadata base offset...
-// CHECK-32:           store [[INT]] [[OFFSET]], [[INT]]* @"$S16class_resilience21ResilientGenericChildCMo"
-
-// CHECK-64:           [[OFFSET_ZEXT:%.*]] = zext i32 [[OFFSET]] to i64
-// CHECK-64:           store [[INT]] [[OFFSET_ZEXT]], [[INT]]* @"$S16class_resilience21ResilientGenericChildCMo"
-
-// CHECK:              [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}} @"$S16class_resilience21ResilientGenericChildCMP" to i8**), [[INT]] {{[0-9]+}}, [[INT]] {{[0-9]+}}, i8** %1, %objc_class* [[SUPER_TMP]], [[INT]] 5)
 // CHECK:              ret %swift.type* [[METADATA]]
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index 1cbe9d4..9dd72e4 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -116,8 +116,6 @@
 // CHECK-SAME:   i32 1,
 // --       No empty cases
 // CHECK-SAME:   i32 0,
-// --       Case type accessor
-// CHECK-SAME:   i32 2,
 // --       generic instantiation function
 // CHECK-SAME:   @"$S4enum16DynamicSingletonOMi"
 // --       generic parameters, requirements, key, extra
diff --git a/test/IRGen/generic_classes.sil b/test/IRGen/generic_classes.sil
index 3700dc5..4e24036 100644
--- a/test/IRGen/generic_classes.sil
+++ b/test/IRGen/generic_classes.sil
@@ -19,12 +19,16 @@
 // CHECK-SAME:   <i32 0x8004_00D0>
 // --       name
 // CHECK-SAME:   [12 x i8]* [[ROOTGENERIC_NAME]]
+// --       negative size in words
+// CHECK-SAME:   i32 2,
+// --       positive size in words
+// CHECK-SAME:   i32 18,
+// --       num immediate members
+// CHECK-SAME:   i32 8,
 // --       num fields
 // CHECK-SAME:   i32 3,
 // --       field offset vector offset
 // CHECK-SAME:   i32 15,
-// --       generic parameter vector offset
-// CHECK-SAME:   i32 10,
 // --       template instantiation function
 // CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_classes11RootGenericCMi"
 // --       template instantiation cache
@@ -38,10 +42,29 @@
 // CHECK-SAME: }
 
 // CHECK-LABEL: @"$S15generic_classes11RootGenericCMP" = internal constant
-// --       nominal type descriptor
-// CHECK-SAME:   @"$S15generic_classes11RootGenericCMn"
+// CHECK-SAME: <{
+// --       heap destructor
+// CHECK-SAME:   @"$S15generic_classes11RootGenericCfD"
 // --       ivar destroyer
-// CHECK-SAME:   i8* null
+// CHECK-SAME:   i8* null,
+// --       flags
+// CHECK_SAME:   i32 3,
+// --       immediate pattern size
+// CHECK-SAME:   i16 0,
+// --       immediate pattern target offset
+// CHECK-SAME:   i16 0,
+// --       extra data size
+// CHECK-SAME-native:   i16 0,
+// CHECK-SAME-objc:     i16 23,
+// --       class ro-data offset
+// CHECK-SAME-native:   i16 0,
+// CHECK-SAME-objc:     i16 5,
+// --       metaclass object offset
+// CHECK-SAME-native:   i16 0,
+// CHECK-SAME-objc:     i16 0,
+// --       class ro-data offset
+// CHECK-SAME-native:   i16 0
+// CHECK-SAME-objc:     i16 14,
 // CHECK-SAME: }>
 
 // -- Check that offset vars are emitted for fixed-layout generics
@@ -87,10 +110,28 @@
 // CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_classes015GenericInheritsC0CMi"
 
 // CHECK: @"$S15generic_classes015GenericInheritsC0CMP" = internal constant
-// --       nominal type descriptor
-// CHECK-SAME:   @"$S15generic_classes015GenericInheritsC0CMn",
+// --       heap destructor
+// CHECK-SAME:   @"$S15generic_classes015GenericInheritsC0CfD"
 // --       ivar destroyer
-// CHECK-SAME:   i8* null
+// CHECK-SAME:   i8* null,
+// --       flags
+// CHECK_SAME:   i32 3,
+// --       immediate pattern size
+// CHECK-SAME:   i16 0,
+// --       immediate pattern target offset
+// CHECK-SAME:   i16 0,
+// --       extra data size
+// CHECK-SAME-native:   i16 0,
+// CHECK-SAME-objc:     i16 23,
+// --       class ro-data offset
+// CHECK-SAME-native:   i16 0,
+// CHECK-SAME-objc:     i16 5,
+// --       metaclass object offset
+// CHECK-SAME-native:   i16 0,
+// CHECK-SAME-objc:     i16 0,
+// --       class ro-data offset
+// CHECK-SAME-native:   i16 0
+// CHECK-SAME-objc:     i16 14,
 // CHECK-SAME: }
 
 // CHECK: @"$S15generic_classes018GenericInheritsNonC0CMP"
@@ -292,13 +333,13 @@
  */
 
 // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes11RootGenericCMi"(%swift.type_descriptor*, i8**) {{.*}} {
-// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, {{.*}}, i64 8)
+// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, {{.*}} @"$S15generic_classes11RootGenericCMP"{{.*}})
 // -- initialize the dependent field offsets
 // CHECK:   call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}})
 // CHECK: }
 
 // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S15generic_classes22RootGenericFixedLayoutCMi"(%swift.type_descriptor*, i8**) {{.*}} {
-// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, {{.*}}, i64 5)
+// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, {{.*}} @"$S15generic_classes22RootGenericFixedLayoutCMP"{{.*}})
 // CHECK:   call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 3, i8*** {{%.*}}, i64* {{%.*}})
 // CHECK: }
 
@@ -309,10 +350,7 @@
 // CHECK:   [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
 // CHECK:   %B  = load %swift.type*, %swift.type** [[T1]]
 //   Construct the superclass.
-// CHECK:   [[SUPER:%.*]] = call %swift.type* @"$S15generic_classes11RootGenericCMa"(%swift.type* %A)
-// CHECK:   [[T0:%.*]] = bitcast %swift.type* [[SUPER]] to %objc_class*
-// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** {{.*}}, i64 96, i64 16, i8** %1, %objc_class* [[T0]], i64 6)
-// CHECK-objc:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** {{.*}}, i64 280, i64 200, i8** %1, %objc_class* [[T0]], i64 6)
+// CHECK:   [[METADATA:%.*]] ={{( tail)?}} call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, {{.*}} @"$S15generic_classes015GenericInheritsC0CMP"{{.*}})
 // CHECK:   [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
 //   Put the generic arguments in their correct positions.
 // CHECK:   [[A_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i64 18
@@ -321,26 +359,10 @@
 // CHECK:   [[B_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i64 19
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* %B to i8*
 // CHECK:   store i8* [[T0]], i8** [[B_ADDR]], align 8
-//   Set up the isa.
-// CHECK-objc:   [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
-// CHECK-objc:   [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 0
-// CHECK-objc:   [[T1:%.*]] = bitcast i8** [[T0]] to %objc_class**
-// CHECK-objc:   [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -25
-// CHECK-objc:   [[METACLASS:%.*]] = bitcast i8** [[T0]] to %objc_class*
-// CHECK-objc:   store %objc_class* [[METACLASS]], %objc_class** [[T1]], align 8
-//   Set up the instance rodata pointer.
-// CHECK-objc:   [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 4
-// CHECK-objc:   [[T1:%.*]] = bitcast i8** [[T0]] to i64*
-// CHECK-objc:   [[RODATA:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -20
-// CHECK-objc:   [[T2:%.*]] = ptrtoint i8** [[RODATA]] to i64
-// CHECK-objc:   [[T3:%.*]] = or i64 [[T2]], 1
-// CHECK-objc:   store i64 [[T3]], i64* [[T1]], align 8
-//   Set up the class rodata pointer.
-// CHECK-objc:   [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -21
-// CHECK-objc:   [[T1:%.*]] = bitcast i8** [[T0]] to i64*
-// CHECK-objc:   [[META_RODATA:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 -11
-// CHECK-objc:   [[T2:%.*]] = ptrtoint i8** [[META_RODATA]] to i64
-// CHECK-objc:   store i64 [[T2]], i64* [[T1]], align 8
+// CHECK:   [[SUPER:%.*]] ={{( tail)?}} call %swift.type* @"$S15generic_classes11RootGenericCMa"(%swift.type* %A)
+// CHECK:   [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type**
+// CHECK:   [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
+// CHECK:   store %swift.type* [[SUPER]], %swift.type** [[T1]],
 //   Initialize our own dependent field offsets.
 // CHECK:   [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i64*
 // CHECK:   [[OFFSETS:%.*]] = getelementptr inbounds i64, i64* [[METADATA_ARRAY]], i64 23
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 7af64cd..cfe09bc 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -29,8 +29,6 @@
 // CHECK-SAME:   i32 1,
 // --       field offset vector offset
 // CHECK-SAME:   i32 3,
-// --       generic parameter vector offset
-// CHECK-SAME:   i32 2,
 // --       generic instantiation info
 // CHECK-SAME:   %swift.type* (%swift.type_descriptor*, i8**)* @"$S15generic_structs13SingleDynamicVMi"
 // CHECK-SAME:   [{{[0-9]+}} x i8*]* @"$S15generic_structs13SingleDynamicVMI"
@@ -59,8 +57,6 @@
 // CHECK-SAME: i32 2,
 // --       field offset vector offset
 // CHECK-SAME: i32 6,
-// --       generic parameter vector offset
-// CHECK-SAME: i32 2,
 // --       generic params, requirements, key args, extra args
 // CHECK-SAME: i32 2, i32 2, i32 2, i32 2,
 // --       generic parameters
diff --git a/test/IRGen/generic_types.swift b/test/IRGen/generic_types.swift
index a6dc47d..bae4cd4 100644
--- a/test/IRGen/generic_types.swift
+++ b/test/IRGen/generic_types.swift
@@ -11,30 +11,43 @@
 // CHECK-LABEL: @"$S13generic_types1ACMI" = internal global [16 x i8*] zeroinitializer, align 8
 
 // CHECK-LABEL: @"$S13generic_types1ACMn" = hidden constant
+// CHECK-SAME:   i32 -2147221296,
+// CHECK-SAME:   @"$S13generic_typesMXM"
+//               <name>
 // CHECK-SAME:   @"$S13generic_types1ACMa"
+// -- superclass
+// CHECK-SAME:   i32 0,
+// -- negative size in words
+// CHECK-SAME:   i32 2,
+// -- positive size in words
+// CHECK-SAME:   i32 17,
+// -- num immediate members
+// CHECK-SAME:   i32 7,
+// -- num fields
+// CHECK-SAME:   i32 1,
+// -- field offset vector offset
+// CHECK-SAME:   i32 16,
+// -- instantiation function
 // CHECK-SAME:   @"$S13generic_types1ACMi"
+// -- instantiation cache
 // CHECK-SAME:   @"$S13generic_types1ACMI"
+// -- num generic params
+// CHECK-SAME:   i32 1,
+// -- num generic requirement
+// CHECK-SAME:   i32 0,
+// -- num key arguments
+// CHECK-SAME:   i32 1,
+// -- num extra arguments
+// CHECK-SAME:   i32 0,
+// -- parameter descriptor 1
+// CHECK-SAME:   i8 -128,
 
 // CHECK-LABEL: @"$S13generic_types1ACMP" = internal constant
 // CHECK-SAME:   void ([[A]]*)* @"$S13generic_types1ACfD",
-// CHECK-SAME:   i8** @"$SBoWV",
-// CHECK-SAME:   i64 0,
-// CHECK-SAME:   %swift.type* null,
-// CHECK-native-SAME: %swift.opaque* null,
-// CHECK-objc-SAME:   %swift.opaque* @_objc_empty_cache,
-// CHECK-SAME:   %swift.opaque* null,
-// CHECK-SAME:   i64 {{1|2}},
-// CHECK-SAME:   i32 {{3|2}},
-// CHECK-SAME:   i32 0,
-// CHECK-SAME:   i32 24,
-// CHECK-SAME:   i16 7,
-// CHECK-SAME:   i16 0,
-// CHECK-SAME:   i32 152,
-// CHECK-SAME:   i32 16,
-// -- nominal type descriptor
-// CHECK-SAME:   @"$S13generic_types1ACMn",
 // -- ivar destroyer
-// CHECK-SAME:   i8* null
+// CHECK-SAME:   i8* null,
+// -- flags
+// CHECK-SAME:   i32 {{3|2}},
 // CHECK-SAME: }
 
 // CHECK-LABEL: @"$S13generic_types1BCMI" = internal global [16 x i8*] zeroinitializer, align 8
@@ -46,77 +59,29 @@
 
 // CHECK-LABEL: @"$S13generic_types1BCMP" = internal constant
 // CHECK-SAME:   void ([[B]]*)* @"$S13generic_types1BCfD",
-// CHECK-SAME:   i8** @"$SBoWV",
-// CHECK-SAME:   i64 0,
-// CHECK-SAME:   %swift.type* null,
-// CHECK-native-SAME: %swift.opaque* null,
-// CHECK-objc-SAME:   %swift.opaque* @_objc_empty_cache,
-// CHECK-SAME:   %swift.opaque* null,
-// CHECK-SAME:   i64 {{1|2}},
-// CHECK-SAME:   i32 {{3|2}},
-// CHECK-SAME:   i32 0,
-// CHECK-SAME:   i32 24,
-// CHECK-SAME:   i16 7,
-// CHECK-SAME:   i16 0,
-// CHECK-SAME:   i32 144,
-// CHECK-SAME:   i32 16,
-// -- nominal type descriptor
-// CHECK-SAME:   @"$S13generic_types1BCMn",
 // -- ivar destroyer
 // CHECK-SAME:   i8* null
+// CHECK-SAME:   i32 {{3|2}},
 // CHECK-SAME: }
 
 // CHECK-LABEL: @"$S13generic_types1CCMP" = internal constant
 // CHECK-SAME:   void ([[C]]*)* @"$S13generic_types1CCfD",
-// CHECK-SAME:   i8** @"$SBoWV",
-// CHECK-SAME:   i64 0,
-// CHECK-SAME:   %swift.type* null,
-// CHECK-native-SAME: %swift.opaque* null,
-// CHECK-objc-SAME:   %swift.opaque* @_objc_empty_cache,
-// CHECK-SAME:   %swift.opaque* null,
-// CHECK-SAME:   i64 {{1|2}},
-// CHECK-SAME:   i32 {{3|2}},
-// CHECK-SAME:   i32 0,
-// CHECK-SAME:   i32 24,
-// CHECK-SAME:   i16 7,
-// CHECK-SAME:   i16 0,
-// CHECK-SAME:   i32 160,
-// CHECK-SAME:   i32 16,
-// -- nominal type descriptor
-// CHECK-SAME:   @"$S13generic_types1CCMn",
 // -- ivar destroyer
 // CHECK-SAME:   i8* null
+// CHECK-SAME:   i32 {{3|2}},
 // CHECK-SAME: }
 
 // CHECK-LABEL: @"$S13generic_types1DCMP" = internal constant
 // CHECK-SAME:   void ([[D]]*)* @"$S13generic_types1DCfD",
-// CHECK-SAME:   i8** @"$SBoWV",
-// CHECK-SAME:   i64 0,
-// CHECK-SAME:   %swift.type* null,
-// CHECK-native-SAME: %swift.opaque* null,
-// CHECK-objc-SAME:   %swift.opaque* @_objc_empty_cache,
-// CHECK-SAME:   %swift.opaque* null,
-// CHECK-SAME:   i64 {{1|2}},
-// CHECK-SAME:   i32 {{3|2}},
-// CHECK-SAME:   i32 0,
-// CHECK-SAME:   i32 24,
-// CHECK-SAME:   i16 7,
-// CHECK-SAME:   i16 0,
-// CHECK-SAME:   i32 160,
-// CHECK-SAME:   i32 16,
-// -- nominal type descriptor
-// CHECK-SAME:   @"$S13generic_types1DCMn",
 // -- ivar destroyer
 // CHECK-SAME:   i8* null
+// CHECK-SAME:   i32 {{3|2}},
 // CHECK-SAME: }
 
 // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S13generic_types1ACMi"(%swift.type_descriptor*, i8**) {{.*}} {
 // CHECK:   [[T0:%.*]] = bitcast i8** %1 to %swift.type**
 // CHECK:   %T = load %swift.type*, %swift.type** [[T0]],
-// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}}* @"$S13generic_types1ACMP" to i8**), i64 96, i64 16, i8** %1, %objc_class* null, i64 7)
-// CHECK-objc:   [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$__TtCs12_SwiftObject"
-// CHECK-objc:   [[SUPER:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T0]])
-// CHECK-objc:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}}* @"$S13generic_types1ACMP" to i8**), i64 280, i64 200, i8** %1, %objc_class* [[SUPER]], i64 7)
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** bitcast ({{.*}}* @"$S13generic_types1ACMP" to i8**))
 // CHECK:   [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
 // CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i64 10
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* %T to i8*
@@ -127,10 +92,7 @@
 // CHECK-LABEL: define{{( protected)?}} internal %swift.type* @"$S13generic_types1BCMi"(%swift.type_descriptor*, i8**) {{.*}} {
 // CHECK:   [[T0:%.*]] = bitcast i8** %1 to %swift.type**
 // CHECK:   %T = load %swift.type*, %swift.type** [[T0]],
-// CHECK-native: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}}* @"$S13generic_types1BCMP" to i8**), i64 96, i64 16, i8** %1, %objc_class* null, i64 6)
-// CHECK-objc:   [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$__TtCs12_SwiftObject"
-// CHECK-objc:   [[SUPER:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T0]])
-// CHECK-objc:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}}* @"$S13generic_types1BCMP" to i8**), i64 280, i64 200, i8** %1, %objc_class* [[SUPER]], i64 6)
+// CHECK:   [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** bitcast ({{.*}}* @"$S13generic_types1BCMP" to i8**))
 // CHECK:   [[SELF_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
 // CHECK:   [[T1:%.*]] = getelementptr inbounds i8*, i8** [[SELF_ARRAY]], i64 10
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* %T to i8*
diff --git a/test/IRGen/generic_vtable.swift b/test/IRGen/generic_vtable.swift
index dd5c8f0..4b972ef 100644
--- a/test/IRGen/generic_vtable.swift
+++ b/test/IRGen/generic_vtable.swift
@@ -63,8 +63,6 @@
 //// instantiation time.
 
 // CHECK-LABEL: @"$S14generic_vtable7DerivedCMP" = internal constant <{{.*}}> <{
-// -- nominal type descriptor
-// CHECK-SAME: @"$S14generic_vtable7DerivedCMn",
 // -- ivar destroyer
 // CHECK-SAME: i8* null
 // --
@@ -105,7 +103,7 @@
 // - 2 immediate members:
 //   - type metadata for generic parameter T,
 //   - and vtable entry for 'm3()'
-// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** bitcast ({{.*}} @"$S14generic_vtable7DerivedCMP" to i8**), i64 {{[0-9]+}}, i64 {{[0-9]+}}, i8** %1, {{.*}}, i64 2)
+// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_descriptor* %0, i8** %1, i8** bitcast ({{.*}} @"$S14generic_vtable7DerivedCMP" to i8**))
 
 // CHECK: call void @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 0, {{.*}})
 
diff --git a/test/IRGen/objc_bridged_generic_conformance.swift b/test/IRGen/objc_bridged_generic_conformance.swift
index f13b2e6..bf103db 100644
--- a/test/IRGen/objc_bridged_generic_conformance.swift
+++ b/test/IRGen/objc_bridged_generic_conformance.swift
@@ -3,7 +3,7 @@
 
 // CHECK-NOT: _TMnCSo
 
-// CHECK: @"$SSo6ThingyCyxG32objc_bridged_generic_conformance1PADMc" = hidden constant %swift.protocol_conformance_descriptor {{.*}} @"OBJC_CLASS_REF_$_Thingy"
+// CHECK: @"$SSo6ThingyCyxG32objc_bridged_generic_conformance1PADMc" = hidden constant %swift.protocol_conformance_descriptor {{.*}} @"got.OBJC_CLASS_$_Thingy"
 
 // CHECK-NOT: _TMnCSo
 
diff --git a/test/IRGen/objc_retainAutoreleasedReturnValue.swift b/test/IRGen/objc_retainAutoreleasedReturnValue.swift
index a8d1a27..204c791 100644
--- a/test/IRGen/objc_retainAutoreleasedReturnValue.swift
+++ b/test/IRGen/objc_retainAutoreleasedReturnValue.swift
@@ -24,13 +24,15 @@
 // popq   %rbp  ;<== Blocks the handshake from objc_autoreleaseReturnValue
 // jmp    0x01ec20 ; symbol stub for: objc_retainAutoreleasedReturnValue
 
-// CHECK-LABEL: define {{.*}}swiftcc void @"$S34objc_retainAutoreleasedReturnValue4testyySo12NSDictionaryCFyADXEfU_"(%TSo12NSDictionaryC*)
+// CHECK-LABEL: define {{.*}}swiftcc %TSo12NSEnumeratorC* @"$S34objc_retainAutoreleasedReturnValue4testyySo12NSDictionaryCFSo12NSEnumeratorCADXEfU_"(%TSo12NSDictionaryC*)
 // CHECK: entry:
 // CHECK:   call {{.*}}@objc_msgSend
 // CHECK:   notail call i8* @objc_retainAutoreleasedReturnValue
-// CHECK:   ret void
+// CHECK:   ret %TSo12NSEnumeratorC*
 
-// OPT-LABEL: define {{.*}}swiftcc void @"$S34objc_retainAutoreleasedReturnValue4testyySo12NSDictionaryCFyADXEfU_"(%TSo12NSDictionaryC*)
+// CHECK-LABEL: define {{.*}}swiftcc void @"$SSo12NSDictionaryCSo12NSEnumeratorCIgxo_ABIegx_TR"(%TSo12NSDictionaryC*, i8*, %swift.opaque*)
+
+// OPT-LABEL: define {{.*}}swiftcc void @"$S34objc_retainAutoreleasedReturnValue10useClosureyySo12NSDictionaryC_yADXEtF06$SSo12h44CSo12NSEnumeratorCIgxo_ABIegx_TR049$S34objc_bcD42Value4testyySo12a6CFSo12B8CADXEfU_Tf3npf_nTf1nc_nTf4g_n"(%TSo12NSDictionaryC*)
 // OPT: entry:
 // OPT:   call {{.*}}@objc_msgSend
 // OPT:   notail call i8* @objc_retainAutoreleasedReturnValue
diff --git a/test/IRGen/protocol_conformance_records_objc.swift b/test/IRGen/protocol_conformance_records_objc.swift
index ca77b8d..c323623 100644
--- a/test/IRGen/protocol_conformance_records_objc.swift
+++ b/test/IRGen/protocol_conformance_records_objc.swift
@@ -30,7 +30,7 @@
 // -- protocol descriptor
 // CHECK-SAME:           [[RUNCIBLE]]
 // -- class object reference
-// CHECK-SAME:           @"OBJC_CLASS_REF_$_Gizmo"
+// CHECK-SAME:           @"got.OBJC_CLASS_$_Gizmo"
 // -- witness table
 // CHECK-SAME:           @"$SSo5GizmoC33protocol_conformance_records_objc8RuncibleACWP"
 // -- flags
diff --git a/test/IRGen/super.sil b/test/IRGen/super.sil
index 6128570..e236e47 100644
--- a/test/IRGen/super.sil
+++ b/test/IRGen/super.sil
@@ -54,7 +54,7 @@
 // ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly.
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S5super22ChildToResilientParentC6methodyyF"(%T5super22ChildToResilientParentC* swiftself)
 // CHECK: [[SUPER_METADATA:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
-// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo"
+// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS:{.*}]], {{.*}}* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
 // CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{20|40}}
 // CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8*
 // CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]]
@@ -76,7 +76,7 @@
 // ChildToResilientParent is in our resilience domain - can load the superclass's metadata directly.
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @"$S5super22ChildToResilientParentC11classMethodyyFZ"(%swift.type* swiftself)
 // CHECK: [[SUPER_METADATA:%.*]] = call %swift.type* @"$S15resilient_class22ResilientOutsideParentCMa"()
-// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo"
+// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
 // CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{24|48}}
 // CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8*
 // CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]]
@@ -151,7 +151,7 @@
 // CHECK: [[OPAQUE_METADATA:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type**
 // CHECK: [[SUPER_METADATA_PTR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1
 // CHECK: [[SUPER_METADATA:%.*]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]]
-// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo"
+// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
 // CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{20|40}}
 // CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8*
 // CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]]
@@ -177,7 +177,7 @@
 // CHECK: [[OPAQUE_METADATA:%.*]] = bitcast %swift.type* [[METADATA]] to %swift.type**
 // CHECK: [[SUPER_METADATA_PTR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[OPAQUE_METADATA]], i32 1
 // CHECK: [[SUPER_METADATA:%.*]] = load %swift.type*, %swift.type** [[SUPER_METADATA_PTR]]
-// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* @"$S15resilient_class22ResilientOutsideParentCMo"
+// CHECK: [[BASE:%.*]] = load [[INT]], [[INT]]* getelementptr inbounds ([[BOUNDS]], [[BOUNDS]]* @"$S15resilient_class22ResilientOutsideParentCMo", i32 0, i32 0)
 // CHECK: [[VTABLE_OFFSET:%.*]] = add [[INT]] [[BASE]], {{24|48}}
 // CHECK: [[SUPER_ADDR:%.*]] = bitcast %swift.type* [[SUPER_METADATA]] to i8*
 // CHECK: [[VTABLE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SUPER_ADDR]], [[INT]] [[VTABLE_OFFSET]]
diff --git a/test/Inputs/conditional_conformance_basic_conformances.swift b/test/Inputs/conditional_conformance_basic_conformances.swift
index 047a9cb..fdbf82c 100644
--- a/test/Inputs/conditional_conformance_basic_conformances.swift
+++ b/test/Inputs/conditional_conformance_basic_conformances.swift
@@ -323,3 +323,11 @@
 func dynamicCastToP1(_ value: Any) -> P1? {
   return value as? P1
 }
+
+protocol P4 {}
+typealias P4Typealias = P4
+protocol P5 {}
+
+struct SR7101<T> {}
+extension SR7101 : P5 where T == P4Typealias {}
+
diff --git a/test/Interpreter/class_in_constrained_extension.swift b/test/Interpreter/class_in_constrained_extension.swift
new file mode 100644
index 0000000..7ffad46
--- /dev/null
+++ b/test/Interpreter/class_in_constrained_extension.swift
@@ -0,0 +1,16 @@
+// RUN: %target-run-simple-swift | %FileCheck %s
+// REQUIRES: executable_test
+
+class Foo {}
+
+extension Array where Element == Foo {
+  class Bar { var foo = Foo() }
+  
+  init(withAThing: String) {
+    self = [Bar(), Bar(), Bar()].map { $0.foo }
+  }
+}
+
+// CHECK: [main.Foo, main.Foo, main.Foo]
+let foos = [Foo](withAThing: "Hi")
+print(foos)
diff --git a/test/Misc/Inputs/serialized-diagnostics-batch-mode-helper.swift b/test/Misc/Inputs/serialized-diagnostics-batch-mode-helper.swift
new file mode 100644
index 0000000..d65201b
--- /dev/null
+++ b/test/Misc/Inputs/serialized-diagnostics-batch-mode-helper.swift
@@ -0,0 +1,3 @@
+func testHelper() {
+  nonexistent()
+}
diff --git a/test/Misc/Inputs/serialized-diagnostics-batch-mode-other.swift b/test/Misc/Inputs/serialized-diagnostics-batch-mode-other.swift
new file mode 100644
index 0000000..d0d8ce2
--- /dev/null
+++ b/test/Misc/Inputs/serialized-diagnostics-batch-mode-other.swift
@@ -0,0 +1,6 @@
+func foo() {}
+func foo() {}
+
+func bar() {
+  shouldNotShowUpInOutput()
+}
diff --git a/test/Misc/serialized-diagnostics-batch-mode.swift b/test/Misc/serialized-diagnostics-batch-mode.swift
new file mode 100644
index 0000000..2b25fab
--- /dev/null
+++ b/test/Misc/serialized-diagnostics-batch-mode.swift
@@ -0,0 +1,33 @@
+// RUN: rm -f %t.*
+
+// RUN: not %target-swift-frontend -typecheck -primary-file %s  -serialize-diagnostics-path %t.main.dia -primary-file %S/Inputs/serialized-diagnostics-batch-mode-helper.swift  -serialize-diagnostics-path %t.helper.dia %S/Inputs/serialized-diagnostics-batch-mode-other.swift 2> %t.stderr.txt
+// RUN: %FileCheck -check-prefix=CHECK-STDERR %s < %t.stderr.txt
+// RUN: %FileCheck -check-prefix=NEGATIVE-STDERR %s < %t.stderr.txt
+
+// RUN: c-index-test -read-diagnostics %t.main.dia 2> %t.main.txt
+// RUN: %FileCheck -check-prefix=CHECK-MAIN %s < %t.main.txt
+// RUN: %FileCheck -check-prefix=NEGATIVE-MAIN %s < %t.main.txt
+
+// RUN: c-index-test -read-diagnostics %t.helper.dia 2> %t.helper.txt
+// RUN: %FileCheck -check-prefix=CHECK-HELPER %s < %t.helper.txt
+// RUN: %FileCheck -check-prefix=NEGATIVE-HELPER %s < %t.helper.txt
+
+// NEGATIVE-MAIN-NOT: shouldNotShowUpInOutput
+// NEGATIVE-HELPER-NOT: shouldNotShowUpInOutput
+// NEGATIVE-STDERR-NOT: shouldNotShowUpInOutput
+
+// NEGATIVE-MAIN-NOT: serialized-diagnostics-batch-mode-helper.swift
+// NEGATIVE-HELPER-NOT: serialized-diagnostics-batch-mode.swift
+
+// CHECK-MAIN-DAG: serialized-diagnostics-batch-mode-other.swift:{{[0-9]+}}:6: error: invalid redeclaration of 'foo()' 
+// CHECK-HELPER-DAG: serialized-diagnostics-batch-mode-other.swift:{{[0-9]+}}:6: error: invalid redeclaration of 'foo()'
+// CHECK-STDERR-DAG: serialized-diagnostics-batch-mode-other.swift:{{[0-9]+}}:6: error: invalid redeclaration of 'foo()'
+
+func test() {
+  nonexistent() // CHECK-MAIN-DAG: serialized-diagnostics-batch-mode.swift:[[@LINE]]:3: error: use of unresolved identifier 'nonexistent'
+  // CHECK-STDERR-DAG: serialized-diagnostics-batch-mode.swift:[[@LINE-1]]:3: error: use of unresolved identifier 'nonexistent'
+
+  // The other file has a similar call.
+  // CHECK-HELPER-DAG: serialized-diagnostics-batch-mode-helper.swift:{{[0-9]+}}:3: error: use of unresolved identifier 'nonexistent'
+  // CHECK-STDERR-DAG: serialized-diagnostics-batch-mode-helper.swift:{{[0-9]+}}:3: error: use of unresolved identifier 'nonexistent'
+}
diff --git a/test/Parse/ConditionalCompilation/language_version_explicit.swift b/test/Parse/ConditionalCompilation/language_version_explicit.swift
index 5baef8a..83fd2da 100644
--- a/test/Parse/ConditionalCompilation/language_version_explicit.swift
+++ b/test/Parse/ConditionalCompilation/language_version_explicit.swift
@@ -21,10 +21,19 @@
   asdf asdf asdf asdf
 #endif
 
-#if swift(>=4.0.1)
-  let z = 1
+// NOTE: Please modify this condition...
+#if swift(>=4.2)
+  let b = 1
 #else
   // This shouldn't emit any diagnostics.
   asdf asdf asdf asdf
 #endif
 
+// NOTE: ...and modify this condition...
+#if swift(>=4.2.1)
+  // This shouldn't emit any diagnostics.
+  asdf asdf asdf asdf
+#else
+  let c = 1
+#endif
+// NOTE: ...the next time the version goes up.
diff --git a/test/SILGen/shared.swift b/test/SILGen/shared.swift
index b0d549a..dd3c974 100644
--- a/test/SILGen/shared.swift
+++ b/test/SILGen/shared.swift
@@ -124,3 +124,58 @@
 
 // CHECK-LABEL: sil hidden @$S6shared0A17_closure_loweringyyySi_AA14ValueAggregateVAA03RefE0CtchF : $@convention(thin) (@guaranteed @callee_guaranteed (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> ()
 func shared_closure_lowering(_ f : __shared (Int, ValueAggregate, RefAggregate) -> Void) {}
+
+struct Foo {
+    var x: ValueAggregate
+
+    // CHECK-LABEL: sil hidden @$S6shared3FooV21methodSharedArguments7trivial5value3refySih_AA14ValueAggregateVhAA03RefJ0ChtF : $@convention(method) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate, @guaranteed Foo) -> () {
+    func methodSharedArguments(trivial : __shared Int, value : __shared ValueAggregate, ref : __shared RefAggregate) {
+        // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @guaranteed $ValueAggregate, [[REF_VAL:%[0-9]+]] : @guaranteed $RefAggregate, [[SELF:%[0-9]+]] : @guaranteed $Foo):
+        // CHECK: [[COPY_VALUE_VAL:%[0-9]+]] = copy_value [[VALUE_VAL]] : $ValueAggregate
+        // CHECK: [[COPY_REF_VAL:%[0-9]+]] = copy_value [[REF_VAL]] : $RefAggregate
+        // CHECK: [[OWNED_FUNC:%[0-9]+]] = function_ref @$S6shared3FooV20methodOwnedArguments7trivial5value3refySi_AA14ValueAggregateVAA03RefJ0CtF
+        // CHECK: {{%.*}} = apply [[OWNED_FUNC]]([[TRIVIAL_VAL]], [[COPY_VALUE_VAL]], [[COPY_REF_VAL]], [[SELF]]) : $@convention(method) (Int, @owned ValueAggregate, @owned RefAggregate, @guaranteed Foo) -> ()
+        // CHECK: } // end sil function '$S6shared3FooV21methodSharedArguments7trivial5value3refySih_AA14ValueAggregateVhAA03RefJ0ChtF'
+        return methodOwnedArguments(trivial: trivial, value: value, ref: ref)
+    }
+
+    // CHECK-LABEL: sil hidden @$S6shared3FooV20methodOwnedArguments7trivial5value3refySi_AA14ValueAggregateVAA03RefJ0CtF : $@convention(method) (Int, @owned ValueAggregate, @owned RefAggregate, @guaranteed Foo) -> () {
+    func methodOwnedArguments(trivial : Int, value : ValueAggregate, ref : RefAggregate) {
+        // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @owned $ValueAggregate, [[REF_VAL:%[0-9]+]] : @owned $RefAggregate, [[SELF:%[0-9]+]] : @guaranteed $Foo):
+        // CHECK: [[BORROW_VALUE_VAL:%[0-9]+]] = begin_borrow [[VALUE_VAL]] : $ValueAggregate
+        // CHECK: [[BORROW_REF_VAL:%[0-9]+]] = begin_borrow [[REF_VAL]] : $RefAggregate
+        // CHECK: [[SHARED_FUNC:%[0-9]+]] = function_ref @$S6shared3FooV21methodSharedArguments7trivial5value3refySih_AA14ValueAggregateVhAA03RefJ0ChtF
+        // CHECK: {{%.*}} = apply [[SHARED_FUNC]]([[TRIVIAL_VAL]], [[BORROW_VALUE_VAL]], [[BORROW_REF_VAL]], [[SELF]])
+        // CHECK: end_borrow [[BORROW_REF_VAL]] from [[REF_VAL]] : $RefAggregate, $RefAggregate
+        // CHECK: end_borrow [[BORROW_VALUE_VAL]] from [[VALUE_VAL]] : $ValueAggregate, $ValueAggregate
+        // CHECK: destroy_value [[REF_VAL]] : $RefAggregate
+        // CHECK: destroy_value [[VALUE_VAL]] : $ValueAggregate
+        // CHECK: } // end sil function '$S6shared3FooV20methodOwnedArguments7trivial5value3refySi_AA14ValueAggregateVAA03RefJ0CtF'
+        return methodSharedArguments(trivial: trivial, value: value, ref: ref)
+    }
+
+    // CHECK-LABEL: sil hidden @$S6shared3FooV21staticSharedArguments7trivial5value3refySih_AA14ValueAggregateVhAA03RefJ0ChtFZ : $@convention(method) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate, @thin Foo.Type) -> () {
+    static func staticSharedArguments(trivial : __shared Int, value : __shared ValueAggregate, ref : __shared RefAggregate) {
+        // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @guaranteed $ValueAggregate, [[REF_VAL:%[0-9]+]] : @guaranteed $RefAggregate, [[SELF_METATYPE:%[0-9]+]] : @trivial $@thin Foo.Type):
+        // CHECK: [[COPY_VALUE_VAL:%[0-9]+]] = copy_value [[VALUE_VAL]] : $ValueAggregate
+        // CHECK: [[COPY_REF_VAL:%[0-9]+]] = copy_value [[REF_VAL]] : $RefAggregate
+        // CHECK: [[OWNED_FUNC:%[0-9]+]] = function_ref @$S6shared3FooV20staticOwnedArguments7trivial5value3refySi_AA14ValueAggregateVAA03RefJ0CtFZ
+        // CHECK: {{%.*}} = apply [[OWNED_FUNC]]([[TRIVIAL_VAL]], [[COPY_VALUE_VAL]], [[COPY_REF_VAL]], [[SELF_METATYPE]]) : $@convention(method) (Int, @owned ValueAggregate, @owned RefAggregate, @thin Foo.Type) -> ()
+        // CHECK: } // end sil function '$S6shared3FooV21staticSharedArguments7trivial5value3refySih_AA14ValueAggregateVhAA03RefJ0ChtFZ'
+        return staticOwnedArguments(trivial: trivial, value: value, ref: ref)
+    }
+    // CHECK-LABEL: sil hidden @$S6shared3FooV20staticOwnedArguments7trivial5value3refySi_AA14ValueAggregateVAA03RefJ0CtFZ : $@convention(method) (Int, @owned ValueAggregate, @owned RefAggregate, @thin Foo.Type) -> () {
+    static func staticOwnedArguments(trivial : Int, value : ValueAggregate, ref : RefAggregate) {
+        // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @owned $ValueAggregate, [[REF_VAL:%[0-9]+]] : @owned $RefAggregate, [[SELF_METATYPE:%[0-9]+]] : @trivial $@thin Foo.Type):
+        // CHECK: [[BORROW_VALUE_VAL:%[0-9]+]] = begin_borrow [[VALUE_VAL]] : $ValueAggregate
+        // CHECK: [[BORROW_REF_VAL:%[0-9]+]] = begin_borrow [[REF_VAL]] : $RefAggregate
+        // CHECK: [[SHARED_FUNC:%[0-9]+]] = function_ref @$S6shared3FooV21staticSharedArguments7trivial5value3refySih_AA14ValueAggregateVhAA03RefJ0ChtFZ
+        // CHECK: {{%.*}} = apply [[SHARED_FUNC]]([[TRIVIAL_VAL]], [[BORROW_VALUE_VAL]], [[BORROW_REF_VAL]], [[SELF_METATYPE]])
+        // CHECK: end_borrow [[BORROW_REF_VAL]] from [[REF_VAL]] : $RefAggregate, $RefAggregate
+        // CHECK: end_borrow [[BORROW_VALUE_VAL]] from [[VALUE_VAL]] : $ValueAggregate, $ValueAggregate
+        // CHECK: destroy_value [[REF_VAL]] : $RefAggregate
+        // CHECK: destroy_value [[VALUE_VAL]] : $ValueAggregate
+        // CHECK: } // end sil function '$S6shared3FooV20staticOwnedArguments7trivial5value3refySi_AA14ValueAggregateVAA03RefJ0CtFZ'
+        return staticSharedArguments(trivial: trivial, value: value, ref: ref)
+    }
+}
diff --git a/test/SILOptimizer/access_enforcement_selection.sil b/test/SILOptimizer/access_enforcement_selection.sil
index edc9bab..da682f9 100644
--- a/test/SILOptimizer/access_enforcement_selection.sil
+++ b/test/SILOptimizer/access_enforcement_selection.sil
@@ -228,3 +228,36 @@
   %closure = partial_apply %f(%0) : $@convention(thin) (@inout_aliasable Builtin.Int64) -> ()
   unreachable
 }
+
+sil [canonical] @serializedClosureCapturingByStorageAddress : $@convention(thin) (@inout_aliasable Builtin.Int64) -> () {
+bb0(%0 : @trivial $*Builtin.Int64):
+  %2 = begin_access [read] [unknown] %0 : $*Builtin.Int64
+  %3 = load [trivial] %2 : $*Builtin.Int64
+  end_access %2 : $*Builtin.Int64
+  %10 = tuple ()
+  return %10 : $()
+}
+
+// A begin_access may not be used by a partial_apply or a nested
+// begin_access prior to mandatory inlining. Nonetheless, this does
+// occur in deserialzied SIL. This SIL is only well-formed because the
+// function is marked [canonical].
+sil [canonical] @accessAroundClosure : $@convention(thin) () -> () {
+bb0:
+  %1 = alloc_box ${ var Builtin.Int64 }, var, name "x"
+  %2 = copy_value %1 : ${ var Builtin.Int64 }
+  %3 = project_box %1 : ${ var Builtin.Int64 }, 0
+  // outer access (presumably its uses were mandatory inlined)
+  %4 = begin_access [modify] [static] %3 : $*Builtin.Int64
+  %5 = function_ref @serializedClosureCapturingByStorageAddress : $@convention(thin) (@inout_aliasable Builtin.Int64) -> ()
+  %6 = partial_apply %5(%4) : $@convention(thin) (@inout_aliasable Builtin.Int64) -> ()
+  %7 = begin_access [modify] [static] %4 : $*Builtin.Int64
+  %8 = function_ref @takesInoutAndClosure : $@convention(thin) (@inout Builtin.Int64, @owned @callee_owned () -> ()) -> ()
+  %9 = apply %8(%7, %6) : $@convention(thin) (@inout Builtin.Int64, @owned @callee_owned () -> ()) -> ()
+  end_access %7 : $*Builtin.Int64
+  end_access %4 : $*Builtin.Int64
+  destroy_value %2 : ${ var Builtin.Int64 }
+  destroy_value %1 : ${ var Builtin.Int64 }
+  %10 = tuple ()
+  return %10 : $()
+}
diff --git a/test/Serialization/Recovery/crash-recovery.swift b/test/Serialization/Recovery/crash-recovery.swift
index aecd4d2..e198b5d 100644
--- a/test/Serialization/Recovery/crash-recovery.swift
+++ b/test/Serialization/Recovery/crash-recovery.swift
@@ -14,7 +14,7 @@
 
 // CHECK-CRASH: error: fatal error encountered while reading from module 'Lib'; please file a bug report with your project and the crash log
 // CHECK-CRASH-3-NOT: note
-// CHECK-CRASH-4: note: compiling as Swift 4.1, with 'Lib' built as Swift 3.3
+// CHECK-CRASH-4: note: compiling as Swift 4.2, with 'Lib' built as Swift 3.4
 // CHECK-CRASH-LABEL: *** DESERIALIZATION FAILURE (please include this section in any bug report) ***
 // CHECK-CRASH: could not find 'disappearingMethod()' in parent class
 // CHECK-CRASH: While loading members for 'Sub' in module 'Lib'
diff --git a/test/Serialization/Recovery/types-4-to-3.swift b/test/Serialization/Recovery/types-4-to-3.swift
index 380c3d0..f1e216f 100644
--- a/test/Serialization/Recovery/types-4-to-3.swift
+++ b/test/Serialization/Recovery/types-4-to-3.swift
@@ -16,8 +16,8 @@
 func requiresConformance(_: B_RequiresConformance<B_ConformsToProto>) {}
 func requiresConformance(_: B_RequiresConformance<C_RelyOnConformanceImpl.Assoc>) {}
 
-class Sub: Base {} // expected-error {{cannot inherit from class 'Base' (compiled with Swift 4.1) because it has overridable members that could not be loaded in Swift 3.3}}
-class Impl: Proto {} // expected-error {{type 'Impl' cannot conform to protocol 'Proto' (compiled with Swift 4.1) because it has requirements that could not be loaded in Swift 3.3}}
+class Sub: Base {} // expected-error {{cannot inherit from class 'Base' (compiled with Swift 4.2) because it has overridable members that could not be loaded in Swift 3.4}}
+class Impl: Proto {} // expected-error {{type 'Impl' cannot conform to protocol 'Proto' (compiled with Swift 4.2) because it has requirements that could not be loaded in Swift 3.4}}
 
 #else // TEST
 
diff --git a/test/Syntax/round_trip_nul.swift b/test/Syntax/round_trip_nul.swift
new file mode 100644
index 0000000..c53e9b9
--- /dev/null
+++ b/test/Syntax/round_trip_nul.swift
@@ -0,0 +1,5 @@
+// RUN: cat %s | tr '\132' '\0' > %t.tr
+// RUN: cp -f %t.tr %t
+// RUN: %round-trip-syntax-test --swift-syntax-test %swift-syntax-test --file %t
+let a = Z3Z // nul(Z)
+func b() {}
diff --git a/test/Syntax/tokens_nul.swift b/test/Syntax/tokens_nul.swift
new file mode 100644
index 0000000..4dd4efc
--- /dev/null
+++ b/test/Syntax/tokens_nul.swift
@@ -0,0 +1,28 @@
+// RUN: cat %s | tr '\132' '\0' > %t.tmp
+// RUN: cp -f %t.tmp %t
+// RUN: %swift-syntax-test -input-source-filename %t -dump-full-tokens 2>&1 | %FileCheck %t
+let a = Z3Z // nul(Z)
+func b() {}
+
+// CHECK: 4:9: warning: nul character embedded in middle of file
+// CHECK: 4:11: warning: nul character embedded in middle of file
+// CHECK: 4:20: warning: nul character embedded in middle of file
+
+// CHECK-LABEL: 4:7
+// CHECK-NEXT:(Token equal
+// CHECK-NEXT: (text="=")
+// CHECK-NEXT: (trivia space 1)
+// CHECK-NEXT: (trivia garbage_text \000))
+
+// CHECK-LABEL: 4:10
+// CHECK-NEXT:(Token integer_literal
+// CHECK-NEXT: (text="3")
+// CHECK-NEXT: (trivia garbage_text \000)
+// CHECK-NEXT: (trivia space 1))
+
+// CHECK-LABEL: 5:1
+// CHECK-NEXT:(Token kw_func
+// CHECK-NEXT: (trivia line_comment // nul(\000))
+// CHECK-NEXT: (trivia newline 1)
+// CHECK-NEXT: (text="func")
+// CHECK-NEXT: (trivia space 1))
diff --git a/test/api-digester/Inputs/cake.swift b/test/api-digester/Inputs/cake.swift
index 05f2188..5f69e0d 100644
--- a/test/api-digester/Inputs/cake.swift
+++ b/test/api-digester/Inputs/cake.swift
@@ -1,4 +1,6 @@
-public struct S1 {
+public protocol P1 {}
+public protocol P2 {}
+public struct S1: P1 {
   public static func foo1() {}
   mutating public func foo2() {}
   internal func foo3() {}
@@ -7,6 +9,8 @@
   public func foo6() -> Void {}
 }
 
+extension S1: P2 {}
+
 public class C0<T1, T2, T3> {}
 
 public class C1: C0<S1, S1, S1> {
@@ -24,4 +28,8 @@
 }
 
 public func foo1(_ a: Int = 1, b: S1) {}
-public func foo2(_ a: Int = #line, b: S1) {}
\ No newline at end of file
+public func foo2(_ a: Int = #line, b: S1) {}
+
+public enum Number: Int {
+  case one
+}
\ No newline at end of file
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index 286c8f0..db252e1 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -5,6 +5,24 @@
   "children": [
     {
       "kind": "TypeDecl",
+      "name": "P1",
+      "printedName": "P1",
+      "declKind": "Protocol",
+      "usr": "s:4cake2P1P",
+      "location": "",
+      "moduleName": "cake"
+    },
+    {
+      "kind": "TypeDecl",
+      "name": "P2",
+      "printedName": "P2",
+      "declKind": "Protocol",
+      "usr": "s:4cake2P2P",
+      "location": "",
+      "moduleName": "cake"
+    },
+    {
+      "kind": "TypeDecl",
       "name": "C0",
       "printedName": "C0",
       "declKind": "Class",
@@ -93,6 +111,10 @@
       "usr": "s:4cake2S1V",
       "location": "",
       "moduleName": "cake",
+      "conformingProtocols": [
+        "P1",
+        "P2"
+      ],
       "children": [
         {
           "kind": "Function",
@@ -389,6 +411,166 @@
           "printedName": "S1"
         }
       ]
+    },
+    {
+      "kind": "TypeDecl",
+      "name": "Number",
+      "printedName": "Number",
+      "declKind": "Enum",
+      "usr": "s:4cake6NumberO",
+      "location": "",
+      "moduleName": "cake",
+      "conformingProtocols": [
+        "Equatable",
+        "Hashable",
+        "RawRepresentable"
+      ],
+      "enumRawTypeName": "Int",
+      "children": [
+        {
+          "kind": "Var",
+          "name": "one",
+          "printedName": "one",
+          "declKind": "EnumElement",
+          "usr": "s:4cake6NumberO3oneyA2CmF",
+          "location": "",
+          "moduleName": "cake",
+          "children": [
+            {
+              "kind": "TypeFunc",
+              "name": "Function",
+              "printedName": "(Number.Type) -> Number",
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Number",
+                  "printedName": "Number"
+                },
+                {
+                  "kind": "TypeNominal",
+                  "name": "Metatype",
+                  "printedName": "Number.Type",
+                  "children": [
+                    {
+                      "kind": "TypeNominal",
+                      "name": "Number",
+                      "printedName": "Number"
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "kind": "TypeAlias",
+          "name": "RawValue",
+          "printedName": "RawValue",
+          "declKind": "TypeAlias",
+          "usr": "s:4cake6NumberO8RawValuea",
+          "location": "",
+          "moduleName": "cake",
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int"
+            }
+          ]
+        },
+        {
+          "kind": "Var",
+          "name": "hashValue",
+          "printedName": "hashValue",
+          "declKind": "Var",
+          "usr": "s:4cake6NumberO9hashValueSivp",
+          "location": "",
+          "moduleName": "cake",
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int"
+            },
+            {
+              "kind": "Getter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake6NumberO9hashValueSivg",
+              "location": "",
+              "moduleName": "cake",
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "kind": "Constructor",
+          "name": "init",
+          "printedName": "init(rawValue:)",
+          "declKind": "Constructor",
+          "usr": "s:4cake6NumberO8rawValueACSgSi_tcfc",
+          "location": "",
+          "moduleName": "cake",
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "Optional",
+              "printedName": "Number?",
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Number",
+                  "printedName": "Number"
+                }
+              ]
+            },
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int"
+            }
+          ]
+        },
+        {
+          "kind": "Var",
+          "name": "rawValue",
+          "printedName": "rawValue",
+          "declKind": "Var",
+          "usr": "s:4cake6NumberO8rawValueSivp",
+          "location": "",
+          "moduleName": "cake",
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int"
+            },
+            {
+              "kind": "Getter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake6NumberO8rawValueSivg",
+              "location": "",
+              "moduleName": "cake",
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int"
+                }
+              ]
+            }
+          ]
+        }
+      ]
     }
   ]
 }
\ No newline at end of file
diff --git a/test/expr/closure/closures.swift b/test/expr/closure/closures.swift
index 6d043e9..2539461 100644
--- a/test/expr/closure/closures.swift
+++ b/test/expr/closure/closures.swift
@@ -259,7 +259,6 @@
 func takesVoidFunc(_ f: () -> ()) {}
 var i: Int = 1
 
-// expected-warning @+1 {{expression of type 'Int' is unused}}
 takesVoidFunc({i})
 // expected-warning @+1 {{expression of type 'Int' is unused}}
 var f1: () -> () = {i}
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index bb6927d..4a21be6 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -328,10 +328,12 @@
   bool IsMutating = false;
   bool IsStatic = false;
   Optional<uint8_t> SelfIndex;
-  Ownership Ownership = Ownership::Strong;
+  ReferenceOwnership ReferenceOwnership = ReferenceOwnership::Strong;
   std::vector<SDKDeclAttrKind> DeclAttrs;
   std::vector<TypeAttrKind> TypeAttrs;
+  std::vector<StringRef> ConformingProtocols;
   StringRef SuperclassUsr;
+  StringRef EnumRawTypeName;
   ParentExtensionInfo *ExtInfo = nullptr;
   TypeInitInfo TypeInfo;
 
@@ -401,17 +403,18 @@
   StringRef ModuleName;
   std::vector<SDKDeclAttrKind> DeclAttributes;
   bool IsStatic;
-  uint8_t Ownership;
+  uint8_t ReferenceOwnership;
   bool hasDeclAttribute(SDKDeclAttrKind DAKind) const;
   // Non-null ExtInfo implies this decl is defined in an type extension.
   ParentExtensionInfo *ExtInfo;
 
 protected:
-  SDKNodeDecl(SDKNodeInitInfo Info, SDKNodeKind Kind) : SDKNode(Info, Kind),
-    DKind(Info.DKind), Usr(Info.USR), Location(Info.Location),
-    ModuleName(Info.ModuleName), DeclAttributes(Info.DeclAttrs),
-    IsStatic(Info.IsStatic), Ownership(uint8_t(Info.Ownership)),
-    ExtInfo(Info.ExtInfo) {}
+  SDKNodeDecl(SDKNodeInitInfo Info, SDKNodeKind Kind)
+      : SDKNode(Info, Kind), DKind(Info.DKind), Usr(Info.USR),
+        Location(Info.Location), ModuleName(Info.ModuleName),
+        DeclAttributes(Info.DeclAttrs), IsStatic(Info.IsStatic),
+        ReferenceOwnership(uint8_t(Info.ReferenceOwnership)),
+        ExtInfo(Info.ExtInfo) {}
 
 public:
   StringRef getUsr() const { return Usr; }
@@ -420,7 +423,9 @@
   StringRef getHeaderName() const;
   void addDeclAttribute(SDKDeclAttrKind DAKind);
   ArrayRef<SDKDeclAttrKind> getDeclAttributes() const;
-  swift::Ownership getOwnership() const { return swift::Ownership(Ownership); }
+  swift::ReferenceOwnership getReferenceOwnership() const {
+    return swift::ReferenceOwnership(ReferenceOwnership);
+  }
   bool isObjc() const { return Usr.startswith("c:"); }
   static bool classof(const SDKNode *N);
   DeclKind getDeclKind() const { return DKind; }
@@ -774,11 +779,26 @@
 
 class SDKNodeTypeDecl : public SDKNodeDecl {
   StringRef SuperclassUsr;
+  std::vector<StringRef> ConformingProtocols;
+  StringRef EnumRawTypeName;
 public:
   SDKNodeTypeDecl(SDKNodeInitInfo Info) : SDKNodeDecl(Info, SDKNodeKind::TypeDecl),
-                                          SuperclassUsr(Info.SuperclassUsr) {}
+                                          SuperclassUsr(Info.SuperclassUsr),
+                                ConformingProtocols(Info.ConformingProtocols),
+                                        EnumRawTypeName(Info.EnumRawTypeName) {}
   static bool classof(const SDKNode *N);
   StringRef getSuperClassUsr() const { return SuperclassUsr; }
+  ArrayRef<StringRef> getAllProtocols() const { return ConformingProtocols; }
+
+#define NOMINAL_TYPE_DECL(ID, PARENT) \
+  bool is##ID() const { return getDeclKind() == DeclKind::ID; }
+#define DECL(ID, PARENT)
+#include "swift/AST/DeclNodes.def"
+
+  StringRef getEnumRawTypeName() const {
+    assert(isEnum());
+    return EnumRawTypeName;
+  }
 
   Optional<SDKNodeTypeDecl*> getSuperclass() const {
     if (SuperclassUsr.empty())
@@ -946,6 +966,18 @@
       }
       break;
     }
+    case KeyKind::KK_conformingProtocols: {
+      assert(Info.ConformingProtocols.empty());
+      for (auto &Name : *cast<llvm::yaml::SequenceNode>(Pair.getValue())) {
+        Info.ConformingProtocols.push_back(GetScalarString(&Name));
+      }
+      break;
+    }
+    case KeyKind::KK_enumRawTypeName: {
+      assert(Info.DKind == DeclKind::Enum);
+      Info.EnumRawTypeName = GetScalarString(Pair.getValue());
+      break;
+    }
     case KeyKind::KK_printedName:
       Info.PrintedName = GetScalarString(Pair.getValue());
       break;
@@ -968,8 +1000,9 @@
       Info.IsStatic = true;
       break;
     case KeyKind::KK_ownership:
-      Info.Ownership = swift::Ownership(getAsInt(Pair.getValue()));
-      assert(Info.Ownership != swift::Ownership::Strong &&
+      Info.ReferenceOwnership =
+          swift::ReferenceOwnership(getAsInt(Pair.getValue()));
+      assert(Info.ReferenceOwnership != swift::ReferenceOwnership::Strong &&
              "Strong is implied.");
       break;
 
@@ -1067,7 +1100,7 @@
       auto Right = (&Other)->getAs<SDKNodeDecl>();
       if (Left->isStatic() ^ Right->isStatic())
         return false;
-      if (Left->getOwnership() != Right->getOwnership())
+      if (Left->getReferenceOwnership() != Right->getReferenceOwnership())
         return false;
       LLVM_FALLTHROUGH;
     }
@@ -1228,11 +1261,11 @@
   return None;
 }
 
-static Ownership getOwnership(ValueDecl *VD) {
-  if (auto OA = VD->getAttrs().getAttribute<OwnershipAttr>()) {
+static ReferenceOwnership getReferenceOwnership(ValueDecl *VD) {
+  if (auto OA = VD->getAttrs().getAttribute<ReferenceOwnershipAttr>()) {
     return OA->get();
   }
-  return Ownership::Strong;
+  return ReferenceOwnership::Strong;
 }
 
 SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
@@ -1244,14 +1277,15 @@
     TypeAttrs.push_back(TypeAttrKind::TAK_noescape);
 }
 
-SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD) : Ctx(Ctx),
-    Name(VD->hasName() ? getEscapedName(VD->getBaseName()) : Ctx.buffer("_")),
-    PrintedName(getPrintedName(Ctx, VD)), DKind(VD->getKind()),
-    USR(calculateUsr(Ctx, VD)), Location(calculateLocation(Ctx, VD)),
-    ModuleName(VD->getModuleContext()->getName().str()),
-    IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)),
-    IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)),
-    Ownership(getOwnership(VD)), ExtInfo(nullptr) {
+SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD)
+    : Ctx(Ctx),
+      Name(VD->hasName() ? getEscapedName(VD->getBaseName()) : Ctx.buffer("_")),
+      PrintedName(getPrintedName(Ctx, VD)), DKind(VD->getKind()),
+      USR(calculateUsr(Ctx, VD)), Location(calculateLocation(Ctx, VD)),
+      ModuleName(VD->getModuleContext()->getName().str()),
+      IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)),
+      IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)),
+      ReferenceOwnership(getReferenceOwnership(VD)), ExtInfo(nullptr) {
 
   // Calculate usr for its super class.
   if (auto *CD = dyn_cast_or_null<ClassDecl>(VD)) {
@@ -1272,6 +1306,22 @@
       ExtInfo->Requirements.emplace_back(Ctx.buffer(OS.str()));
     }
   }
+
+  // Get all protocol names this type decl conforms to.
+  if (auto *NTD = dyn_cast<NominalTypeDecl>(VD)) {
+    for (auto *P: NTD->getAllProtocols()) {
+      ConformingProtocols.push_back(P->getName().str());
+    }
+  }
+
+  // Get enum raw type name if this is an enum.
+  if (auto *ED = dyn_cast<EnumDecl>(VD)) {
+    if (auto RT = ED->getRawType()) {
+      if (auto *D = RT->getNominalOrBoundGenericNominal()) {
+        EnumRawTypeName = D->getName().str();
+      }
+    }
+  }
 }
 
 SDKNode *SDKNodeInitInfo::createSDKNode(SDKNodeKind Kind) {
@@ -1647,6 +1697,20 @@
               out.mapRequired(getKeyContent(Ctx, KeyKind::KK_superclassUsr).data(),
                               Super);
             }
+            auto Pros = TD->getAllProtocols();
+            if (!Pros.empty()) {
+              out.mapRequired(getKeyContent(Ctx,
+                                        KeyKind::KK_conformingProtocols).data(),
+                              Pros);
+            }
+
+            auto RawTypeName = TD->isEnum() ? TD->getEnumRawTypeName() : StringRef();
+            if (!RawTypeName.empty()) {
+              out.mapRequired(getKeyContent(Ctx,
+                                            KeyKind::KK_enumRawTypeName).data(),
+                              RawTypeName);
+            }
+
           }
           if (D->isFromExtension()) {
             // Even if we don't have any requirements on this parent extension,
@@ -1662,8 +1726,8 @@
             out.mapRequired(getKeyContent(Ctx, KeyKind::KK_declAttributes).data(),
                             Attributes);
           // Strong reference is implied, no need for serialization.
-          if (D->getOwnership() != Ownership::Strong) {
-            uint8_t Raw = uint8_t(D->getOwnership());
+          if (D->getReferenceOwnership() != ReferenceOwnership::Strong) {
+            uint8_t Raw = uint8_t(D->getReferenceOwnership());
             out.mapRequired(getKeyContent(Ctx, KeyKind::KK_ownership).data(), Raw);
           }
         } else if (auto T = dyn_cast<SDKNodeType>(value)) {
@@ -2227,7 +2291,7 @@
     auto *RD = R->getAs<SDKNodeDecl>();
     if (LD->isStatic() ^ RD->isStatic())
       L->annotate(NodeAnnotation::StaticChange);
-    if (LD->getOwnership() != RD->getOwnership())
+    if (LD->getReferenceOwnership() != RD->getReferenceOwnership())
       L->annotate(NodeAnnotation::OwnershipChange);
     detectRename(L, R);
   }
@@ -3070,22 +3134,25 @@
     return;
   }
   case NodeAnnotation::OwnershipChange: {
-    auto getOwnershipDescription = [&](swift::Ownership O) {
+    auto getOwnershipDescription = [&](swift::ReferenceOwnership O) {
       switch (O) {
-      case Ownership::Strong:    return Ctx.buffer("strong");
-      case Ownership::Weak:      return Ctx.buffer("weak");
-      case Ownership::Unowned:   return Ctx.buffer("unowned");
-      case Ownership::Unmanaged: return Ctx.buffer("unowned(unsafe)");
+      case ReferenceOwnership::Strong:
+        return Ctx.buffer("strong");
+      case ReferenceOwnership::Weak:
+        return Ctx.buffer("weak");
+      case ReferenceOwnership::Unowned:
+        return Ctx.buffer("unowned");
+      case ReferenceOwnership::Unmanaged:
+        return Ctx.buffer("unowned(unsafe)");
       }
 
       llvm_unreachable("Unhandled Ownership in switch.");
     };
     auto *Count = UpdateMap.findUpdateCounterpart(Node)->getAs<SDKNodeDecl>();
-    AttrChangedDecls.Diags.emplace_back(ScreenInfo,
-                                        Node->getDeclKind(),
-                                        Node->getFullyQualifiedName(),
-                                  getOwnershipDescription(Node->getOwnership()),
-                                getOwnershipDescription(Count->getOwnership()));
+    AttrChangedDecls.Diags.emplace_back(
+        ScreenInfo, Node->getDeclKind(), Node->getFullyQualifiedName(),
+        getOwnershipDescription(Node->getReferenceOwnership()),
+        getOwnershipDescription(Count->getReferenceOwnership()));
     return;
   }
   default:
diff --git a/tools/swift-syntax-test/swift-syntax-test.cpp b/tools/swift-syntax-test/swift-syntax-test.cpp
index f4d00a9..3f4e8b0 100644
--- a/tools/swift-syntax-test/swift-syntax-test.cpp
+++ b/tools/swift-syntax-test/swift-syntax-test.cpp
@@ -112,11 +112,13 @@
 int getTokensFromFile(unsigned BufferID,
                       LangOptions &LangOpts,
                       SourceManager &SourceMgr,
-                      DiagnosticEngine &Diags,
+                      swift::DiagnosticEngine &Diags,
                       std::vector<std::pair<RC<syntax::RawSyntax>,
                       syntax::AbsolutePosition>> &Tokens) {
-  Tokens = tokenizeWithTrivia(LangOpts, SourceMgr, BufferID);
-  return Diags.hadAnyError() ? EXIT_FAILURE : EXIT_SUCCESS;
+  Tokens = tokenizeWithTrivia(LangOpts, SourceMgr, BufferID,
+                              /*Offset=*/0, /*EndOffset=*/0,
+                              &Diags);
+  return EXIT_SUCCESS;
 }
 
 
@@ -191,7 +193,7 @@
     TokAndPos.first->print(llvm::outs(), {});
   }
 
-  return Diags.hadAnyError() ? EXIT_FAILURE : EXIT_SUCCESS;
+  return EXIT_SUCCESS;
 }
 
 int doDumpRawTokenSyntax(const StringRef InputFilename) {
@@ -215,7 +217,7 @@
     llvm::outs() << "\n";
   }
 
-  return Diags.hadAnyError() ? EXIT_FAILURE : EXIT_SUCCESS;
+  return EXIT_SUCCESS;
 }
 
 int doFullParseRoundTrip(const char *MainExecutablePath,
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index da8699c..5c58c84 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_swift_unittest(SwiftASTTests
+  DiagnosticConsumerTests.cpp
   SourceLocTests.cpp
   TestContext.cpp
   TypeMatchTests.cpp
diff --git a/unittests/AST/DiagnosticConsumerTests.cpp b/unittests/AST/DiagnosticConsumerTests.cpp
new file mode 100644
index 0000000..2339395
--- /dev/null
+++ b/unittests/AST/DiagnosticConsumerTests.cpp
@@ -0,0 +1,533 @@
+//===--- DiagnosticConsumerTests.cpp --------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "swift/AST/DiagnosticConsumer.h"
+#include "swift/Basic/SourceManager.h"
+#include "gtest/gtest.h"
+
+using namespace swift;
+
+namespace {
+  using ExpectedDiagnostic = std::pair<SourceLoc, StringRef>;
+
+  class ExpectationDiagnosticConsumer: public DiagnosticConsumer {
+    ExpectationDiagnosticConsumer *previous;
+    SmallVector<ExpectedDiagnostic, 4> expected;
+    bool hasFinished = false;
+
+  public:
+    ExpectationDiagnosticConsumer(ExpectationDiagnosticConsumer *previous,
+                                  ArrayRef<ExpectedDiagnostic> expected)
+      : previous(previous), expected(expected.begin(), expected.end()) {}
+
+    ~ExpectationDiagnosticConsumer() override {
+      EXPECT_TRUE(hasFinished);
+      EXPECT_TRUE(expected.empty());
+    }
+
+    void handleDiagnostic(SourceManager &SM, SourceLoc loc, DiagnosticKind kind,
+                          StringRef formatString,
+                          ArrayRef<DiagnosticArgument> formatArgs,
+                          const DiagnosticInfo &info) override {
+      ASSERT_FALSE(expected.empty());
+      EXPECT_EQ(std::make_pair(loc, formatString), expected.front());
+      expected.erase(expected.begin());
+    }
+
+    bool finishProcessing() override {
+      EXPECT_FALSE(hasFinished);
+      if (previous)
+        EXPECT_TRUE(previous->hasFinished);
+      hasFinished = true;
+      return false;
+    }
+  };
+} // end anonymous namespace
+
+TEST(FileSpecificDiagnosticConsumer, SubConsumersFinishInOrder) {
+  SourceManager sourceMgr;
+  (void)sourceMgr.addMemBufferCopy("abcde", "A");
+  (void)sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, None);
+  auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), None);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("", std::move(consumerUnaffiliated));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.finishProcessing();
+}
+
+TEST(FileSpecificDiagnosticConsumer, InvalidLocDiagsGoToEveryConsumer) {
+  SourceManager sourceMgr;
+  (void)sourceMgr.addMemBufferCopy("abcde", "A");
+  (void)sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  ExpectedDiagnostic expected[] = { {SourceLoc(), "dummy"} };
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expected);
+  auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expected);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("", std::move(consumerUnaffiliated));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, SourceLoc(), DiagnosticKind::Error,
+                               "dummy", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
+
+TEST(FileSpecificDiagnosticConsumer, ErrorsWithLocationsGoToExpectedConsumers) {
+  SourceManager sourceMgr;
+  //                                             01234
+  unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A");
+  unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  SourceLoc frontOfA = sourceMgr.getLocForOffset(bufferA, 0);
+  SourceLoc middleOfA = sourceMgr.getLocForOffset(bufferA, 2);
+  SourceLoc backOfA = sourceMgr.getLocForOffset(bufferA, 4);
+
+  SourceLoc frontOfB = sourceMgr.getLocForOffset(bufferB, 0);
+  SourceLoc middleOfB = sourceMgr.getLocForOffset(bufferB, 2);
+  SourceLoc backOfB = sourceMgr.getLocForOffset(bufferB, 4);
+
+  ExpectedDiagnostic expectedA[] = {
+    {frontOfA, "front"},
+    {middleOfA, "middle"},
+    {backOfA, "back"},
+  };
+  ExpectedDiagnostic expectedB[] = {
+    {frontOfB, "front"},
+    {middleOfB, "middle"},
+    {backOfB, "back"}
+  };
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expectedA);
+  auto consumerB = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expectedB);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("B", std::move(consumerB));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "front", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Error,
+                               "front", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Error,
+                               "middle", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Error,
+                               "middle", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Error,
+                               "back", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Error,
+                               "back", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
+
+TEST(FileSpecificDiagnosticConsumer,
+     ErrorsInUnaffiliatedFilesGoToEveryConsumer) {
+  SourceManager sourceMgr;
+  //                                             01234
+  unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A");
+  unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  SourceLoc frontOfA = sourceMgr.getLocForOffset(bufferA, 0);
+  SourceLoc middleOfA = sourceMgr.getLocForOffset(bufferA, 2);
+  SourceLoc backOfA = sourceMgr.getLocForOffset(bufferA, 4);
+
+  SourceLoc frontOfB = sourceMgr.getLocForOffset(bufferB, 0);
+  SourceLoc middleOfB = sourceMgr.getLocForOffset(bufferB, 2);
+  SourceLoc backOfB = sourceMgr.getLocForOffset(bufferB, 4);
+
+  ExpectedDiagnostic expectedA[] = {
+    {frontOfA, "front"},
+    {frontOfB, "front"},
+    {middleOfA, "middle"},
+    {middleOfB, "middle"},
+    {backOfA, "back"},
+    {backOfB, "back"}
+  };
+  ExpectedDiagnostic expectedUnaffiliated[] = {
+    {frontOfB, "front"},
+    {middleOfB, "middle"},
+    {backOfB, "back"}
+  };
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expectedA);
+  auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expectedUnaffiliated);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("", std::move(consumerUnaffiliated));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "front", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Error,
+                               "front", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Error,
+                               "middle", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Error,
+                               "middle", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Error,
+                               "back", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Error,
+                               "back", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
+
+TEST(FileSpecificDiagnosticConsumer, WarningsAndRemarksAreTreatedLikeErrors) {
+  SourceManager sourceMgr;
+  //                                             01234
+  unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A");
+  unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  SourceLoc frontOfA = sourceMgr.getLocForBufferStart(bufferA);
+  SourceLoc frontOfB = sourceMgr.getLocForBufferStart(bufferB);
+
+  ExpectedDiagnostic expectedA[] = {
+    {frontOfA, "warning"},
+    {frontOfB, "warning"},
+    {frontOfA, "remark"},
+    {frontOfB, "remark"},
+  };
+  ExpectedDiagnostic expectedUnaffiliated[] = {
+    {frontOfB, "warning"},
+    {frontOfB, "remark"},
+  };
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expectedA);
+  auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expectedUnaffiliated);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("", std::move(consumerUnaffiliated));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Warning,
+                               "warning", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Warning,
+                               "warning", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Remark,
+                               "remark", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Remark,
+                               "remark", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
+
+TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrors) {
+  SourceManager sourceMgr;
+  //                                             01234
+  unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A");
+  unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  SourceLoc frontOfA = sourceMgr.getLocForOffset(bufferA, 0);
+  SourceLoc middleOfA = sourceMgr.getLocForOffset(bufferA, 2);
+  SourceLoc backOfA = sourceMgr.getLocForOffset(bufferA, 4);
+
+  SourceLoc frontOfB = sourceMgr.getLocForOffset(bufferB, 0);
+  SourceLoc middleOfB = sourceMgr.getLocForOffset(bufferB, 2);
+  SourceLoc backOfB = sourceMgr.getLocForOffset(bufferB, 4);
+
+  ExpectedDiagnostic expectedA[] = {
+    {frontOfA, "error"},
+    {middleOfA, "note"},
+    {backOfA, "note"},
+    {frontOfB, "error"},
+    {middleOfB, "note"},
+    {backOfB, "note"},
+    {frontOfA, "error"},
+    {middleOfA, "note"},
+    {backOfA, "note"},
+  };
+  ExpectedDiagnostic expectedUnaffiliated[] = {
+    {frontOfB, "error"},
+    {middleOfB, "note"},
+    {backOfB, "note"},
+  };
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expectedA);
+  auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expectedUnaffiliated);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("", std::move(consumerUnaffiliated));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
+
+TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToWarningsAndRemarks) {
+  SourceManager sourceMgr;
+  //                                             01234
+  unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A");
+  unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  SourceLoc frontOfA = sourceMgr.getLocForOffset(bufferA, 0);
+  SourceLoc middleOfA = sourceMgr.getLocForOffset(bufferA, 2);
+  SourceLoc backOfA = sourceMgr.getLocForOffset(bufferA, 4);
+
+  SourceLoc frontOfB = sourceMgr.getLocForOffset(bufferB, 0);
+  SourceLoc middleOfB = sourceMgr.getLocForOffset(bufferB, 2);
+  SourceLoc backOfB = sourceMgr.getLocForOffset(bufferB, 4);
+
+  ExpectedDiagnostic expectedA[] = {
+    {frontOfA, "warning"},
+    {middleOfA, "note"},
+    {backOfA, "note"},
+    {frontOfB, "warning"},
+    {middleOfB, "note"},
+    {backOfB, "note"},
+    {frontOfA, "remark"},
+    {middleOfA, "note"},
+    {backOfA, "note"},
+  };
+  ExpectedDiagnostic expectedUnaffiliated[] = {
+    {frontOfB, "warning"},
+    {middleOfB, "note"},
+    {backOfB, "note"},
+  };
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expectedA);
+  auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expectedUnaffiliated);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("", std::move(consumerUnaffiliated));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Warning,
+                               "warning", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Warning,
+                               "warning", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Remark,
+                               "remark", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
+
+TEST(FileSpecificDiagnosticConsumer, NotesAreAttachedToErrorsEvenAcrossFiles) {
+  SourceManager sourceMgr;
+  //                                             01234
+  unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A");
+  unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  SourceLoc frontOfA = sourceMgr.getLocForOffset(bufferA, 0);
+  SourceLoc middleOfA = sourceMgr.getLocForOffset(bufferA, 2);
+  SourceLoc backOfA = sourceMgr.getLocForOffset(bufferA, 4);
+
+  SourceLoc frontOfB = sourceMgr.getLocForOffset(bufferB, 0);
+  SourceLoc middleOfB = sourceMgr.getLocForOffset(bufferB, 2);
+  SourceLoc backOfB = sourceMgr.getLocForOffset(bufferB, 4);
+
+  ExpectedDiagnostic expectedA[] = {
+    {frontOfA, "error"},
+    {middleOfB, "note"},
+    {backOfA, "note"},
+    {frontOfA, "error"},
+    {middleOfB, "note"},
+    {backOfA, "note"},
+  };
+  ExpectedDiagnostic expectedB[] = {
+    {frontOfB, "error"},
+    {middleOfA, "note"},
+    {backOfB, "note"},
+  };
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expectedA);
+  auto consumerB = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expectedB);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("B", std::move(consumerB));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
+
+TEST(FileSpecificDiagnosticConsumer,
+     NotesAreAttachedToErrorsEvenAcrossFilesWithUnaffiliatedConsumer) {
+  SourceManager sourceMgr;
+  //                                             01234
+  unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A");
+  unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  SourceLoc frontOfA = sourceMgr.getLocForOffset(bufferA, 0);
+  SourceLoc middleOfA = sourceMgr.getLocForOffset(bufferA, 2);
+  SourceLoc backOfA = sourceMgr.getLocForOffset(bufferA, 4);
+
+  SourceLoc frontOfB = sourceMgr.getLocForOffset(bufferB, 0);
+  SourceLoc middleOfB = sourceMgr.getLocForOffset(bufferB, 2);
+  SourceLoc backOfB = sourceMgr.getLocForOffset(bufferB, 4);
+
+  ExpectedDiagnostic expectedA[] = {
+    {frontOfA, "error"},
+    {middleOfB, "note"},
+    {backOfA, "note"},
+    {frontOfB, "error"},
+    {middleOfA, "note"},
+    {backOfB, "note"},
+    {frontOfA, "error"},
+    {middleOfB, "note"},
+    {backOfA, "note"},
+  };
+  ExpectedDiagnostic expectedUnaffiliated[] = {
+    {frontOfB, "error"},
+    {middleOfA, "note"},
+    {backOfB, "note"},
+  };
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expectedA);
+  auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expectedUnaffiliated);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("", std::move(consumerUnaffiliated));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, middleOfB, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, backOfA, DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
+
+
+TEST(FileSpecificDiagnosticConsumer,
+     NotesWithInvalidLocsAreStillAttachedToErrors) {
+  SourceManager sourceMgr;
+  //                                             01234
+  unsigned bufferA = sourceMgr.addMemBufferCopy("abcde", "A");
+  unsigned bufferB = sourceMgr.addMemBufferCopy("vwxyz", "B");
+
+  SourceLoc frontOfA = sourceMgr.getLocForBufferStart(bufferA);
+  SourceLoc frontOfB = sourceMgr.getLocForBufferStart(bufferB);
+
+  ExpectedDiagnostic expectedA[] = {
+    {frontOfA, "error"},
+    {SourceLoc(), "note"},
+    {frontOfB, "error"},
+    {SourceLoc(), "note"},
+    {frontOfA, "error"},
+    {SourceLoc(), "note"},
+  };
+  ExpectedDiagnostic expectedUnaffiliated[] = {
+    {frontOfB, "error"},
+    {SourceLoc(), "note"},
+  };
+
+  auto consumerA = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      nullptr, expectedA);
+  auto consumerUnaffiliated = llvm::make_unique<ExpectationDiagnosticConsumer>(
+      consumerA.get(), expectedUnaffiliated);
+
+  SmallVector<FileSpecificDiagnosticConsumer::ConsumerPair, 2> consumers;
+  consumers.emplace_back("A", std::move(consumerA));
+  consumers.emplace_back("", std::move(consumerUnaffiliated));
+
+  FileSpecificDiagnosticConsumer topConsumer(consumers);
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, SourceLoc(), DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfB, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, SourceLoc(), DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, frontOfA, DiagnosticKind::Error,
+                               "error", {}, DiagnosticInfo());
+  topConsumer.handleDiagnostic(sourceMgr, SourceLoc(), DiagnosticKind::Note,
+                               "note", {}, DiagnosticInfo());
+  topConsumer.finishProcessing();
+}
diff --git a/unittests/Parse/LexerTests.cpp b/unittests/Parse/LexerTests.cpp
index 76172d8..c64aa40 100644
--- a/unittests/Parse/LexerTests.cpp
+++ b/unittests/Parse/LexerTests.cpp
@@ -35,7 +35,7 @@
     if (KeepEOF)
       Toks = tokenizeAndKeepEOF(BufID);
     else
-      Toks = tokenize(LangOpts, SourceMgr, BufID, 0, 0, KeepComments);
+      Toks = tokenize(LangOpts, SourceMgr, BufID, 0, 0, /*Diags=*/nullptr, KeepComments);
     EXPECT_EQ(ExpectedTokens.size(), Toks.size());
     for (unsigned i = 0, e = ExpectedTokens.size(); i != e; ++i) {
       EXPECT_EQ(ExpectedTokens[i], Toks[i].getKind()) << "i = " << i;
@@ -685,7 +685,7 @@
 TEST_F(LexerTest, NoPlaceholder) {
   auto checkTok = [&](StringRef Source) {
     unsigned BufID = SourceMgr.addMemBufferCopy(Source);
-    std::vector<Token> Toks = tokenize(LangOpts, SourceMgr, BufID, 0, 0, false);
+    std::vector<Token> Toks = tokenize(LangOpts, SourceMgr, BufID, 0, 0, /*Diags=*/nullptr, false);
     ASSERT_FALSE(Toks.empty());
     EXPECT_NE(tok::identifier, Toks[0].getKind());
   };
diff --git a/unittests/Parse/TokenizerTests.cpp b/unittests/Parse/TokenizerTests.cpp
index 42b8166..cb9a12f 100644
--- a/unittests/Parse/TokenizerTests.cpp
+++ b/unittests/Parse/TokenizerTests.cpp
@@ -98,6 +98,7 @@
                            BufID, 
                            /* Offset = */ 0,
                            /* EndOffset = */ 0,
+                           /* Diags = */nullptr,
                            /* KeepComments = */ true,
                            /* TokenizeInterpolatedString = */ true,
                            SplitTokens);
diff --git a/unittests/runtime/Array.cpp b/unittests/runtime/Array.cpp
index 40c8023..eb0d46a 100644
--- a/unittests/runtime/Array.cpp
+++ b/unittests/runtime/Array.cpp
@@ -80,8 +80,7 @@
 
 static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
   { { &destroyTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
-  { { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK,
-  ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
+  { { nullptr }, ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
 };
 
 /// Create an object that, when deallocated, stores the given value to
diff --git a/unittests/runtime/LongTests/CMakeLists.txt b/unittests/runtime/LongTests/CMakeLists.txt
index ed074a0..665cf5e 100644
--- a/unittests/runtime/LongTests/CMakeLists.txt
+++ b/unittests/runtime/LongTests/CMakeLists.txt
@@ -38,6 +38,14 @@
     $<TARGET_OBJECTS:swiftRuntime${SWIFT_PRIMARY_VARIANT_SUFFIX}>
     )
 
+  # The local stdlib implementation provides definitions of the swiftCore
+  # interfaes to avoid pulling in swiftCore itself.  Build the
+  # SwiftRuntimeLongTests with swiftCore_EXPORTS to permit exporting the stdlib
+  # interfaces.
+  target_compile_definitions(SwiftRuntimeLongTests
+                             PRIVATE
+                               swiftCore_EXPORTS)
+
   # FIXME: cross-compile for all variants.
   target_link_libraries(SwiftRuntimeLongTests
     swiftCore${SWIFT_PRIMARY_VARIANT_SUFFIX}
diff --git a/unittests/runtime/LongTests/LongRefcounting.cpp b/unittests/runtime/LongTests/LongRefcounting.cpp
index d954a89..779ec0f 100644
--- a/unittests/runtime/LongTests/LongRefcounting.cpp
+++ b/unittests/runtime/LongTests/LongRefcounting.cpp
@@ -98,8 +98,7 @@
 
 static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
   { { &deinitTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
-  { { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK,
-  ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
+  { { nullptr }, ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
 };
 
 /// Create an object that, when deinited, stores the given value to
diff --git a/unittests/runtime/Metadata.cpp b/unittests/runtime/Metadata.cpp
index 509ee4f..d57e4fc 100644
--- a/unittests/runtime/Metadata.cpp
+++ b/unittests/runtime/Metadata.cpp
@@ -252,8 +252,7 @@
 
 FullMetadata<ClassMetadata> MetadataTest2 = {
   { { nullptr }, { &VALUE_WITNESS_SYM(Bo) } },
-  { { { MetadataKind::Class } }, nullptr, /*rodata*/ 1,
-    ClassFlags(), 0, 0, 0, 0, 0, 0 }
+  { { nullptr }, ClassFlags(), 0, 0, 0, 0, 0, 0 }
 };
 
 TEST(MetadataTest, getMetatypeMetadata) {
diff --git a/unittests/runtime/Refcounting.cpp b/unittests/runtime/Refcounting.cpp
index e6f60a3..ca66391 100644
--- a/unittests/runtime/Refcounting.cpp
+++ b/unittests/runtime/Refcounting.cpp
@@ -31,8 +31,7 @@
 
 static const FullMetadata<ClassMetadata> TestClassObjectMetadata = {
   { { &destroyTestObject }, { &VALUE_WITNESS_SYM(Bo) } },
-  { { { MetadataKind::Class } }, 0, SWIFT_CLASS_IS_SWIFT_MASK,
-  ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
+  { { nullptr }, ClassFlags::UsesSwiftRefcounting, 0, 0, 0, 0, 0, 0 }
 };
 
 /// Create an object that, when deallocated, stores the given value to
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 9d1fb48..da3bdb7 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -2011,10 +2011,10 @@
                         -DSWIFT_ANDROID_NDK_PATH:STRING="${ANDROID_NDK}"
                         -DSWIFT_ANDROID_NDK_GCC_VERSION:STRING="${ANDROID_NDK_GCC_VERSION}"
                         -DSWIFT_ANDROID_SDK_PATH:STRING="${ANDROID_NDK}/platforms/android-${ANDROID_API_LEVEL}/arch-arm"
-                        -DSWIFT_ANDROID_${HOST}_ICU_UC:STRING="${ANDROID_ICU_UC}"
-                        -DSWIFT_ANDROID_${HOST}_ICU_UC_INCLUDE:STRING="${ANDROID_ICU_UC_INCLUDE}"
-                        -DSWIFT_ANDROID_${HOST}_ICU_I18N:STRING="${ANDROID_ICU_I18N}"
-                        -DSWIFT_ANDROID_${HOST}_ICU_I18N_INCLUDE:STRING="${ANDROID_ICU_I18N_INCLUDE}"
+                        -DSWIFT_ANDROID_armv7_ICU_UC:STRING="${ANDROID_ICU_UC}"
+                        -DSWIFT_ANDROID_armv7_ICU_UC_INCLUDE:STRING="${ANDROID_ICU_UC_INCLUDE}"
+                        -DSWIFT_ANDROID_armv7_ICU_I18N:STRING="${ANDROID_ICU_I18N}"
+                        -DSWIFT_ANDROID_armv7_ICU_I18N_INCLUDE:STRING="${ANDROID_ICU_I18N_INCLUDE}"
                         -DSWIFT_ANDROID_DEPLOY_DEVICE_PATH:STRING="${ANDROID_DEPLOY_DEVICE_PATH}"
                     )
                 fi
@@ -2875,6 +2875,7 @@
                 XCTEST_BUILD_DIR=$(build_directory ${host} xctest)
                 call "${XCTEST_SOURCE_DIR}"/build_script.py test \
                     --swiftc="${SWIFTC_BIN}" \
+                    --lit="${LLVM_SOURCE_DIR}/utils/lit/lit.py" \
                     --foundation-build-dir="${FOUNDATION_BUILD_DIR}/Foundation" \
                     ${LIBDISPATCH_BUILD_ARGS} \
                     $XCTEST_BUILD_ARGS \
diff --git a/utils/build_swift/defaults.py b/utils/build_swift/defaults.py
index bbf5830..51b7441 100644
--- a/utils/build_swift/defaults.py
+++ b/utils/build_swift/defaults.py
@@ -40,7 +40,7 @@
 CMAKE_GENERATOR = 'Ninja'
 
 COMPILER_VENDOR = 'none'
-SWIFT_USER_VISIBLE_VERSION = CompilerVersion('4.1')
+SWIFT_USER_VISIBLE_VERSION = CompilerVersion('4.2')
 CLANG_USER_VISIBLE_VERSION = CompilerVersion('5.0.0')
 SWIFT_ANALYZE_CODE_COVERAGE = 'false'
 
diff --git a/utils/gyb.py b/utils/gyb.py
index 0831f4a..2630d71 100755
--- a/utils/gyb.py
+++ b/utils/gyb.py
@@ -6,6 +6,7 @@
 
 import os
 import re
+import sys
 try:
     from cStringIO import StringIO
 except ImportError:
@@ -572,6 +573,8 @@
                 # We can only insert the line directive at a line break
                 if len(self.result_text) == 0 \
                    or self.result_text[-1].endswith('\n'):
+                    if sys.platform == 'win32':
+                        file = file.replace('\\', '/')
                     substitutions = {'file': file, 'line': line + 1}
                     format_str = self.line_directive + '\n'
                     self.result_text.append(format_str % substitutions)
diff --git a/utils/static-executable-args.lnk b/utils/static-executable-args.lnk
index 0d34ebd..f3da0ed 100644
--- a/utils/static-executable-args.lnk
+++ b/utils/static-executable-args.lnk
@@ -1,5 +1,6 @@
 -static
 -lswiftCore
+-lswiftImageInspectionShared
 -Xlinker
 --defsym=__import_pthread_self=pthread_self
 -Xlinker
diff --git a/validation-test/stdlib/Arrays.swift.gyb b/validation-test/stdlib/Arrays.swift.gyb
index ea11358..032b4d9 100644
--- a/validation-test/stdlib/Arrays.swift.gyb
+++ b/validation-test/stdlib/Arrays.swift.gyb
@@ -1513,7 +1513,7 @@
   expectFalse(a.isEmpty)
 }
 
-% for Kind in ['Array', 'ContiguousArray']:
+% for Kind in ['Array', 'ContiguousArray', 'ArraySlice']:
 ArrayTestSuite.test("${Kind}/popLast") {
   // Empty
   do {
diff --git a/validation-test/stdlib/Lazy.swift.gyb b/validation-test/stdlib/Lazy.swift.gyb
index c24608a..8e2393b 100644
--- a/validation-test/stdlib/Lazy.swift.gyb
+++ b/validation-test/stdlib/Lazy.swift.gyb
@@ -40,7 +40,7 @@
     iteratorType: IndexingIterator<Subject>.self,
     subSequenceType: Slice<Subject>.self,
     indexType: Int.self,
-    indicesType: CountableRange<Int>.self)
+    indicesType: Range<Int>.self)
 }
 
 LazyTestSuite.test("repeatedValue()/TypeInference") {
@@ -122,7 +122,7 @@
     iteratorType: IteratorOverOne<OpaqueValue<Int>>.self,
     subSequenceType: Slice<Subject>.self,
     indexType: Int.self,
-    indicesType: CountableRange<Int>.self)
+    indicesType: Range<Int>.self)
 }
 
 % for (name, operation, indices) in [
@@ -245,7 +245,7 @@
     iteratorType: EmptyIterator<OpaqueValue<Int>>.self,
     subSequenceType: Subject.self,
     indexType: Int.self,
-    indicesType: CountableRange<Int>.self)
+    indicesType: Range<Int>.self)
 }
 
 % for (name, operation) in [
@@ -1207,8 +1207,8 @@
 
 do {
   struct Sample {
-    var expected: CountableRange<Int>
-    var data: [CountableRange<Int>]
+    var expected: Range<Int>
+    var data: [Range<Int>]
   }
 
   let flattenSamples: [Sample] = [
@@ -1399,7 +1399,7 @@
   typealias Subject = LazyDropWhileSequence<Base>
   expectSequenceAssociatedTypes(
     sequenceType: Subject.self,
-    iteratorType: LazyDropWhileIterator<Base.Iterator>.self,
+    iteratorType: LazyDropWhileSequence<Base>.Iterator.self,
     subSequenceType: AnySequence<OpaqueValue<Int>>.self)
 }
 
@@ -1408,21 +1408,21 @@
   typealias Subject = LazyDropWhileCollection<Base>
   expectCollectionAssociatedTypes(
     collectionType: Subject.self,
-    iteratorType: LazyDropWhileIterator<Base.Iterator>.self,
+    iteratorType: LazyDropWhileSequence<Base>.Iterator.self,
     subSequenceType: Slice<Subject>.self,
-    indexType: LazyDropWhileIndex<Base>.self,
+    indexType: LazyDropWhileCollection<Base>.Index.self,
     indicesType: DefaultIndices<Subject>.self)
 }
 
 tests.test("LazyDropWhileBidirectionalCollection/AssociatedTypes") {
   typealias Base = MinimalBidirectionalCollection<OpaqueValue<Int>>
-  typealias Subject = LazyDropWhileBidirectionalCollection<Base>
+  typealias Subject = LazyDropWhileCollection<Base>
   expectBidirectionalCollectionAssociatedTypes(
     collectionType: Subject.self,
-    iteratorType: LazyDropWhileIterator<Base.Iterator>.self,
+    iteratorType: LazyDropWhileSequence<Base>.Iterator.self,
     // FIXME(ABI)#83 (Associated Types with where clauses): SubSequence should be `LazyFilterBidirectionalCollection<Base.Slice>`.
     subSequenceType: Slice<Subject>.self,
-    indexType: LazyDropWhileIndex<Base>.self,
+    indexType: LazyDropWhileCollection<Base>.Index.self,
     indicesType: DefaultIndices<Subject>.self)
 }