Merge branch 'master' into remotemirror-hide-reflection-sections
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 31373ee..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
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 5f191ce..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()
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 c4ec76d..e295f3b 100644
--- a/include/swift/IDE/DigesterEnums.def
+++ b/include/swift/IDE/DigesterEnums.def
@@ -92,6 +92,7 @@
 KEY(parentExtensionReqs)
 KEY(hasDefaultArg)
 KEY(conformingProtocols)
+KEY(enumRawTypeName)
 
 KNOWN_TYPE(Optional)
 KNOWN_TYPE(ImplicitlyUnwrappedOptional)
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 b2e4667..3459362 100644
--- a/include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h
+++ b/include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h
@@ -20,6 +20,7 @@
 #ifndef SWIFT_REMOTE_MIRROR_H
 #define SWIFT_REMOTE_MIRROR_H
 
+#include "Platform.h"
 #include "MemoryReaderInterface.h"
 #include "SwiftRemoteMirrorTypes.h"
 
@@ -37,24 +38,26 @@
 #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,
-    uint8_t PointerSize,
-    FreeBytesFunction Free,
-    ReadBytesFunction ReadBytes,
-    GetStringLengthFunction GetStringLength,
-    GetSymbolAddressFunction GetSymbolAddress);
+swift_reflection_createReflectionContext(void *ReaderContext,
+                                         uint8_t PointerSize,
+                                         FreeBytesFunction Free,
+                                         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.
+SWIFT_REMOTE_MIRROR_LINKAGE
 void
 swift_reflection_addReflectionInfo(SwiftReflectionContextRef ContextRef,
                                    swift_reflection_info_t Info);
@@ -62,6 +65,7 @@
 #if defined(__APPLE__) && defined(__MACH__)
 /// Add reflection information from a loaded Swift image.
 /// Returns true on success, false if the image's memory couldn't be read.
+SWIFT_REMOTE_MIRROR_LINKAGE
 int
 swift_reflection_addImage(SwiftReflectionContextRef ContextRef,
                           swift_addr_t imageStart);
@@ -69,9 +73,9 @@
 
 /// 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.
@@ -79,6 +83,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);
@@ -91,10 +96,12 @@
 /// positive if the address in question is not really a Swift or
 /// Objective-C object. If addReflectionInfo is used, the return value
 /// will always be false.
+SWIFT_REMOTE_MIRROR_LINKAGE
 int
 swift_reflection_ownsObject(SwiftReflectionContextRef ContextRef, uintptr_t Object);
 
 /// Returns the metadata pointer for a given object.
+SWIFT_REMOTE_MIRROR_LINKAGE
 uintptr_t
 swift_reflection_metadataForObject(SwiftReflectionContextRef ContextRef,
                                    uintptr_t Object);
@@ -105,11 +112,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,
@@ -117,47 +126,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);
@@ -181,6 +195,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,
@@ -188,17 +203,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);
 
@@ -209,10 +228,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/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 f98e69c..ec0f4c2 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -3342,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/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/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/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/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/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/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/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/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/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index b3e0f75..db252e1 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -425,6 +425,7 @@
         "Hashable",
         "RawRepresentable"
       ],
+      "enumRawTypeName": "Int",
       "children": [
         {
           "kind": "Var",
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index e5576c1..4a21be6 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -328,11 +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;
 
@@ -402,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; }
@@ -421,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; }
@@ -776,13 +780,26 @@
 class SDKNodeTypeDecl : public SDKNodeDecl {
   StringRef SuperclassUsr;
   std::vector<StringRef> ConformingProtocols;
+  StringRef EnumRawTypeName;
 public:
   SDKNodeTypeDecl(SDKNodeInitInfo Info) : SDKNodeDecl(Info, SDKNodeKind::TypeDecl),
                                           SuperclassUsr(Info.SuperclassUsr),
-                                ConformingProtocols(Info.ConformingProtocols){}
+                                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())
       return None;
@@ -956,6 +973,11 @@
       }
       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;
@@ -978,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;
 
@@ -1077,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;
     }
@@ -1238,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,
@@ -1254,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)) {
@@ -1289,6 +1313,15 @@
       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) {
@@ -1670,6 +1703,14 @@
                                         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,
@@ -1685,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)) {
@@ -2250,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);
   }
@@ -3093,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/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 {